Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 58 additions & 27 deletions .github/workflows/screenshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ on:

permissions:
contents: write
pull-requests: read

# A second push supersedes the first: the older run would recapture a tree
# nobody is on, and its push would lose the race anyway.
Expand All @@ -21,7 +22,37 @@ concurrency:
cancel-in-progress: true

jobs:
recapture:
# Keep the relevance decision on the hosted runner. Starting the renderer
# container is most of the cost of a pull request that needs no capture.
relevant:
runs-on: ubuntu-latest
outputs:
capture: ${{ steps.relevant.outputs.capture }}
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- id: relevant
name: Decide whether anything can have moved a picture
env:
CHANGED_FILES: ${{ github.event.pull_request.changed_files }}
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
if [ "$CHANGED_FILES" -gt 3000 ]; then
echo "capture=true" >> "$GITHUB_OUTPUT"
exit 0
fi
gh api --paginate \
"/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files?per_page=100" \
--jq '.[] | .filename, (.previous_filename // empty)' \
| tee /tmp/changed
node scripts/screenshots/affects.mjs < /tmp/changed >> "$GITHUB_OUTPUT"

capture:
needs: relevant
if: needs.relevant.outputs.capture == 'true'
runs-on: ubuntu-latest
# Pinned rather than ubuntu-latest: the runner image's fonts and libraries
# move between releases, and every glyph a capture rasterises comes from
Expand All @@ -33,48 +64,33 @@ jobs:
- uses: actions/checkout@v7
with:
# A pull_request run checks out the merge commit, which is no branch;
# the recapture has to land on the branch. Full history so the step
# below can reach the base's merge point.
# the recapture has to land on the branch.
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 0
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: |
package-lock.json
scripts/screenshots/package-lock.json
# bb-app builds node-pty from source here, which the image has no
# compiler for; and git refuses a checkout it did not make itself.
cache-dependency-path: package-lock.json
# node-pty is the only package without a Linux prebuild. The image
# already carries Python, so only its compiler is missing.
- name: Prepare the container
run: |
apt-get update -qq
apt-get install -y -qq python3 make g++
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- run: npm ci --workspaces=false
# Takes seconds and needs no bb. Only a change that can have moved a
# screenshot is worth the five-minute capture below.
- id: relevant
name: Decide whether anything can have moved a picture
run: |
git fetch --no-tags origin "+refs/heads/$GITHUB_BASE_REF:refs/remotes/origin/$GITHUB_BASE_REF"
git diff --name-only "origin/$GITHUB_BASE_REF...HEAD" | tee /tmp/changed
node scripts/screenshots/affects.mjs < /tmp/changed >> "$GITHUB_OUTPUT"
# Installs bb, which only the capture needs.
- if: steps.relevant.outputs.capture == 'true'
run: npm ci --prefix scripts/screenshots
- if: steps.relevant.outputs.capture == 'true'
run: npm run screenshots
- if: steps.relevant.outputs.capture == 'true'
name: Commit what changed
apt-get install -y -qq make g++
# Install every workspace together so the screenshot harness and all
# five plugins share one bb-app and one node-pty build.
- run: npm ci
- run: npm run screenshots
- name: Commit what changed
# Whoever opened the pull request chose these. Interpolating them with
# ${{ }} would paste them into the script for bash to parse; read from
# the environment they are values, not code.
env:
HEAD_REF: ${{ github.event.pull_request.head.ref }}
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git add -A assets plugins/*/assets
if git diff --cached --quiet; then
echo "The capture reproduced what is committed; nothing to push."
Expand All @@ -90,3 +106,18 @@ jobs:
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git commit -m "Recapture the screenshots this branch moved"
git push origin "HEAD:$HEAD_REF"

# The stable required-check name. A skipped capture is success; a failed or
# cancelled relevance/capture job is not.
recapture:
needs: [relevant, capture]
if: always()
runs-on: ubuntu-latest
steps:
- name: The screenshot check passed
run: |
results='${{ join(needs.*.result, ' ') }}'
echo "$results"
case "$results" in
*failure*|*cancelled*) echo "::error::the screenshot check did not pass"; exit 1 ;;
esac
Binary file modified assets/hero-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/hero-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading