Skip to content

Commit fc7301a

Browse files
cguldnerclaude
andcommitted
Add spec_update workflow for automated API spec updates
Add a GitHub Actions workflow that updates the dropbox-api-spec submodule, regenerates Java SDK code via Gradle, and opens a PR. Uses OIDC + GitHub App token via AWS Secrets Manager, closes superseded PRs, and labels for tracking. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 754a2bb commit fc7301a

1 file changed

Lines changed: 141 additions & 0 deletions

File tree

‎.github/workflows/spec_update.yml‎

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
name: Spec Update
2+
on:
3+
workflow_dispatch:
4+
repository_dispatch:
5+
types: [spec_update]
6+
7+
permissions:
8+
id-token: write
9+
contents: read
10+
11+
jobs:
12+
Update:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Configure AWS credentials
16+
uses: aws-actions/configure-aws-credentials@v6
17+
with:
18+
role-to-assume: arn:aws:iam::082972943155:role/oidc-github-dropbox-dropbox-sdk-java-repo
19+
aws-region: us-west-2
20+
21+
- name: Fetch GitHub App credentials from Secrets Manager
22+
uses: aws-actions/aws-secretsmanager-get-secrets@v3
23+
with:
24+
secret-ids: |
25+
SDK_UPDATER,sdk-updater-github-app
26+
parse-json-secrets: true
27+
28+
- name: Generate GitHub App installation token
29+
id: app-token
30+
uses: actions/create-github-app-token@v3
31+
with:
32+
client-id: ${{ env.SDK_UPDATER_CLIENT_ID }}
33+
private-key: ${{ env.SDK_UPDATER_PRIVATE_KEY }}
34+
35+
- uses: actions/checkout@v7
36+
- name: Set up JDK 21
37+
uses: actions/setup-java@v5
38+
with:
39+
java-version: '21'
40+
distribution: 'zulu'
41+
- name: Set up Python
42+
uses: actions/setup-python@v6
43+
with:
44+
python-version: '3.9.14'
45+
- run: python -m pip install ply six packaging
46+
- name: Get current time
47+
uses: 1466587594/get-current-time@v2
48+
id: current-time
49+
with:
50+
format: YYYY_MM_DD
51+
utcOffset: "-08:00"
52+
- name: Grant execute permissions
53+
run: chmod +x gradlew && chmod +x update-submodules
54+
- name: Set up submodules
55+
run: ./update-submodules
56+
- name: Update spec submodule
57+
run: |
58+
git submodule update --remote core/src/main/stone
59+
- name: Generate Branch Name
60+
id: git-branch
61+
env:
62+
FORMATTED_TIME: ${{ steps.current-time.outputs.formattedTime }}
63+
run: |
64+
echo "branch=spec_update_${FORMATTED_TIME}" >> "$GITHUB_OUTPUT"
65+
- name: Generate Num Diffs
66+
id: git-diff-num
67+
run: |
68+
diffs=$(git diff --submodule core/src/main/stone | grep ">" | wc -l)
69+
echo "Number of Spec diffs: $diffs"
70+
echo "num-diff=$diffs" >> "$GITHUB_OUTPUT"
71+
- name: Generate Diff
72+
id: git-diff
73+
env:
74+
NUM_DIFF: ${{ steps.git-diff-num.outputs.num-diff }}
75+
run: |
76+
cd core/src/main/stone
77+
gitdiff=$(git log -n "$NUM_DIFF" --pretty="format:%n %H %n%n %b")
78+
commit="Automated Spec Update $gitdiff"
79+
while true; do
80+
delimiter="SPEC_UPDATE_EOF_$(python -c 'import uuid; print(uuid.uuid4())')"
81+
if ! grep -Fxq "$delimiter" <<< "$commit"; then
82+
break
83+
fi
84+
done
85+
{
86+
printf 'commit<<%s\n' "$delimiter"
87+
printf '%s\n' "$commit"
88+
printf '%s\n' "$delimiter"
89+
} >> "$GITHUB_OUTPUT"
90+
cd ../../../..
91+
- name: Generate Stone
92+
run: ./gradlew :core:generateStone
93+
94+
- name: Close Old Pull Requests
95+
id: close-old-prs
96+
if: steps.git-diff-num.outputs.num-diff != 0
97+
run: |
98+
closed=""
99+
while read -r pr_num; do
100+
echo "Closing old PR #$pr_num"
101+
gh pr close "$pr_num" --delete-branch
102+
closed="${closed:+$closed,}$pr_num"
103+
done < <(gh pr list --label "automated-spec-update" --state open --json number --jq '.[].number')
104+
echo "closed=$closed" >> "$GITHUB_OUTPUT"
105+
shell: bash
106+
env:
107+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
108+
109+
- name: Create Pull Request
110+
id: create-pr
111+
uses: peter-evans/create-pull-request@v8
112+
if: steps.git-diff-num.outputs.num-diff != 0
113+
with:
114+
token: ${{ steps.app-token.outputs.token }}
115+
commit-message: |
116+
${{ steps.git-diff.outputs.commit}}
117+
branch: ${{ steps.git-branch.outputs.branch }}
118+
delete-branch: true
119+
title: 'Automated Spec Update - ${{ steps.current-time.outputs.formattedTime }}'
120+
body: |
121+
${{ steps.git-diff.outputs.commit}}
122+
base: 'main'
123+
labels: |
124+
automated-spec-update
125+
draft: false
126+
127+
- name: Comment on closed PRs
128+
if: steps.create-pr.outputs.pull-request-number && steps.close-old-prs.outputs.closed
129+
run: |
130+
IFS=',' read -ra prs <<< "${{ steps.close-old-prs.outputs.closed }}"
131+
for pr_num in "${prs[@]}"; do
132+
gh pr comment "$pr_num" --body "Superseded by #${{ steps.create-pr.outputs.pull-request-number }}"
133+
done
134+
env:
135+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
136+
137+
# - name: Enable Pull Request Automerge
138+
# if: steps.create-pr.outputs.pull-request-number
139+
# run: gh pr merge --merge --auto "${{ steps.create-pr.outputs.pull-request-number }}"
140+
# env:
141+
# GH_TOKEN: ${{ steps.app-token.outputs.token }}

0 commit comments

Comments
 (0)