Skip to content

Commit e4b2876

Browse files
committed
Add scripts for syncing api.md
1 parent 2d24fa9 commit e4b2876

11 files changed

Lines changed: 797 additions & 5 deletions

.github/workflows/commenter.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: API.md Consistency Commenter
2+
3+
on:
4+
workflow_run:
5+
workflows: ["API.md Consistency"]
6+
types: [completed]
7+
8+
permissions:
9+
actions: read
10+
pull-requests: write
11+
12+
jobs:
13+
commenter:
14+
if: ${{ github.event.workflow_run.event == 'pull_request' }}
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Prepare artifact directory
18+
run: mkdir -p "${{ runner.temp }}/api-md-comment"
19+
20+
- name: Download comment artifact
21+
uses: actions/download-artifact@v8
22+
with:
23+
name: api-md-comment
24+
run-id: ${{ github.event.workflow_run.id }}
25+
github-token: ${{ secrets.GITHUB_TOKEN }}
26+
path: ${{ runner.temp }}/api-md-comment
27+
28+
- name: Create or update PR comment
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
COMMENT_FILE: ${{ runner.temp }}/api-md-comment/comment.json
32+
DEFAULT_PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
33+
shell: bash
34+
run: |
35+
set -euo pipefail
36+
python scripts/api_md_workflow/post_comment.py

.github/workflows/consistency.yml

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
name: API.md Consistency
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened, ready_for_review]
6+
paths:
7+
- "sdk/**"
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
consistency:
14+
if: ${{ !github.event.pull_request.draft }}
15+
runs-on: ubuntu-latest
16+
outputs:
17+
changed_count: ${{ steps.changed.outputs.count || '0' }}
18+
mismatch_count: ${{ steps.consistency.outputs.mismatch_count || '0' }}
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v6
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Setup Python
26+
uses: actions/setup-python@v5
27+
with:
28+
python-version: "3.12"
29+
30+
- name: Find changed SDK packages
31+
id: changed
32+
env:
33+
API_MD_BASE_REF: ${{ github.event.pull_request.base.ref }}
34+
API_MD_PACKAGES_FILE: .artifacts/affected_package_dirs.txt
35+
API_MD_CHANGED_FILE: .artifacts/changed_package_dirs.txt
36+
shell: bash
37+
run: |
38+
set -euo pipefail
39+
python scripts/api_md_workflow/find_affected.py
40+
41+
- name: Generate API.md for affected packages
42+
if: ${{ steps.changed.outputs.count != '0' }}
43+
env:
44+
API_MD_PACKAGES_FILE: .artifacts/affected_package_dirs.txt
45+
shell: bash
46+
run: |
47+
set -euo pipefail
48+
python -m pip install --upgrade pip
49+
python scripts/api_md_workflow/regenerate.py
50+
51+
- name: Check API.md consistency
52+
id: consistency
53+
env:
54+
API_MD_PACKAGES_FILE: .artifacts/affected_package_dirs.txt
55+
API_MD_MISMATCHES_FILE: .artifacts/mismatched_api_files.txt
56+
shell: bash
57+
run: |
58+
set -euo pipefail
59+
if [ "${{ steps.changed.outputs.count }}" = "0" ]; then
60+
echo "mismatch_count=0" >> "$GITHUB_OUTPUT"
61+
exit 0
62+
fi
63+
64+
python scripts/api_md_workflow/find_mismatches.py
65+
66+
- name: Upload apply context artifact
67+
if: always()
68+
uses: actions/upload-artifact@v7
69+
with:
70+
name: api-md-context
71+
path: |
72+
.artifacts/affected_package_dirs.txt
73+
.artifacts/mismatched_api_files.txt
74+
retention-days: 1
75+
76+
- name: Build PR comment payload
77+
if: always()
78+
shell: bash
79+
env:
80+
PR_NUMBER: ${{ github.event.pull_request.number }}
81+
REPOSITORY: ${{ github.repository }}
82+
RUN_ID: ${{ github.run_id }}
83+
RUN_ATTEMPT: ${{ github.run_attempt }}
84+
MISMATCH_COUNT: ${{ steps.consistency.outputs.mismatch_count || '0' }}
85+
CHANGED_COUNT: ${{ steps.changed.outputs.count || '0' }}
86+
API_MD_MISMATCHES_FILE: .artifacts/mismatched_api_files.txt
87+
API_MD_COMMENT_FILE: .artifacts/comment/comment.json
88+
run: |
89+
set -euo pipefail
90+
python scripts/api_md_workflow/build_comment_payload.py
91+
92+
- name: Upload comment artifact
93+
if: always()
94+
uses: actions/upload-artifact@v7
95+
with:
96+
name: api-md-comment
97+
path: .artifacts/comment/comment.json
98+
retention-days: 1
99+
100+
- name: Fail when API.md is out of date
101+
if: ${{ steps.changed.outputs.count != '0' && steps.consistency.outputs.mismatch_count != '0' }}
102+
shell: bash
103+
run: |
104+
echo "Generated API.md does not match committed API.md, or API.md is missing, for one or more affected packages."
105+
echo "Re-run this workflow to apply and commit updates to the same PR branch."
106+
exit 1
107+
108+
apply-updates:
109+
name: Apply API.md updates on rerun
110+
needs: consistency
111+
if: >
112+
github.run_attempt > 1 &&
113+
needs.consistency.outputs.mismatch_count != '0' &&
114+
github.event.pull_request.head.repo.full_name == github.repository
115+
runs-on: ubuntu-latest
116+
permissions:
117+
contents: write
118+
pull-requests: write
119+
steps:
120+
- name: Checkout PR head branch
121+
uses: actions/checkout@v6
122+
with:
123+
ref: ${{ github.event.pull_request.head.ref }}
124+
fetch-depth: 0
125+
126+
- name: Setup Python
127+
uses: actions/setup-python@v5
128+
with:
129+
python-version: "3.12"
130+
131+
- name: Download apply context
132+
uses: actions/download-artifact@v8
133+
with:
134+
name: api-md-context
135+
path: .artifacts
136+
137+
- name: Regenerate API.md for affected packages
138+
env:
139+
API_MD_PACKAGES_FILE: .artifacts/affected_package_dirs.txt
140+
shell: bash
141+
run: |
142+
set -euo pipefail
143+
144+
if [ ! -s .artifacts/affected_package_dirs.txt ]; then
145+
echo "No affected packages found; nothing to apply."
146+
exit 0
147+
fi
148+
149+
python -m pip install --upgrade pip
150+
python scripts/api_md_workflow/regenerate.py
151+
152+
- name: Commit and push API.md updates
153+
id: commit
154+
shell: bash
155+
run: |
156+
set -euo pipefail
157+
158+
if [ ! -f .artifacts/mismatched_api_files.txt ] || [ ! -s .artifacts/mismatched_api_files.txt ]; then
159+
echo "created=false" >> "$GITHUB_OUTPUT"
160+
exit 0
161+
fi
162+
163+
git config user.name "github-actions[bot]"
164+
git config user.email "github-actions[bot]@users.noreply.github.com"
165+
166+
while IFS= read -r api_file; do
167+
if [ -f "${api_file}" ] && ! git diff --quiet -- "${api_file}"; then
168+
git add "${api_file}"
169+
fi
170+
done < .artifacts/mismatched_api_files.txt
171+
172+
if git diff --cached --quiet; then
173+
echo "created=false" >> "$GITHUB_OUTPUT"
174+
exit 0
175+
fi
176+
177+
git commit -m "Update API.md for PR #${{ github.event.pull_request.number }}"
178+
git push origin "HEAD:${{ github.event.pull_request.head.ref }}"
179+
180+
echo "created=true" >> "$GITHUB_OUTPUT"
181+
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
182+
183+
- name: Build apply result payload
184+
shell: bash
185+
env:
186+
COMMIT_CREATED: ${{ steps.commit.outputs.created || 'false' }}
187+
COMMIT_SHA: ${{ steps.commit.outputs.sha || '' }}
188+
PR_NUMBER: ${{ github.event.pull_request.number }}
189+
HEAD_REF: ${{ github.event.pull_request.head.ref }}
190+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
191+
API_MD_APPLY_RESULT_FILE: .artifacts/comment/apply-result.json
192+
run: |
193+
set -euo pipefail
194+
python scripts/api_md_workflow/build_apply_result_payload.py
195+
196+
- name: Post apply result comment
197+
env:
198+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
199+
COMMENT_FILE: .artifacts/comment/apply-result.json
200+
shell: bash
201+
run: |
202+
set -euo pipefail
203+
python scripts/api_md_workflow/post_comment.py

0 commit comments

Comments
 (0)