Skip to content

Commit 6d01e3d

Browse files
ci: fix all four pre-existing workflow failures (#73)
Every one of these predates today's work; all four failed at workflow LOAD time (zero jobs), so nothing they gate has actually run in weeks: - secret-scanner.yml: caller granted only contents:read but the called reusable's gitleaks job requests pull-requests:write + actions:read. A called workflow can only narrow the caller's token, never exceed it -> startup_failure on every run since the 2026-06-24 repin (#62). Caller now grants the superset. (The reusable's comment claiming its permissions 'override the caller's' is backwards — flagged for standards separately.) - scorecard.yml: same class — read-all cannot cover the callee's security-events:write + id-token:write. Explicit grant block added. - dogfood-gate.yml: an inline python3 -c snippet was written at column 1 inside a run:| literal block, terminating the block scalar and making the entire file unparseable (path-as-name, zero jobs — all six jobs invisible). Script moved to the step's env.PYCODE block scalar (YAML strips base indentation there) and invoked as python3 -c "$PYCODE". - instant-sync.yml: secrets context is not available in step-level if: — workflow-file error at load. Secret hoisted to job env and the step gated on env.FARM_DISPATCH_TOKEN instead. (When the secret is absent the step skips and the job is green, which matches the recorded plan to drop FARM_DISPATCH_TOKEN after the credential rebuild.) Validated: actionlint clean across .github/workflows; all four parse with the expected job sets. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 700ea13 commit 6d01e3d

4 files changed

Lines changed: 53 additions & 24 deletions

File tree

.github/workflows/dogfood-gate.yml

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,33 @@ jobs:
249249

250250
- name: Check and validate eclexiaiser manifest
251251
id: eclex
252+
# The validation script lives in env: rather than inline in run:
253+
# because a YAML literal block ends at the first column-1 line — an
254+
# unindented heredoc/py-snippet inside run: silently truncates the
255+
# block and makes the whole workflow file unparseable (zero jobs,
256+
# path shown as the workflow name). env: block scalars strip the
257+
# base indentation, so Python receives clean unindented code.
258+
env:
259+
PYCODE: |
260+
import tomllib, sys
261+
with open('eclexiaiser.toml', 'rb') as f:
262+
data = tomllib.load(f)
263+
project = data.get('project', {})
264+
if not project.get('name', '').strip():
265+
print('ERROR: project.name is required', file=sys.stderr)
266+
sys.exit(1)
267+
functions = data.get('functions', [])
268+
if not functions:
269+
print('ERROR: at least one [[functions]] entry is required', file=sys.stderr)
270+
sys.exit(1)
271+
for fn in functions:
272+
if not fn.get('name', '').strip():
273+
print('ERROR: function name cannot be empty', file=sys.stderr)
274+
sys.exit(1)
275+
if not fn.get('source', '').strip():
276+
print(f'ERROR: function {fn["name"]} has no source path', file=sys.stderr)
277+
sys.exit(1)
278+
print(f'Valid: {project["name"]} ({len(functions)} function(s))')
252279
run: |
253280
if [ ! -f "eclexiaiser.toml" ]; then
254281
# Check if repo has a Containerfile — if so, recommend eclexiaiser
@@ -261,28 +288,9 @@ jobs:
261288
262289
echo "has_manifest=true" >> "$GITHUB_OUTPUT"
263290
264-
# Validate TOML structure using Python 3.11+ tomllib
265-
python3 -c "
266-
import tomllib, sys
267-
with open('eclexiaiser.toml', 'rb') as f:
268-
data = tomllib.load(f)
269-
project = data.get('project', {})
270-
if not project.get('name', '').strip():
271-
print('ERROR: project.name is required', file=sys.stderr)
272-
sys.exit(1)
273-
functions = data.get('functions', [])
274-
if not functions:
275-
print('ERROR: at least one [[functions]] entry is required', file=sys.stderr)
276-
sys.exit(1)
277-
for fn in functions:
278-
if not fn.get('name', '').strip():
279-
print('ERROR: function name cannot be empty', file=sys.stderr)
280-
sys.exit(1)
281-
if not fn.get('source', '').strip():
282-
print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr)
283-
sys.exit(1)
284-
print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))')
285-
" || {
291+
# Validate TOML structure using Python 3.11+ tomllib (script in
292+
# the step's env.PYCODE — see comment above)
293+
python3 -c "$PYCODE" || {
286294
echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details"
287295
exit 1
288296
}

.github/workflows/instant-sync.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,15 @@ jobs:
1212
dispatch:
1313
runs-on: ubuntu-latest
1414
timeout-minutes: 15
15+
# The `secrets` context is not available in step-level `if:` — using it
16+
# there is a workflow-file error, so every run failed at load time with
17+
# zero jobs. Hoist the secret into env (where `secrets` IS available)
18+
# and gate the step on env instead.
19+
env:
20+
FARM_DISPATCH_TOKEN: ${{ secrets.FARM_DISPATCH_TOKEN }}
1521
steps:
1622
- name: Trigger Propagation
17-
if: ${{ secrets.FARM_DISPATCH_TOKEN != '' }}
23+
if: ${{ env.FARM_DISPATCH_TOKEN != '' }}
1824
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v3
1925
with:
2026
token: ${{ secrets.FARM_DISPATCH_TOKEN }}

.github/workflows/scorecard.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@ on:
88
push:
99
branches: [main]
1010

11-
permissions: read-all
11+
# The called reusable's scorecard job requests security-events:write +
12+
# id-token:write at job level. read-all cannot cover write scopes and a
13+
# called workflow can only narrow the caller's token — so every run was
14+
# a startup_failure. Grant exactly the superset the callee needs.
15+
permissions:
16+
contents: read
17+
actions: read
18+
security-events: write
19+
id-token: write
1220

1321
jobs:
1422
analysis:

.github/workflows/secret-scanner.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@ concurrency:
1010
group: ${{ github.workflow }}-${{ github.ref }}
1111
cancel-in-progress: true
1212

13+
# The called reusable's gitleaks job requests pull-requests:write +
14+
# actions:read at job level. A called workflow can only NARROW the
15+
# caller's token, never exceed it — granting only contents:read here
16+
# made every run a startup_failure ("workflow file issue", zero jobs)
17+
# since the 2026-06-24 repin. The caller must grant the superset.
1318
permissions:
1419
contents: read
20+
pull-requests: write
21+
actions: read
1522

1623
jobs:
1724
scan:

0 commit comments

Comments
 (0)