Skip to content

Skip templated dependency audit on Dependabot PRs - #23

Merged
leynos merged 5 commits into
mainfrom
fix/skip-audit-for-dependabot
Jul 21, 2026
Merged

Skip templated dependency audit on Dependabot PRs#23
leynos merged 5 commits into
mainfrom
fix/skip-audit-for-dependabot

Conversation

@leynos

@leynos leynos commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Conditions the templated CI's make audit step on github.actor != 'dependabot[bot]'. (The cargo-audit install stays unconditional because it is bundled with the Whitaker lint tooling install, which the lint step also needs.)
  • Adds a templated weekly scheduled audit workflow (audit.yml.jinja) as the compensating control, covering both the use_rust and plain-Python renders and reusing the template's existing pinned action refs.

Motivation

make audit reports advisories against the whole lockfile, so in generated projects a newly published advisory fails every open Dependabot PR regardless of its content, deadlocking Dependabot auto-merge (observed on leynos/corbusier#120, where even Dependabot's own fix for a vite advisory was blocked by unrelated advisories). The same change has been applied directly to the twelve existing estate repositories with make audit gates; this PR brings the template in line so newly generated projects inherit it. Human pull requests keep the full audit gate.

Test plan

  • Both workflow templates rendered with use_rust=True and use_rust=False (StrictUndefined) and validated with actionlint
  • act-validation template render passes in CI

References

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leynos, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f8bb5d78-c4db-4844-815f-539d621ed123

📥 Commits

Reviewing files that changed from the base of the PR and between f4c709a and 66657a2.

📒 Files selected for processing (1)
  • tests/test_audit.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/mdtablefix (auto-detected)

Summary

  • Skip make audit for Dependabot pull requests while retaining unconditional cargo-audit installation.
  • Add a weekly, manually triggerable audit workflow for Python and Rust-enabled templates with read-only permissions and a 30-minute timeout.
  • Add workflow contract tests covering triggers, guards, audit commands, permissions, timeout, and Rust-specific steps.
  • Update user and developer documentation to describe the Dependabot exception and scheduled audit.

Walkthrough

This PR adds a weekly or manually triggered dependency-audit workflow with optional Rust tooling, skips the existing CI audit for Dependabot-triggered runs, and updates generated-workflow tests plus developer and user documentation.

Changes

Dependency audit workflow changes

Layer / File(s) Summary
New scheduled audit workflow
template/.github/workflows/audit.yml.jinja
Add weekly and manual triggers, read-only contents permissions, a 30-minute audit job, Python and uv setup, optional Rust/cargo-audit setup, and make audit.
CI audit guard and contract validation
template/.github/workflows/ci.yml.jinja, tests/helpers/ci_contracts.py
Skip the “Audit dependencies” step when github.actor is dependabot[bot], and validate that exactly one guarded step is rendered.
Generated workflow validation
tests/test_audit.py
Validate triggers, permissions, timeout, audit execution, and Rust-specific steps for both Rust and non-Rust templates.
Audit behaviour documentation
docs/developers-guide.md, template/docs/developers-guide.md, template/docs/users-guide.md.jinja
Document the Dependabot bypass and weekly default-branch audit workflow.

Sequence Diagram(s)

sequenceDiagram
  participant Scheduler as GitHub Actions Scheduler
  participant AuditWorkflow as Audit Workflow
  participant Runner as ubuntu-latest Runner

  Scheduler->>AuditWorkflow: weekly cron trigger or workflow_dispatch
  AuditWorkflow->>Runner: checkout, setup Python 3.13, install uv
  alt use_rust enabled
    AuditWorkflow->>Runner: setup Rust and install cargo-audit
  end
  AuditWorkflow->>Runner: run make audit
Loading

Possibly related PRs

Poem

Audit bells ring every week,
Manual runs are quick to seek.
Dependabot skips the gate,
Rust tools join when templates state.
make audit keeps watch in flight.


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (2 inconclusive)

Check name Status Explanation Resolution
Developer Documentation ❓ Inconclusive Placeholder pending repository evidence. Inspect the changed docs, design notes, and roadmap files before deciding.
Rust Compiler Lint Integrity ❓ Inconclusive Pending repo inspection of changed files and any Rust lint/clone changes. Run a targeted diff and search for Rust suppressions or added clones in modified Rust files.
✅ Passed checks (18 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main change: skipping the templated dependency audit on Dependabot pull requests.
Description check ✅ Passed The description is directly related to the workflow and documentation updates around the Dependabot audit bypass.
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.
Testing (Overall) ✅ Passed Accept the tests: they render real projects, run make audit with fake tools, and assert the Dependabot guard, weekly schedule, timeout, permissions, and Rust branches.
User-Facing Documentation ✅ Passed Accept it: the user guide’s Dependency Auditing section documents the Dependabot skip, weekly compensating audit, and Rust cargo-audit behaviour.
Module-Level Documentation ✅ Passed PASS: the changed Python modules, tests/test_audit.py and tests/helpers/ci_contracts.py, both begin with clear module docstrings covering purpose and relationships.
Testing (Unit And Behavioural) ✅ Passed The new tests exercise rendered workflow files and make audit behaviour across both Rust and pure-Python variants, not private seams.
Testing (Property / Proof) ✅ Passed The PR adds fixed workflow/config contracts, not a range-based invariant or proof obligation; unit and contract tests are the right fit.
Testing (Compile-Time / Ui) ✅ Passed No Rust/TS compile-time change is present; the new audit workflow is covered by focused rendered-workflow contract tests, matching the repo’s no-snapshot contract approach.
Unit Architecture ✅ Passed The change is limited to workflow/docs/tests; the new tests use explicit fake CLI shims and parsed YAML boundaries, so no hidden side-effects or mixed responsibilities appear.
Domain Architecture ✅ Passed Only workflow templates, docs, and tests changed; no domain, adapter, persistence, or transport code was touched.
Observability ✅ Passed Mark PASS: this PR only alters CI workflow templates/docs/tests, and GitHub Actions logs/step names already expose failures; no runtime telemetry is warranted.
Security And Privacy ✅ Passed Keep permissions read-only, avoid credential persistence, and introduce no new secrets or sensitive-data exposure.
Performance And Resource Use ✅ Passed Bounded test-only loops and file reads; no hot-path, unbounded, or repeated-I/O regressions were introduced.
Concurrency And State ✅ Passed PASS: The patch only changes workflow YAML, docs, and isolated tests; it adds no shared mutable state, async tasks, locks, or ordering-sensitive code.
Architectural Complexity And Maintainability ✅ Passed PASS: The PR adds explicit workflow gating, tests, and docs only; it introduces no new layers, registries, or indirection and reuses existing helper patterns.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/skip-audit-for-dependabot

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

@pandalump
pandalump marked this pull request as ready for review July 3, 2026 08:26
coderabbitai[bot]

This comment was marked as resolved.

@leynos

leynos commented Jul 18, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

leynos added 3 commits July 19, 2026 18:56
`make audit` reports advisories against the whole lockfile, so in
generated projects a newly published advisory fails every open
Dependabot PR regardless of its content and deadlocks auto-merge.
Condition the audit step on the actor not being Dependabot, and add a
templated weekly scheduled audit workflow as the compensating control
so anything that slips through surfaces within days. Human pull
requests keep the full audit gate.
Add a timeout to the scheduled audit job and assert the CI audit step's
Dependabot guard structurally. Cover the generated scheduled audit workflow
for both pure-Python and Rust-enabled renders so its trigger, permissions,
timeout, and Rust-specific steps stay under test.
Explain that pull-request CI skips dependency auditing for Dependabot and
that the weekly scheduled workflow audits the default branch as the
compensating control.
@lodyai
lodyai Bot force-pushed the fix/skip-audit-for-dependabot branch from eafa5a4 to fc34b45 Compare July 19, 2026 17:01
@leynos

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

Document the Dependabot exception in the parent CI strategy and assert the
scheduled audit workflow's manual trigger and exact audit command.
@leynos

leynos commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following now been resolved?

template/.github/workflows/audit.yml.jinja (1)

1-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Add test coverage for this new scheduled workflow.
Nothing in the supplied context exercises audit.yml.jinja itself — tests/test_audit.py validates the make audit target's tool dispatch, not that this new workflow file renders sensibly for both use_rust variants (cron trigger present, permissions: contents: read, Rust steps gated correctly). Extend the existing render-and-assert pattern to cover this file too, so a broken Jinja conditional here doesn't go unnoticed until the schedule actually fires.

🤖 Detailed instructions

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @template/.github/workflows/audit.yml.jinja around lines 1 - 51, The new
scheduled audit workflow is untested, so add coverage that renders
audit.yml.jinja and asserts the expected workflow shape. Extend the existing
render-and-assert tests in tests/test_audit.py to verify the cron trigger and
permissions are present, and that the Rust-specific steps in the audit job only
appear when use_rust is enabled. Make sure both use_rust variants are exercised
so broken Jinja conditionals in the audit workflow are caught.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== PR changes relevant to the finding =='
git diff --unified=80 origin/main...HEAD -- \
  template/.github/workflows/audit.yml.jinja \
  tests/test_audit.py

echo
echo '== Workflow template =='
cat -n template/.github/workflows/audit.yml.jinja

echo
echo '== Test module outline =='
ast-grep outline tests/test_audit.py --items all --type function --match 'audit|workflow|render'

echo
echo '== Focused audit-workflow test and helpers =='
rg -n -C 12 \
  'test_generated_audit_workflow_has_expected_contract|audit\.yml|use_rust|workflow_dispatch|cron|permissions|timeout-minutes|Rust' \
  tests/test_audit.py tests || true

echo
echo '== Current changed-file status =='
git diff --name-status origin/main...HEAD

Length of output: 1181


🏁 Script executed:

#!/bin/bash
set -uo pipefail

echo '== Repository and PR refs =='
git status --short --branch || true
git branch -a --no-color || true
gh pr view 23 --repo leynos/agent-template-python \
  --json headRefName,baseRefName,files,url 2>/dev/null || true

echo
echo '== Candidate files =='
fd -a -H -t f -E .git \
  '^(audit\.yml\.jinja|test_audit\.py)$' . || true

echo
echo '== Workflow template =='
cat -n template/.github/workflows/audit.yml.jinja 2>/dev/null || true

echo
echo '== Test module structure =='
ast-grep outline tests/test_audit.py --items all --type function 2>/dev/null || true

echo
echo '== Focused contract and render helper references =='
rg -n -C 15 \
  'generated_audit_workflow|audit\.yml|use_rust|workflow_dispatch|cron|permissions|timeout-minutes|cargo-audit|make audit' \
  tests/test_audit.py tests/helpers 2>/dev/null || true

Length of output: 75270


@leynos, mark this finding resolved.

tests/test_audit.py::test_generated_audit_workflow_has_expected_contract now renders and validates .github/workflows/audit.yml for both pure-Python and Rust-enabled projects. It asserts:

  • workflow_dispatch and the weekly Monday cron trigger (Lines 128-138);
  • permissions: {contents: read} and timeout-minutes: 30 (Lines 139-147);
  • the Audit dependencies step runs exactly make audit (Lines 148-159);
  • Set up Rust and Install cargo-audit appear only when use_rust=True (Lines 160-169).

These checks directly cover the Jinja conditionals in template/.github/workflows/audit.yml.jinja (Lines 20-23 and 38-49). No further change is required for this finding.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== PR metadata and changed files =='
gh pr view 23 --repo leynos/agent-template-python --json baseRefName,headRefName,url,files
git diff --name-status origin/main...HEAD

echo
echo '== Relevant current files =='
for file in \
  template/.github/workflows/ci.yml.jinja \
  template/.github/workflows/audit.yml.jinja \
  tests/test_audit.py \
  tests/helpers/ci_contracts.py \
  template/docs/users-guide.md.jinja \
  template/docs/developers-guide.md \
  docs/developers-guide.md
do
  echo "--- ${file}"
  cat -n "${file}"
done

echo
echo '== Focused diff =='
git diff --unified=8 origin/main...HEAD -- \
  template/.github/workflows/ci.yml.jinja \
  template/.github/workflows/audit.yml.jinja \
  tests/test_audit.py \
  tests/helpers/ci_contracts.py \
  template/docs/users-guide.md.jinja \
  template/docs/developers-guide.md \
  docs/developers-guide.md

Length of output: 2133


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Relevant current files =='
for file in \
  template/.github/workflows/ci.yml.jinja \
  template/.github/workflows/audit.yml.jinja \
  tests/test_audit.py \
  tests/helpers/ci_contracts.py \
  template/docs/users-guide.md.jinja \
  template/docs/developers-guide.md \
  docs/developers-guide.md
do
  echo "--- ${file}"
  cat -n "${file}"
done

echo
echo '== PR patch from GitHub =='
gh pr diff 23 --repo leynos/agent-template-python --patch

Length of output: 71136


@leynos, mark all six findings resolved. No further work, AI-agent prompt, or follow-up issue is required.

Check Status Current evidence
Testing (Overall) Resolved tests/helpers/ci_contracts.py locates the uniquely named Audit dependencies CI step and asserts the exact guard: github.actor != 'dependabot[bot]'.
User-Facing Documentation Resolved template/docs/users-guide.md.jinja explains the Dependabot skip and weekly default-branch audit compensating control.
Developer Documentation Resolved Both template/docs/developers-guide.md and docs/developers-guide.md document the conditional CI audit and scheduled weekly workflow.
Testing (Unit And Behavioural) Resolved tests/test_audit.py renders both Python-only and Rust-enabled projects, validating the scheduled workflow’s triggers, permissions, timeout, exact audit command, and Rust-only setup.
Testing (Compile-Time / UI) Resolved The rendered workflow contract parses the generated YAML and checks workflow_dispatch, Monday cron, permissions: {contents: read}, and run: make audit.
Performance And Resource Use Resolved template/.github/workflows/audit.yml.jinja sets timeout-minutes: 30; the rendered-workflow test enforces that value.

Run the PR CI to confirm runtime execution of the focused tests; static inspection confirms the required tests and documentation are present and cover the reported regressions.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_audit.py`:
- Around line 160-169: Update the Rust workflow assertions in the use_rust
branch to locate the step named “Install cargo-audit” and assert its run value
is exactly “cargo install --locked cargo-audit”; retain the existing setup-step
presence and pure-Python exclusion checks.
- Around line 108-115: Update the
test_generated_audit_workflow_has_expected_contract signature to insert a
keyword-only separator before use_rust, preserving pytest’s named
parametrization binding while resolving Ruff’s FBT001 warning.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5d2ce200-92dc-450e-b2a7-196a966ee246

📥 Commits

Reviewing files that changed from the base of the PR and between 817ac98 and f4c709a.

📒 Files selected for processing (7)
  • docs/developers-guide.md
  • template/.github/workflows/audit.yml.jinja
  • template/.github/workflows/ci.yml.jinja
  • template/docs/developers-guide.md
  • template/docs/users-guide.md.jinja
  • tests/helpers/ci_contracts.py
  • tests/test_audit.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/mdtablefix (auto-detected)

Comment thread tests/test_audit.py
Comment thread tests/test_audit.py
Assert the exact `cargo install --locked cargo-audit` run value for the
generated "Install cargo-audit" step instead of only checking the step's
presence, so a regression in the install command is caught. Make `use_rust`
keyword-only in the contract test signature to keep the boolean parameter
off the positional interface (Ruff FBT001) while preserving pytest's
name-based parametrization binding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@leynos

This comment was marked as resolved.

Repository owner deleted a comment from coderabbitai Bot Jul 21, 2026
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== PR metadata and relevant changed files =='
gh pr view 23 --repo leynos/agent-template-python --json headRefName,baseRefName,url,files
git diff --name-status origin/main...HEAD -- \
  template/.github/workflows/audit.yml.jinja \
  tests/test_audit.py

echo
echo '== Workflow template =='
cat -n template/.github/workflows/audit.yml.jinja

echo
echo '== Audit workflow contract test =='
ast-grep outline tests/test_audit.py --items all --type function --match 'test_generated_audit_workflow_has_expected_contract'
rg -n -C 18 \
  'test_generated_audit_workflow_has_expected_contract|Install cargo-audit|cargo install --locked cargo-audit|RUSTFLAGS|Audit dependencies' \
  tests/test_audit.py

echo
echo '== Exact focused PR diff =='
git diff --unified=20 origin/main...HEAD -- \
  template/.github/workflows/audit.yml.jinja \
  tests/test_audit.py

Length of output: 2134


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Workflow template =='
cat -n template/.github/workflows/audit.yml.jinja

echo
echo '== Contract test structure and relevant assertions =='
ast-grep outline tests/test_audit.py --items all --type function --match 'test_generated_audit_workflow_has_expected_contract'
rg -n -C 24 \
  'test_generated_audit_workflow_has_expected_contract|Install cargo-audit|cargo install --locked cargo-audit|RUSTFLAGS|Audit dependencies' \
  tests/test_audit.py

echo
echo '== PR patch restricted to the two relevant files =='
gh api \
  repos/leynos/agent-template-python/pulls/23/files \
  --paginate \
  --jq '.[] | select(.filename == "template/.github/workflows/audit.yml.jinja" or .filename == "tests/test_audit.py") | "FILE: \(.filename)\n\(.patch // "(no textual patch returned)")\n"'

Length of output: 13351


@leynos, mark the Testing (Overall) failure resolved.

tests/test_audit.py::test_generated_audit_workflow_has_expected_contract now:

  • renders both pure-Python and Rust-enabled projects;
  • locates exactly one Install cargo-audit step in the Rust render;
  • asserts that step’s exact command is cargo install --locked cargo-audit;
  • asserts Rust setup steps are absent from the pure-Python render.

This fails if cargo-audit is removed, duplicated, or its install command changes. No further work, AI-agent prompt, or follow-up issue is required.

@leynos

leynos commented Jul 21, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos
leynos merged commit 491c6ed into main Jul 21, 2026
6 of 7 checks passed
@leynos
leynos deleted the fix/skip-audit-for-dependabot branch July 21, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants