Skip to content

refresh

refresh #32

Workflow file for this run

name: refresh
# Periodically checks upstream images, computes the graph of outdated build
# targets, caches it, and dispatches a build.yaml run for each target in
# topological order (parents before children).
on:
workflow_dispatch:
inputs:
build:
description: "Dispatch builds for outdated targets (always on for scheduled runs)."
type: boolean
default: true
schedule:
- cron: "0 6 * * *" # daily at 06:00 UTC
permissions:
contents: read
actions: write # required to dispatch build.yaml
packages: read # required to stat ghcr images (authenticated, so missing images return 404 not DENIED)
jobs:
refresh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
# Persist registry metadata across runs to conserve rate limits.
- uses: actions/cache@v5
with:
path: ~/.cache/clade
key: clade-cache-${{ github.run_id }}
restore-keys: clade-cache-
- run: go build -o /usr/local/bin/clade .
# Authenticate to ghcr so Stat can distinguish a missing image (404) from a
# private one. Anonymous requests get a 403 DENIED for both, which clade
# cannot treat as "needs build".
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Compute outdated graph
id: outdated
run: |
clade outdated --format json > graph.json
cat graph.json | jq .
targets=$(jq -c '[(.nodes // [])[].id]' graph.json)
count=$(jq '(.nodes // []) | length' graph.json)
echo "targets=${targets}" >> "$GITHUB_OUTPUT"
echo "count=${count}" >> "$GITHUB_OUTPUT"
echo "found ${count} outdated target(s)"
- uses: actions/upload-artifact@v4
with:
name: graph
path: graph.json
- name: Dispatch builds in topological order
# Scheduled runs always build; manual runs build only when requested, so a
# workflow_dispatch can be used to inspect the plan artifact without building.
if: >-
steps.outdated.outputs.count != '0' &&
(github.event_name == 'schedule' || inputs.build)
env:
GH_TOKEN: ${{ github.token }}
REF: ${{ github.ref_name }}
TARGETS: ${{ steps.outdated.outputs.targets }}
run: |
# Dispatch each build sequentially and wait for it to finish before
# the next, so an internal base is pushed before its dependents build.
echo "$TARGETS" | jq -r '.[]' | while read -r node; do
echo "::group::build ${node}"
gh workflow run build.yaml --ref "$REF" -f node="$node"
# `gh workflow run` does not return the run id; wait for the new run
# to register, then watch it (failing the loop on a failed build).
sleep 10
run_id=$(gh run list \
--workflow build.yaml --branch "$REF" --event workflow_dispatch \
--limit 1 --json databaseId --jq '.[0].databaseId')
gh run watch "$run_id" --exit-status
echo "::endgroup::"
done