Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: automate announcements for pre release #786

Merged
merged 3 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions components/git/security.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import CLI from '../../lib/cli.js';
import SecurityReleaseSteward from '../../lib/prepare_security.js';
import UpdateSecurityRelease from '../../lib/update_security_release.js';
import SecurityBlog from '../../lib/security_blog.js';
import SecurityAnnouncement from '../../lib/security-announcement.js';

export const command = 'security [options]';
export const describe = 'Manage an in-progress security release or start a new one.';
Expand All @@ -26,6 +27,10 @@ const securityOptions = {
'pre-release': {
describe: 'Create the pre-release announcement',
type: 'boolean'
},
'notify-pre-release': {
describe: 'Notify the community about the security release',
type: 'boolean'
}
};

Expand All @@ -52,6 +57,9 @@ export function builder(yargs) {
.example(
'git node security --pre-release' +
'Create the pre-release announcement on the Nodejs.org repo'
).example(
'git node security --notify-pre-release' +
'Notifies the community about the security release'
);
}

Expand All @@ -71,6 +79,9 @@ export function handler(argv) {
if (argv['remove-report']) {
return removeReport(argv);
}
if (argv['notify-pre-release']) {
return notifyPreRelease(argv);
}
yargsInstance.showHelp();
}

Expand Down Expand Up @@ -111,3 +122,10 @@ async function startSecurityRelease() {
const release = new SecurityReleaseSteward(cli);
return release.start();
}

async function notifyPreRelease() {
const logStream = process.stdout.isTTY ? process.stdout : process.stderr;
const cli = new CLI(logStream);
const preRelease = new SecurityAnnouncement(cli);
return preRelease.notifyPreRelease();
}
83 changes: 83 additions & 0 deletions lib/security-announcement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {
NEXT_SECURITY_RELEASE_REPOSITORY,
checkoutOnSecurityReleaseBranch,
getVulnerabilitiesJSON,
validateDate,
formatDateToYYYYMMDD
} from './security-release/security-release.js';
import auth from './auth.js';
import Request from './request.js';

export default class SecurityAnnouncement {
repository = NEXT_SECURITY_RELEASE_REPOSITORY;
req;
constructor(cli) {
this.cli = cli;
}

async notifyPreRelease() {
const { cli } = this;

const credentials = await auth({
github: true,
h1: true
});

this.req = new Request(credentials);

// checkout on security release branch
checkoutOnSecurityReleaseBranch(cli, this.repository);
// read vulnerabilities JSON file
const content = getVulnerabilitiesJSON(cli);
// validate the release date read from vulnerabilities JSON
if (!content.releaseDate) {
cli.error('Release date is not set in vulnerabilities.json,' +
' run `git node security --update-date=YYYY/MM/DD` to set the release date.');
process.exit(1);
}

validateDate(content.releaseDate);
const releaseDate = new Date(content.releaseDate);

await Promise.all([this.createDockerNodeIssue(releaseDate),
this.createBuildWGIssue(releaseDate)]);
}

async createBuildWGIssue(releaseDate) {
const repository = {
owner: 'nodejs',
repo: 'build'
};

const { title, content } = this.createPreleaseAnnouncementIssue(releaseDate);
await this.createIssue(title, content, repository);
}

createPreleaseAnnouncementIssue(releaseDate) {
const title = `[NEXT-SECURITY-RELEASE] Heads up on upcoming Node.js\
security release ${formatDateToYYYYMMDD(releaseDate)}`;
const content = 'As per security release workflow,' +
' creating issue to give docker team a heads up.';
return { title, content };
}

async createDockerNodeIssue(releaseDate) {
const repository = {
owner: 'nodejs',
repo: 'docker-node'
};

const { title, content } = this.createPreleaseAnnouncementIssue(releaseDate);
await this.createIssue(title, content, repository);
}

async createIssue(title, content, repository) {
const data = await this.req.createIssue(title, content, repository);
if (data.html_url) {
this.cli.ok(`Created: ${data.html_url}`);
} else {
this.cli.error(data);
process.exit(1);
}
}
}
10 changes: 10 additions & 0 deletions lib/security-release/security-release.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,13 @@ export function validateDate(releaseDate) {
throw new Error('Invalid date format');
}
}

export function formatDateToYYYYMMDD(date) {
// Get year, month, and day
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are zero-based
const day = String(date.getDate()).padStart(2, '0');

// Concatenate year, month, and day with slashes
return `${year}/${month}/${day}`;
}
Loading