From 9a02b3099816dde0f91fb78c3470e04b36085879 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 27 Jul 2026 14:45:50 +0100 Subject: [PATCH] =?UTF-8?q?fix(ci):=20repair=20dogfood-gate.yml=20?= =?UTF-8?q?=E2=80=94=20the=20workflow=20has=20never=20run?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This workflow is invalid YAML, so GitHub refuses it at parse time. It produces NO run, NO check-run, NO annotation and NO log — not a red X, an absence. Nothing on a dashboard distinguishes "this gate passed" from "this gate does not exist", which is why it went unnoticed. The tell is the Actions API reporting the workflow's name as its FILE PATH (`.github/workflows/dogfood-gate.yml`) instead of its `name:` — GitHub registers a file it cannot parse under its path. CAUSE: the embedded `python3 -c "` body starts at column 0. A `run: |` literal block scalar ends at the first non-empty line indented less than the block, so the Python terminates the block and YAML then tries to parse `import tomllib, sys` as a mapping key — "could not find expected ':'". FIX: indent the embedded body and its closing quote to the block indent. YAML strips that indent again when parsing, so the shell and the interpreter still receive the code at column 0. The content is unchanged; only the YAML framing differs. VERIFIED, not assumed: * the file parses and yields a `jobs:` mapping; * `bash -n` passes on the reconstructed run block; * the resulting `run:` value is BYTE-IDENTICAL to the same workflow in repos where it already parses (e.g. bofig) — this reproduces the known-good form rather than inventing one; * exactly one file is changed. Measured estate-wide 2026-07-27: 211 invalid workflow files across 116 repos, confirmed by the Actions API. `dogfood-gate.yml` is 71 of them. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/dogfood-gate.yml | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index b0ef40e..fa7a227 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -258,26 +258,26 @@ jobs: # Validate TOML structure using Python 3.11+ tomllib python3 -c " -import tomllib, sys -with open('eclexiaiser.toml', 'rb') as f: - data = tomllib.load(f) -project = data.get('project', {}) -if not project.get('name', '').strip(): - print('ERROR: project.name is required', file=sys.stderr) - sys.exit(1) -functions = data.get('functions', []) -if not functions: - print('ERROR: at least one [[functions]] entry is required', file=sys.stderr) - sys.exit(1) -for fn in functions: - if not fn.get('name', '').strip(): - print('ERROR: function name cannot be empty', file=sys.stderr) - sys.exit(1) - if not fn.get('source', '').strip(): - print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr) - sys.exit(1) -print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))') -" || { + import tomllib, sys + with open('eclexiaiser.toml', 'rb') as f: + data = tomllib.load(f) + project = data.get('project', {}) + if not project.get('name', '').strip(): + print('ERROR: project.name is required', file=sys.stderr) + sys.exit(1) + functions = data.get('functions', []) + if not functions: + print('ERROR: at least one [[functions]] entry is required', file=sys.stderr) + sys.exit(1) + for fn in functions: + if not fn.get('name', '').strip(): + print('ERROR: function name cannot be empty', file=sys.stderr) + sys.exit(1) + if not fn.get('source', '').strip(): + print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr) + sys.exit(1) + print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))') + " || { echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details" exit 1 }