Skip to content

Commit 9ece3fa

Browse files
ci: Add CI enforcement to prevent manual CHANGELOG.md edits
Add a new workflow that checks PRs for CHANGELOG.md modifications and fails unless the PR title starts with `meta(changelog):`. When a violation is detected, posts a comment explaining the automated changelog policy and what action to take. Fixes #3072 Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 42a6125 commit 9ece3fa

File tree

2 files changed

+87
-2
lines changed

2 files changed

+87
-2
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Changelog Enforcement
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
check-changelog:
8+
name: Check Changelog Changes
9+
runs-on: ubuntu-24.04
10+
if: ${{ github.event_name == 'pull_request' }}
11+
12+
permissions:
13+
contents: read
14+
pull-requests: write
15+
16+
steps:
17+
- name: Check for CHANGELOG.md modifications
18+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # 8.0.0
19+
with:
20+
script: |
21+
const prNumber = context.payload.pull_request.number;
22+
const prTitle = context.payload.pull_request.title;
23+
const isChangelogPR = prTitle.startsWith('meta(changelog):');
24+
25+
const { data: files } = await github.rest.pulls.listFiles({
26+
owner: context.repo.owner,
27+
repo: context.repo.repo,
28+
pull_number: prNumber,
29+
per_page: 100
30+
});
31+
32+
const changelogModified = files.some(file => file.filename === 'CHANGELOG.md');
33+
34+
console.log(`PR Title: ${prTitle}`);
35+
console.log(`Is Changelog PR: ${isChangelogPR}`);
36+
console.log(`CHANGELOG.md Modified: ${changelogModified}`);
37+
38+
if (changelogModified && !isChangelogPR) {
39+
const commentBody = `## :warning: Manual Changelog Changes Detected
40+
41+
This PR modifies \`CHANGELOG.md\`, but the PR title does not start with \`meta(changelog):\`.
42+
43+
**Changelogs in this repository are generated automatically during releases.** Manual edits to \`CHANGELOG.md\` are not allowed in regular PRs.
44+
45+
### What to do:
46+
47+
1. **If this change is intentional**: Create a separate PR with a title starting with \`meta(changelog):\` to make changelog edits.
48+
49+
2. **If this was unintentional**: Remove the \`CHANGELOG.md\` changes from this PR.`;
50+
51+
// Avoid posting duplicate comments on re-runs
52+
const { data: comments } = await github.rest.issues.listComments({
53+
owner: context.repo.owner,
54+
repo: context.repo.repo,
55+
issue_number: prNumber
56+
});
57+
58+
const botComment = comments.find(comment =>
59+
comment.user.type === 'Bot' &&
60+
comment.body.includes('Manual Changelog Changes Detected')
61+
);
62+
63+
if (!botComment) {
64+
await github.rest.issues.createComment({
65+
owner: context.repo.owner,
66+
repo: context.repo.repo,
67+
issue_number: prNumber,
68+
body: commentBody
69+
});
70+
console.log('Posted comment explaining changelog policy');
71+
} else {
72+
console.log('Comment already exists, skipping');
73+
}
74+
75+
core.setFailed('CHANGELOG.md changes are not allowed unless PR title starts with "meta(changelog):"');
76+
} else if (changelogModified && isChangelogPR) {
77+
console.log('CHANGELOG.md changes allowed in meta(changelog): PR');
78+
} else {
79+
console.log('No CHANGELOG.md changes detected');
80+
}

.github/workflows/ci.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,23 @@ jobs:
3737
name: Test Swift
3838
uses: ./.github/workflows/swift-test.yml
3939

40+
changelog:
41+
name: Changelog
42+
uses: ./.github/workflows/changelog-enforcement.yml
43+
4044
required:
4145
name: Check required jobs
4246
runs-on: ubuntu-24.04
43-
needs: [lint, test, test_node, test_swift]
47+
needs: [lint, test, test_node, test_swift, changelog]
4448
if: always()
4549
steps:
4650
- name: Check for failure
4751
if: ${{
4852
needs.lint.result != 'success' ||
4953
needs.test.result != 'success' ||
5054
needs.test_node.result != 'success' ||
51-
needs.test_swift.result != 'success'
55+
needs.test_swift.result != 'success' ||
56+
(needs.changelog.result != 'success' && needs.changelog.result != 'skipped')
5257
}}
5358
run: |
5459
echo "One or more jobs failed"

0 commit comments

Comments
 (0)