Skip to content

Commit 0027409

Browse files
committed
Update changeset.yaml
1 parent 08b12d6 commit 0027409

1 file changed

Lines changed: 191 additions & 0 deletions

File tree

.github/workflows/changeset.yaml

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Copyright 2025 LiveKit, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: Changeset Check
16+
17+
on:
18+
pull_request:
19+
branches: [main]
20+
21+
permissions:
22+
contents: read
23+
pull-requests: write
24+
25+
jobs:
26+
changeset:
27+
name: Changeset & Breaking Change Check
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 0
33+
34+
- name: Check for changeset entries
35+
id: changeset
36+
run: |
37+
count=$(find .changes -maxdepth 1 -type f ! -name '.*' 2>/dev/null | wc -l | tr -d ' ')
38+
echo "count=$count" >> "$GITHUB_OUTPUT"
39+
40+
has_major=false
41+
if [ "$count" -gt 0 ]; then
42+
if grep -rq '^major ' .changes/ 2>/dev/null; then
43+
has_major=true
44+
fi
45+
fi
46+
echo "has_major=$has_major" >> "$GITHUB_OUTPUT"
47+
48+
- uses: ./.github/actions/setup-flutter
49+
50+
- name: Detect breaking changes
51+
id: breaking
52+
run: |
53+
BASE_TAG=$(git describe --tags --abbrev=0 origin/main 2>/dev/null || echo "")
54+
if [ -z "$BASE_TAG" ]; then
55+
echo "No base tag found, skipping breaking change detection"
56+
echo "has_breaking=false" >> "$GITHUB_OUTPUT"
57+
exit 0
58+
fi
59+
60+
echo "Comparing public API against $BASE_TAG"
61+
62+
dart pub global activate dart_apitool
63+
REPO_URL="git://${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}:${BASE_TAG}"
64+
65+
DIFF_OUTPUT=$(dart-apitool diff \
66+
--old "$REPO_URL" \
67+
--new . \
68+
--force-use-flutter 2>&1) || true
69+
70+
echo "--- dart-apitool output ---"
71+
echo "$DIFF_OUTPUT"
72+
echo "---"
73+
74+
# Extract breaking changes from the output
75+
BREAKING_LINES=$(echo "$DIFF_OUTPUT" | grep -i "breaking" || true)
76+
77+
if [ -n "$BREAKING_LINES" ]; then
78+
echo "has_breaking=true" >> "$GITHUB_OUTPUT"
79+
{
80+
echo "details<<EOF"
81+
echo "$DIFF_OUTPUT"
82+
echo "EOF"
83+
} >> "$GITHUB_OUTPUT"
84+
else
85+
echo "has_breaking=false" >> "$GITHUB_OUTPUT"
86+
echo "No breaking changes detected"
87+
fi
88+
89+
- name: Manage PR comments
90+
uses: actions/github-script@v7
91+
with:
92+
script: |
93+
const changesetCount = parseInt('${{ steps.changeset.outputs.count }}');
94+
const hasMajor = '${{ steps.changeset.outputs.has_major }}' === 'true';
95+
const hasBreaking = '${{ steps.breaking.outputs.has_breaking }}' === 'true';
96+
const details = `${{ steps.breaking.outputs.details }}`.trim();
97+
98+
const { data: comments } = await github.rest.issues.listComments({
99+
owner: context.repo.owner,
100+
repo: context.repo.repo,
101+
issue_number: context.issue.number,
102+
});
103+
104+
// --- Changeset missing comment ---
105+
const changesetMarker = '<!-- changeset-check -->';
106+
const existingChangeset = comments.find(c => c.body.includes(changesetMarker));
107+
108+
if (changesetCount === 0) {
109+
const body = [
110+
changesetMarker,
111+
'> [!WARNING]',
112+
'> **No changeset found**',
113+
'>',
114+
'> If this PR includes user-facing changes, please add a changeset file in `.changes/`',
115+
'',
116+
'**Format:** `level type="kind" "description"`',
117+
'',
118+
'```',
119+
'patch type="fixed" "Fix audio frame generation"',
120+
'minor type="added" "Add support for custom audio processing"',
121+
'major type="changed" "Breaking: Rename Room.connect() to Room.join()"',
122+
'```',
123+
].join('\n');
124+
125+
if (existingChangeset) {
126+
await github.rest.issues.updateComment({
127+
owner: context.repo.owner,
128+
repo: context.repo.repo,
129+
comment_id: existingChangeset.id,
130+
body,
131+
});
132+
} else {
133+
await github.rest.issues.createComment({
134+
owner: context.repo.owner,
135+
repo: context.repo.repo,
136+
issue_number: context.issue.number,
137+
body,
138+
});
139+
}
140+
} else if (existingChangeset) {
141+
await github.rest.issues.deleteComment({
142+
owner: context.repo.owner,
143+
repo: context.repo.repo,
144+
comment_id: existingChangeset.id,
145+
});
146+
}
147+
148+
// --- Breaking change without major changeset comment ---
149+
const breakingMarker = '<!-- breaking-change-check -->';
150+
const existingBreaking = comments.find(c => c.body.includes(breakingMarker));
151+
152+
if (hasBreaking && !hasMajor) {
153+
const body = [
154+
breakingMarker,
155+
'> [!CAUTION]',
156+
'> **Breaking change detected without major changeset**',
157+
'',
158+
'`dart-apitool` detected the following breaking changes:',
159+
'',
160+
'```',
161+
details,
162+
'```',
163+
'',
164+
'If this is intentional, please add a changeset with `major` level in `.changes/`:',
165+
'```',
166+
'major type="changed" "Description of breaking change"',
167+
'```',
168+
].join('\n');
169+
170+
if (existingBreaking) {
171+
await github.rest.issues.updateComment({
172+
owner: context.repo.owner,
173+
repo: context.repo.repo,
174+
comment_id: existingBreaking.id,
175+
body,
176+
});
177+
} else {
178+
await github.rest.issues.createComment({
179+
owner: context.repo.owner,
180+
repo: context.repo.repo,
181+
issue_number: context.issue.number,
182+
body,
183+
});
184+
}
185+
} else if (existingBreaking) {
186+
await github.rest.issues.deleteComment({
187+
owner: context.repo.owner,
188+
repo: context.repo.repo,
189+
comment_id: existingBreaking.id,
190+
});
191+
}

0 commit comments

Comments
 (0)