drills/README.md — the standing runner-probe venue, and why the drill disposal rule does not apply to it (#202) #207
2 changed files with 46 additions and 8 deletions
|
|
@ -37,8 +37,19 @@
|
||||||
distinguishes ceremony's internal self-checkouts from the consumer checkouts
|
distinguishes ceremony's internal self-checkouts from the consumer checkouts
|
||||||
that must stay `${{ github.repository }}` (#202).
|
that must stay `${{ github.repository }}` (#202).
|
||||||
|
|
||||||
- Both published snippets parse, lint clean and were driven against a
|
- Both published snippets are ShellCheck-clean when extracted and linted
|
||||||
constructed armed/probe pair: deletion, both role swaps, wrong owner, wrong
|
directly, not merely as part of the repository sweep (#202).
|
||||||
|
|
||||||
|
- The checker validates the MANIFEST against the target it was given, so a
|
||||||
|
manifest that describes a wrong arming consistently — wrong fork, or the
|
||||||
|
armed SHA where the candidate belongs — refuses instead of matching a tree
|
||||||
|
rewritten to the same wrong value (#202).
|
||||||
|
|
||||||
|
- The manifest is generated from the PRE-arming tree, which is the only order
|
||||||
|
that enumerates the carriers that must change (#202).
|
||||||
|
|
||||||
|
- Both published snippets were driven against a constructed candidate/probe
|
||||||
|
pair: deletion, both role swaps, wrong owner, wrong
|
||||||
SHA, wrong path, a deleted caller class and an extra carrier all refuse, and
|
SHA, wrong path, a deleted caller class and an extra carrier all refuse, and
|
||||||
the armed control passes (#202).
|
the armed control passes (#202).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,11 @@ So:
|
||||||
the **candidate code SHA**. Never create a branch on
|
the **candidate code SHA**. Never create a branch on
|
||||||
`heavy-duty/ceremony` named like a tag: it shadows that tag for every
|
`heavy-duty/ceremony` named like a tag: it shadows that tag for every
|
||||||
consumer until somebody remembers to delete it.
|
consumer until somebody remembers to delete it.
|
||||||
2. **Commit the arming on top of it, and write the manifest.** In that same
|
2. **Write the manifest FIRST, from the pre-arming tree, then commit the
|
||||||
|
arming.** The manifest enumerates the carriers *that must change*, so it is
|
||||||
|
generated before they do — running it afterwards would enumerate
|
||||||
|
already-rewritten rows and lose the canonical internal-checkout ones
|
||||||
|
entirely (@codex-reviewer-andresmgsl, #202 review). In that same
|
||||||
fork branch rewrite, for **every** carrier the manifest below enumerates:
|
fork branch rewrite, for **every** carrier the manifest below enumerates:
|
||||||
ceremony's own internal `repository:` checkouts → `<identity>/ceremony`, and
|
ceremony's own internal `repository:` checkouts → `<identity>/ceremony`, and
|
||||||
**every** `CEREMONY_SELF_REF` value → the **candidate code SHA** from step 1.
|
**every** `CEREMONY_SELF_REF` value → the **candidate code SHA** from step 1.
|
||||||
|
|
@ -152,7 +156,10 @@ So:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# write-manifest <armed-checkout> <probe-checkout> <fork> <code-sha> <armed-sha>
|
# write-manifest <candidate-checkout> <probe-checkout> <fork> <code-sha> <armed-sha>
|
||||||
|
#
|
||||||
|
# Run against the PRE-ARMING tree and the UNPINNED probe: this records what
|
||||||
|
# each carrier must BECOME, so it has to see them before they change.
|
||||||
#
|
#
|
||||||
# `|| true` on every extraction, for the same reason the checker needs it:
|
# `|| true` on every extraction, for the same reason the checker needs it:
|
||||||
# git grep exits 1 on no-match and `set -e` would abort BEFORE the manifest
|
# git grep exits 1 on no-match and `set -e` would abort BEFORE the manifest
|
||||||
|
|
@ -160,7 +167,8 @@ So:
|
||||||
# produced no file and no diagnostic when a probe exercised only one layer
|
# produced no file and no diagnostic when a probe exercised only one layer
|
||||||
# (@codex-reviewer-andresmgsl). A probe need not use both.
|
# (@codex-reviewer-andresmgsl). A probe need not use both.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
armed="$1"; probe="$2"; fork="$3"; code_sha="$4"; armed_sha="$5"
|
armed="$1"; probe="$2"; fork="$3"; code_sha="$4"; armed_sha="$5" # $1 = pre-arming
|
||||||
|
# shellcheck disable=SC2016 # `${{ github.repository }}` is literal YAML, not a shell expansion
|
||||||
{
|
{
|
||||||
git -C "$armed" grep -n 'CEREMONY_SELF_REF:' -- .github/workflows \
|
git -C "$armed" grep -n 'CEREMONY_SELF_REF:' -- .github/workflows \
|
||||||
| cut -d: -f1,2 | sed "s|$|\tself_ref\t$code_sha|" || true
|
| cut -d: -f1,2 | sed "s|$|\tself_ref\t$code_sha|" || true
|
||||||
|
|
@ -182,8 +190,7 @@ So:
|
||||||
[ "$callers" -gt 0 ] || { echo "manifest: no ceremony callers found in $probe" >&2; exit 1; }
|
[ "$callers" -gt 0 ] || { echo "manifest: no ceremony callers found in $probe" >&2; exit 1; }
|
||||||
```
|
```
|
||||||
|
|
||||||
Run it against the **pre-arming** tree — that is what enumerates the
|
Then arm — rewrite and commit — and check the result against it:
|
||||||
carriers that must change — then arm, then check:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
@ -200,7 +207,27 @@ So:
|
||||||
[ "$(grep -cE '(workflow|action)_caller' "$manifest" || true)" -gt 0 ] \
|
[ "$(grep -cE '(workflow|action)_caller' "$manifest" || true)" -gt 0 ] \
|
||||||
|| fail "manifest names no ceremony callers — it cannot prove an arming"
|
|| fail "manifest names no ceremony callers — it cannot prove an arming"
|
||||||
|
|
||||||
actual="$(mktemp)"
|
# THE MANIFEST ITSELF IS CHECKED AGAINST THE TARGET, not trusted. Comparing
|
||||||
|
# only tree-vs-manifest proves consistency, and a manifest generated with the
|
||||||
|
# armed SHA where the candidate SHA belonged — or with the wrong fork —
|
||||||
|
# describes a WRONG arming perfectly. The tree would then match it and the
|
||||||
|
# gate would pass (@codex-reviewer-andresmgsl, #202 review).
|
||||||
|
# shellcheck disable=SC2016 # `${{ github.repository }}` below is literal YAML
|
||||||
|
while IFS=$'\t' read -r loc kind want; do
|
||||||
|
case "$kind" in
|
||||||
|
self_ref) [ "$want" = "$code_sha" ] || fail "manifest $loc: self_ref should be the CANDIDATE sha" ;;
|
||||||
|
internal_repo) [ "$want" = "$fork" ] || fail "manifest $loc: internal repo should be $fork" ;;
|
||||||
|
consumer_repo) [ "$want" = '${{ github.repository }}' ] \
|
||||||
|
|| fail "manifest $loc: consumer checkout must stay dynamic" ;;
|
||||||
|
workflow_caller) [ "$want" = "$fork/${want#*/ceremony/}" ] || fail "manifest $loc: caller owner"
|
||||||
|
[ "${want##*@}" = "$armed_sha" ] || fail "manifest $loc: workflow caller should be the ARMED sha" ;;
|
||||||
|
action_caller) [ "$want" = "$fork/${want#*/ceremony/}" ] || fail "manifest $loc: caller owner"
|
||||||
|
[ "${want##*@}" = "$code_sha" ] || fail "manifest $loc: action caller should be the CANDIDATE sha" ;;
|
||||||
|
*) fail "manifest $loc: unknown kind '$kind'" ;;
|
||||||
|
esac
|
||||||
|
done <"$manifest"
|
||||||
|
|
||||||
|
actual="$(mktemp)"; trap 'rm -f "$actual"' EXIT
|
||||||
{
|
{
|
||||||
git -C "$armed" grep -nP '(?<=CEREMONY_SELF_REF: ")[^"]+' -- .github/workflows \
|
git -C "$armed" grep -nP '(?<=CEREMONY_SELF_REF: ")[^"]+' -- .github/workflows \
|
||||||
| sed -E 's/^([^:]+):([0-9]+):.*CEREMONY_SELF_REF: "([^"]*)".*/\1:\2\tself_ref\t\3/' || true
|
| sed -E 's/^([^:]+):([0-9]+):.*CEREMONY_SELF_REF: "([^"]*)".*/\1:\2\tself_ref\t\3/' || true
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue