ci: use a maintained commitlint action fork - #20
Conversation
There was a problem hiding this comment.
Replaces wagoid/commitlint-github-action (pinned to @commitlint/ensure ^19) with a direct npx run pinned to @commitlint/cli@21.2.1 / @commitlint/config-conventional@21.2.0, matching the pre-commit hook's version floor. Verified locally against this repo's actual commit history: the pinned command runs cleanly against the existing commit range (including the dependabot bump commits and this PR's own commit), and the permissions change (pull-requests: read -> contents: read) is correct since the commit range now comes from local git rather than the API. BASE_SHA/HEAD_SHA are passed through env vars rather than interpolated into the script, avoiding injection. No stale references to the old action remain elsewhere in the repo. Clean, well-scoped CI fix.
There was a problem hiding this comment.
Re-review after the prior bot APPROVE was dismissed by a new commit. That commit replaces the npx-based commitlint invocation with a package.json/package-lock.json tracked in .github/commitlint, installed via npm ci and cached by actions/setup-node, plus a matching Dependabot npm entry for that directory. This directly addresses the issue title ("pin commitlint in a tracked manifest") and is a strict improvement over the previous npx approach: the exact versions are now visible to Dependabot and reviewable in diffs rather than embedded in a workflow run command. Verified: the install step's working-directory and the binary path used in the lint step are consistent (.github/commitlint/node_modules/.bin/commitlint from repo root), the lockfile's pinned versions match package.json exactly, cache-dependency-path points at the right lockfile, the new dependabot.yml entry's directory matches, permissions (contents: read) are sufficient for checkout+local git range, and BASE_SHA/HEAD_SHA are passed via env vars rather than interpolated into the shell command. No stale references to the old npx/action-based approach remain elsewhere in the repo. No Critical or Important findings.
7150108 to
d470186
Compare
There was a problem hiding this comment.
Prior bot reviews were both dismissed by later commits that replaced the fix entirely (npx-pinned commitlint, then a tracked package.json/lockfile), so neither's findings carry over to this diff — this is a third, unrelated approach (repointing the workflow at a personally-maintained fork of the upstream action) and none of my earlier findings apply here. The diff itself (7 lines in ci.yml) does what it says: swaps wagoid/commitlint-github-action@v6.2.1 for yo61/commitlint-github-action@v6.3.0, SHA-pinned. I confirmed the pinned commit (31e5e045...) is real, on the fork's master, and its package.json is at version 6.3.0 with @commitlint/* bumped to ^21 as claimed. One real gap: the fork's action.yml runs docker://ghcr.io/yo61/commitlint-github-action:6.3.0 — a mutable registry tag, not a digest — so the git-SHA pin on the uses: line doesn't actually pin what gets executed.
| # containing a URL added in v20. Dependabot bodies are markdown link lists | ||
| # well over 100 chars, so ^19 fails them on body-max-line-length while the | ||
| # pre-commit hook (v21) passes them. | ||
| - uses: yo61/commitlint-github-action@31e5e0454fc0709625e6dcfb502ea18978f45f15 # v6.3.0 |
There was a problem hiding this comment.
[Important] SHA pin doesn't cover the actual executed artifact — the Docker image is referenced by mutable tag
This pins the git ref of yo61/commitlint-github-action to a commit SHA, but the fork's action.yml declares runs.using: docker with image: docker://ghcr.io/yo61/commitlint-github-action:6.3.0 — a registry tag, not a digest. GitHub Actions pulls that pre-built image straight from ghcr.io at run time rather than building it from the pinned commit; the SHA pin only fixes which action.yml gets read, not which container gets executed. If tag 6.3.0 is ever repushed on ghcr.io (deliberately or via a compromised token), every CI run using this SHA-pinned reference silently starts running different code, with no diff or commit to review. The PR body's "Actions SHA-pinned" claim doesn't hold for the actual runtime artifact. Pinning by digest (ghcr.io/yo61/commitlint-github-action@sha256:...) in the fork's action.yml would close this; as-is, worth calling out since the whole point of this PR is tightening trust in the commitlint pipeline.
73243fb to
2b7d043
Compare
There was a problem hiding this comment.
Re-review after the last bot review (COMMENTED, sha d470186). Prior-findings ledger: [Important] Docker image pinned by mutable tag rather than digest — still open. The only change since that review is a reword of the code comment above the uses: line (message text swapped for a different phrasing of the same rationale); the uses: yo61/commitlint-github-action@31e5e0454... pin and the fork's action.yml are unchanged. I re-fetched the fork's action.yml at the pinned commit and confirmed runs.using: docker still points at docker://ghcr.io/yo61/commitlint-github-action:6.3.0, a mutable registry tag rather than a digest, so the finding stands unchanged.
| # two majors behind. This fork runs commitlint v21 on node 24, matching | ||
| # the version the pre-commit hook resolves. | ||
| - uses: yo61/commitlint-github-action@31e5e0454fc0709625e6dcfb502ea18978f45f15 # v6.3.0 | ||
| with: |
There was a problem hiding this comment.
[Important] SHA pin still doesn't cover the executed artifact — fork's action.yml runs a mutable Docker tag
Unchanged from the last review: the git-SHA pin on yo61/commitlint-github-action@31e5e045... only fixes which action.yml gets read. That file declares runs.using: docker with image: docker://ghcr.io/yo61/commitlint-github-action:6.3.0 (confirmed by fetching action.yml at this exact SHA) — a registry tag, not a digest. GitHub Actions pulls that pre-built image from ghcr.io at run time, so if tag 6.3.0 is ever repushed, every CI run using this SHA-pinned reference silently executes different code with no diff to review. Since this PR's stated purpose is tightening the commitlint pipeline's supply-chain hygiene, pinning the fork's action.yml to ghcr.io/yo61/commitlint-github-action@sha256:... would close the gap.
2b7d043 to
962afb1
Compare
There was a problem hiding this comment.
Re-review after the previous COMMENTED review. Prior-findings ledger: [Important] Docker image pinned by mutable registry tag rather than digest — still open. The only change since that review is a reword of the code comment above the uses: line; the uses: yo61/commitlint-github-action@31e5e0454... pin and the fork's action.yml are otherwise unchanged. I re-fetched the fork's action.yml at the pinned commit and confirmed runs.using: docker still resolves to docker://ghcr.io/yo61/commitlint-github-action:6.3.0, a mutable tag, so the finding stands and this stays a COMMENT rather than an APPROVE.
| # Fork of wagoid/commitlint-github-action. Upstream is unmaintained: no | ||
| # commit to master since 2025-01-14, and it pins @commitlint/ensure ^19, | ||
| # two majors behind. This fork runs commitlint v21 on node 24. | ||
| - uses: yo61/commitlint-github-action@31e5e0454fc0709625e6dcfb502ea18978f45f15 # v6.3.0 |
There was a problem hiding this comment.
[Important] SHA pin doesn't cover the executed artifact — fork's action.yml runs a mutable Docker tag
The uses: line pins the git ref of yo61/commitlint-github-action to commit 31e5e0454..., but that commit's action.yml declares runs.using: docker with image: docker://ghcr.io/yo61/commitlint-github-action:6.3.0 — a registry tag, not a digest (verified by fetching action.yml at this exact SHA). GitHub Actions pulls that pre-built image from ghcr.io at run time; the SHA pin only fixes which action.yml is read, not which container executes. If tag 6.3.0 is ever repushed on ghcr.io, every CI run using this SHA-pinned reference silently executes different code with no diff to review — undermining the PR's own stated goal of tightening the commitlint pipeline's supply-chain hygiene. Pinning the fork's action.yml to ghcr.io/yo61/commitlint-github-action@sha256:... would close this gap.
wagoid/commitlint-github-action pins @commitlint/ensure ^19. The exemption for long lines containing a URL landed in v20, so CI enforced a stricter rule than the config intended and failed Dependabot commits on body-max-line-length, while the pre-commit hook resolving v21 passed the same commit. Upstream is unmaintained: master has had no commit since 2025-01-14 and the v20 bump has sat open since July. Point at yo61/commitlint-github-action instead, which runs commitlint v21 on node 24 and is published to ghcr.io.
962afb1 to
55fa660
Compare
There was a problem hiding this comment.
Prior-findings ledger: [Important] Docker image pinned by mutable registry tag rather than digest — fixed. The only change since the last review is the uses: SHA (31e5e045... -> 501ff7bb...) and the code comment. I fetched the fork's action.yml at the new pinned commit and confirmed runs.using: docker now targets docker://ghcr.io/yo61/commitlint-github-action@sha256:78d4769928... — a digest, not a tag — closing the supply-chain gap raised in every prior review. package.json at that commit is version 6.3.0 with @commitlint/* at ^21.2.0, matching the PR body's claims. The workflow diff itself is otherwise unchanged (still 6 lines in ci.yml, same permissions, same configFile input). No remaining Critical or Important findings.
What
Points the commitlint job at
yo61/commitlint-github-action— a maintained fork running commitlint v21 on Node 24.Why
Dependabot PRs fail the commitlint job on
body-max-line-length, while the pre-commitlintjob passes the same commit. Same commit, samecommitlint.config.mjs, different verdict.@commitlint/ensurev20 added an exemption for long lines containing a URL:wagoid/commitlint-github-action@v6.2.1is the latest release and pins@commitlint/ensure: ^19.0.3, so CI enforced a stricter rule than the config intends. Dependabot bodies are markdown link lists — one real example is 314 characters on a single line.Upstream is unmaintained: no commit to
mastersince 2025-01-14, and the v20 bump (PR #837) has been open and mergeable since July with no response.The fork
yo61/commitlint-github-action@v6.3.0— all@commitlint/*at^21, Node 24.19.0 LTS (v21 needsnode >= 22.12),commitlint-plugin-function-rulesat^5(v4's peer range caps at<20and breaksnpm ci), published toghcr.iofrom a pushed tag. Actions SHA-pinned, least-privilege permissions,actionlintandzizmorclean.Verified against the action's own load+lint path with a real
commitlint.config.mjs:subject-case: [0].mjsoverride is honoredCommit subjects stay validated for Dependabot as well as humans, rather than exempting bot commits.