From 224c29786758c233aa413e6418b5165be4cb0c40 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 14 May 2026 14:56:36 +0100 Subject: [PATCH] fix(ci): move secret-scanner Cargo.toml gate from job-level if: to step-level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `secret-scanner.yml` has had 0 successful runs since creation across all 60 estate consumers — every run completes in 0 seconds with `conclusion=failure` and zero jobs spawned (a GitHub Actions startup_failure). The workflow file looks syntactically valid; `gh workflow view` returns it cleanly; both action SHAs exist. ## Root cause The `rust-secrets` job has a job-level `if:` clause: ```yaml rust-secrets: runs-on: ubuntu-latest if: hashFiles('**/Cargo.toml') != '' ``` GitHub Actions **does not support** the `hashFiles()` expression in **job-level** `if:` conditions. From the docs: "the hashFiles function is available in the runtime environment when steps are running". Only step-level `if:` and other expression contexts work. When `hashFiles()` is evaluated at job-eligibility time, the workflow run fails to schedule any jobs and is marked as a failed startup. Wrapping it in ${{ }} makes no difference. Bisect tested 10 variants on a branch: | Variant | Content | Result | |---|---|---| | A | minimal trigger + 1 echo job | OK 1 job spawned | | C | minimal + only trufflehog job | OK 1 job spawned | | D | full original (all 3 jobs) | FAIL 0 jobs | | E | minimal + only gitleaks job | OK 1 job spawned | | F | minimal + only rust-secrets job | FAIL 0 jobs | | G | minimal + rust-secrets with `if:` and trivial body | FAIL 0 jobs | | H | minimal + rust-secrets WITHOUT `if:` | OK 1 job spawned | | I | rust-secrets with ${{ hashFiles... }} wrapper | FAIL 0 jobs | | J | full minus `if:` + step-level Cargo guard | OK 3 jobs spawned | ## Fix Remove the job-level `if:` line and replace with a step-level guard at the top of the existing run block: ```bash if ! find . -name Cargo.toml -not -path './target/*' -print -quit | grep -q .; then echo "No Cargo.toml found — skipping Rust secrets check" exit 0 fi ``` Same semantics (skip when no `Cargo.toml`), but at a context where the expression works. Affects 60 estate consumers — sweep PR follows. --- .github/workflows/secret-scanner.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 4fe2bda..783011f 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -38,12 +38,15 @@ jobs: # Rust-specific: Check for hardcoded crypto values rust-secrets: runs-on: ubuntu-latest - if: hashFiles('**/Cargo.toml') != '' steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 - name: Check for hardcoded secrets in Rust run: | + if ! find . -name Cargo.toml -not -path './target/*' -print -quit | grep -q .; then + echo 'No Cargo.toml found — skipping Rust secrets check' + exit 0 + fi # Patterns that suggest hardcoded secrets PATTERNS=( 'const.*SECRET.*=.*"'