Skip to content

Commit

Permalink
infra: publish PR previews for docs
Browse files Browse the repository at this point in the history
  • Loading branch information
neongreen committed Nov 11, 2024
1 parent 8179602 commit 23b0db7
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 0 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/docs-preview-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

# This workflow builds the docs for each PR (including from forks), and uploads
# the rendered docs as an artifact.
#
# The artifact will be picked up by docs-preview-deploy.yml and uploaded to
# https://jj-preview.github.io/docs/.
#
# The split into "build" and "deploy" follows GitHub's guide at
# https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/.
# The build workflow has no access to the repo secrets. The deploy workflow runs
# in the context of the main repo rather than the PR branch.

name: docs-preview-build

on:
pull_request:
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'pyproject.toml'
- 'uv.lock'
- '.github/workflows/docs-preview-build.yml'

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: Install uv
uses: astral-sh/setup-uv@2e657c127d5b1635d5a8e3fa40e0ac50a5bf6992

- name: Build the docs
# Intentionally without --strict, to have previews even if the docs are
# mildly broken
run: uv run mkdocs build

- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882
with:
name: rendered-docs
path: rendered-docs

- run: |
echo ${{ github.event.pull_request.number }} > pr_number
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882
with:
name: pr_number
path: pr_number
30 changes: 30 additions & 0 deletions .github/workflows/docs-preview-cleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: docs-preview-cleanup

permissions:
contents: write

on:
# This always uses the workflow file from the base branch, and only runs if
# base == main
pull_request_target:
types: [closed]

jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- run: mkdir -p empty-dir

- name: Deploy
uses: JamesIves/github-pages-deploy-action@62fec3add6773ec5dbbf18d2ee4260911aa35cf4
with:
folder: empty-dir
repository-name: jj-preview/docs
branch: 'main'
clean: true
target-folder: 'pr-${{ github.event.pull_request.number }}'
ssh-key: ${{ secrets.DOCS_DEPLOY_KEY }}
commit-message: "Remove preview for PR ${{ github.event.pull_request.number }}"
single-commit: true
91 changes: 91 additions & 0 deletions .github/workflows/docs-preview-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# This workflow pushes docs rendered by docs-preview-build.yml to
# https://github.com/jj-preview/docs.
#
# There, GitHub's own "deploy pages" action will run to publish the static files
# to https://jj-preview.github.io/docs/. This adds a 30s delay before the docs
# are actually published/updated.
#
# jj-preview/docs has a top-level .nojekyll file. Otherwise GitHub will try
# rendering with Jekyll, and the delay will be longer.
#
# We use a separate repo for two reasons:
# 1. No chance to accidentally mess up the main GH Pages
# 2. Avoid the impression that the published content is "official"

# TODO: PRs touching workflows should be approved by a maintainer
# TODO: enable docs-preview-build for PRs from forks

name: docs-preview-deploy

permissions:
contents: write
pull-requests: write

on:
# NB: 'workflow_run' only triggers if this workflow is on the default branch,
# which is needed for security but makes it a bit annoying to test
workflow_run:
workflows: [docs-preview-build]
types: [completed]

# Limit to one concurrent deployment.
#
# If we ever need parallel deployments, we'll need single-commit=false and
# force=false in the deploy step.
concurrency:
group: preview_deploy

jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
with:
name: rendered-docs
path: rendered-docs
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
with:
name: pr_number
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

# Security note: The PR number is uploaded by the build workflow, and can
# be manipulated. The only thing an attacker can do, though, is overwrite
# someone else's docs preview. See
# https://github.com/orgs/community/discussions/25220
- run: |
echo "PR_NUMBER=$(grep -o '[0-9]\+' pr_number)" >> $GITHUB_ENV
- name: Deploy
uses: JamesIves/github-pages-deploy-action@62fec3add6773ec5dbbf18d2ee4260911aa35cf4
with:
folder: rendered-docs
repository-name: jj-preview/docs
branch: main
clean: true
target-folder: 'pr-${{ env.PR_NUMBER }}'
# This key allows pushing to jj-preview/docs. How to set it up:
#
# 1. ssh-keygen -t ed25519 -C "" -N "" -f <where to put the keypair>
# 2. Add the public key to https://github.com/jj-preview/docs/settings/keys/new
# 3. Add the private key to https://github.com/martinvonz/jj/settings/secrets/actions/new
ssh-key: ${{ secrets.DOCS_DEPLOY_KEY }}
commit-message: "Update preview for PR ${{ env.PR_NUMBER }}"
single-commit: true

- name: Post a link to the docs in the PR
uses: thollander/actions-comment-pull-request@65f9e5c9a1f2cd378bd74b2e057c9736982a8e74
with:
message: |
**📖 Documentation preview is published to https://jj-preview.github.io/docs/pr-${{ env.PR_NUMBER }}.**
Thanks for working on the docs!
Note: it will take about 30 seconds before the preview is available.
pr-number: ${{ env.PR_NUMBER }}
comment-tag: docs-preview

0 comments on commit 23b0db7

Please sign in to comment.