-
Notifications
You must be signed in to change notification settings - Fork 0
66 lines (58 loc) · 2.8 KB
/
Copy pathcommit-message.yml
File metadata and controls
66 lines (58 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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@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@v7
with:
# renovate: datasource=github-releases depName=astral-sh/uv
version: "0.10.0"
- 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