Skip to content

fix(ci): widen the marker check to the filters it guards - #279

Merged
allanbowe merged 3 commits into
mainfrom
fix/widen-marker-check
Oct 6, 2026
Merged

allanbowe merged 3 commits into
mainfrom
fix/widen-marker-check

Conversation

@sasjs-dev

@sasjs-dev sasjs-dev Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

What

The marker check was narrower than the filters it guards.

semantic-release's skip filter is case-insensitive and accepts any run of whitespace (/\[skip\s+release]|\[release\s+skip]/i, lib/definitions/plugins.js), so [SKIP RELEASE] and [release skip] passed this hook and still suppressed the release. GitHub also skips the push or pull_request run entirely on [ci skip], [no ci], [skip actions] and [actions skip], none of which were covered - only [skip ci] was.

The pattern now mirrors both, and semantic-release's own chore(release): X [skip ci] commit stays exempt (it is pushed straight to the branch, never squash-merged).

Why it is here and not on #277

Found in review on sasjs/adapter#919, which carries a byte-identical copy of this hook. The two are kept identical, so the fix belongs in both. #277 and #278 are already merged, hence this PR.

Verification

12 subject shapes, all as expected:

  • rejected: [skip release], [SKIP RELEASE], [release skip], [skip release], [ci skip], [no ci], [skip actions], [actions skip]
  • accepted: chore(release): 3.7.1 [skip ci], chore(deps): refresh the lockfile, fix(utils): ..., and a fix: whose body mentions the markers (the body never reaches the squash commit)

@sasjs-dev sasjs-dev Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full base...head diff (one file, .git-hooks/commit-msg) against semantic-release 25.0.9's preprocess filter and GitHub's documented skip markers. The widening is correct in coverage: the new pattern at :40 catches both whitespace-tolerant release forms, all four GitHub skip strings, and the case-insensitive variants the old pattern let through, while the chore(release) exemption at :17-22 still precedes it. Two findings, one on the change and one on the PR itself:

  • .git-hooks/commit-msg:40 - the pattern uses \s inside grep -E. GNU grep accepts it; BSD grep, the default on macOS where contributors run this hook, does not treat \s as whitespace, so on those machines the widened pattern silently stops matching every real marker and the guard fails open - the exact failure this PR exists to close. Replace each \s with [[:space:]] (POSIX ERE, both greps). The identical line also ships in sasjs/adapter#919, so the fix belongs in both.

  • this PR's head commit e26b30f has produced zero workflow runs - no check runs, no check suites, nothing queued - while its parent on main and the neighbouring PRs all ran. The cause is in the commit itself: its body carries the literal strings "[skip ci]", "[no ci]", "[skip actions]" and "[actions skip]" (the verification paragraph listing the shapes), and GitHub's skip instruction matches the marker anywhere in the commit message, not only in the subject. The very hook this PR widens exists because of that mechanism, and its own documentation has tripped it: the run-tests and windows workflows that would have gated this PR never started, so the PR shows green-by-absence rather than green. Amend the commit (or push a new one) with the markers obfuscated - for example bracket-joined like "[skip" + " ci]" or spelled out in words - the same care the hook's comments take when naming them, and so the PR gets a real CI verdict before merge. Note the hook itself checks only the subject, so the reworded body stays hook-clean.

2 findings above for review.

sasjs-dev Bot added 3 commits October 6, 2026 10:01
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.
…udit

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.
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.
@sasjs-dev
sasjs-dev Bot force-pushed the fix/widen-marker-check branch from e26b30f to 6365758 Compare October 6, 2026 10:01
@sasjs-dev

sasjs-dev Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor Author

Both findings fixed, and thank you - the second one is the root cause of a CI anomaly I had been chasing for hours.

Finding 1 - \s is not POSIX. Fixed in both hooks. The pattern now uses [[:space:]], which POSIX ERE defines and both grep implementations honour, so the guard no longer fails open on macOS. Re-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 in the body only still passes. The identical line in sasjs/adapter#919 is fixed in the same commit there (c6f7b62).

Finding 2 - the body carried the markers. This is the cause of something I had recorded as an unexplained anomaly: utils#277 and adapter#919 produced no pull_request runs at all while neighbouring PRs ran normally, and I could not account for it. The head commit's body listed the marker shapes verbatim in its verification paragraph, and GitHub matches the skip instruction anywhere in the message. Green by absence, exactly as you describe.

The commit is amended. The body now names the markers in words rather than quoting them - the release marker, ci-skip, no-ci, skip-actions, actions-skip - and backslash-s is described rather than written. Confirmed clean:

git log -1 --format=%B | grep -cEi '\[(skip|ci|no|actions)[[:space:]]'  ->  0

The hook itself checks only the subject, so the reworded body stays hook-clean.

Also folded in: utils#280 (the toolchain-audit exemption for the new postcss-selector-parser advisory) now lives on this branch rather than as a separate PR, so this is one utils change to review. Its two commits are 052f55e and 6365758.

@allanbowe
allanbowe merged commit 3a9d08d into main Oct 6, 2026
2 checks passed
@allanbowe
allanbowe deleted the fix/widen-marker-check branch October 6, 2026 10:05
sasjs-gha Bot pushed a commit that referenced this pull request Oct 6, 2026
## [3.7.2](v3.7.1...v3.7.2) (2026-10-06)

### Bug Fixes

* **ci:** widen the marker check to the filters it guards ([#279](#279)) ([3a9d08d](3a9d08d)), closes [#274](#274)
@sasjs-gha

sasjs-gha Bot commented Oct 6, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 3.7.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@sasjs-gha sasjs-gha Bot added the released label Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant