Skip to content

Commit 0bc9ca2

Browse files
cguldnerclaude
andauthored
Update spec_update workflow to use GitHub App token and modern patterns (#402)
Switch from repo-specific PAT secret to shared GitHub App token via AWS Secrets Manager, use random delimiter for heredoc-based multiline output, close superseded PRs before opening new ones, and add the automated-spec-update label for tracking. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bbed058 commit 0bc9ca2

1 file changed

Lines changed: 65 additions & 19 deletions

File tree

.github/workflows/spec_update.yml

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,37 @@ on:
44
repository_dispatch:
55
types: [spec_update]
66

7-
permissions: # least privilege; the Update job overrides this for OIDC
7+
permissions:
8+
id-token: write
89
contents: read
910

1011
jobs:
1112
Update:
1213
runs-on: ubuntu-latest
13-
permissions: # required for OIDC authentication
14-
id-token: write
15-
contents: read
1614
steps:
17-
- uses: actions/checkout@v7
18-
- name: Configure AWS credentials (OIDC)
15+
- name: Configure AWS credentials
1916
uses: aws-actions/configure-aws-credentials@v6
2017
with:
2118
role-to-assume: arn:aws:iam::082972943155:role/oidc-github-dropbox-dropbox-sdk-dotnet-repo
2219
aws-region: us-west-2
23-
- name: Get spec-update token from AWS Secrets Manager
20+
21+
- name: Fetch GitHub App credentials from Secrets Manager
2422
uses: aws-actions/aws-secretsmanager-get-secrets@v3
2523
with:
2624
secret-ids: |
27-
SPEC_UPDATE_TOKEN,spec-update-token-dropbox-sdk-dotnet
28-
parse-json-secrets: false
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
2936
- name: Setup Python environment
30-
uses: actions/setup-python@v6.3.0
37+
uses: actions/setup-python@v6
3138
with:
3239
python-version: '3.11'
3340
- name: Get current time
@@ -64,30 +71,69 @@ jobs:
6471
cd spec
6572
gitdiff=$(git log -n "$NUM_DIFF" --pretty="format:%n %H %n%n %b")
6673
commit="Automated Spec Update $gitdiff"
74+
while true; do
75+
delimiter="SPEC_UPDATE_EOF_$(python -c 'import uuid; print(uuid.uuid4())')"
76+
if ! grep -Fxq "$delimiter" <<< "$commit"; then
77+
break
78+
fi
79+
done
6780
{
68-
echo "commit<<SPEC_UPDATE_EOF"
69-
echo "$commit"
70-
echo "SPEC_UPDATE_EOF"
81+
printf 'commit<<%s\n' "$delimiter"
82+
printf '%s\n' "$commit"
83+
printf '%s\n' "$delimiter"
7184
} >> "$GITHUB_OUTPUT"
85+
cd ..
7286
- name: Generate New Routes
7387
run: |
7488
python generator/generate_routes.py
7589
git add dropbox-sdk-dotnet/Dropbox.Api/Generated
7690
git add spec
91+
92+
- name: Close Old Pull Requests
93+
id: close-old-prs
94+
if: steps.git-diff-num.outputs.num-diff != 0
95+
run: |
96+
closed=""
97+
while read -r pr_num; do
98+
echo "Closing old PR #$pr_num"
99+
gh pr close "$pr_num" --delete-branch
100+
closed="${closed:+$closed,}$pr_num"
101+
done < <(gh pr list --label "automated-spec-update" --state open --json number --jq '.[].number')
102+
echo "closed=$closed" >> "$GITHUB_OUTPUT"
103+
shell: bash
104+
env:
105+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
106+
77107
- name: Create Pull Request
78-
uses: peter-evans/create-pull-request@v8.1.1
108+
id: create-pr
109+
uses: peter-evans/create-pull-request@v8
79110
if: steps.git-diff-num.outputs.num-diff != 0
80111
with:
81-
token: ${{ env.SPEC_UPDATE_TOKEN }}
112+
token: ${{ steps.app-token.outputs.token }}
82113
commit-message: |
83114
${{ steps.git-diff.outputs.commit}}
84115
branch: ${{ steps.git-branch.outputs.branch }}
85116
delete-branch: true
86-
title: 'Automated Spec Update'
117+
title: 'Automated Spec Update - ${{ steps.current-time.outputs.formattedTime }}'
87118
body: |
88119
${{ steps.git-diff.outputs.commit}}
89120
base: 'main'
90-
team-reviewers: |
91-
owners
92-
maintainers
121+
labels: |
122+
automated-spec-update
93123
draft: false
124+
125+
- name: Comment on closed PRs
126+
if: steps.create-pr.outputs.pull-request-number && steps.close-old-prs.outputs.closed
127+
run: |
128+
IFS=',' read -ra prs <<< "${{ steps.close-old-prs.outputs.closed }}"
129+
for pr_num in "${prs[@]}"; do
130+
gh pr comment "$pr_num" --body "Superseded by #${{ steps.create-pr.outputs.pull-request-number }}"
131+
done
132+
env:
133+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
134+
135+
# - name: Enable Pull Request Automerge
136+
# if: steps.create-pr.outputs.pull-request-number
137+
# run: gh pr merge --merge --auto "${{ steps.create-pr.outputs.pull-request-number }}"
138+
# env:
139+
# GH_TOKEN: ${{ steps.app-token.outputs.token }}

0 commit comments

Comments
 (0)