From baced6e20ff2bc290e257315df6cbcd9c7767193 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Sun, 13 Sep 2026 18:27:39 -0700 Subject: [PATCH] ci: propagate main's release-cut commitlint depth to develop On a `pull_request` event GitHub runs the workflow definition from the PR's HEAD branch, not its base. A `develop -> main` release PR therefore executes develop's copy of `.github/workflows/commitlint.yml`, and main's copy is never consulted. Develop's copy lints the entire inherited `main..develop` range, so a release cut fails on immutable historical commit messages that were written long before the current PR. Main already carries the fix: a `commitDepth: 1` job gated on `github.base_ref == 'main'` for release cuts, the full-range job gated on `!= 'main'` for feature branches, and a PR-title lint that appends `(#PR_NUMBER)` before linting. Because the release-cut branch of that fix only ever runs from the HEAD branch of a cut, and cuts run from develop, it has never once applied to a cut. The file never reached develop because the `-s ours` reconciliation at cd8ce7b8 records ancestry without bringing any content across. This commit takes main's version verbatim -- it is already reviewed and already required-green on main. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/commitlint.yml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 9f1d6884..2d0588a7 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -28,7 +28,20 @@ jobs: with: fetch-depth: 0 - - name: Lint PR commits + # A main-base PR is a develop -> main release cut: every commit in main..develop + # was already linted at its own PR, while that commit was still mutable and its + # author could still fix it. Re-linting the whole inherited range at cut time adds + # no information and cannot be satisfied (the commits are now immutable, pinned by + # gitlinks and rev-pinned deps). Lint only what THIS PR introduces: its own commit(s). + - name: Lint PR commits (release cut — this PR's own commits only) + if: github.base_ref == 'main' + uses: wagoid/commitlint-github-action@v6 + with: + configFile: commitlint.config.mjs + commitDepth: 1 + + - name: Lint PR commits (feature branch — full PR range) + if: github.base_ref != 'main' uses: wagoid/commitlint-github-action@v6 with: configFile: commitlint.config.mjs @@ -37,9 +50,13 @@ jobs: if: github.event_name == 'pull_request' env: PR_TITLE: ${{ github.event.pull_request.title }} + PR_NUMBER: ${{ github.event.pull_request.number }} run: | set -euo pipefail # Install both @commitlint/cli AND the extended shareable config so the # `extends: ['@commitlint/config-conventional']` in commitlint.config.mjs resolves. - echo "$PR_TITLE" | npx --yes -p @commitlint/cli -p @commitlint/config-conventional \ + # GitHub's squash merge lands "$PR_TITLE (#$PR_NUMBER)" as the commit subject — + # lint that exact string, not the title alone, or a title within the length + # limit can still produce an over-limit commit subject once merged. + printf '%s (#%s)\n' "$PR_TITLE" "$PR_NUMBER" | npx --yes -p @commitlint/cli -p @commitlint/config-conventional \ commitlint --config commitlint.config.mjs