You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Fix Dependabot auto-merge
## Summary
Fixes the Dependabot auto-merge workflow, which was previously
configured to make a single timed-out attempt rather than waiting for
required CI checks to pass.
## Changes
### Dependabot auto-merge overhaul
(`scripts/ci/enable-dependabot-automerge.sh`,
`.github/workflows/dependabot-auto-merge.yml`)
- **Removed one-shot mode.** The old workflow ran the script with a
45-second hard timeout (`DEPENDABOT_AUTOMERGE_ONE_SHOT=true`), causing
it to bail before CI checks could settle. The script now always polls
until checks complete.
- **Increased job timeout** from 1 minute to 40 minutes to give the
polling loop enough time to observe all required checks.
- **Added `SIGTERM` handler** so the job can emit a clear error message
if the runner kills it at the job timeout boundary.
- **Broadened failure detection** (allowlist instead of denylist):
checks and statuses are now considered failed if their conclusion/state
is anything other than `success`, `skipped`, `neutral`, or `pending` —
catching conclusions like `startup_failure` and `stale` that the old
explicit list missed.
- **Added fallback when all required checks belong to the current job**:
if the only required checks reported are the auto-merge job itself, the
script now falls back to gating on all non-self check-runs/statuses
instead of treating the gate as already satisfied.
- **Removed `jq` conditional guard**: `jq` is now always required (it
was already required in practice).
### New agent preflight script (`scripts/ci/agent-preflight.py`,
`scripts/tests/test_agent_preflight.py`)
Adds a changed-file-aware preflight script for agentic workflows. It
runs a targeted set of validations (version-sync checks, LLM skill
linting, etc.) based on which files are staged, so agents catch issues
before hitting pre-commit hooks. Ships with a full test suite (`248`
test cases).
### Dependency pin rollback (all CI workflows)
Rolls back `mozilla-actions/sccache-action` from `v0.0.10` to `v0.0.9`
across all workflows (`ci-rust.yml`, `ci-benchmarks.yml`,
`ci-network.yml`, `ci-security.yml`, `ci-verification.yml`,
`publish.yml`).
Dependabot auto-merge policy: this repository is squash-only. Use `scripts/ci/enable-dependabot-automerge.sh` (which enforces `--squash`, supports one-shot enable mode for fast auto-merge setup, defaults to waiting for checks with fallback when required-check metadata is unavailable, and checks policy drift) instead of inline merge commands in workflows.
162
+
Dependabot auto-merge policy: this repository is squash-only and the auto-merge job MUST wait for every non-self CI gate on the PR head SHA to reach an explicitly accepted state (`success`, `skipped`, `neutral`) before enabling merge. Anything else -- including `failure`, `timed_out`, `cancelled`, `action_required`, `startup_failure`, `stale`, missing/`null` conclusions, or future GitHub-added states -- refuses the merge (allow-list semantics). Use `scripts/ci/enable-dependabot-automerge.sh` -- never inline `gh pr merge` in workflows, never re-introduce a "one-shot" / bypass path, never wrap the script in a sub-job-level `timeout`. Regression-tested in `scripts/tests/test_enable_dependabot_automerge.py`.
@@ -220,12 +220,15 @@ For protocol tests that poll in loops (`poll_remote_clients()` / protocol `poll(
220
220
221
221
**Unreleased code rule:** Never add separate "Fixed" or "Changed" entries for code that has not yet been released. Fixes to unreleased features should be folded into the existing "Added" entry describing that feature. The changelog should describe the final shipped state, not intermediate development history.
222
222
223
+
**Version sync rule:** If `Cargo.toml` is `X.Y.Z`, the matching changelog header must be `## [X.Y.Z] - YYYY-MM-DD` (ISO date required). Keep `## [Unreleased]` undated. Validate with `bash scripts/sync-version.sh --check`; auto-fix with `bash scripts/sync-version.sh --changelog-only`.
-**Before finalizing agent work:**`python3 scripts/ci/agent-preflight.py --auto-fix` (changed-file-aware early checks; if output includes `Falling back to --all checks.`, resolve git-state issues and rerun)
Copy file name to clipboardExpand all lines: .llm/skills/ci-cd-tooling/github-actions.md
+14Lines changed: 14 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -230,3 +230,17 @@ env:
230
230
- [ ] Verify `permissions:` block is minimal
231
231
- [ ] Verify `runs-on` uses valid runner labels
232
232
- [ ] Validate matrix combinations
233
+
234
+
## Dependabot auto-merge gating
235
+
236
+
Auto-merge polls `gh pr checks --required` for the PR head SHA (the primary path). When required-check metadata is unavailable -- no required checks are configured for the branch, or the only required check is the auto-merge job itself -- it falls back to `repos/{owner}/{repo}/commits/{sha}/check-runs` and `…/status`. Both paths exclude the auto-merge job's own entries by filtering `link`/`details_url`/`target_url` against `GITHUB_RUN_ID`.
237
+
238
+
Failure classification uses an **allow-list**: only `success`, `skipped`, and `neutral` proceed; everything else (including `failure`, `timed_out`, `cancelled`, `action_required`, `startup_failure`, `stale`, missing/`null`, or future GitHub-added states) blocks the merge. `skipped` is allowed because matrix builds and conditional jobs legitimately produce it; `neutral` is allowed because GitHub-native advisory checks (e.g. `dependency-review-action`) emit it for non-failure findings.
239
+
240
+
Three regression guardrails in `scripts/tests/test_enable_dependabot_automerge.py` lock in this policy:
241
+
242
+
1. `test_workflow_does_not_set_one_shot_env` -- fails CI if the bypass env var is reintroduced.
243
+
2. `test_workflow_run_command_is_pure_script_invocation` -- fails CI if the script is wrapped in `timeout`, `xargs`, or any prefix command.
244
+
3. `test_workflow_timeout_is_sufficient_for_polling` -- fails CI if the workflow `timeout-minutes` falls below 32 minutes (the polling settle ceiling + a 2-minute buffer).
245
+
246
+
Branch protection is a defense layer, not a substitute. Configure `main` to require the relevant CI checks so GitHub's native auto-merge respects them too -- but the script's own gating remains the source of truth.
Copy file name to clipboardExpand all lines: AGENTS.md
-4Lines changed: 0 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,3 @@
3
3
**Read and follow [`.llm/context.md`](.llm/context.md)** — the canonical source of truth for all project context, development policies, testing guidelines, and coding standards. You must read it before making any changes.
4
4
5
5
When clarifying questions are needed, follow [`.llm/templates/ask-user-question.md`](.llm/templates/ask-user-question.md) to keep questions concise and actionable.
6
-
7
-
## Critical Rules
8
-
9
-
-**Test output:** NEVER pipe test output through `tail`/`head` (e.g., `cargo nextest run 2>&1 | tail -40`). Instead, redirect to a temp file and read it: `cargo nextest run --no-capture > /tmp/test-results.txt 2>&1`. For repeated runs, use a for loop.
Copy file name to clipboardExpand all lines: CLAUDE.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,7 @@ When clarifying questions are needed, follow [`.llm/templates/ask-user-question.
8
8
9
9
-**Zero-panic:** No `unwrap()`, `expect()`, `panic!()`, `todo!()` in production code
10
10
-**Pre-commit:**`cargo fmt && cargo clippy --all-targets --features tokio,json && cargo nextest run --no-capture` (or `cargo c && cargo t`)
11
+
-**Agent preflight:** Before finalizing changes, run `python3 scripts/ci/agent-preflight.py --auto-fix`. If output includes `Falling back to --all checks.`, resolve the git-state issue and rerun preflight.
11
12
-**Test output:** NEVER pipe test output through `tail`/`head` (e.g., `cargo nextest run 2>&1 | tail -40`). Instead, redirect to a temp file and read it: `cargo nextest run --no-capture > /tmp/test-results.txt 2>&1`. For repeated runs, use a for loop.
12
13
-**Kani:** Always add `#[kani::unwind(N)]` to proofs; CI uses `--default-unwind 8` via `--quick` mode
13
14
-**Changelog:** Ask "Does this affect `pub` items or user-observable behavior?" — if yes, update `CHANGELOG.md`
0 commit comments