mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
The Validation step "Assert the base branch is fully merged into the PR head" ran main_merged.sh, which fetches the live tip of main when the job starts. PR runs wait in the queue for hours while image-update PRs land on main several times an hour, so nearly every queued run failed Validation on start and had to be re-pushed after another main merge (PR #1265: behind_by=0 at push, behind_by=9 while its run still queued). main_merged.sh takes a new INFINITO_MAIN_COMMIT override: when set, it fetches that full commit SHA from the remote and requires HEAD to contain it instead of the live tip; a set but malformed or empty value exits 2. The Validation step passes github.event.pull_request.base.sha, the main tip at event time, which the step's pull_request-only guard always provides. The run tests the merge against that base, so the gate still guarantees the tested tree contains it. The local pre-push hook (make test-main-merged) leaves the override unset and keeps checking the live tip: a push happens right now, so lagging the current main is the real defect there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
206 lines
7.9 KiB
YAML
206 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 event's base commit is 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 }}
|
|
INFINITO_MAIN_COMMIT: ${{ github.event.pull_request.base.sha }}
|
|
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
|