Skip to content

preview-image

preview-image #296

Workflow file for this run

# The preview's computer image, built by master's merge queue ahead of the
# master push that deploys it (xtask/src/image/preview.rs, `--queue`). A
# master push's `preview-image` (ci.yml) then copies it to its input tag
# and finds it prepared, instead of spending 10 minutes building it.
#
# A workflow of its own, not a job of ci.yml's: a master push holds ci.yml's
# queue run to its success (`proven`), and this job may still be preparing
# its image when the run's checks are green, or fail. It is never a required
# check, so the queue never waits for it, and it never deploys: it pushes
# only `queue-<key>` tags (master's job alone writes `inputs-<key>`) to the
# preview account's registry.
#
# Its environment, `preview-image`, is least-privileged: a Cloudflare API
# token with the preview account's Containers permission alone (no
# Workers, no DNS, no deploy config) and the account's id, usable only by
# master's queue (its deployment branch policy: `gh-readonly-queue/master/*`).
name: preview-image
on:
merge_group:
types: [checks_requested]
jobs:
prebuild:
if: github.event.merge_group.base_ref == 'refs/heads/master'
runs-on: ubuntu-latest
# build and push, plus prepare.rs's 40-minute preparation limit, as
# master's job
timeout-minutes: 65
permissions:
contents: read
environment: preview-image
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
steps:
- run: |
for v in CLOUDFLARE_API_TOKEN CLOUDFLARE_ACCOUNT_ID; do
test -n "${!v}" || { echo "::error::the environment preview-image has no $v"; exit 1; }
done
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@stable
# master's preview-image caches, read only: a queue's would be its
# own ref's, which no later run reads
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
shared-key: preview-image
cache-targets: false
cache-directories: target/debug
cache-bin: false
save-if: false
- uses: actions/cache/restore@v4
with:
path: target/tools
key: node-${{ runner.os }}-${{ hashFiles('crates/devstack/src/node_release.rs') }}
- run: command -v skopeo > /dev/null || { sudo apt-get update -q && sudo apt-get install -y -q skopeo; }
# nothing to build when master's input tag or a queue build of these
# inputs is there already
- id: probe
run: |
cargo xtask image preview --output "$RUNNER_TEMP/preview-image.json"
echo "build=$(jq -r .build "$RUNNER_TEMP/preview-image.json")" >> "$GITHUB_OUTPUT"
# its disk freed before it builds: the image, held by BuildKit's
# builder and copied to Docker by `--queue`, filled a 72 GB runner (the
# action says)
- if: steps.probe.outputs.build == 'true'
uses: ./.github/actions/free-disk
- id: buildx
if: steps.probe.outputs.build == 'true'
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- if: steps.probe.outputs.build == 'true'
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
env:
DOCKER_BUILD_SUMMARY: false
DOCKER_BUILD_RECORD_UPLOAD: false
with:
context: .
file: images/hermes/Dockerfile
platforms: linux/amd64
provenance: false
cache-from: type=gha,scope=preview-hermes
- if: steps.probe.outputs.build == 'true'
env:
BUILDX_BUILDER: ${{ steps.buildx.outputs.name }}
run: cargo xtask image preview --queue --output "$RUNNER_TEMP/preview-image.json"
- if: always() && steps.probe.outputs.build == 'true'
name: disk, after
run: |
docker system df; df -h /; free -h
echo "peak: $(awk '$1 > d { d = $1 } END { print d }' "$RUNNER_TEMP/disk-used") MiB of the disk used, $(awk '$2 > m { m = $2 } END { print m }' "$RUNNER_TEMP/disk-used") MiB of the memory"