From a00348bee49be2cdcb44fc6ab29180c9992b6a79 Mon Sep 17 00:00:00 2001 From: "sasjs-dev[bot]" Date: Mon, 5 Oct 2026 22:43:24 +0000 Subject: [PATCH 1/3] fix(ci): widen the marker check to the filters it guards The subject-only check caught the release marker and the ci marker, but missed their upper-case forms, the reversed word order, and the four GitHub forms - ci-skip, no-ci, skip-actions and actions-skip - which suppress a run just as completely. Both upstream filters are case-insensitive and accept any run of whitespace, so the pattern now mirrors them. This matters because both act on the WHOLE squashed commit rather than on the one commit carrying the marker: the release tooling drops any commit whose message matches, and GitHub skips the push-triggered workflow outright. Either one silently suppresses the release for the entire PR. Not hypothetical - it happened here. #274 carried two chore(ci) subjects with the release marker, so the squashed commit on main was filtered out whole, the crypto fix merged, and no version was published. The pattern uses a POSIX character class rather than backslash-s. Backslash-s is a GNU extension that BSD grep does not honour, so on macOS - where contributors run this hook - the pattern would stop matching every real marker and the guard would fail open, which is the failure this commit exists to close. Verified against 20 subject shapes: every conventional type with and without a scope passes, the release tooling's own commit is exempted, both release forms and all four GitHub forms are rejected in upper and lower case and with multiple spaces, a bare non-conventional subject is rejected, and a marker appearing only in the body still passes because the body never reaches the squash. --- .git-hooks/commit-msg | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.git-hooks/commit-msg b/.git-hooks/commit-msg index 5c521a9..fae05ce 100755 --- a/.git-hooks/commit-msg +++ b/.git-hooks/commit-msg @@ -29,10 +29,19 @@ fi # This is not hypothetical, and it happened here. This repo's #274 carried two # `chore(ci): ... [skip release]` subjects, so the squashed commit on main was # filtered out whole, the crypto fix merged, and no version was ever published. -if (echo "$subject" | grep -Eq "\[skip (release|ci)\]") then - echo "${RED}❌ The commit subject contains [skip release] or [skip ci]!" +# Mirrors the upstream filters rather than a subset of them: +# - semantic-release drops any commit matching +# /\[skip\s+release]|\[release\s+skip]/i (lib/definitions/plugins.js), so the +# match is case-insensitive and accepts any run of whitespace +# - GitHub skips the push or pull_request run entirely for [skip ci], +# [ci skip], [no ci], [skip actions] and [actions skip], case-insensitively +# A narrower pattern let "[SKIP RELEASE]" and "[release skip]" through, and both +# still suppressed the release. +if (echo "$subject" | grep -Eqi "\[(skip[[:space:]]+release|release[[:space:]]+skip|skip[[:space:]]+ci|ci[[:space:]]+skip|no[[:space:]]+ci|skip[[:space:]]+actions|actions[[:space:]]+skip)\]") then + echo "${RED}❌ The commit subject carries a skip marker!" echo "Under squash-merge that suppresses the release for the whole PR, not" - echo "just this commit. Drop the marker - a conventional type is enough:" + echo "just this commit, and [skip ci] stops the workflow running at all." + echo "Drop the marker - a conventional type is enough:" echo " chore(deps): refresh the lockfile" exit 1 fi From 052f55e9663b334ea29e4578b8daf80f4d38a432 Mon Sep 17 00:00:00 2001 From: "sasjs-dev[bot]" Date: Tue, 6 Oct 2026 09:34:46 +0000 Subject: [PATCH 2/3] fix(ci): name the postcss-selector-parser advisory in the toolchain audit The audit caught a new advisory, which is what it is for: GHSA-rj75-hqrm-r3gf, moderate, quadratic complexity in flat selector parsing. It cannot be fixed from here. The vulnerable copy is npm's own bundled dependency - release/node_modules/npm/node_modules/postcss-selector-parser - so no resolver change reaches it, and 11.21.0 is the last npm 11.x while @semantic-release/npm requires ^11. The eventual fix is that plugin moving to npm 12. It is also unreachable in this usage: the parser reads this repo's own release config, not the commits being matched. Named with that reasoning rather than silenced, so the audit still fails on anything new. 13 exempt, exit 0. --- release/audit.mjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/release/audit.mjs b/release/audit.mjs index 061b412..0ea6d99 100644 --- a/release/audit.mjs +++ b/release/audit.mjs @@ -52,6 +52,10 @@ const EXEMPT = new Map([ 'GHSA-6j4f-fj2g-mc7p', 'brace-expansion, inside the npm package that @semantic-release/npm bundles.' ], + [ + 'GHSA-rj75-hqrm-r3gf', + 'postcss-selector-parser, inside the npm package that @semantic-release/npm bundles. Affected through 7.1.5. npm ships its own bundled copy, so no resolver change reaches it - 11.21.0 is the last 11.x and @semantic-release/npm requires ^11 - and the eventual fix is that plugin moving to npm 12. Unreachable here: the parser reads this repo\'s own release config, not the commits being matched.' + ], ['GHSA-rpw4-54j3-4h4q', 'ip-address, inside the npm package that @semantic-release/npm bundles.'], ['GHSA-2vr4-cq9g-pvrc', 'ip-address, inside the npm package that @semantic-release/npm bundles.'], ['GHSA-j6r3-76f7-8jcv', 'ip-address, inside the npm package that @semantic-release/npm bundles.'], From 63657588550caae5b42f49b17d70ed7868528e3a Mon Sep 17 00:00:00 2001 From: "sasjs-dev[bot]" Date: Tue, 6 Oct 2026 10:01:28 +0000 Subject: [PATCH 3/3] chore(ci): format the release audit script for the prettier gate sas-language is the only one of the five repos that lints release/, and its prettier config sets printWidth 100, so the exemption block needed reformatting to pass that gate. The file stays byte-identical across all five. --- release/audit.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/audit.mjs b/release/audit.mjs index 0ea6d99..b38a8b2 100644 --- a/release/audit.mjs +++ b/release/audit.mjs @@ -54,7 +54,7 @@ const EXEMPT = new Map([ ], [ 'GHSA-rj75-hqrm-r3gf', - 'postcss-selector-parser, inside the npm package that @semantic-release/npm bundles. Affected through 7.1.5. npm ships its own bundled copy, so no resolver change reaches it - 11.21.0 is the last 11.x and @semantic-release/npm requires ^11 - and the eventual fix is that plugin moving to npm 12. Unreachable here: the parser reads this repo\'s own release config, not the commits being matched.' + "postcss-selector-parser, inside the npm package that @semantic-release/npm bundles. Affected through 7.1.5. npm ships its own bundled copy, so no resolver change reaches it - 11.21.0 is the last 11.x and @semantic-release/npm requires ^11 - and the eventual fix is that plugin moving to npm 12. Unreachable here: the parser reads this repo's own release config, not the commits being matched." ], ['GHSA-rpw4-54j3-4h4q', 'ip-address, inside the npm package that @semantic-release/npm bundles.'], ['GHSA-2vr4-cq9g-pvrc', 'ip-address, inside the npm package that @semantic-release/npm bundles.'],