Skip to content

Add scheduled mutation testing to generated repos#52

Open
leynos wants to merge 2 commits into
mainfrom
add-mutation-testing-template
Open

Add scheduled mutation testing to generated repos#52
leynos wants to merge 2 commits into
mainfrom
add-mutation-testing-template

Conversation

@leynos

@leynos leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

Adds template/.github/workflows/mutation-testing.yml so newly generated Rust repositories get scheduled mutation testing by default, matching the pattern already rolled out across the estate (for example leynos/mapsplice).

The workflow is a thin caller of the shared reusable workflow leynos/shared-actions/.github/workflows/mutation-cargo.yml, pinned to 2b09d10192627fd6e1034e7c12625dd266b45503. Caller guide: https://github.com/leynos/shared-actions/blob/main/docs/mutation-cargo-workflow.md.

Details:

  • Triggers: daily schedule plus workflow_dispatch. The default cron is 15 9 * * *; the estate already occupies the 03:05–09:05 UTC slots, and an inline comment tells maintainers of generated repositories to stagger their slot to avoid concurrent runs across the estate.
  • Root permissions: {}; the mutation job opts in to contents: read and id-token: write (OIDC workflow-source resolution).
  • Concurrency group mutation-testing-${{ github.ref }} with cancel-in-progress: false, so dispatches queue behind scheduled runs rather than racing or cancelling.
  • extra-args: "--all-features" mirrors the template CI test baseline (make test runs with --all-targets --all-features). Workspace-related inputs are omitted because the generated project is a single root crate.
  • The file is plain YAML rather than Jinja-templated, matching ci.yml and act-validation.yml, as it needs no template variables; this also sidesteps the ${{ }} Jinja/Actions syntax collision.
  • The generated docs/repository-layout.md is updated to list the new workflow.

Validation

  • copier copy --defaults renders cleanly and the workflow is copied verbatim.
  • actionlint passes on the rendered file.
  • make test: 47 passed, 1 skipped; the 3 failures in tests/test_template/test_lint_targets.py are pre-existing on main and unrelated to this change.

Add a mutation-testing caller workflow to the template so newly
generated Rust projects run scheduled mutation testing by default. The
workflow is a thin caller of the shared mutation-cargo reusable
workflow in leynos/shared-actions, pinned to a full commit SHA in line
with the template's action-pinning convention.

The workflow runs daily at 09:15 UTC with a comment advising
maintainers to stagger the slot per repository, and supports manual
dispatch. It defaults the token to no scopes, with the job opting in to
contents: read and id-token: write. The extra-args input mirrors the
CI test baseline (--all-features); workspace inputs are omitted as the
generated project is a single crate.

The file is plain YAML rather than Jinja-templated, matching ci.yml
and act-validation.yml, as it needs no template variables. The
generated repository-layout document is updated to list the new
workflow.

@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 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 8 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9ab04c94-50cc-4341-8b75-d1b153ad37e0

📥 Commits

Reviewing files that changed from the base of the PR and between 7d7eb00 and facc38a.

📒 Files selected for processing (2)
  • template/.github/workflows/mutation-testing.yml
  • template/docs/repository-layout.md.jinja

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

Walkthrough

Adds a new GitHub Actions workflow, mutation-testing.yml, which triggers mutation testing on a daily schedule or manual dispatch via a shared reusable workflow, with restricted permissions and per-ref concurrency control. Updates the repository-layout documentation to reflect this new workflow file.

Changes

Mutation testing workflow

Layer / File(s) Summary
Mutation-testing workflow definition
template/.github/workflows/mutation-testing.yml
New workflow with cron (09:15 UTC) and workflow_dispatch triggers, default-deny permissions with job-level contents: read and id-token: write, per-ref concurrency serialisation, invocation of the shared mutation-cargo.yml reusable workflow with --all-features, and setup commands installing clang, lld, and mold.
Repository layout documentation update
template/docs/repository-layout.md.jinja
Adds mutation-testing.yml to the repository tree listing and describes it in the path-responsibilities bullets as running scheduled mutation testing via the shared mutation-cargo workflow.

Possibly related PRs

  • leynos/shared-actions#319: Adds the reusable mutation-cargo.yml workflow that this PR's new caller workflow directly invokes.
  • leynos/wireframe#572: Refactors a mutation-testing workflow into a thin caller of the same shared mutation-cargo.yml reusable workflow with matching configuration.
  • leynos/cmd-mox#187: Introduces an equivalent mutation-testing.yml caller with the same schedule, permissions, and concurrency contract.

Poem

A rabbit hops through cron and gate,
Mutating code at nine-fifteen straight,
With clang, lld, and mold in tow,
Least-privilege tokens, off it goes,
One ref at a time — no overlap, no wait! 🐇⚙️


Caution

Pre-merge checks failed

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

  • Ignore

❌ Failed checks (1 error, 3 warnings)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error No test exercises mutation-testing.yml; current rendered-project tests cover ci/act/release only, so altering the new workflow would not fail. Add a rendered-project contract test that parses mutation-testing.yml and asserts the pinned reusable workflow, permissions, concurrency, cron, and setup-commands.
User-Facing Documentation ⚠️ Warning The new scheduled mutation-testing workflow is not documented in docs/users-guide.md; only repository-layout mentions it. Add a user-guide entry in template/docs/users-guide.md.jinja and docs/users-guide.md explaining the new scheduled mutation-testing workflow and its impact.
Testing (Unit And Behavioural) ⚠️ Warning No unit or behavioural test was added for mutation-testing.yml; existing template tests cover CI/act/release, not this new workflow contract. Add a rendered-project contract or snapshot test that asserts mutation-testing.yml, including the pinned reusable-workflow SHA, scoped permissions, and setup-commands.
Testing (Compile-Time / Ui) ⚠️ Warning No test was added for the new workflow; existing contract and snapshot tests cover ci/act/release only, so the YAML contract is unguarded. Add a focused tooling-contract assertion or a tight snapshot for the rendered mutation-testing workflow and its docs entry.
✅ Passed checks (16 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises adding scheduled mutation testing to generated repositories.
Description check ✅ Passed The description directly describes the new mutation-testing workflow and documentation update.
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.
Developer Documentation ✅ Passed docs/developers-guide.md already covers clang/lld/mold, and repository-layout.md records the new workflow; no ADR or roadmap update is needed.
Module-Level Documentation ✅ Passed No Rust modules changed; the PR only adds a workflow YAML and repository-layout docs, so the module-docstring requirement is not applicable.
Testing (Property / Proof) ✅ Passed This PR adds static workflow/docs configuration only; it introduces no input/state invariant or lemma that would justify property or proof testing.
Unit Architecture ✅ Passed PASS: the change is a declarative workflow/docs addition; dependencies and side-effects stay explicit via reusable-workflow inputs and scoped permissions, with no hidden query/command boundary.
Domain Architecture ✅ Passed Only a GitHub Actions workflow and repository-layout docs changed; no domain code, invariants, or boundary logic were touched.
Observability ✅ Passed PASS: this change only adds a GitHub Actions workflow; job/setup logs expose failures and no new metrics, tracing, or alerts are needed.
Security And Privacy ✅ Passed PASS: The workflow adds no secrets or user data, keeps permissions scoped to contents:read and id-token:write, and uses static commands with no untrusted inputs.
Performance And Resource Use ✅ Passed No hot-path code changed; the new workflow is bounded CI config, mirrors existing CI package installs, and adds no unbounded loops, caches, or polling.
Concurrency And State ✅ Passed Concurrency is explicit via per-ref concurrency with cancel-in-progress: false; no shared mutable state or unsafe locking is introduced.
Architectural Complexity And Maintainability ✅ Passed Adds one explicit workflow caller and a docs note, reusing the shared mutation workflow; no new abstractions, layers, or indirection are introduced.
Rust Compiler Lint Integrity ✅ Passed No Rust files changed; the diff only touches workflow and docs, with no new lint suppressions or clone-heavy code.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-mutation-testing-template

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

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5cb3aa8dbe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread template/.github/workflows/mutation-testing.yml Outdated
The generated .cargo/config.toml links Linux dev targets with clang
and -fuse-ld=mold, and the generated ci.yml installs mold before any
cargo command, but the mutation workflow's mutants jobs had no way to
install it, so the cargo-mutants baseline would fail to link on a bare
ubuntu-latest runner.

Bump the shared workflow pin to 0c8bd605f8966a004decb0b54f717a745f51bc57,
which introduces the setup-commands input, and use it to install clang,
lld, and mold exactly as the generated ci.yml does. The install is
unconditional, matching ci.yml's own convention: CI always runs on
Linux runners, and ci.yml installs the packages regardless of the
dev_target chosen at generation time, so the workflow stays a plain
copied file rather than becoming Jinja-templated.
@leynos

leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Review feedback addressed in facc38a: the generated .cargo/config.toml links Linux dev targets with clang and -fuse-ld=mold, so the mutants jobs would have failed to link on a bare ubuntu-latest runner.

  • Bumped the shared workflow pin to 0c8bd605f8966a004decb0b54f717a745f51bc57, which introduces the setup-commands input.
  • Added setup-commands installing clang lld mold exactly as the generated ci.yml does (same apt-get invocation and comment).
  • Kept the install unconditional and the file plain-copied: ci.yml itself installs these packages regardless of the dev_target chosen at generation time (the mold config in .cargo/config.toml is conditional on a Linux dev_target, but the workflow convention is not), so no Jinja conversion was needed.

Re-validated: copier copy --defaults renders for both the default Linux dev_target and aarch64-apple-darwin (workflow identical and verbatim in both), actionlint passes on the rendered file, and the contract suite shows the same 3 pre-existing failures tracked in #53, with no new failures (47 passed, 1 skipped).

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 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: 1

🤖 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 `@template/.github/workflows/mutation-testing.yml`:
- Around line 1-47: The workflow contract for mutation testing is not covered by
assertions, so changes to the pinned reusable-workflow SHA, the setup package
list, or the job permissions could slip through. Extend the existing
tooling-contract tests around mutation-testing.yml to verify the job uses the
expected pinned ref in the mutation job, the setup-commands installs the
required packages, and the mutation job permissions remain scoped to contents:
read and id-token: write.
🪄 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: 27643c2a-2103-4b4a-9c4f-1d5db8d3a601

📥 Commits

Reviewing files that changed from the base of the PR and between 7d7eb00 and facc38a.

📒 Files selected for processing (2)
  • template/.github/workflows/mutation-testing.yml
  • template/docs/repository-layout.md.jinja

Comment on lines +1 to +47
name: Mutation testing

# Thin caller of the shared mutation-testing reusable workflow; caller
# guide: leynos/shared-actions docs/mutation-cargo-workflow.md.
# Scheduled runs mutate only files changed within the detection window;
# manual dispatch runs mutate everything, fanned out across shards. To
# test a branch, select it in the Actions "Run workflow" control.

'on':
schedule:
# Daily, 09:15 UTC. Stagger this slot when adopting the workflow in a
# new repository: the estate already occupies 03:05-09:05 UTC, so pick
# an unclaimed slot to avoid concurrent runs across repositories.
- cron: "15 9 * * *"
workflow_dispatch:

# Default the token to no scopes; the job opts in explicitly.
permissions: {}

# Serialize runs per ref: a dispatch during a scheduled run (or vice
# versa) queues rather than racing. Runs are informational, so queued
# runs wait instead of cancelling.
concurrency:
group: mutation-testing-${{ github.ref }}
cancel-in-progress: false

jobs:
mutation:
permissions:
contents: read
id-token: write # OIDC workflow-source resolution
uses: leynos/shared-actions/.github/workflows/mutation-cargo.yml@0c8bd605f8966a004decb0b54f717a745f51bc57
with:
# Match the CI baseline (`make test` runs --all-targets
# --all-features) so the test command exercised against mutants
# mirrors what gates pull requests.
extra-args: "--all-features"
# .cargo/config.toml links Linux dev targets with clang and
# -fuse-ld=mold, so the mutants jobs need the same packages that
# ci.yml installs before any cargo command runs on a bare
# ubuntu-latest runner. The reusable workflow executes these under
# bash with `set -euo pipefail`.
setup-commands: |
export DEBIAN_FRONTEND=noninteractive
# mold accelerates dev builds; coverage uses lld for llvm-tools compatibility.
sudo apt-get update \
&& sudo apt-get install --yes --no-install-recommends clang lld mold

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check whether a contract test references mutation-testing.yml.

rg -n 'mutation-testing' tests/ --type=py

Repository: leynos/agent-template-rust

Length of output: 164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## files under tests\n'
git ls-files tests | sed -n '1,200p'

printf '\n## workflow contract helpers\n'
rg -n 'assert_.*workflow|ci.yml|mutation-testing|tooling_contracts' tests/ --type=py -A 3 -B 3

printf '\n## helper file outline\n'
ast-grep outline tests/helpers/tooling_contracts/workflows.py --view expanded

Repository: leynos/agent-template-rust

Length of output: 11403


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## workflow helper file\n'
if [ -f tests/helpers/tooling_contracts/workflows.py ]; then
  cat -n tests/helpers/tooling_contracts/workflows.py | sed -n '1,260p'
else
  echo 'missing: tests/helpers/tooling_contracts/workflows.py'
fi

printf '\n## tests importing workflow helpers\n'
rg -n 'tooling_contracts\.workflows|assert_ci_coverage_action_contract|assert_.*contract' tests/ --type=py -A 2 -B 2

printf '\n## any references to workflow filenames in tests\n'
rg -n 'ci\.yml|mutation-testing\.yml|workflows/' tests/ --type=py -A 2 -B 2

Repository: leynos/agent-template-rust

Length of output: 26294


Add a contract assertion for template/.github/workflows/mutation-testing.yml. Extend the existing tooling-contract tests so the pinned SHA, setup-commands package list, and scoped job permissions stay locked to the workflow contract.

🤖 Prompt for 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.

In `@template/.github/workflows/mutation-testing.yml` around lines 1 - 47, The
workflow contract for mutation testing is not covered by assertions, so changes
to the pinned reusable-workflow SHA, the setup package list, or the job
permissions could slip through. Extend the existing tooling-contract tests
around mutation-testing.yml to verify the job uses the expected pinned ref in
the mutation job, the setup-commands installs the required packages, and the
mutation job permissions remain scoped to contents: read and id-token: write.

Source: Coding guidelines

@leynos

leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 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.

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