refresh #30
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |