Repository navigation
chore(deps): lock file maintenance #472
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Validate Commit Message | |
| on: | |
| pull_request: | |
| types: [opened, edited, synchronize, reopened] | |
| branches: [main] | |
| # Least-privilege default: read-only token. | |
| permissions: | |
| contents: read | |
| jobs: | |
| validate-commit-message: | |
| name: Validate Commit Message | |
| runs-on: ubuntu-latest | |
| # This job always runs so it can be a *required* status check. A job gated off at the | |
| # job level is skipped and reports no conclusion, which leaves a required check stuck | |
| # "waiting" and blocks the PR. Instead the single-commit gate lives on each step: on a | |
| # multi-commit PR the steps skip and the job still reports success, so the ruleset can | |
| # require it unconditionally. | |
| # | |
| # Why single-commit only: GitHub's `squash_merge_commit_title` defaults to | |
| # COMMIT_OR_PR_TITLE, which takes the squash title from the commit when a PR has | |
| # exactly one commit and from the PR title otherwise. So this is precisely the case | |
| # where the commit message -- not the PR title -- is what git-cliff reads into the | |
| # changelog, and the case pr-title.yml structurally cannot cover. Multi-commit PRs | |
| # ship their title, so their intermediate commits stay free-form on purpose: | |
| # requiring conventional WIP messages that get squashed away is pure friction. | |
| # | |
| # `commits` is the PR's commit count, the same input GitHub uses to make that choice. | |
| steps: | |
| - name: Checkout the commit that will ship | |
| if: ${{ github.event.pull_request.commits == 1 }} | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| # The PR head itself, not the merge commit checkout/@v7 defaults to -- the | |
| # merge commit's message is GitHub's, not the contributor's. | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| fetch-depth: 1 | |
| - name: Install uv | |
| if: ${{ github.event.pull_request.commits == 1 }} | |
| uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 | |
| with: | |
| # renovate: datasource=github-releases depName=astral-sh/uv | |
| version: "0.12.23" | |
| - name: Set up Python | |
| if: ${{ github.event.pull_request.commits == 1 }} | |
| run: uv python install | |
| - name: Validate the commit message that becomes the squash title | |
| if: ${{ github.event.pull_request.commits == 1 }} | |
| run: | | |
| git log -1 --format=%B HEAD > "$RUNNER_TEMP/commit-msg" | |
| echo "Validating the message that will become the squash commit title:" | |
| cat "$RUNNER_TEMP/commit-msg" | |
| # Runs the same commitizen hook, at the same pinned rev, that the local | |
| # commit-msg hook runs. Deliberately not a second copy of the grammar: a | |
| # CI check that disagrees with the local hook is worse than no check. | |
| uv run --locked prek run \ | |
| --stage commit-msg \ | |
| --commit-msg-filename "$RUNNER_TEMP/commit-msg" \ | |
| commitizen |