Files
computer-playbook/.github/workflows/call-validation.yml
T
kevinveenbirkenbachandClaude Opus 5.5 b055eece05 feat(ci): keep GitHub-hosted runner labels current through the updater
The workflows pin `runs-on: ubuntu-NN.NN`, so no job moves to a new Ubuntu
release behind our back, but nothing raised the pin either. A sixth job of
`🔄 Update versions` closes that: `utils/update/runner.py` reads the image
table of actions/runner-images, takes the newest x64 Ubuntu label whose
image carries no preview or beta badge, and raises every older bare
`runs-on: ubuntu-NN.NN` to it; arch-suffixed labels stay untouched. The job
opens the change as one PR over `.github/workflows`, so its CI run tests
the new image before it reaches main.

This commit carries the updater's first result: every job now runs on
ubuntu-26.04 (49 `runs-on`).

actionlint 1.7.12, the newest release, does not know `ubuntu-26.04` yet
(rhysd/actionlint#682, fix proposed in rhysd/actionlint#743), so
`.github/actionlint.yaml` declares the label until a release knows it.

act maps each `ubuntu-NN.NN` label the workflows use to the local platform
image, derived from `.github/workflows`, instead of a fixed list that did
not know ubuntu-26.04.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:56:52 +02:00

205 lines
7.9 KiB
YAML

# The gate every entry point passes before it spends a runner on anything else.
# What it checks depends on the event and on the inputs it is handed, not on
# which workflow called it: a pull request gets its branch prefix and its merge
# base asserted, a run that carries a selection gets that selection checked
# against the branch it would deploy from, and a fork PR waits here for the
# privileged run's images. Nothing downstream may start before this is green,
# so a refusal fails the whole run instead of surfacing as one red job beside a
# chain that keeps going.
#
# Under pull_request_target the token is privileged and the head belongs to the
# fork, so the code under test is not checked out at all there and the branch
# prefix is validated from the calling ref's own tooling. Only the merge
# assertion and the selection check read the head, and both are reachable on
# pull_request and workflow_dispatch alone.
name: "✅ CI: Validation"
on:
workflow_call:
inputs:
pr_scope:
description: "🔎 Detected PR scope. Set: the branch prefix is validated against it. Empty: not a PR entry, skipped."
required: false
type: string
default: ""
whitelist:
description: "🎯 Selection to validate against this branch. Empty: nothing to check."
required: false
type: string
default: ""
priority:
description: "⭐ Priority line to validate against this branch. Empty: nothing to check."
required: false
type: string
default: ""
mode:
description: "🚀 Deploy modes the run draws from; narrows what a pinned mode may be."
required: false
type: string
default: "auto"
tor:
description: "🧅 Tor axis of the run; decides whether a pinned onion state is reachable."
required: false
type: string
default: "auto"
distros:
description: "🐧 Distro pool of the run; narrows what a pinned distro may be."
required: false
type: string
default: ""
filesystem:
description: "🗄️ Filesystem pool of the run; narrows what a pinned filesystem may be."
required: false
type: string
default: ""
lifecycles:
description: "♻️ Lifecycle envelope; a role outside it has no row to match."
required: false
type: string
default: ""
fork_prereqs:
description: "🍴 Wait for the privileged fork run's images. Off for entries that build their own."
required: false
type: boolean
default: false
trusted_pr:
description: "🛡️ True when the PR carries the maintainer Trusted label; skips the fork-prereq wait."
required: false
type: boolean
default: false
image_wait_attempts:
description: "🔁 Polling attempts while waiting on prebuilt or mirrored images."
required: false
type: string
default: "1980"
image_wait_sleep_seconds:
description: "⏱️ Polling interval in seconds while waiting on images."
required: false
type: string
default: "10"
permissions:
contents: read
jobs:
validation:
name: ✅ Validation
runs-on: ubuntu-26.04
steps:
- name: ⬇️ Checkout the calling ref for its tooling
uses: actions/checkout@v7.0.0
with:
path: .base-tooling
persist-credentials: false
- name: ⬇️ Checkout the code under test
if: ${{ github.event_name != 'pull_request_target' }}
uses: actions/checkout@v7.0.0
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: ${{ inputs.pr_scope != '' && '0' || '1' }}
path: pr-head
persist-credentials: false
- name: 🧭 Validate the branch prefix against the detected scope
if: ${{ inputs.pr_scope != '' }}
working-directory: .base-tooling
env:
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_SCOPE: ${{ inputs.pr_scope }}
run: ./scripts/meta/resolve/pr/branch_prefix.sh
- name: 🔀 Assert the base branch is fully merged into the PR head
if: ${{ github.event_name == 'pull_request' && inputs.pr_scope != '' }}
working-directory: pr-head
env:
INFINITO_MAIN_REMOTE: origin
INFINITO_MAIN_BRANCH: ${{ github.event.pull_request.base.ref }}
run: bash "${GITHUB_WORKSPACE}/.base-tooling/scripts/git/assert/main_merged.sh"
- name: 🔧 Set up Python
if: ${{ inputs.whitelist != '' || inputs.priority != '' }}
uses: actions/setup-python@v6
with:
python-version: "3.12"
# Exception: no pip cache. The steps below run the PR head's own code,
# which would write a cache that a default-branch run later restores.
- name: 📦 Install project (host venv)
if: ${{ inputs.whitelist != '' || inputs.priority != '' }}
working-directory: pr-head
shell: bash
run: make install
- name: 🎯 Validate the selection against this branch
if: ${{ inputs.whitelist != '' || inputs.priority != '' }}
working-directory: pr-head
shell: bash
env:
INPUT_WHITELIST: ${{ inputs.whitelist }}
INPUT_PRIORITY: ${{ inputs.priority }}
INPUT_MODE: ${{ inputs.mode }}
INPUT_TOR: ${{ inputs.tor }}
INPUT_DISTROS: ${{ inputs.distros }}
INPUT_FILESYSTEM: ${{ inputs.filesystem }}
INPUT_LIFECYCLES: ${{ inputs.lifecycles }}
run: ./scripts/github/validate/selection.sh
wait-fork-prereq-run:
name: ⏳ Wait for fork run
if: ${{ inputs.fork_prereqs }}
runs-on: ubuntu-26.04
env:
WAIT_REQUIRED: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && !inputs.trusted_pr }}
steps:
- name: 🏷️ Mark fork prerequisites as ready outside fork PRs or for trusted PRs
if: ${{ env.WAIT_REQUIRED != 'true' }}
shell: bash
run: |
set -euo pipefail
echo "Fork prerequisites are implicitly ready (non-fork PR or '🛡️ Trusted' label)."
- name: ⬇️ Checkout trusted workflow repo (helpers)
if: ${{ env.WAIT_REQUIRED == 'true' }}
uses: actions/checkout@v7.0.0
with:
ref: ${{ github.event.pull_request.base.sha }}
persist-credentials: false
- name: 🔑 Login to GHCR for CI image checks
if: ${{ env.WAIT_REQUIRED == 'true' }}
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: ⏳ Wait for privileged fork CI images
if: ${{ env.WAIT_REQUIRED == 'true' }}
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WORKFLOW_FILE: entry-pr-change-orchestrate.yml
TARGET_EVENT: pull_request_target
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_UPDATED_AT: ${{ github.event.pull_request.updated_at }}
INFINITO_DISTROS: "arch debian ubuntu fedora centos"
IMAGE_TAG: ci-${{ github.sha }}
WAIT_ATTEMPTS: ${{ inputs.image_wait_attempts }}
WAIT_SLEEP_SECONDS: ${{ inputs.image_wait_sleep_seconds }}
run: ./scripts/meta/wait/images.sh
fork-prereqs-ready:
name: 🚦 Gate Dependencies
needs: wait-fork-prereq-run
if: ${{ !cancelled() && inputs.fork_prereqs }}
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@v7.0.0
- name: ✅ Assert privileged prerequisites are ready
shell: bash
env:
RESULT: ${{ needs.wait-fork-prereq-run.result }}
run: ./scripts/github/gate/fork_prereqs.sh