Skip to content

Commit 6b820be

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 439dda4 commit 6b820be

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

.github/workflows/test.yml

+84
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,87 @@ 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-pr-${{ github.event.pull_request.number }}
23+
path: _book/**
24+
25+
preview:
26+
runs-on: ubuntu-latest
27+
needs: build
28+
steps:
29+
- name: Set preview domain
30+
run: echo "PREVIEW_DOMAIN=$(echo ${{ github.repository }} | tr / - )-${{ github.job }}-pr-${{ github.event.pull_request.number }}.surge.sh" >> $GITHUB_ENV
31+
32+
- name: Install surge
33+
run: npm install surge
34+
35+
- name: Install diffstat and pygments
36+
run: |
37+
sudo apt-get update
38+
sudo apt-get install -y diffstat python3-pygments
39+
40+
# TODO: can this download from the existing pages or a cache?
41+
- name: Checkout
42+
uses: actions/checkout@v4
43+
with:
44+
repository: ${{ github.event.pull_request.base.repo.full_name }}
45+
ref: ${{ github.event.pull_request.base.ref }}
46+
persist-credentials: false
47+
48+
- name: Build current pages
49+
run: |
50+
npm install
51+
npx honkit build
52+
mv _book current
53+
54+
- name: Download preview pages
55+
uses: actions/download-artifact@v4
56+
with:
57+
# TODO: store output in upload step?
58+
name: github-pages-pr-${{ github.event.pull_request.number }}
59+
path: preview
60+
61+
- name: Remove indeterminism
62+
run: |
63+
find current/ preview/ -type f -exec sed -i '/gitbook.page.hasChanged/d' {} +
64+
65+
- name: Create diff to current
66+
run: |
67+
diff -Nrwu --exclude search_index.json current/ preview/ | cat > preview/diff.patch
68+
if [[ -s preview/diff.patch ]] ; then
69+
pygmentize -o preview/diff.html -l diff -f html -O full preview/diff.patch
70+
diffstat -l -p2 preview/diff.patch > diff.txt
71+
fi
72+
73+
- name: Deploy to surge.sh
74+
run: npx surge ./preview $PREVIEW_DOMAIN --token ${{ secrets.SURGE_TOKEN }}
75+
76+
- name: Generate summary
77+
run: |
78+
echo "The PR preview for ${{ github.event.pull_request.head.sha }} is available at [${{ env.PREVIEW_DOMAIN }}](https://${{ env.PREVIEW_DOMAIN }})" > pr.md
79+
echo "" >> pr.md
80+
81+
if [[ -f preview/diff.txt ]] ; then
82+
echo "The following output files are affected by this PR:" >> pr.md
83+
sed -E "s#(.*)#- [\1](https://${{ env.PREVIEW_DOMAIN }}/\1)#" preview/diff.txt >> pr.md
84+
else
85+
echo "No diff compared to the current website" >> pr.md
86+
fi
87+
88+
if [[ -s preview/diff.patch ]] ; then
89+
echo "" >> pr.md
90+
echo "[show diff](https://${{ env.PREVIEW_DOMAIN }}/diff.patch)" >> pr.md
91+
fi
92+
93+
if [[ -f preview/diff.html ]] ; then
94+
echo "" >> pr.md
95+
echo "[show diff as HTML](https://${{ env.PREVIEW_DOMAIN }}/diff.html)" >> pr.md
96+
fi
97+
98+
- name: Comment on PR
99+
uses: marocchino/sticky-pull-request-comment@v2
100+
with:
101+
path: pr.md

0 commit comments

Comments
 (0)