-
Notifications
You must be signed in to change notification settings - Fork 1
154 lines (135 loc) · 5.3 KB
/
breaking-change-detection.yml
File metadata and controls
154 lines (135 loc) · 5.3 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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
name: Breaking Change Detection
on:
pull_request:
types: [opened, synchronize, edited]
permissions:
contents: read
issues: write
pull-requests: write
jobs:
detect-breaking-changes:
name: Detect API Breaking Changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch base branch
run: git fetch origin ${{ github.base_ref }}
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install griffe
run: pip install griffe
- name: Check for breaking changes
id: griffe
run: |
set +e
OUTPUT=$(griffe check infrafoundry \
--against "origin/${{ github.base_ref }}" \
--search src \
--verbose 2>&1)
EXIT_CODE=$?
set -e
echo "$OUTPUT"
if [ $EXIT_CODE -ne 0 ] && [ -n "$OUTPUT" ]; then
echo "has_breaking=true" >> "$GITHUB_OUTPUT"
else
echo "has_breaking=false" >> "$GITHUB_OUTPUT"
fi
# Save output for comment step (handle multiline)
{
echo "details<<EOF"
echo "$OUTPUT"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Report breaking changes
if: always()
uses: actions/github-script@v8
env:
HAS_BREAKING: ${{ steps.griffe.outputs.has_breaking }}
GRIFFE_OUTPUT: ${{ steps.griffe.outputs.details }}
with:
script: |
const pr = context.payload.pull_request;
const body = pr.body || '';
const hasBreaking = process.env.HAS_BREAKING === 'true';
const griffeOutput = process.env.GRIFFE_OUTPUT || '';
// Check if BREAKING CHANGE is documented
const hasBreakingChangeDoc = /BREAKING CHANGE:/i.test(body) ||
/breaking change/i.test(body);
// Find existing bot comment
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number
});
const marker = '<!-- breaking-change-detection -->';
const botComment = comments.data.find(c =>
c.body.includes(marker)
);
if (!hasBreaking) {
// No breaking changes - remove old comment if it exists
if (botComment) {
await github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id
});
}
console.log('✅ No breaking changes detected');
return;
}
// Build report
let report = `${marker}\n`;
report += '## ⚠️ API Breaking Changes Detected\n\n';
report += 'The following breaking changes were detected by [griffe](https://mkdocstrings.github.io/griffe/):\n\n';
report += '```\n';
report += griffeOutput.trim();
report += '\n```\n\n';
if (!hasBreakingChangeDoc) {
report += '### ❌ Required Actions\n\n';
report += 'Breaking changes detected but not documented!\n\n';
report += '**You must:**\n';
report += '1. Add `BREAKING CHANGE:` footer to your commit message\n';
report += '2. Document the breaking change in the PR description\n';
report += '3. Add migration guide to CHANGELOG.md\n';
report += '4. Update documentation\n\n';
report += '**Commit message format:**\n';
report += '```\n';
report += 'feat: description of change\n\n';
report += 'BREAKING CHANGE: describe what broke and how to migrate.\n';
report += '```\n';
} else {
report += '### ✅ Breaking Change Documented\n\n';
report += 'This PR includes breaking change documentation.\n\n';
report += '**Before merging, verify:**\n';
report += '- [ ] Migration guide in CHANGELOG.md\n';
report += '- [ ] Documentation updated\n';
report += '- [ ] Version will be bumped appropriately (major version)\n';
}
// Create or update comment
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: report
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: report
});
}
// Fail if not documented
if (!hasBreakingChangeDoc) {
core.setFailed(
'❌ Breaking changes detected but not documented! ' +
'Add BREAKING CHANGE: footer to commit message and document in PR description.'
);
} else {
console.log('✅ Breaking changes properly documented');
}