FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat: check for reports without PR_URL on H1 by RafaelGSS · Pull Request #1074 · nodejs/node-core-utils · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .js  (2) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
8 changes: 8 additions & 0 deletions lib/cli.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ export default class CLI {
return answer;
}

async promptCheckbox(message, choices) {
if (this.assumeYes) {
return choices.filter((c) => c.checked).map((c) => c.value);
}

return inquirer.checkbox({ message, choices });
}

setAssumeYes() {
this.assumeYes = true;
}
Expand Down
68 changes: 64 additions & 4 deletions lib/prepare_security.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,19 @@ import {
validateDate,
promptDependencies,
getSupportedVersions,
getReportSeverity,
pickReport,
SecurityRelease
} from './security-release/security-release.js';
import _ from 'lodash';

function relativeDate(date) {
const days = Math.floor((Date.now() - date) / (1000 * 60 * 60 * 24));
if (days < 30) return days === 1 ? '1 day ago' : `${days} days ago`;
const months = Math.floor(days / 30);
return months === 1 ? '1 month ago' : `${months} months ago`;
}

export default class PrepareSecurityRelease extends SecurityRelease {
title = 'Next Security Release';

Expand All @@ -25,6 +33,13 @@ export default class PrepareSecurityRelease extends SecurityRelease {
});

this.req = new Request(credentials);

let excludedReports = [];
const showTriaged = await this.promptShowTriagedWithoutPR();
if (showTriaged) {
excludedReports = await this.showTriagedReportsWithoutPR();
}

const releaseDate = await this.promptReleaseDate();
if (releaseDate !== 'TBD') {
validateDate(releaseDate);
Expand All @@ -34,7 +49,8 @@ export default class PrepareSecurityRelease extends SecurityRelease {
let securityReleasePRUrl;
const content = await this.buildDescription(releaseDate, securityReleasePRUrl);
if (createVulnerabilitiesJSON) {
securityReleasePRUrl = await this.startVulnerabilitiesJSONCreation(releaseDate, content);
securityReleasePRUrl = await this.startVulnerabilitiesJSONCreation(
releaseDate, content, excludedReports);
}

this.cli.ok('Done!');
Expand Down Expand Up @@ -93,12 +109,12 @@ export default class PrepareSecurityRelease extends SecurityRelease {
this.cli.ok('Done!');
}

async startVulnerabilitiesJSONCreation(releaseDate, content) {
async startVulnerabilitiesJSONCreation(releaseDate, content, excludedReports = []) {
// checkout on the next-security-release branch
checkoutOnSecurityReleaseBranch(this.cli, this.repository);

// choose the reports to include in the security release
const reports = await this.chooseReports();
const reports = await this.chooseReports(excludedReports);
const depUpdates = await this.getDependencyUpdates();
const deps = _.groupBy(depUpdates, 'name');

Expand Down Expand Up @@ -184,17 +200,61 @@ export default class PrepareSecurityRelease extends SecurityRelease {
{ defaultAnswer: true });
}

async promptShowTriagedWithoutPR() {
return this.cli.prompt(
'Do you want to see which reports are triaged but have no PR URL?',
{ defaultAnswer: true });
}

async showTriagedReportsWithoutPR() {
this.cli.info('Fetching triaged reports without PR URL...');
const reports = await this.req.getTriagedReports();
const reportsWithoutPR = reports.data.filter(
(report) => !report.relationships.custom_field_values.data.length
);
if (!reportsWithoutPR.length) {
this.cli.ok('All triaged reports have a PR URL.');
return [];
}
const severityRank = { critical: 0, high: 1, medium: 2, low: 3 };
const choices = reportsWithoutPR
.sort((a, b) => {
const dateA = new Date(a.attributes.created_at);
const dateB = new Date(b.attributes.created_at);
if (dateB - dateA !== 0) return dateB - dateA;
const rankA = severityRank[getReportSeverity(a).rating] ?? 4;
const rankB = severityRank[getReportSeverity(b).rating] ?? 4;
return rankA - rankB;
})
.map((report) => {
const { id, attributes: { title, created_at } } = report;
const { rating } = getReportSeverity(report);
const openedDate = relativeDate(new Date(created_at));
const link = `https://hackerone.com/reports/${id}`;
return {
name: `[${openedDate}] (${rating}) ${title} - ${link}`,
value: id,
checked: true
};
});
return this.cli.promptCheckbox(
'Select reports to exclude from the upcoming security release:',
choices
);
}

async buildDescription() {
const template = await this.getSecurityIssueTemplate();
return template;
}

async chooseReports() {
async chooseReports(excludedReports = []) {
this.cli.info('Getting triaged H1 reports...');
const reports = await this.req.getTriagedReports();
const selectedReports = [];

for (const report of reports.data) {
if (excludedReports.includes(report.id)) continue;
const rep = await pickReport(report, { cli: this.cli, req: this.req });
if (!rep) continue;
selectedReports.push(rep);
Expand Down
Loading

Back | FazBrowse Home | New Git URL