From 75be28233c7ba4270499ed5e6c1e4d340fd1655f Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 17 Dec 2024 15:20:55 +0100 Subject: [PATCH 01/11] tools: validate commit list as part of `lint-release-commit` --- .github/workflows/lint-release-proposal.yml | 50 ++++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index 1ea2b4b1b173e2..a3d6042973c609 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -46,17 +46,53 @@ jobs: [ "$PR_HEAD" = "$GITHUB_SHA" ] env: GH_TOKEN: ${{ github.token }} + - name: Verify it's release-ready + run: | + SKIP_XZ=1 make release-only - name: Validate CHANGELOG id: releaser-info run: | EXPECTED_CHANGELOG_TITLE_INTRO="## $COMMIT_SUBJECT, @" echo "Expected CHANGELOG section title: $EXPECTED_CHANGELOG_TITLE_INTRO" - CHANGELOG_TITLE="$(grep "$EXPECTED_CHANGELOG_TITLE_INTRO" "doc/changelogs/CHANGELOG_V${COMMIT_SUBJECT:20:2}.md")" + CHANGELOG_PATH="doc/changelogs/CHANGELOG_V${COMMIT_SUBJECT:20:2}.md" + CHANGELOG_TITLE="$(grep "$EXPECTED_CHANGELOG_TITLE_INTRO" "$CHANGELOG_PATH")" echo "Actual: $CHANGELOG_TITLE" [ "${CHANGELOG_TITLE%%@*}@" = "$EXPECTED_CHANGELOG_TITLE_INTRO" ] - - name: Verify NODE_VERSION_IS_RELEASE bit is correctly set - run: | - grep -q '^#define NODE_VERSION_IS_RELEASE 1$' src/node_version.h - - name: Check for placeholders in documentation - run: | - ! grep "REPLACEME" doc/api/*.md + MAJOR=$(awk '/^#define NODE_MAJOR_VERSION / { print $3 }' src/node_version.h) + gh api \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + --jq '.commits | map({ smallSha: .sha[0:10], splitTitle: .commit.message|split("\n\n")|first|split(":") })' \ + "176b16a61c7ef3e8c36f9c64c14246d5331c2c53...v23.4.0" --paginate |\ + jq -r '.[] | "* [[`" + .smallSha + "`](https://github.com/nodejs/node/commit/" + .smallSha + ")] - **" + (.splitTitle|first) + "**:" + (.splitTitle[1:]|join(":"))' |\ + node --input-type=module -e ' + import assert from "node:assert"; + import {readFile} from "node:fs/promises"; + import {createInterface} from "node:readline"; + const [,CHANGELOG_PATH, GITHUB_SHA] = process.argv; + const changelog = await readFile(CHANGELOG_PATH, "utf-8"); + const startCommitListing = changelog.indexOf("\n### Commits\n"); + const commitList = changelog.slice(startCommitListing, changelog.indexOf("\n\n Date: Tue, 17 Dec 2024 16:27:01 +0100 Subject: [PATCH 02/11] fixup! tools: validate commit list as part of `lint-release-commit` --- .github/workflows/lint-release-proposal.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index a3d6042973c609..9a87281860e9d0 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -87,7 +87,7 @@ jobs: ); continue; } - + assert(commitList.includes("\n"+line), `Missing "${line}" in commit list`); expectedNumberOfCommitsLeft--; } @@ -95,4 +95,3 @@ jobs: ' "$CHANGELOG_PATH" "$GITHUB_SHA" env: GH_TOKEN: ${{ github.token }} - From 60a0bce1d01f9aa508b8bd5c5a729d05c6b857ac Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 17 Dec 2024 18:04:53 +0100 Subject: [PATCH 03/11] Update .github/workflows/lint-release-proposal.yml --- .github/workflows/lint-release-proposal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index 9a87281860e9d0..a097672c36efb1 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -63,7 +63,7 @@ jobs: -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ --jq '.commits | map({ smallSha: .sha[0:10], splitTitle: .commit.message|split("\n\n")|first|split(":") })' \ - "176b16a61c7ef3e8c36f9c64c14246d5331c2c53...v23.4.0" --paginate |\ + "/repos/${GITHUB_REPOSITORY}/compare/v${MAJOR}.x...$GITHUB_SHA" --paginate |\ jq -r '.[] | "* [[`" + .smallSha + "`](https://github.com/nodejs/node/commit/" + .smallSha + ")] - **" + (.splitTitle|first) + "**:" + (.splitTitle[1:]|join(":"))' |\ node --input-type=module -e ' import assert from "node:assert"; From 5e54f8f7c1f0b527f4dc4a3fe5d4f7abc023fdc1 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 17 Dec 2024 18:06:59 +0100 Subject: [PATCH 04/11] fixup! tools: validate commit list as part of `lint-release-commit` --- .github/workflows/lint-release-proposal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index a097672c36efb1..40c9fa7a9d1bbd 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -54,11 +54,11 @@ jobs: run: | EXPECTED_CHANGELOG_TITLE_INTRO="## $COMMIT_SUBJECT, @" echo "Expected CHANGELOG section title: $EXPECTED_CHANGELOG_TITLE_INTRO" - CHANGELOG_PATH="doc/changelogs/CHANGELOG_V${COMMIT_SUBJECT:20:2}.md" + MAJOR=$(awk '/^#define NODE_MAJOR_VERSION / { print $3 }' src/node_version.h) + CHANGELOG_PATH="doc/changelogs/CHANGELOG_V${MAJOR}.md" CHANGELOG_TITLE="$(grep "$EXPECTED_CHANGELOG_TITLE_INTRO" "$CHANGELOG_PATH")" echo "Actual: $CHANGELOG_TITLE" [ "${CHANGELOG_TITLE%%@*}@" = "$EXPECTED_CHANGELOG_TITLE_INTRO" ] - MAJOR=$(awk '/^#define NODE_MAJOR_VERSION / { print $3 }' src/node_version.h) gh api \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ From 686d5cb3afe68076574345ad0319e0dd13563107 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Wed, 18 Dec 2024 16:15:46 +0100 Subject: [PATCH 05/11] minor fixes and improvements --- .github/workflows/lint-release-proposal.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index 40c9fa7a9d1bbd..767559532b385e 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -33,13 +33,12 @@ jobs: echo "COMMIT_SUBJECT=$COMMIT_SUBJECT" >> "$GITHUB_ENV" - name: Lint release commit message trailers run: | - EXPECTED_TRAILER="^PR-URL: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/pull/[[:digit:]]+\$" + EXPECTED_TRAILER="^$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/pull/[[:digit:]]+\$" echo "Expected trailer format: $EXPECTED_TRAILER" - ACTUAL="$(git --no-pager log -1 --format=%b | git interpret-trailers --parse --no-divider)" + PR_URL=$(git --no-pager log -1 --format='%(trailers:key=PR-URL,valueonly)') echo "Actual: $ACTUAL" - echo "$ACTUAL" | grep -E -q "$EXPECTED_TRAILER" + echo "$PR_URL" | grep -E -q "$EXPECTED_TRAILER" - PR_URL="${ACTUAL:8}" PR_HEAD="$(gh pr view "$PR_URL" --json headRefOid -q .headRefOid)" echo "Head of $PR_URL: $PR_HEAD" echo "Current commit: $GITHUB_SHA" @@ -64,11 +63,12 @@ jobs: -H "X-GitHub-Api-Version: 2022-11-28" \ --jq '.commits | map({ smallSha: .sha[0:10], splitTitle: .commit.message|split("\n\n")|first|split(":") })' \ "/repos/${GITHUB_REPOSITORY}/compare/v${MAJOR}.x...$GITHUB_SHA" --paginate |\ - jq -r '.[] | "* [[`" + .smallSha + "`](https://github.com/nodejs/node/commit/" + .smallSha + ")] - **" + (.splitTitle|first) + "**:" + (.splitTitle[1:]|join(":"))' |\ + jq -r '.[] | "* [[`" + .smallSha + "`](" + env.GITHUB_SERVER_URL + "/" + env.GITHUB_REPOSITORY + "/commit/" + .smallSha + ")] - **" + (.splitTitle|first) + "**:" + (.splitTitle[1:]|join(":"))' |\ node --input-type=module -e ' import assert from "node:assert"; import {readFile} from "node:fs/promises"; import {createInterface} from "node:readline"; + const stdinLineByLine = createInterface(process.stdin)[Symbol.asyncIterator](); const [,CHANGELOG_PATH, GITHUB_SHA] = process.argv; const changelog = await readFile(CHANGELOG_PATH, "utf-8"); const startCommitListing = changelog.indexOf("\n### Commits\n"); @@ -79,7 +79,7 @@ jobs: .replaceAll("\\", ""); let expectedNumberOfCommitsLeft = commitList.match(/\n\* \[/g).length; - for await (const line of createInterface(process.stdin)) { + for await (const line of stdinLineByLine) { if (line.includes(GITHUB_SHA.slice(0, 10))) { assert.strictEqual( expectedNumberOfCommitsLeft, 0, From d69f02752cabaf375f0a086d2878d66995492da8 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Wed, 18 Dec 2024 22:17:32 +0100 Subject: [PATCH 06/11] move JS to a separate file --- .github/workflows/lint-release-proposal.yml | 34 ++----------------- .../lint-release-proposal-commit-list.mjs | 33 ++++++++++++++++++ 2 files changed, 36 insertions(+), 31 deletions(-) create mode 100755 tools/actions/lint-release-proposal-commit-list.mjs diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index 767559532b385e..2a46051664b061 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -35,7 +35,7 @@ jobs: run: | EXPECTED_TRAILER="^$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/pull/[[:digit:]]+\$" echo "Expected trailer format: $EXPECTED_TRAILER" - PR_URL=$(git --no-pager log -1 --format='%(trailers:key=PR-URL,valueonly)') + PR_URL="$(git --no-pager log -1 --format='%(trailers:key=PR-URL,valueonly)')" echo "Actual: $ACTUAL" echo "$PR_URL" | grep -E -q "$EXPECTED_TRAILER" @@ -53,7 +53,7 @@ jobs: run: | EXPECTED_CHANGELOG_TITLE_INTRO="## $COMMIT_SUBJECT, @" echo "Expected CHANGELOG section title: $EXPECTED_CHANGELOG_TITLE_INTRO" - MAJOR=$(awk '/^#define NODE_MAJOR_VERSION / { print $3 }' src/node_version.h) + MAJOR="$(awk '/^#define NODE_MAJOR_VERSION / { print $3 }' src/node_version.h)" CHANGELOG_PATH="doc/changelogs/CHANGELOG_V${MAJOR}.md" CHANGELOG_TITLE="$(grep "$EXPECTED_CHANGELOG_TITLE_INTRO" "$CHANGELOG_PATH")" echo "Actual: $CHANGELOG_TITLE" @@ -64,34 +64,6 @@ jobs: --jq '.commits | map({ smallSha: .sha[0:10], splitTitle: .commit.message|split("\n\n")|first|split(":") })' \ "/repos/${GITHUB_REPOSITORY}/compare/v${MAJOR}.x...$GITHUB_SHA" --paginate |\ jq -r '.[] | "* [[`" + .smallSha + "`](" + env.GITHUB_SERVER_URL + "/" + env.GITHUB_REPOSITORY + "/commit/" + .smallSha + ")] - **" + (.splitTitle|first) + "**:" + (.splitTitle[1:]|join(":"))' |\ - node --input-type=module -e ' - import assert from "node:assert"; - import {readFile} from "node:fs/promises"; - import {createInterface} from "node:readline"; - const stdinLineByLine = createInterface(process.stdin)[Symbol.asyncIterator](); - const [,CHANGELOG_PATH, GITHUB_SHA] = process.argv; - const changelog = await readFile(CHANGELOG_PATH, "utf-8"); - const startCommitListing = changelog.indexOf("\n### Commits\n"); - const commitList = changelog.slice(startCommitListing, changelog.indexOf("\n\n Date: Wed, 18 Dec 2024 22:57:24 +0100 Subject: [PATCH 07/11] fix for revert commits --- tools/actions/lint-release-proposal-commit-list.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/actions/lint-release-proposal-commit-list.mjs b/tools/actions/lint-release-proposal-commit-list.mjs index f6a6803d3cfd0c..493f346f054cd6 100755 --- a/tools/actions/lint-release-proposal-commit-list.mjs +++ b/tools/actions/lint-release-proposal-commit-list.mjs @@ -27,7 +27,10 @@ for await (const line of stdinLineByLine) { continue; } - assert(commitList.includes('\n' + line), `Missing "${line}" in commit list`); + // Revert commit have a special treatment. + const fixedLine = line.replace(' - **Revert \"', ' - _**Revert**_ "**'); + + assert(commitList.includes('\n' + fixedLine), `Missing "${fixedLine}" in commit list`); expectedNumberOfCommitsLeft--; } assert.strictEqual(expectedNumberOfCommitsLeft, 0, 'Release commit is not the last commit in the proposal'); From e8bb005e4428139d9a24f7bb8335b58fa81cf28d Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Thu, 19 Dec 2024 17:52:07 +0100 Subject: [PATCH 08/11] add validation for dont-land labels --- .github/workflows/lint-release-proposal.yml | 14 +++++-- .../lint-release-proposal-commit-list.mjs | 39 +++++++++++++++---- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index 2a46051664b061..221e81627a8de5 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -61,9 +61,15 @@ jobs: gh api \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - --jq '.commits | map({ smallSha: .sha[0:10], splitTitle: .commit.message|split("\n\n")|first|split(":") })' \ - "/repos/${GITHUB_REPOSITORY}/compare/v${MAJOR}.x...$GITHUB_SHA" --paginate |\ - jq -r '.[] | "* [[`" + .smallSha + "`](" + env.GITHUB_SERVER_URL + "/" + env.GITHUB_REPOSITORY + "/commit/" + .smallSha + ")] - **" + (.splitTitle|first) + "**:" + (.splitTitle[1:]|join(":"))' |\ - node tools/actions/lint-release-proposal-commit-list.mjs "$CHANGELOG_PATH" "$GITHUB_SHA" + --jq '.commits.[] | { smallSha: .sha[0:10], splitTitle: .commit.message|split("\n\n")|first|split(":") } + (.commit.message|capture("\nPR-URL: (?.+)\n"))' \ + "/repos/${GITHUB_REPOSITORY}/compare/v${MAJOR}.x...$GITHUB_SHA" --paginate \ + | node tools/actions/lint-release-proposal-commit-list.mjs "$CHANGELOG_PATH" "$GITHUB_SHA" \ + | while IFS= read -r PR_URL; do + LABEL="dont-land-on-v${MAJOR}.x" gh pr view \ + --json labels,url \ + --jq 'if (.labels|map(.name==env.LABEL)|any) then error("\(.url) has the \(env.LABEL) label, forbidding it to be in this release proposal") end' \ + "$PR_URL" > /dev/null + done + shell: bash # See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference, we want the pipefail option env: GH_TOKEN: ${{ github.token }} diff --git a/tools/actions/lint-release-proposal-commit-list.mjs b/tools/actions/lint-release-proposal-commit-list.mjs index 493f346f054cd6..74ec4b91f60a8b 100755 --- a/tools/actions/lint-release-proposal-commit-list.mjs +++ b/tools/actions/lint-release-proposal-commit-list.mjs @@ -1,17 +1,26 @@ #!/usr/bin/env node +// Takes a stream of JSON objects as inputs, validates the CHANGELOG contains a +// line corresponding, then outputs the prURL value. +// +// $ ./lint-release-proposal-commit-list.mjs "path/to/CHANGELOG.md" "deadbeef00" <<'EOF' +// {"prURL":"https://github.com/nodejs/node/pull/56131","smallSha":"d48b5224c0","splitTitle":["doc"," fix module.md headings"]} +// {"prURL":"https://github.com/nodejs/node/pull/56123","smallSha":"f1c2d2f65e","splitTitle":["doc"," update blog release-post link"]} +// EOF + const [,, CHANGELOG_PATH, RELEASE_COMMIT_SHA] = process.argv; import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import { createInterface } from 'node:readline'; -// Creating the iterator early to avoid missing any data +// Creating the iterator early to avoid missing any data: const stdinLineByLine = createInterface(process.stdin)[Symbol.asyncIterator](); const changelog = await readFile(CHANGELOG_PATH, 'utf-8'); -const startCommitListing = changelog.indexOf('\n### Commits\n'); -const commitList = changelog.slice(startCommitListing, changelog.indexOf('\n\n lineStart, `Commit title doesn't match`); + } catch (e) { + if (e?.code === 'ERR_ASSERTION') { + e.operator = 'includes'; + e.expected = expectedCommitTitle; + e.actual = commitList.slice(lineStart + 1, lineEnd); + } + throw e; + } + assert.strictEqual(commitList.slice(lineEnd - prURL.length - 2, lineEnd), `(${prURL})`); - assert(commitList.includes('\n' + fixedLine), `Missing "${fixedLine}" in commit list`); expectedNumberOfCommitsLeft--; + console.log(prURL); } assert.strictEqual(expectedNumberOfCommitsLeft, 0, 'Release commit is not the last commit in the proposal'); From 6022db50ea1acd76a48cf03e36a909bc762bee56 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Thu, 19 Dec 2024 17:58:56 +0100 Subject: [PATCH 09/11] fixup! add validation for dont-land labels --- .github/workflows/lint-release-proposal.yml | 2 +- tools/actions/lint-release-proposal-commit-list.mjs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index 221e81627a8de5..35646b76f96016 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -70,6 +70,6 @@ jobs: --jq 'if (.labels|map(.name==env.LABEL)|any) then error("\(.url) has the \(env.LABEL) label, forbidding it to be in this release proposal") end' \ "$PR_URL" > /dev/null done - shell: bash # See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference, we want the pipefail option + shell: bash # See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference, we want the pipefail option. env: GH_TOKEN: ${{ github.token }} diff --git a/tools/actions/lint-release-proposal-commit-list.mjs b/tools/actions/lint-release-proposal-commit-list.mjs index 74ec4b91f60a8b..3f3aad379529cc 100755 --- a/tools/actions/lint-release-proposal-commit-list.mjs +++ b/tools/actions/lint-release-proposal-commit-list.mjs @@ -38,11 +38,11 @@ for await (const line of stdinLineByLine) { continue; } - const lineStart = commitList.indexOf(`\n* \[[\`${smallSha}\`]`); + const lineStart = commitList.indexOf(`\n* [[\`${smallSha}\`]`); assert.notStrictEqual(lineStart, -1, `Cannot find ${smallSha} on the list`); const lineEnd = commitList.indexOf('\n', lineStart + 1); - const expectedCommitTitle = `${`**${splitTitle.shift()}`.replace('**Revert \"', '_**Revert**_ "**')}**:${splitTitle.join(':')}`; + const expectedCommitTitle = `${`**${splitTitle.shift()}`.replace('**Revert "', '_**Revert**_ "**')}**:${splitTitle.join(':')}`; try { assert(commitList.lastIndexOf(`/${smallSha})] - ${expectedCommitTitle} (`, lineEnd) > lineStart, `Commit title doesn't match`); } catch (e) { From 2ec8cbd4602102f88d17fc3bd6af7c4f2bef5fc8 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Thu, 19 Dec 2024 19:43:49 +0100 Subject: [PATCH 10/11] use a format of input somewhat compatible with `git log` --- .github/workflows/lint-release-proposal.yml | 2 +- tools/actions/lint-release-proposal-commit-list.mjs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index 35646b76f96016..ecda2b616c0d02 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -61,7 +61,7 @@ jobs: gh api \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - --jq '.commits.[] | { smallSha: .sha[0:10], splitTitle: .commit.message|split("\n\n")|first|split(":") } + (.commit.message|capture("\nPR-URL: (?.+)\n"))' \ + --jq '.commits.[] | { smallSha: .sha[0:10] } + (.commit.message|capture("^(?.+)\n\n(.*\n)*PR-URL: (?<prURL>.+)\n"))' \ "/repos/${GITHUB_REPOSITORY}/compare/v${MAJOR}.x...$GITHUB_SHA" --paginate \ | node tools/actions/lint-release-proposal-commit-list.mjs "$CHANGELOG_PATH" "$GITHUB_SHA" \ | while IFS= read -r PR_URL; do diff --git a/tools/actions/lint-release-proposal-commit-list.mjs b/tools/actions/lint-release-proposal-commit-list.mjs index 3f3aad379529cc..e4cb04cf3225dc 100755 --- a/tools/actions/lint-release-proposal-commit-list.mjs +++ b/tools/actions/lint-release-proposal-commit-list.mjs @@ -3,10 +3,10 @@ // Takes a stream of JSON objects as inputs, validates the CHANGELOG contains a // line corresponding, then outputs the prURL value. // -// $ ./lint-release-proposal-commit-list.mjs "path/to/CHANGELOG.md" "deadbeef00" <<'EOF' -// {"prURL":"https://github.com/nodejs/node/pull/56131","smallSha":"d48b5224c0","splitTitle":["doc"," fix module.md headings"]} -// {"prURL":"https://github.com/nodejs/node/pull/56123","smallSha":"f1c2d2f65e","splitTitle":["doc"," update blog release-post link"]} -// EOF +// Example: +// $ git log upstream/vXX.x...upstream/vX.X.X-proposal \ +// --format='{"prURL":"%(trailers:key=PR-URL,valueonly,separator=)","title":"%s","smallSha":"%h"}' \ +// | ./lint-release-proposal-commit-list.mjs "path/to/CHANGELOG.md" "$(git rev-parse upstream/vX.X.X-proposal)" const [,, CHANGELOG_PATH, RELEASE_COMMIT_SHA] = process.argv; @@ -28,7 +28,7 @@ const commitList = changelog.slice(commitListingStart, commitListingEnd === -1 ? let expectedNumberOfCommitsLeft = commitList.match(/\n\* \[/g).length; for await (const line of stdinLineByLine) { - const { smallSha, splitTitle, prURL } = JSON.parse(line); + const { smallSha, title, prURL } = JSON.parse(line); if (smallSha === RELEASE_COMMIT_SHA.slice(0, 10)) { assert.strictEqual( @@ -42,7 +42,8 @@ for await (const line of stdinLineByLine) { assert.notStrictEqual(lineStart, -1, `Cannot find ${smallSha} on the list`); const lineEnd = commitList.indexOf('\n', lineStart + 1); - const expectedCommitTitle = `${`**${splitTitle.shift()}`.replace('**Revert "', '_**Revert**_ "**')}**:${splitTitle.join(':')}`; + const colonIndex = title.indexOf(':'); + const expectedCommitTitle = `${`**${title.slice(0, colonIndex)}`.replace('**Revert "', '_**Revert**_ "**')}**${title.slice(colonIndex)}`; try { assert(commitList.lastIndexOf(`/${smallSha})] - ${expectedCommitTitle} (`, lineEnd) > lineStart, `Commit title doesn't match`); } catch (e) { From ba114e961927a5304277223c07ba278e2d790d67 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel <duhamelantoine1995@gmail.com> Date: Sat, 21 Dec 2024 01:01:39 +0100 Subject: [PATCH 11/11] add error message to help with debugging --- tools/actions/lint-release-proposal-commit-list.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/actions/lint-release-proposal-commit-list.mjs b/tools/actions/lint-release-proposal-commit-list.mjs index e4cb04cf3225dc..b9745bad3c30c1 100755 --- a/tools/actions/lint-release-proposal-commit-list.mjs +++ b/tools/actions/lint-release-proposal-commit-list.mjs @@ -54,7 +54,7 @@ for await (const line of stdinLineByLine) { } throw e; } - assert.strictEqual(commitList.slice(lineEnd - prURL.length - 2, lineEnd), `(${prURL})`); + assert.strictEqual(commitList.slice(lineEnd - prURL.length - 2, lineEnd), `(${prURL})`, `when checking ${smallSha} ${title}`); expectedNumberOfCommitsLeft--; console.log(prURL);