mirror of
https://github.com/martinvonz/jj.git
synced 2024-12-24 12:48:55 +00:00
infra: publish PR previews for docs
This commit is contained in:
parent
c0a9e20222
commit
26d9d5a507
2 changed files with 218 additions and 0 deletions
80
.github/workflows/docs-preview-build.yml
vendored
Normal file
80
.github/workflows/docs-preview-build.yml
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
# This workflow builds the docs for each PR, and uploads the rendered docs as an
|
||||
# artifact.
|
||||
#
|
||||
# The artifact will be picked up by docs-preview-deploy.yml and published at
|
||||
# https://jj-preview.github.io/docs/pr-<number>.
|
||||
#
|
||||
# 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 deploy key. The deploy workflow has
|
||||
# access, but is only allowed to run from the main branch (by requesting the
|
||||
# 'preview' environment).
|
||||
|
||||
name: docs-preview-build
|
||||
|
||||
permissions: read-all
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
# Run the workflow only when these paths have changed
|
||||
paths:
|
||||
- "docs/**"
|
||||
- "mkdocs.yml"
|
||||
- "pyproject.toml"
|
||||
- "uv.lock"
|
||||
- ".github/workflows/docs-preview-build.yml"
|
||||
# Run the workflow when anything changes OR when the PR is merged/closed.
|
||||
# When the PR is closed, we will push a dir with a special file to tell the
|
||||
# deploy workflow to remove the preview.
|
||||
types: [opened, reopened, synchronize, closed]
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
upload-pr-number:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- env:
|
||||
PR_NUMBER: ${{ github.event.number }}
|
||||
run: |
|
||||
echo "$PR_NUMBER" > pr_number
|
||||
|
||||
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882
|
||||
with:
|
||||
name: pr_number
|
||||
path: pr_number
|
||||
|
||||
# This job runs whenever the PR is opened, reopened, or pushed into.
|
||||
build-preview:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.action != 'closed' }}
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- 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
|
||||
|
||||
# This job runs whenever the PR is closed.
|
||||
delete-preview:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.action == 'closed' }}
|
||||
steps:
|
||||
- run: |
|
||||
mkdir -p rendered-docs
|
||||
touch rendered-docs/.delete-this-preview
|
||||
|
||||
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882
|
||||
with:
|
||||
name: rendered-docs
|
||||
path: rendered-docs
|
138
.github/workflows/docs-preview-deploy.yml
vendored
Normal file
138
.github/workflows/docs-preview-deploy.yml
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
# 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"
|
||||
|
||||
name: docs-preview-deploy
|
||||
|
||||
permissions: read-all
|
||||
|
||||
# Security note: 'on: workflow_run' workflows must be very careful about referencing any
|
||||
# PR-author-controlled strings (branch names, emails, etc). Ideally - don't do it
|
||||
# at all. This workflow only references the PR number, and takes care to validate it
|
||||
# before using it.
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [docs-preview-build]
|
||||
types: [completed]
|
||||
|
||||
jobs:
|
||||
get-pr-number:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
PR_NUMBER: ${{ steps.result.outputs.PR_NUMBER }}
|
||||
steps:
|
||||
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
|
||||
with:
|
||||
name: pr_number
|
||||
path: 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
|
||||
- id: result
|
||||
run: |
|
||||
PR_NUMBER=$(cat pr_number/pr_number)
|
||||
if [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
|
||||
echo "PR_NUMBER=$PR_NUMBER"
|
||||
echo "PR_NUMBER=$PR_NUMBER" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "PR_NUMBER must contain only digits; something went wrong"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
# Give this job access to the deploy key in the 'preview' environment's secrets
|
||||
environment: preview
|
||||
permissions:
|
||||
pull-requests: write # Needed to post a comment with the preview URL
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
needs: [get-pr-number]
|
||||
# Never run jobs for different PRs in parallel, since they push to the same
|
||||
# jj-preview/docs repo
|
||||
concurrency:
|
||||
group: docs-preview-${{ needs.get-pr-number.outputs.PR_NUMBER }}
|
||||
# It is tempting to use cancel-in-progress: true, but then people will get
|
||||
# spammed with cancellation notifications.
|
||||
cancel-in-progress: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
|
||||
with:
|
||||
name: rendered-docs
|
||||
path: rendered-docs
|
||||
# The token has to be provided explicitly when downloading artifacts
|
||||
# from a different workflow run (docs-preview-build.yml in this case)
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
|
||||
# This workflow is used both for *publishing* previews and for *deleting*
|
||||
# previews. We have to know if we are deleting or publishing a preview.
|
||||
- name: Check if we are asked to delete the preview
|
||||
id: should-delete
|
||||
run: |
|
||||
if [[ -f rendered-docs/.delete-this-preview ]]; then
|
||||
echo "delete=true" >> $GITHUB_OUTPUT
|
||||
rm rendered-docs/.delete-this-preview
|
||||
else
|
||||
echo "delete=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@62fec3add6773ec5dbbf18d2ee4260911aa35cf4
|
||||
with:
|
||||
folder: rendered-docs
|
||||
repository-name: jj-preview/docs
|
||||
branch: main
|
||||
target-folder: "pr-${{ needs.get-pr-number.outputs.PR_NUMBER }}"
|
||||
# This key allows pushing to jj-preview/docs. It was set up like this:
|
||||
#
|
||||
# 1. ssh-keygen -t ed25519 -C "" -N "" -f <where to save the keys>
|
||||
# 2. Add the public key to https://github.com/jj-preview/docs/settings/keys/new
|
||||
# 3. Add the private key to a 'preview' environment secret in the main repo
|
||||
ssh-key: ${{ secrets.DOCS_DEPLOY_KEY }}
|
||||
git-config-name: "jj-docs[bot]"
|
||||
git-config-email: "jj-docs[bot]@users.noreply.github.io"
|
||||
commit-message: "Update preview for PR ${{ needs.get-pr-number.outputs.PR_NUMBER }}"
|
||||
force: false
|
||||
|
||||
- name: Post a link to the docs in the PR
|
||||
uses: thollander/actions-comment-pull-request@65f9e5c9a1f2cd378bd74b2e057c9736982a8e74
|
||||
if: ${{ steps.should-delete.outputs.delete == 'false' }}}
|
||||
with:
|
||||
# (double blank line = new paragraph)
|
||||
message: >
|
||||
**📖 The documentation preview has been published to
|
||||
https://jj-preview.github.io/docs/pr-${{ needs.get-pr-number.outputs.PR_NUMBER }}.**
|
||||
Thanks for working on the docs!
|
||||
|
||||
|
||||
Note: it will take about 30 seconds before the preview is available.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
<sup>If the preview isn't working, please file an issue or reach out to us in Discord/IRC.
|
||||
You can also build the docs on your own machine by following the instructions at
|
||||
https://martinvonz.github.io/jj/prerelease/contributing/#previewing-the-html-documentation.</sup>
|
||||
|
||||
pr-number: ${{ needs.get-pr-number.outputs.PR_NUMBER }}
|
||||
comment-tag: docs-preview
|
Loading…
Reference in a new issue