Skip to content

Commit 098a432

Browse files
authored
ci: use GitHub App token for workflows that open PRs and push commits (#1174)
* ci: use GitHub App token for workflows that open PRs and push commits Workflows triggered by GITHUB_TOKEN do not start downstream workflow runs, so the PRs opened by the daily metadata and catalog-data jobs, and the auto-update commits pushed onto contributor PR branches by update-tools, were landing without CI runs. Switch to a GitHub App installation token (the same RELEASE_APP_* pattern already used in toolhive-registry-server) for the steps that open PRs or push commits, so CI runs as expected. Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com> * ci: tighten app token usage (perms, concurrency, bot identity) - Scope the minted installation token to only contents:write and pull_requests:write via permission-* inputs, instead of inheriting the full set of permissions the GitHub App has on the installation. - Move workflow-level permissions on update-metadata.yml to the job level, leaving the workflow with permissions: {}. - Add a concurrency group to update-metadata.yml (workflow-level) and to ci.yml's update-catalog-data job, so overlapping schedule and workflow_dispatch runs cannot race on the force-pushed branch. - Set git author/committer to the App's bot identity (<id>+<app-slug>[bot]@users.noreply.github.com) in all three jobs that commit, so commits are unambiguously attributed and can be targeted by branch-protection rules. Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com> --------- Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
1 parent 7940114 commit 098a432

3 files changed

Lines changed: 84 additions & 13 deletions

File tree

.github/workflows/ci.yml

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,34 @@ jobs:
7777
permissions:
7878
contents: write
7979
pull-requests: write
80+
concurrency:
81+
group: update-catalog-data
82+
cancel-in-progress: false
8083
needs: [lint, validate-and-test]
8184
if: github.ref == 'refs/heads/main' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
8285
steps:
86+
- name: Generate app token
87+
id: app-token
88+
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
89+
with:
90+
client-id: ${{ vars.RELEASE_APP_CLIENT_ID }}
91+
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
92+
permission-contents: write
93+
permission-pull-requests: write
94+
95+
- name: Get app user ID
96+
id: app-user
97+
env:
98+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
99+
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
100+
run: |
101+
USER_ID=$(gh api "/users/${APP_SLUG}[bot]" --jq .id)
102+
echo "id=$USER_ID" >> "$GITHUB_OUTPUT"
103+
83104
- name: Checkout code
84105
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
106+
with:
107+
token: ${{ steps.app-token.outputs.token }}
85108

86109
- name: Set up Go
87110
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
@@ -111,8 +134,8 @@ jobs:
111134
run: |
112135
BRANCH="update-catalog-data-${VERSION}"
113136
114-
git config --local user.email "action@github.com"
115-
git config --local user.name "GitHub Action"
137+
git config --local user.name "${APP_SLUG}[bot]"
138+
git config --local user.email "${APP_USER_ID}+${APP_SLUG}[bot]@users.noreply.github.com"
116139
117140
# Create or reset the branch
118141
git checkout -B "$BRANCH"
@@ -162,8 +185,10 @@ jobs:
162185
gh pr merge "$BRANCH" --auto --squash || true
163186
fi
164187
env:
165-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
188+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
166189
VERSION: ${{ steps.metadata.outputs.version }}
190+
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
191+
APP_USER_ID: ${{ steps.app-user.outputs.id }}
167192

168193
build-pr:
169194
name: Build Check

.github/workflows/update-metadata.yml

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,42 @@ on:
1212
default: '5'
1313
type: string
1414

15-
permissions:
16-
contents: write
17-
pull-requests: write
15+
permissions: {}
16+
17+
concurrency:
18+
group: ${{ github.workflow }}
19+
cancel-in-progress: false
1820

1921
jobs:
2022
update-metadata:
2123
name: Update Server Metadata
2224
runs-on: ubuntu-latest
25+
permissions:
26+
contents: write
27+
pull-requests: write
2328
steps:
29+
- name: Generate app token
30+
id: app-token
31+
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
32+
with:
33+
client-id: ${{ vars.RELEASE_APP_CLIENT_ID }}
34+
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
35+
permission-contents: write
36+
permission-pull-requests: write
37+
38+
- name: Get app user ID
39+
id: app-user
40+
env:
41+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
42+
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
43+
run: |
44+
USER_ID=$(gh api "/users/${APP_SLUG}[bot]" --jq .id)
45+
echo "id=$USER_ID" >> "$GITHUB_OUTPUT"
46+
2447
- name: Checkout code
2548
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
2649
with:
27-
token: ${{ secrets.GITHUB_TOKEN }}
50+
token: ${{ steps.app-token.outputs.token }}
2851

2952
- name: Set up Go
3053
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
@@ -42,11 +65,14 @@ jobs:
4265
INPUT_COUNT: ${{ github.event.inputs.count || '5' }}
4366

4467
- name: Switch to metadata branch
68+
env:
69+
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
70+
APP_USER_ID: ${{ steps.app-user.outputs.id }}
4571
run: |
4672
BRANCH="catalog-update-metadata"
4773
48-
git config --local user.email "action@github.com"
49-
git config --local user.name "GitHub Action"
74+
git config --local user.name "${APP_SLUG}[bot]"
75+
git config --local user.email "${APP_USER_ID}+${APP_SLUG}[bot]@users.noreply.github.com"
5076
5177
# Fetch remote branch if it exists so we can build on it
5278
git fetch origin "$BRANCH" 2>/dev/null || true
@@ -118,5 +144,5 @@ jobs:
118144
gh pr merge "$BRANCH" --auto --squash || true
119145
fi
120146
env:
121-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
147+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
122148
UPDATE_COUNT: ${{ steps.count.outputs.value }}

.github/workflows/update-tools.yml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,28 @@ jobs:
351351
if: always() && needs.detect-changes.outputs.has-changes == 'true' && github.event_name == 'pull_request'
352352
runs-on: ubuntu-latest
353353
steps:
354+
- name: Generate app token
355+
id: app-token
356+
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
357+
with:
358+
client-id: ${{ vars.RELEASE_APP_CLIENT_ID }}
359+
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
360+
permission-contents: write
361+
permission-pull-requests: write
362+
363+
- name: Get app user ID
364+
id: app-user
365+
env:
366+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
367+
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
368+
run: |
369+
USER_ID=$(gh api "/users/${APP_SLUG}[bot]" --jq .id)
370+
echo "id=$USER_ID" >> "$GITHUB_OUTPUT"
371+
354372
- name: Checkout code
355373
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
356374
with:
357-
token: ${{ secrets.GITHUB_TOKEN }}
375+
token: ${{ steps.app-token.outputs.token }}
358376
ref: ${{ github.head_ref || github.ref }}
359377

360378
- name: Download all commit info artifacts
@@ -379,8 +397,8 @@ jobs:
379397
- name: Commit and push all changes
380398
if: steps.check_changes.outputs.changes == 'true'
381399
run: |
382-
git config --local user.email "action@github.com"
383-
git config --local user.name "GitHub Action"
400+
git config --local user.name "${APP_SLUG}[bot]"
401+
git config --local user.email "${APP_USER_ID}+${APP_SLUG}[bot]@users.noreply.github.com"
384402
385403
# Pull any remote changes first to avoid conflicts
386404
git pull origin "$BRANCH_REF" --rebase
@@ -436,6 +454,8 @@ jobs:
436454
env:
437455
BRANCH_REF: ${{ github.head_ref || github.ref_name }}
438456
GH_ACTOR: ${{ github.actor }}
457+
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
458+
APP_USER_ID: ${{ steps.app-user.outputs.id }}
439459

440460
comment-summary:
441461
name: Post Summary Comment

0 commit comments

Comments
 (0)