Skip to content

Commit 9a79485

Browse files
committed
Implement previews for GitHub pull requests
When a contributor submits a PR, we always perform a build. This takes it a step further and uploads that a custom surge.sh domain. It adds a sticky comment to link to that preview while also generating some diffs. This means reviews easier. In the implementation an additional preview step is added. This first builds the base (target of the PR) as the current. Then it downloads the generated preview that was added as an artifact in the original build step. Creating a reasonably sized diff was tricky, because there's a long Javascript line that includes the mtime, making it indeterministic. That line isn't relevant anyway, so it's removed. The diff command also ignores the search index. All of that is placed in the preview, making it readable. A sticky comment is added with a summary, making it easy to use. The sticky comment is updated for every push, rather than added a comment for every push. This keeps the PR conversation usable.
1 parent f72dfe3 commit 9a79485

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

.github/workflows/preview.yml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: Preview
2+
3+
on:
4+
workflow_run:
5+
workflows:
6+
- Build
7+
types:
8+
- completed
9+
10+
jobs:
11+
preview-failed:
12+
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion != 'success'
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Download metadata artifact
16+
run: gh run download '${{ github.event.workflow_run.id }}' --name pr
17+
env:
18+
GH_TOKEN: ${{ github.token }}
19+
20+
- name: Read PR data
21+
run: echo "PR_NUMBER=$(cat ./pr)" >> $GITHUB_ENV
22+
23+
- name: Comment on PR
24+
uses: marocchino/sticky-pull-request-comment@v2
25+
with:
26+
number: ${{ env.PR_NUMBER }}
27+
message: "The PR preview for ${{ github.event.workflow_run.head_sha }} could not be generated"
28+
29+
preview:
30+
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
31+
runs-on: ubuntu-latest
32+
steps:
33+
# TODO: can this download from the existing pages or a cache?
34+
- name: Checkout
35+
uses: actions/checkout@v4
36+
with:
37+
persist-credentials: false
38+
39+
- name: Build current pages
40+
run: |
41+
npm install
42+
npx honkit build
43+
mv _book current
44+
45+
- name: Download preview artifact
46+
run: gh run download '${{ github.event.workflow_run.id }}' --name github-pages --dir preview
47+
env:
48+
GH_TOKEN: ${{ github.token }}
49+
50+
- name: Remove indeterminism
51+
run: |
52+
find current/ preview/ -type f -exec sed -i '/gitbook.page.hasChanged/d' {} +
53+
54+
- name: Create diff to current
55+
run: |
56+
diff -Nrwu --exclude search_index.json current/ preview/ > diff.patch || true
57+
if [[ -s diff.patch ]] ; then
58+
sudo apt-get update
59+
sudo apt-get install -y diffstat python3-pygments
60+
61+
mv diff.patch preview/diff.patch
62+
pygmentize -o preview/diff.html -l diff -f html -O full preview/diff.patch
63+
diffstat -l -p1 preview/diff.patch > preview/diff.txt
64+
fi
65+
66+
- name: Download metadata artifact
67+
run: gh run download '${{ github.event.workflow_run.id }}' --name pr
68+
env:
69+
GH_TOKEN: ${{ github.token }}
70+
71+
- name: Read PR data
72+
run: echo "PR_NUMBER=$(cat ./pr)" >> $GITHUB_ENV
73+
74+
- name: Set preview domain
75+
run: echo "PREVIEW_DOMAIN=$(echo ${{ github.repository }} | tr / - )-${{ github.job }}-pr-${{ env.PR_NUMBER }}.surge.sh" >> $GITHUB_ENV
76+
77+
- name: Install surge
78+
run: npm install surge
79+
80+
- name: Deploy to surge.sh
81+
run: npx surge ./preview $PREVIEW_DOMAIN --token ${{ secrets.SURGE_TOKEN }}
82+
83+
- name: Generate summary
84+
run: |
85+
echo "The PR preview for ${{ github.event.workflow_run.head_sha }} is available at [${{ env.PREVIEW_DOMAIN }}](https://${{ env.PREVIEW_DOMAIN }})" >> pr.md
86+
echo "" >> pr.md
87+
88+
if [[ -f preview/diff.txt ]] ; then
89+
echo "The following output files are affected by this PR:" >> pr.md
90+
sed -E "s#(.*)#- [\1](https://${{ env.PREVIEW_DOMAIN }}/\1)#" preview/diff.txt >> pr.md
91+
else
92+
echo "No diff compared to the current website" >> pr.md
93+
fi
94+
95+
if [[ -s preview/diff.patch ]] ; then
96+
echo "" >> pr.md
97+
echo "[show diff](https://${{ env.PREVIEW_DOMAIN }}/diff.patch)" >> pr.md
98+
fi
99+
100+
if [[ -f preview/diff.html ]] ; then
101+
echo "" >> pr.md
102+
echo "[show diff as HTML](https://${{ env.PREVIEW_DOMAIN }}/diff.html)" >> pr.md
103+
fi
104+
105+
- name: Comment on PR
106+
uses: marocchino/sticky-pull-request-comment@v2
107+
with:
108+
number: ${{ env.PR_NUMBER }}
109+
path: pr.md

.github/workflows/test.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,18 @@ jobs:
1515
run: |
1616
npm install
1717
npx honkit build
18+
19+
- name: Upload artifact
20+
uses: actions/upload-artifact@v4
21+
with:
22+
name: github-pages
23+
path: _book/**
24+
25+
- name: Save PR metadata
26+
run: |
27+
echo ${{ github.event.number }} > ./pr
28+
29+
- uses: actions/upload-artifact@v4
30+
with:
31+
name: pr
32+
path: ./pr

0 commit comments

Comments
 (0)