Repository: nodejs/node
Pull request: tools: improve release proposal linter

- Add an annotation on the line that's causing the linter to fail (if applicable)
- Do not exit the program on the first error (in case there are several errors)
- Improve some error messages

<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: tools/actions/lint-release-proposal-commit-list.mjs
patch: @@ -5,7 +5,8 @@
 //
 // Example:
 // $ git log upstream/vXX.x...upstream/vX.X.X-proposal \
-//     --format='{"prURL":"%(trailers:key=PR-URL,valueonly,separator=)","title":"%s","smallSha":"%h"}' \
+//     --reverse --format='{"prURL":"%(trailers:key=PR-URL,valueonly,separator=)","title":"%s","smallSha":"%h"}' \
+//   | sed 's/,"title":"Revert "\([^"]\+\)""/,"title":"Revert \\"\1\\""/g' \
 //   | ./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;
@@ -52,20 +53,33 @@ for await (const line of stdinLineByLine) {
   assert.notStrictEqual(lineStart, -1, `Cannot find ${smallSha} on the list`);
   const lineEnd = commitList.indexOf('\n', lineStart + 1);
 
-  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`);
+    const colonIndex = title.indexOf(':');
+    const expectedCommitTitle = `${`**${title.slice(0, colonIndex)}`.replace('**Revert "', '_**Revert**_ "**')}**${title.slice(colonIndex)}`;
+    try {
+      assert(commitList.lastIndexOf(`/${smallSha})] - ${expectedCommitTitle} (`, lineEnd) > lineStart, `Changelog entry doesn't match for ${smallSha}`);
+    } 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})`, `when checking ${smallSha} ${title}`);
+
   } catch (e) {
-    if (e?.code === 'ERR_ASSERTION') {
-      e.operator = 'includes';
-      e.expected = expectedCommitTitle;
-      e.actual = commitList.slice(lineStart + 1, lineEnd);
+    if (e?.code !== 'ERR_ASSERTION') {
+      throw e;
     }
-    throw e;
+    let line = 1;
+    for (let i = 0; i < lineStart + commitListingStart; i = changelog.indexOf('\n', i + 1)) {
+      line++;
+    }
+    console.error(`::error file=${CHANGELOG_PATH},line=${line},title=Release proposal linter::${e.message}`);
+    console.error(e);
+    process.exitCode ||= 1;
   }
-  assert.strictEqual(commitList.slice(lineEnd - prURL.length - 2, lineEnd), `(${prURL})`, `when checking ${smallSha} ${title}`);
-
   expectedNumberOfCommitsLeft--;
   console.log(prURL);
 }