Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 27 additions & 14 deletions .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: changelog

permissions:
contents: read
pull-requests: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.id }}
Expand All @@ -10,24 +11,36 @@ concurrency:
on:
pull_request:
branches: ["main"]
# labeled/unlabeled: skip-changelog and changelog-version-edit waive parts
# of this check, so the verdict is only valid for the label set it was
# computed under. Without these types, removing a label leaves the green
# run that the label produced standing, and the gate silently stays open.
#
# The job cannot cheaply no-op on an unrelated label: a job skipped by `if`
# reports its check as skipped, which branch protection counts as passing,
# so it would overwrite a real failure with a green. Every run therefore
# computes the real verdict.
types: [opened, synchronize, reopened, labeled, unlabeled]

jobs:
changelog:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check for skip-changelog label
id: skip
# Read labels from the API so re-runs do not use a stale event payload.
- name: Read PR labels
id: labels
shell: bash
env:
SKIP_CHANGELOG: ${{ contains(github.event.pull_request.labels.*.name, 'skip-changelog') }}
GH_TOKEN: ${{ github.token }}
PR_URL: ${{ github.event.pull_request.url }}
run: |
if [ "$SKIP_CHANGELOG" = "true" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "PR has 'skip-changelog' label; bypassing changelog check."
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
set -euo pipefail
gh api "$PR_URL" --jq '
[.labels[].name] |
"skip=\(index("skip-changelog") != null)",
"version_edit=\(index("changelog-version-edit") != null)"
' >> "$GITHUB_OUTPUT"
# The heading guard runs even for skip-changelog PRs: that label only
# waives the news-fragment requirement, not the publish-trigger guard.
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -40,19 +53,19 @@ jobs:
# from, so the guard and the publisher cannot disagree. Escape hatch
# for deliberate restructuring: the 'changelog-version-edit' label.
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-version-edit') && !startsWith(github.head_ref, 'release/') }}
if: steps.labels.outputs.version_edit != 'true' && !startsWith(github.head_ref, 'release/')
- name: Reject manual changelog version headings
if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-version-edit') && !startsWith(github.head_ref, 'release/') }}
if: steps.labels.outputs.version_edit != 'true' && !startsWith(github.head_ref, 'release/')
env:
BASE_REF: origin/${{ github.base_ref }}
run: uv run --no-config --locked --script scripts/release.py check-headings
- uses: ./.github/actions/setup_build_env
if: steps.skip.outputs.skip != 'true'
if: steps.labels.outputs.skip != 'true'
with:
python-version: "3.14"
run-uv-sync: true
- name: Determine affected packages
if: steps.skip.outputs.skip != 'true'
if: steps.labels.outputs.skip != 'true'
id: affected
shell: bash
run: |
Expand All @@ -75,7 +88,7 @@ jobs:
echo "Affected packages:"
cat affected.txt
- name: Check for news fragments
if: steps.skip.outputs.skip != 'true'
if: steps.labels.outputs.skip != 'true'
shell: bash
run: |
set -euo pipefail
Expand Down
Loading