Skip to content

Commit c404f36

Browse files
authored
Add Documentation Previews to PRs (#495)
Adds 3 workflows to automatically build a preview copy of the documentation whenever the docs are touched in a PR The action only ever creates one 'sticky' comment in the PR with a link to the docs preview, which gets edited. That way the PR thread isn't cluttered with bot comments. When the PR is closed, the cleanup action deletes its files and edits the comment one last time to clear the link.
2 parents 41f02d1 + dc63635 commit c404f36

4 files changed

Lines changed: 186 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Build PR Docs Preview
2+
3+
# Splitting the preview docs build into an (untrusted) build step (this one)
4+
# and a trusted deployment step helps prevent a class of issues that allow
5+
# secret exfiltration from a repo.
6+
# See https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
7+
permissions:
8+
contents: read
9+
10+
# When a new udpate is made to this PR, cancel any still-running builds from previous pushes
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
on:
16+
pull_request:
17+
paths:
18+
- 'docs/**'
19+
- '.github/workflows/docs**'
20+
types:
21+
- opened
22+
- synchronize
23+
- reopened
24+
workflow_dispatch:
25+
26+
jobs:
27+
build-preview:
28+
runs-on: ubuntu-latest
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@v4
32+
33+
- name: Set up Python
34+
uses: actions/setup-python@v5
35+
with:
36+
python-version: '3.12'
37+
cache: 'pip'
38+
39+
- name: Install dependencies
40+
run: |
41+
pip install .[docs]
42+
43+
- name: Build and mkdocs
44+
run: |
45+
mkdocs build --config-file docs/mkdocs.yml --site-dir ./site -v
46+
47+
- name: Upload preview artifact
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: pr-preview-docs-${{ github.event.number }}
51+
path: docs/site
52+
if-no-files-found: error
53+
retention-days: 7
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Remove PR Preview
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
concurrency:
12+
group: pr-cleanup-${{ github.event.pull_request.number }}
13+
cancel-in-progress: false
14+
15+
jobs:
16+
cleanup:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Create empty deploy folder
23+
run: mkdir -p empty
24+
25+
- name: Remove PR Preview folder using GitHub Pages Deploy Action
26+
uses: JamesIves/github-pages-deploy-action@v4
27+
with:
28+
branch: gh-pages
29+
folder: ./empty
30+
target-folder: pr-preview/pr-${{ github.event.pull_request.number }}
31+
token: ${{ secrets.GITHUB_TOKEN }}
32+
clean: true
33+
34+
- name: Get timestamp (UTC)
35+
id: ts
36+
run: echo "utc=$(date -u '+%Y-%m-%d %H:%M UTC')" >> "$GITHUB_OUTPUT"
37+
38+
- name: Post removal sticky PR comment
39+
uses: marocchino/sticky-pull-request-comment@v2
40+
with:
41+
number: ${{ github.event.pull_request.number }}
42+
header: pr-preview
43+
message: |
44+
Documentation Preview
45+
:---:
46+
Preview removed because the pull request was closed.
47+
Preview removed ${{ steps.ts.outputs.utc }}
48+
<!-- Sticky Pull Request Commentpr-preview -->
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
name: Deploy PR Docs Preview
2+
#
3+
# Triggers after 'Build PR Docs Preview' completes successfully.
4+
#
5+
on:
6+
workflow_run:
7+
workflows: [Build PR Docs Preview]
8+
types: [completed]
9+
10+
permissions:
11+
actions: read
12+
contents: write
13+
pages: write
14+
id-token: write
15+
pull-requests: write
16+
17+
concurrency:
18+
group: pr-docs-deploy-${{ github.event.workflow_run.id }}
19+
cancel-in-progress: true
20+
21+
jobs:
22+
deploy:
23+
if: >
24+
github.event.workflow_run.conclusion == 'success' &&
25+
github.event.workflow_run.event == 'pull_request'
26+
runs-on: ubuntu-latest
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
32+
- name: List artifacts
33+
env:
34+
GH_TOKEN: ${{ github.token }}
35+
run: gh api repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/artifacts
36+
37+
- name: Get PR number from artifact name
38+
id: pr
39+
env:
40+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41+
run: |
42+
PR_NUMBER=$(gh api repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/artifacts \
43+
--jq '.artifacts[].name | select(startswith("pr-preview-docs-")) | sub("^pr-preview-docs-"; "")' | head -n1)
44+
if [ -z "$PR_NUMBER" ]; then
45+
echo "Failed to determine PR number from artifacts" >&2
46+
exit 1
47+
fi
48+
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
49+
echo "Deploying preview for PR #$PR_NUMBER"
50+
51+
- name: Download artifact
52+
uses: dawidd6/action-download-artifact@v3
53+
with:
54+
run_id: ${{ github.event.workflow_run.id }}
55+
name: pr-preview-docs-${{ steps.pr.outputs.pr_number }}
56+
path: ./site
57+
58+
- name: List downloaded files (debug)
59+
run: find ./site -maxdepth 4 -type f | head -100
60+
61+
- name: Deploy PR Preview
62+
uses: JamesIves/github-pages-deploy-action@v4
63+
with:
64+
branch: gh-pages
65+
folder: ./site
66+
target-folder: pr-preview/pr-${{ steps.pr.outputs.pr_number }}
67+
token: ${{ secrets.GITHUB_TOKEN }}
68+
69+
- name: Get timestamp (UTC)
70+
id: ts
71+
run: echo "utc=$(date -u '+%Y-%m-%d %H:%M UTC')" >> "$GITHUB_OUTPUT"
72+
73+
- name: Post preview link as sticky PR comment
74+
uses: marocchino/sticky-pull-request-comment@v2
75+
with:
76+
number: ${{ steps.pr.outputs.pr_number }}
77+
header: pr-preview
78+
message: |
79+
[Documentation Preview](https://spylang.github.io/spy/pr-preview/pr-${{ steps.pr.outputs.pr_number }})
80+
:---:
81+
Preview documentation for PR #${{ steps.pr.outputs.pr_number }}.
82+
Last Updated: ${{ steps.ts.outputs.utc }}
83+
<!-- Sticky Pull Request Commentpr-preview -->

docs/src/contributing.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,5 @@ Once you're happy with your changes, add them to your git branch and push them t
7171
```
7272

7373
Finally, open a Pull Request on the [SPy GitHub page](https://github.com/spylang/spy).
74+
75+
Once the pull request is open, a preview build of the documentation site with your changes will be generated automatically. Click on the generated link that appears in a comment on your PR, and give your documentation one final review to ensure everything still looks correct after it's been built in CI.

0 commit comments

Comments
 (0)