Skip to content

ci: fix paths-filter shallow-clone race and scorecard allowlist#2089

Merged
Aureliolo merged 1 commit into
mainfrom
fix/ci-shallow-clone-paths-filter-race
May 24, 2026
Merged

ci: fix paths-filter shallow-clone race and scorecard allowlist#2089
Aureliolo merged 1 commit into
mainfrom
fix/ci-shallow-clone-paths-filter-race

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

What

Two infra bugs caused every recent push to main to show red. Both are CI-infra failures, not code regressions.

Why

1. dorny/paths-filter races on shallow checkouts (push events to main).

The action compares the pushed range by fetching ${{ github.event.before }} and main with two back-to-back git fetch --depth=1 calls. Both rewrite .git/shallow, and the second loses with:

fatal: shallow file has changed since we read it
##[error]The process '/usr/bin/git' failed with exit code 128

The whole Detect Changes job dies, so every downstream job (Lint, Type Check, all the unit / integration test shards, etc.) is skipped and CI Pass fails. The race only fires on push: events because, on PRs, actions/checkout has already fetched the base and paths-filter's local git cat-file -e check short-circuits both fetches.

The race is intermittent (depends on git/fs timing on the runner), which is why codspeed.yml and docker.yml have the same setup but happened to win recent rolls. Last four commits to main all lost: 917d98a, adedc6a, 72c6648, 2592118.

Fix: add fetch-depth: "0" to the Detect Changes checkout in every workflow that runs paths-filter on a push: trigger. With both refs already local, paths-filter skips the remote fetches entirely. Workflows touched:

  • ci.yml (was failing)
  • cli.yml (was failing)
  • codspeed.yml (preemptive — same shape, same race waiting to fire)
  • docker.yml (preemptive — same shape)

lighthouse.yml is pull_request-only and unaffected; left alone.

2. ossf/scorecard-action rejects the local retry-wrapped checkout composite.

Scorecard enforces a workflow-step allowlist on the job containing it. Our local Aureliolo/synthorg/.github/actions/checkout composite is not on that allowlist, so every push (and the weekly schedule) returns:

http response 400, status: 400 Bad Request, error: {"code":400,"message":
"workflow verification failed: workflow verification failed: job has
unallowed step: Aureliolo/synthorg/.github/actions/checkout, see
https://github.com/ossf/scorecard-action#workflow-restrictions for details."}

Fix: in scorecard.yml, the scorecard job switches to actions/checkout@de0fac2… (same v6 SHA pinned inside the composite). The report-failure job keeps the retry-wrapped composite — the allowlist only applies to the job containing scorecard-action.

Latent similar bug surfaced during the sweep

The schema-validate job's "Enforce at most one new revision per PR" step runs:

git fetch origin "$GH_BASE_REF" --depth=1
git diff --name-only --diff-filter=A "$base_ref"...HEAD -- ...

A...B (three-dot) is git diff $(git merge-base A B) B, which is undefined when the local clone has no ancestry shared between the two shallow tips. Depending on which commit happened to be the shallow root, the gate would either miss legitimate additions or fire false positives. Added fetch-depth: "0" on the same checkout and dropped the now-redundant --depth=1 from the explicit fetch.

Holistic sweep (negative findings)

To make sure this fix is complete, I grepped for the two underlying patterns across .github/ and scripts/:

  • Shallow clone + git history operations. Only ci.yml:248 was buggy. auto-rollover.yml, dev-release.yml, graduate.yml, secret-scan.yml, and the cli perf-regression job (line 207) already set fetch-depth: 0 where they need it.
  • Other allowlist-restricted actions (ossf/*, step-security/harden-runner, github/codeql-action/init). Only Scorecard restricts caller steps; nothing else uses the local composite under a similar policy.
  • Scripts called from CI that touch git history (check_cli_bench_regression.sh, check_no_review_origin_in_code.py, check_no_migration_framing.py, compute_release_cadence.py). The only one that needs history is check_cli_bench_regression.sh, and its caller already has fetch-depth: 0.

Intentionally NOT doing

  • Not bumping dorny/paths-filter — the race is shallow-clone semantics, not a paths-filter bug.
  • Not changing the composite checkout's fetch-depth: 1 default — that's correct for most jobs; only detect-changes-style jobs need the override.
  • Not requesting allowlisting of the local composite from upstream OSSF — slow, uncertain, and direct actions/checkout is a clean one-line workflow change.

Verification

  • Local pre-push gates: actionlint, yamllint, zizmor all Passed on the five modified workflows.
  • CI on this branch will exercise the paths-filter fix on the PR event (no race possible) and on push-to-main after merge (the fix's actual target).
  • Scorecard runs only on push: to main and the weekly schedule, so the allowlist fix will be exercised on the first post-merge push.

Two infra bugs caused every recent push-to-main to show red.

1. `dorny/paths-filter` races on shallow checkouts. On `push:` events
   it fetches the base SHA and `main` via two back-to-back
   `git fetch --depth=1` calls that both rewrite `.git/shallow`; the
   second loses with `fatal: shallow file has changed since we read
   it`. Adding `fetch-depth: "0"` to the Detect Changes checkout step
   in ci.yml, cli.yml, codspeed.yml, and docker.yml puts both refs in
   the local repo, so paths-filter skips the remote fetches entirely.
   `lighthouse.yml` runs paths-filter on `pull_request` only and is
   not affected.

2. `ossf/scorecard-action` enforces a workflow-step allowlist on the
   job that contains it. Our local retry-wrapped composite
   `Aureliolo/synthorg/.github/actions/checkout` is not allowlisted,
   so Scorecard rejected every push with HTTP 400 `job has unallowed
   step`. Switching the scorecard job to `actions/checkout@<v6-sha>`
   direct fixes it. The `report-failure` job keeps the retry
   composite since the allowlist only applies to the job containing
   scorecard-action.

Also found and fixed a latent similar bug in the same sweep: the
"Enforce at most one new revision per PR" step in `schema-validate`
uses `git diff <base>...HEAD` (three-dot, merge-base form) against a
shallow checkout, which is undefined when histories don't intersect.
Added `fetch-depth: "0"` on that job's checkout too.

Closes nothing -- ad-hoc CI fix.
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Note

Gemini is unable to generate a summary for this pull request due to the file types involved not being currently supported.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8e1e23dc-8613-4ed3-9828-dc39e3b91057

📥 Commits

Reviewing files that changed from the base of the PR and between 917d98a and bccc57b.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .github/workflows/cli.yml
  • .github/workflows/codspeed.yml
  • .github/workflows/docker.yml
  • .github/workflows/scorecard.yml
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (30)
  • GitHub Check: Dashboard Test
  • GitHub Check: Dashboard Build
  • GitHub Check: Dashboard Type Check
  • GitHub Check: Build Fine-Tune (gpu, fine-tune-gpu)
  • GitHub Check: Build Fine-Tune (cpu, fine-tune-cpu)
  • GitHub Check: Build Sidecar
  • GitHub Check: Test Unit (shard 3)
  • GitHub Check: Test Unit (shard 1)
  • GitHub Check: Test Unit (shard 2)
  • GitHub Check: Test Unit (shard 4)
  • GitHub Check: Test Integration (shard 4)
  • GitHub Check: Lint
  • GitHub Check: Test Integration (shard 1)
  • GitHub Check: Test Integration (shard 2)
  • GitHub Check: Test Conformance (SQLite)
  • GitHub Check: Dashboard Storybook Build
  • GitHub Check: Test Integration (shard 3)
  • GitHub Check: Dashboard Lint
  • GitHub Check: Type Check
  • GitHub Check: Runtime Stats Freshness Gate
  • GitHub Check: Test E2E
  • GitHub Check: CodSpeed Python benchmarks
  • GitHub Check: Build Web Assets (melange)
  • GitHub Check: Build Backend Base (apko)
  • GitHub Check: Build Sandbox Base (apko)
  • GitHub Check: CodSpeed Web benchmarks
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (1)
!(src/synthorg/persistence/**)

📄 CodeRabbit inference engine (CLAUDE.md)

Only src/synthorg/persistence/ may import sqlite/psycopg or emit raw SQL

Files:

  • .github/workflows/scorecard.yml
  • .github/workflows/cli.yml
  • .github/workflows/docker.yml
  • .github/workflows/codspeed.yml
  • .github/workflows/ci.yml
🔇 Additional comments (5)
.github/workflows/ci.yml (1)

47-55: LGTM!

Also applies to: 237-257

.github/workflows/cli.yml (1)

35-40: LGTM!

.github/workflows/codspeed.yml (1)

61-66: LGTM!

.github/workflows/docker.yml (1)

68-73: LGTM!

.github/workflows/scorecard.yml (1)

26-26: ⚡ Quick win

Confirm actions/checkout v6 pin for scorecard workflow

  • The pinned actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd matches the actions/checkout v6 tag.
  • No explicit fetch-depth is set; ensure scorecard doesn’t require full git history or other checkout parameters for this workflow.

Walkthrough

This PR fixes git checkout depth issues across five GitHub Actions workflows. In ci.yml, the changes and schema-validate jobs now use fetch-depth: "0" for full-history checkouts, with added comments explaining that paths-filter on push events and three-dot diffs require shared git ancestry. The schema-validate job's revision-check step also changes from a shallow fetch (--depth=1) to a full fetch of the base branch. Similar fetch-depth: "0" updates are applied to the changes jobs in cli.yml, codspeed.yml, and docker.yml. Additionally, the scorecard.yml workflow's checkout step is changed from a local retry-wrapped composite to the upstream actions/checkout@v6 action, as required by OSSF Scorecard's workflow-step allowlist.

Suggested labels

prio:medium, scope:ci, type:infra

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the two main changes: fixing the paths-filter shallow-clone race issue and resolving the scorecard allowlist problem.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining both bugs, their causes, fixes applied, and verification steps taken.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails
actions/actions/checkout de0fac2e4500dabe0009e67214ff5f5447ce83dd 🟢 5.7
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained⚠️ 01 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
SAST🟢 8SAST tool detected but not run on all commits

Scanned Files

  • .github/workflows/scorecard.yml

@coderabbitai coderabbitai Bot added type:infra CI/CD, tooling, project setup prio:medium Should do, but not blocking scope:ci labels May 24, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 24, 2026

Merging this PR will not alter performance

✅ 54 untouched benchmarks


Comparing fix/ci-shallow-clone-paths-filter-race (bccc57b) with main (917d98a)

Open in CodSpeed

@codecov
Copy link
Copy Markdown

codecov Bot commented May 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.11%. Comparing base (72c6648) to head (bccc57b).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2089   +/-   ##
=======================================
  Coverage   87.11%   87.11%           
=======================================
  Files        2251     2251           
  Lines      130269   130269           
=======================================
  Hits       113481   113481           
  Misses      16773    16773           
  Partials       15       15           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Aureliolo Aureliolo merged commit 7cd7ce8 into main May 24, 2026
100 of 101 checks passed
@Aureliolo Aureliolo deleted the fix/ci-shallow-clone-paths-filter-race branch May 24, 2026 07:04
Aureliolo pushed a commit that referenced this pull request May 24, 2026
<!-- HIGHLIGHTS_START -->
## Highlights

> _AI-generated summary (model: `openai/gpt-4.1-mini` via GitHub
Models). Commit-based changelog below._

### What you'll notice
- New brownfield codebase intake mode supports merger and acquisition
scenarios.
- Added deep CEO interview feature to improve project charter creation.
- Introduced mission control and flight recorder operator cockpit for
better operational oversight.
- Research mode added for enhanced exploratory work.
- Runtime services now log safety-spine state at boot for clearer
diagnostics.

### What's new
- Research mode feature enables deeper data exploration.
- CEO interview integration helps shape project charters.
- Mission control and flight recorder cockpit introduced for operational
tracking.

### Under the hood
- Improved codebase modularity with module-size gates and lint
tightening.
- Added __init__.py to 21 test directories for better test discovery.
- Promoted six transitive dependencies to direct dependencies for
clarity.
- Split codespell ignore list into vocabulary and source renames.
- Decomposed oversized web utilities, hooks, and libraries for
maintainability.
- Enhanced CI with Lychee link checker integration and retry logic for
cosign signing.
- Sharded unit and integration tests and added Postgres service
container in CI.
- Updated infrastructure and web dependencies; maintained lock files.

<!-- HIGHLIGHTS_END -->

:robot: I have created a release *beep* *boop*
---


##
[0.8.8](v0.8.7...v0.8.8)
(2026-05-24)


### Features

* brownfield codebase intake (merger/acquisition entry mode)
([#2042](#2042))
([e287621](e287621)),
closes [#1975](#1975)
* deep CEO interview to project charter
([#2045](#2045))
([904f2fb](904f2fb))
* mission control + flight recorder operator cockpit
([#2044](#2044))
([1c2660b](1c2660b))
* research mode
([#2041](#2041))
([f81a5ac](f81a5ac)),
closes [#1989](#1989)
* surface safety-spine state in runtime-services boot log (closes
[#2096](#2096))
([#2097](#2097))
([f187b31](f187b31))


### Refactoring

* add __init__.py to 21 leaf test directories (INP001)
([#2081](#2081))
([2592118](2592118)),
closes [#2064](#2064)
* codebase modularity (1/4) - module-size gates + lint tightening +
tools ([#2078](#2078))
([556fbd9](556fbd9)),
closes [#2047](#2047)
[#2040](#2040)
* promote 6 transitive deps to direct deps
([#2083](#2083))
([adedc6a](adedc6a))
* split codespell ignore-words-list into vocab + source renames
([#2085](#2085))
([917d98a](917d98a)),
closes [#2074](#2074)
* **web:** PR A foundation, decompose oversized utils/hooks/lib
([#2092](#2092))
([#2098](#2098))
([aedbba5](aedbba5))


### CI/CD

* exclude slsa.dev from lychee (transient timeout on canonical badge)
([#2090](#2090))
([346c51d](346c51d))
* fix paths-filter shallow-clone race and scorecard allowlist
([#2089](#2089))
([7cd7ce8](7cd7ce8))
* refresh .test_durations.{unit,integration}
([#2087](#2087))
([ddf2d86](ddf2d86))
* retry cosign sign on transient GHCR/Rekor failures
([#2100](#2100))
([da9422a](da9422a))
* shard test-unit + test-integration, sysmon coverage, Postgres service
container ([#2080](#2080))
([0768787](0768787))
* wire Lychee link-checker (workflow + installer + pre-push hook)
([#2084](#2084))
([1c0694a](1c0694a))


### Maintenance

* Lock file maintenance
([#2086](#2086))
([a78810a](a78810a))
* Update Infrastructure dependencies
([#2055](#2055))
([041ad8b](041ad8b))
* Update Web dependencies
([#2054](#2054))
([4d57b9a](4d57b9a))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: synthorg-repo-bot[bot] <279117679+synthorg-repo-bot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prio:medium Should do, but not blocking scope:ci type:infra CI/CD, tooling, project setup

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant