Skip to content

Commit

Permalink
Implement previews for GitHub pull requests
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ekohl committed May 18, 2024
1 parent 439dda4 commit 6b820be
Showing 1 changed file with 84 additions and 0 deletions.
84 changes: 84 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,87 @@ jobs:
run: |
npm install
npx honkit build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: github-pages-pr-${{ github.event.pull_request.number }}
path: _book/**

preview:
runs-on: ubuntu-latest
needs: build
steps:
- name: Set preview domain
run: echo "PREVIEW_DOMAIN=$(echo ${{ github.repository }} | tr / - )-${{ github.job }}-pr-${{ github.event.pull_request.number }}.surge.sh" >> $GITHUB_ENV

- name: Install surge
run: npm install surge

- name: Install diffstat and pygments
run: |
sudo apt-get update
sudo apt-get install -y diffstat python3-pygments
# TODO: can this download from the existing pages or a cache?
- name: Checkout
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.base.repo.full_name }}
ref: ${{ github.event.pull_request.base.ref }}
persist-credentials: false

- name: Build current pages
run: |
npm install
npx honkit build
mv _book current
- name: Download preview pages
uses: actions/download-artifact@v4
with:
# TODO: store output in upload step?
name: github-pages-pr-${{ github.event.pull_request.number }}
path: preview

- name: Remove indeterminism
run: |
find current/ preview/ -type f -exec sed -i '/gitbook.page.hasChanged/d' {} +
- name: Create diff to current
run: |
diff -Nrwu --exclude search_index.json current/ preview/ | cat > preview/diff.patch
if [[ -s preview/diff.patch ]] ; then
pygmentize -o preview/diff.html -l diff -f html -O full preview/diff.patch
diffstat -l -p2 preview/diff.patch > diff.txt
fi
- name: Deploy to surge.sh
run: npx surge ./preview $PREVIEW_DOMAIN --token ${{ secrets.SURGE_TOKEN }}

- name: Generate summary
run: |
echo "The PR preview for ${{ github.event.pull_request.head.sha }} is available at [${{ env.PREVIEW_DOMAIN }}](https://${{ env.PREVIEW_DOMAIN }})" > pr.md
echo "" >> pr.md
if [[ -f preview/diff.txt ]] ; then
echo "The following output files are affected by this PR:" >> pr.md
sed -E "s#(.*)#- [\1](https://${{ env.PREVIEW_DOMAIN }}/\1)#" preview/diff.txt >> pr.md
else
echo "No diff compared to the current website" >> pr.md
fi
if [[ -s preview/diff.patch ]] ; then
echo "" >> pr.md
echo "[show diff](https://${{ env.PREVIEW_DOMAIN }}/diff.patch)" >> pr.md
fi
if [[ -f preview/diff.html ]] ; then
echo "" >> pr.md
echo "[show diff as HTML](https://${{ env.PREVIEW_DOMAIN }}/diff.html)" >> pr.md
fi
- name: Comment on PR
uses: marocchino/sticky-pull-request-comment@v2
with:
path: pr.md

0 comments on commit 6b820be

Please sign in to comment.