open-standards/scripts/check-workflow-concurrency-selftest.sh
Transaction Science 4a0ea0f6c6
All checks were successful
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 7s
standards workspaces build + test / macOS energy backends (pull_request) Has been skipped
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 57s
ci: one job for the repository's script checks
Six workflows, nine jobs on every push (lockfiles, tests-in-ci, workflow-hygiene,
wai-section-refs, spec-refs, and no-vanity-metrics' four), each paying for a container
and a checkout to run a script that reads the tree for a few seconds. On 2026-10-14
they were about half of the 119 jobs waiting for the linux-arm64 runner, queued behind
the long standards-build legs; spec-refs held a place on the one x86_64 runner.

repo-checks.yml runs them all in one job on linux-arm64, one step a check, in the same
order with the same self-tests. Every step runs even after an earlier one fails
(`!cancelled()`), so a red job names each failing check, and fails if any did. The
public-name check still runs only on the push to main, where its pattern list is
given. The two path filters (public text, WAI section references) are dropped: the
checks take seconds, and a filter that is wrong skips a check silently.

check-workflow-concurrency-selftest.sh takes the new file as its fixture (it removed
the concurrency block from workflow-hygiene.yml, now gone); CHARTER.md names the new
workflow. Locally: the concurrency self-test and check (24 workflows), the path-gate
self-test, tests-in-ci, spec refs and vanity metrics pass, and the workflow parses
(19 steps).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 12:05:46 -04:00

61 lines
2.3 KiB
Shell
Executable file

#!/usr/bin/env bash
#
# check-workflow-concurrency-selftest.sh
#
# Proves `check-workflow-concurrency.sh` can fail. A check that cannot fail is
# decoration, and this repo has a documented history of gates that passed
# because nothing they guarded was ever read.
#
# Both ways the property can break are exercised against a scratch copy, never
# the working tree:
#
# 1. a workflow with no top-level `concurrency:` block;
# 2. a group that does not vary by `github.ref` — which would serialise every
# branch against every other, worse than having no group at all.
#
# In a script rather than inline in the workflow on purpose. The first version
# embedded a Python heredoc in a `run:` block, and the heredoc body sat at
# column zero, which made the workflow file invalid YAML. An unparseable
# workflow means no CI at all — the exact failure this change exists to
# prevent, reintroduced by the fix for it.
set -euo pipefail
cd "$(dirname "$0")/.."
root=$(pwd)
target=.github/workflows/repo-checks.yml
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
cp -R .github scripts "$tmp/"
# ── 1. remove the block entirely ────────────────────────────────────────────
python3 - "$tmp/$target" <<'PY'
import re, sys
p = sys.argv[1]
s = open(p).read()
out = re.sub(r"^concurrency:\n( .*\n)+", "", s, count=1, flags=re.M)
assert out != s, "fixture unchanged: there was no concurrency block to remove"
open(p, "w").write(out)
PY
if ( cd "$tmp" && ./scripts/check-workflow-concurrency.sh ) >/dev/null 2>&1; then
echo "::error::the check passed a workflow with no concurrency block"
exit 1
fi
# ── 2. a group that does not vary by ref ────────────────────────────────────
cp -f "$root/$target" "$tmp/$target"
python3 - "$tmp/$target" <<'PY'
import re, sys
p = sys.argv[1]
s = open(p).read()
out = re.sub(r"^( group:).*$", r"\1 fixed-for-the-whole-repo", s, count=1, flags=re.M)
assert out != s, "fixture unchanged: there was no group line to rewrite"
open(p, "w").write(out)
PY
if ( cd "$tmp" && ./scripts/check-workflow-concurrency.sh ) >/dev/null 2>&1; then
echo "::error::the check passed a group that does not vary by ref"
exit 1
fi
echo "self-test: the check rejects both a missing block and a fixed group"