From 71407b82cb679700ef2f01792889abfbd9ca8c79 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Tue, 19 Mar 2024 12:13:37 -0700 Subject: [PATCH 1/5] Simplify PR requirements while allowing changelog script to apply to any standalone plugin. --- .github/ISSUE_TEMPLATE/trac_ticket.md | 4 +- .github/PULL_REQUEST_TEMPLATE.md | 4 +- .github/workflows/pr-validation.yml | 6 -- bin/plugin/commands/changelog.js | 119 ++++++++------------------ 4 files changed, 37 insertions(+), 96 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/trac_ticket.md b/.github/ISSUE_TEMPLATE/trac_ticket.md index 85107816b3..30a5b02269 100644 --- a/.github/ISSUE_TEMPLATE/trac_ticket.md +++ b/.github/ISSUE_TEMPLATE/trac_ticket.md @@ -7,9 +7,7 @@ labels: [ "Trac Ticket", "WP Core" ] --- Trac ticket: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index de9cd6f5bc..adfdd22e52 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,7 +12,7 @@ Fixes # diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index f344e7c823..6cd330de83 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -24,12 +24,6 @@ jobs: steps: - if: contains( env.LABELS, '[Type]' ) == false run: exit 1 - check-focus-label: - name: Check [Focus] Label - runs-on: ubuntu-latest - steps: - - if: contains( env.LABELS, '[Focus]' ) == false && contains( env.LABELS, 'Infrastructure' ) == false - run: exit 1 check-milestone: name: Check Milestone runs-on: ubuntu-latest diff --git a/bin/plugin/commands/changelog.js b/bin/plugin/commands/changelog.js index 599534050f..4d7f7af111 100644 --- a/bin/plugin/commands/changelog.js +++ b/bin/plugin/commands/changelog.js @@ -15,16 +15,14 @@ const { const config = require( '../config' ); const MISSING_TYPE = 'MISSING_TYPE'; -const MISSING_FOCUS = 'MISSING_FOCUS'; const TYPE_PREFIX = '[Type] '; -const FOCUS_PREFIX = '[Focus] '; -const INFRASTRUCTURE_LABEL = 'Infrastructure'; const PRIMARY_TYPE_LABELS = { '[Type] Feature': 'Features', '[Type] Enhancement': 'Enhancements', '[Type] Bug': 'Bug Fixes', }; const PRIMARY_TYPE_ORDER = Object.values( PRIMARY_TYPE_LABELS ); +const SKIP_CHANGELOG_LABEL = 'skip changelog'; /** @typedef {import('@octokit/rest')} GitHub */ /** @typedef {import('@octokit/rest').IssuesListForRepoResponseItem} IssuesListForRepoResponseItem */ @@ -102,7 +100,11 @@ async function fetchAllPullRequests( octokit, settings ) { milestone.number, 'closed' ); - return issues.filter( ( issue ) => issue.pull_request ); + + // Return all pull requests except those with the SKIP_CHANGELOG_LABEL. + return issues.filter( + ( issue ) => issue.pull_request && ! issue.labels.find( ( { name } ) => name === SKIP_CHANGELOG_LABEL ) + ); } /** @@ -129,30 +131,6 @@ function getIssueType( issue ) { return typeLabels[ 0 ].replace( TYPE_PREFIX, '' ); } -/** - * Returns a focus label for a given issue object, or MISSING_FOCUS if focus - * cannot be determined. - * - * @param {IssuesListForRepoResponseItem} issue Issue object. - * - * @return {string} Focus label, or MISSING_FOCUS. - */ -function getIssueFocus( issue ) { - const labelNames = issue.labels.map( ( { name } ) => name ); - const focusLabels = labelNames.filter( ( label ) => - label.startsWith( FOCUS_PREFIX ) - ); - - if ( ! focusLabels.length ) { - if ( labelNames.includes( INFRASTRUCTURE_LABEL ) ) { - return INFRASTRUCTURE_LABEL; - } - return MISSING_FOCUS; - } - - return focusLabels[ 0 ].replace( FOCUS_PREFIX, '' ); -} - /** * Formats the changelog string for a given list of pull requests. * @@ -162,7 +140,14 @@ function getIssueFocus( issue ) { * @return {string} The formatted changelog string. */ function formatChangelog( milestone, pullRequests ) { - let changelog = '= ' + milestone.replace( 'PL Plugin ', '' ) + ' =\n\n'; + const version = milestone.match( /\d+\.\d+(\.\d+)?(-[A-Za-z0-9\.]+)?/ ); + if ( ! version ) { + throw new Error( + `The ${ milestone } milestone does not include a version number.` + ); + } + + let changelog = '= ' + version[ 0 ] + ' =\n\n'; // Group PRs by type. const typeGroups = groupBy( pullRequests, getIssueType ); @@ -194,62 +179,26 @@ function formatChangelog( milestone, pullRequests ) { // Start a new section within the changelog. changelog += '**' + group + '**\n\n'; - // Group PRs within this section per focus. - const focusGroups = groupBy( typeGroups[ group ], getIssueFocus ); - if ( focusGroups[ MISSING_FOCUS ] ) { - const prURLs = focusGroups[ MISSING_FOCUS ].map( - ( { html_url } ) => html_url // eslint-disable-line camelcase - ); - throw new Error( - `The following pull-requests are missing a "${ FOCUS_PREFIX }xyz" or "${ INFRASTRUCTURE_LABEL }" label: ${ prURLs.join( - ', ' - ) }` - ); - } - - // Sort focuses alphabetically, except infrastructure which comes last. - const focusGroupNames = Object.keys( focusGroups ).sort( ( a, b ) => { - if ( - ( a !== INFRASTRUCTURE_LABEL && b !== INFRASTRUCTURE_LABEL ) || - a === b - ) { - return a - b; - } - return a !== INFRASTRUCTURE_LABEL ? -1 : 1; - } ); - - // Output all PRs within this section. - focusGroupNames.forEach( ( featureName ) => { - const focusGroupPRs = focusGroups[ featureName ]; - - focusGroupPRs - .map( ( issue ) => { - const title = issue.title - // Strip feature name from title if used as prefix. - .replace( - new RegExp( - `^${ featureName.toLowerCase() }: `, - 'i' - ), - '' - ) - // Strip trailing whitespace. - .trim() - // Ensure first letter is uppercase. - .replace( /^([a-z])/, ( _match, firstLetter ) => - firstLetter.toUpperCase() - ) - // Add trailing period. - .replace( /\s*\.?$/, '' ) - .concat( '.' ); - return `* ${ featureName }: ${ title } ([${ issue.number }](${ issue.html_url }))`; // eslint-disable-line camelcase - } ) - .filter( Boolean ) - .sort() - .forEach( ( entry ) => { - changelog += `${ entry }\n`; - } ); - } ); + const typeGroupPRs = typeGroups[ group ]; + typeGroupPRs + .map( ( issue ) => { + const title = issue.title + // Strip trailing whitespace. + .trim() + // Ensure first letter is uppercase. + .replace( /^([a-z])/, ( _match, firstLetter ) => + firstLetter.toUpperCase() + ) + // Add trailing period. + .replace( /\s*\.?$/, '' ) + .concat( '.' ); + return `* ${ title } ([${ issue.number }](${ issue.html_url }))`; // eslint-disable-line camelcase + } ) + .filter( Boolean ) + .sort() + .forEach( ( entry ) => { + changelog += `${ entry }\n`; + } ); changelog += '\n'; } From 75d30eca4353a94f0e22f6dace6c5891d48d3c2b Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Tue, 19 Mar 2024 12:27:31 -0700 Subject: [PATCH 2/5] Fix Prettier. --- bin/plugin/commands/changelog.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/plugin/commands/changelog.js b/bin/plugin/commands/changelog.js index 4d7f7af111..5ff8fe95b6 100644 --- a/bin/plugin/commands/changelog.js +++ b/bin/plugin/commands/changelog.js @@ -103,7 +103,9 @@ async function fetchAllPullRequests( octokit, settings ) { // Return all pull requests except those with the SKIP_CHANGELOG_LABEL. return issues.filter( - ( issue ) => issue.pull_request && ! issue.labels.find( ( { name } ) => name === SKIP_CHANGELOG_LABEL ) + ( issue ) => + issue.pull_request && + ! issue.labels.find( ( { name } ) => name === SKIP_CHANGELOG_LABEL ) ); } From 44269955f08bc1217f6e9e5de170c4e529e3794a Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Wed, 20 Mar 2024 10:42:41 -0700 Subject: [PATCH 3/5] Fix wording. Co-authored-by: Weston Ruter --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index adfdd22e52..0ee8d94f78 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -13,6 +13,6 @@ Fixes # For maintainers only, please make sure: - PR has a `[Type]` label. -- PR has a plugin specific milestone, or the `no milestone` label if it does not apply to any specific plugin. -- PR has a changelog friendly title, or the `skip changelog` label if it should not be mentioned in the plugin's changelog. +- PR has a plugin-specific milestone, or the `no milestone` label if it does not apply to any specific plugin. +- PR has a changelog-friendly title, or the `skip changelog` label if it should not be mentioned in the plugin's changelog. --> From a71bdac60ad5f0738ab1c44beec9bec580344fbf Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Wed, 20 Mar 2024 10:43:41 -0700 Subject: [PATCH 4/5] Harden version regex to ensure version is at the end. Co-authored-by: Weston Ruter --- bin/plugin/commands/changelog.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/plugin/commands/changelog.js b/bin/plugin/commands/changelog.js index 5ff8fe95b6..cf8d7794e0 100644 --- a/bin/plugin/commands/changelog.js +++ b/bin/plugin/commands/changelog.js @@ -142,10 +142,10 @@ function getIssueType( issue ) { * @return {string} The formatted changelog string. */ function formatChangelog( milestone, pullRequests ) { - const version = milestone.match( /\d+\.\d+(\.\d+)?(-[A-Za-z0-9\.]+)?/ ); + const version = milestone.match( /\d+\.\d+(\.\d+)?(-[A-Za-z0-9\.]+)?$/ ); if ( ! version ) { throw new Error( - `The ${ milestone } milestone does not include a version number.` + `The ${ milestone } milestone does not end with a version number.` ); } From 213d63a80fc6b7fd6afa9887212f15ffd0bc6127 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Wed, 20 Mar 2024 13:21:21 -0700 Subject: [PATCH 5/5] Avoid unnecessary regex escaping. Co-authored-by: Weston Ruter --- bin/plugin/commands/changelog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/plugin/commands/changelog.js b/bin/plugin/commands/changelog.js index cf8d7794e0..d651a45dc7 100644 --- a/bin/plugin/commands/changelog.js +++ b/bin/plugin/commands/changelog.js @@ -142,7 +142,7 @@ function getIssueType( issue ) { * @return {string} The formatted changelog string. */ function formatChangelog( milestone, pullRequests ) { - const version = milestone.match( /\d+\.\d+(\.\d+)?(-[A-Za-z0-9\.]+)?$/ ); + const version = milestone.match( /\d+\.\d+(\.\d+)?(-[A-Za-z0-9.]+)?$/ ); if ( ! version ) { throw new Error( `The ${ milestone } milestone does not end with a version number.`