Skip to content

Commit 2257b7c

Browse files
claudeshaungrady
authored andcommitted
ci: split typedoc workflow to keep PR runs read-only
Previously the docs workflow ran author-controlled code (install + build:docs) on pull_request while holding `contents: write` and pushing a commit back to the PR branch. For same-repo PRs that exposed a write-capable token to untrusted code. Split into two jobs: - verify-docs (pull_request): read-only (`contents: read`), no push. Generates docs and reports drift as a non-blocking warning. - publish-docs (push to main): trusted code only, regenerates and commits docs with `contents: write`. Drop the bot-commit-amend/force-push logic; docs now land as a single plain commit on main per merge.
1 parent 6de28ba commit 2257b7c

1 file changed

Lines changed: 54 additions & 23 deletions

File tree

.github/workflows/typedoc.yml

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,68 @@ name: Update TypeDoc Documentation
33
on:
44
pull_request:
55
branches: ['*']
6+
push:
7+
branches:
8+
- main
69

7-
# Least privilege: this workflow commits regenerated docs back to the PR branch,
8-
# so it needs write access to repository contents and nothing else.
9-
permissions:
10-
contents: write
11-
12-
# Serialize doc-regeneration per branch so concurrent runs don't race on pushes.
10+
# Serialize per ref; newer runs supersede older ones.
1311
concurrency:
1412
group: ${{ github.workflow }}-${{ github.ref }}
1513
cancel-in-progress: true
1614

1715
jobs:
18-
update-docs:
16+
# On pull requests we run author-controlled code (install + build:docs), so
17+
# this job is strictly read-only: no write token, no push. It only verifies
18+
# that docs generate cleanly and reports any drift as a non-blocking warning
19+
# (the push-to-main job below regenerates and commits docs after merge).
20+
verify-docs:
21+
if: github.event_name == 'pull_request'
22+
runs-on: ubuntu-latest
23+
permissions:
24+
contents: read
25+
26+
steps:
27+
- name: Checkout code
28+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
29+
with:
30+
persist-credentials: false
31+
32+
- name: Setup pnpm
33+
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
34+
35+
- name: Setup Node.js
36+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
37+
with:
38+
node-version: '22'
39+
cache: 'pnpm'
40+
41+
- name: Install dependencies
42+
run: pnpm install --frozen-lockfile
43+
44+
- name: Generate TypeDoc documentation
45+
run: pnpm run build:docs
46+
47+
- name: Report documentation drift
48+
run: |
49+
if [ -n "$(git status --porcelain docs/)" ]; then
50+
echo "::warning::Generated docs differ from committed docs; they will be updated automatically on merge to main."
51+
git --no-pager diff --stat docs/
52+
else
53+
echo "Documentation is up to date."
54+
fi
55+
56+
# On push to main the code is trusted, so this job regenerates docs and
57+
# commits them. This is the only place the workflow uses a write token.
58+
publish-docs:
59+
if: github.event_name == 'push'
1960
runs-on: ubuntu-latest
61+
permissions:
62+
contents: write
2063

2164
steps:
2265
- name: Checkout code
2366
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
2467
with:
25-
ref: ${{ github.head_ref }}
2668
fetch-depth: 0
2769

2870
- name: Setup pnpm
@@ -42,23 +84,12 @@ jobs:
4284

4385
- name: Commit documentation changes
4486
run: |
45-
if [ -n "$(git status --porcelain)" ]; then
87+
if [ -n "$(git status --porcelain docs/)" ]; then
4688
git config user.name "github-actions[bot]"
4789
git config user.email "github-actions[bot]@users.noreply.github.com"
48-
49-
# Check if last commit was from bot
50-
LAST_AUTHOR=$(git log -1 --pretty=format:'%an')
51-
if [ "$LAST_AUTHOR" = "github-actions[bot]" ]; then
52-
echo "Amending previous documentation commit"
53-
git add docs/
54-
git commit --amend --no-edit
55-
git push --force-with-lease
56-
else
57-
echo "Creating new documentation commit"
58-
git add docs/
59-
git commit -m "docs: update TypeDoc documentation [skip ci]"
60-
git push
61-
fi
90+
git add docs/
91+
git commit -m "docs: update TypeDoc documentation [skip ci]"
92+
git push
6293
else
6394
echo "No documentation changes detected"
6495
fi

0 commit comments

Comments
 (0)