Skip to content

Commit 3a3d022

Browse files
Reintroduce changelog tool automation
This adds github automation to ensure that PRs contain staged changelog entries by calling the `amend` command of the changelog tool. This command will check the diff of the PR's head against the base branch. If no staged changelog entry is present, it will post a comment reminding the requester to add one and instructing them on how to do so. If a staged changelog entry is present but lacks a PR link (since it's a chicken-and-egg problem), it will post a review comment with a commitable suggestion to add the PR link. This was previously introduced, but had to be reverted after some security concerns were brought up. There were two core issues with the previous iteration: - The workflow job was given `write-all` permissions, which is well beyond the scope of what it needed. The new workflow only has write permissions to issues and pull requests, which it needs to post comments, as well as rights to read the contents of the repo. - The workflow job was checking out the PR branch and running the changelog tool from it. This is a problem because a malicious actor could modify the changelog tool to do whatever they want and it would be run without review. This is made much worse by the permissions issue above. The new workflow now checks out the base branch to run the changelog tool from. The PR's branch is checked out separately for the changelog tool to inspect. Both copies of the repo are checked out shallowly - only the `.changes` dir of the base branch is pulled and only the `.changes/next-release` dir of the pr branch is pulled.
1 parent 72668ce commit 3a3d022

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

.github/workflows/changelog-ci.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: changelog
2+
on: pull_request_target
3+
jobs:
4+
amend:
5+
name: "Validate staged changelogs"
6+
runs-on: ubuntu-latest
7+
permissions:
8+
# Used to pull the PR and detect changes. This is needed to see
9+
# whether the PR introduced a staged changelog entry or not as
10+
# well as to suggest amending the changelog entry if necessary.
11+
contents: read
12+
13+
# Used to write issue comments. This is done when there is no staged
14+
# changelog at all. The comment will include instructions on how to
15+
# create the changelog entry.
16+
issues: write
17+
18+
# Used to write PR comments. This is done when there is a staged
19+
# changelog introduced by the PR, but it lacks a PR link. A PR
20+
# comment is used so that a commitable suggestion may be posted.
21+
pull-requests: write
22+
steps:
23+
24+
# This pulls the base branch, from which we will run the changelog
25+
# tool. Running from the base branch prevents us from picking up
26+
# malicious changes that might be in a PR.
27+
- name: Pull base branch
28+
uses: actions/checkout@v4
29+
with:
30+
path: base
31+
ref: ${{ github.base_ref }}
32+
33+
# Only check out the changes directory. This isn't strictly
34+
# necessary, but it speeds up the checkout since all we care
35+
# about is in that directory.
36+
sparse-checkout: .changes
37+
38+
# This pulls the PR's branch, from which we MUST NOT run any code.
39+
# All we do with it is inspect the changelog entries introduced,
40+
# if any.
41+
- name: Pull the PR
42+
uses: actions/checkout@v4
43+
with:
44+
path: pr
45+
ref: ${{ github.head_ref }}
46+
repository: ${{ github.event.pull_request.head.repo.full_name }}
47+
48+
# The changelog tool only needs to know about staged changelog
49+
# entries in the PR branch, so ONLY check out those. This makes
50+
# the checkout faster, but also makes it harder to accidentally
51+
# run code from the PR branch.
52+
sparse-checkout: .changes/next-release
53+
54+
# This is needed so that the changelog tool can check the diff for
55+
# newly-introduced changes by comparing its head against that of
56+
# the base. We still won't actually run code from that copy.
57+
- name: Fetch base from PR copy
58+
run: |
59+
cd pr
60+
git fetch origin ${{ github.base_ref }}
61+
62+
- name: Install Python
63+
uses: actions/setup-python@v5
64+
with:
65+
python-version-file: "base/.changes/pyproject.toml"
66+
67+
- name: Install uv
68+
uses: astral-sh/setup-uv@v6
69+
with:
70+
version-file: "base/.changes/pyproject.toml"
71+
72+
- name: Install changelog tool
73+
run: |
74+
cd base/.changes
75+
uv sync --locked --all-extras --all-groups --dev
76+
77+
- name: Run validation script
78+
env:
79+
GITHUB_TOKEN: ${{ github.token }}
80+
TARGET_SHA: ${{ github.event.pull_request.head.sha }}
81+
PR_TITLE: ${{ github.event.pull_request.title }}
82+
run: |
83+
cd base/.changes
84+
uv run amend \
85+
--review-comment \
86+
--pull-request-number ${{ github.event.pull_request.number }} \
87+
--repository-dir ${{ github.workspace }}/pr

0 commit comments

Comments
 (0)