Files
computer-playbook/scripts/github/resolve/pr_affected_roles.sh
kevinveenbirkenbachandClaude Opus 5 5b8465260f feat(ci): deploy only the variants a change reaches
An image bump in a provider redeployed every variant of every consumer,
including the variants that switch that provider off and therefore never
deploy the bumped image at all. The diff-derived whitelist now narrows each
affected role to the variants whose own round closure still reaches a seed,
emitted as `role#0,2` selection tokens. That closure is walked on the same
variant-merged services maps the matrix planner builds its rounds from, so the
narrowing follows a parent's variant choice across every generation of the
chain. It covers every auto-derived whitelist: the weekly update PRs,
Dependabot, and any other diff-driven run.

The narrowing never shrinks the matrix on partial information. A seed role
keeps every variant, because its own files changed. A role reached only
through a run_after edge keeps every variant too, because the round closure
does not follow that edge and a role whose hits are empty is therefore
unnarrowed rather than dropped.

A pinned token naming a role the discovery query does not return now warns
instead of aborting the run. The diff-derived whitelist legitimately names
roles the lifecycle envelope filters out, and once it pins variants such a
token would abort every chunk; role names are still checked against roles/
before the run starts, so a typo is caught one layer earlier.

The round's variant merge moves out of the deploy inventory package into
utils/roles/applications/variants.py. The CI selection has to build the same
maps, and importing the deploy package for them pulls in a module that reads
INFINITO_SRC_DIR at import time, which the runner host does not set.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 22:51:03 +02:00

36 lines
1.4 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Resolve the role whitelist for a pull-request CI run and write
# `whitelist` to GITHUB_OUTPUT. This is the single entry point the
# `detect-affected-roles` job calls; it keeps the subset-vs-diff
# selection logic out of the workflow YAML.
#
# Inputs via env:
# SUBSET_LABELED "true" when the PR carries the '🧩 Subset' label.
# When set, the explicit role list declared in the PR
# body wins, resolved by the cli.meta.ci.subset_roles
# module (strict: it fails the run on
# invalid/empty/unknown roles).
# Otherwise the diff-derived resolver runs unchanged.
# PR_BODY PR body markdown (only read on the subset path).
#
# Outputs (GITHUB_OUTPUT):
# whitelist=<selection token ...|__ALL__>
# a token is a role id, variant-narrowed to `<role>#0,2` where
# only some of the role's variants reach the change.
set -euo pipefail
: "${GITHUB_OUTPUT:?Missing GITHUB_OUTPUT}"
if [[ "${SUBSET_LABELED:-}" == "true" ]]; then
echo "🧩 Subset label present: restricting CI to the roles listed in the PR body."
# shellcheck source=scripts/meta/env/load.sh
source "scripts/meta/env/load.sh"
exec "${PYTHON}" -m cli.meta.ci.subset_roles
fi
resolved="$(./scripts/meta/resolve/diff/affected_roles.sh)"
echo "Resolver output: ${resolved}"
printf 'whitelist=%s\n' "${resolved}" >>"${GITHUB_OUTPUT}"