Skip to content

Adopt the estate CodeScene coverage pattern in generated repos - #32

Merged
leynos merged 1 commit into
mainfrom
codescene-coverage-template
Jul 14, 2026
Merged

Adopt the estate CodeScene coverage pattern in generated repos#32
leynos merged 1 commit into
mainfrom
codescene-coverage-template

Conversation

@leynos

@leynos leynos commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

Generated repos are now born with the estate's CodeScene coverage
pattern (the Python leg proven in
cmd-mox#190), so a new
project no longer needs a follow-up onboarding PR to wire coverage.

The change touches the templated workflows only; pins are handled
manually, as with the Dependabot and mutation rollouts.

  • Templated ci.yml (template/.github/workflows/ci.yml.jinja):
    checkout gains fetch-depth: 0; the shared generate-coverage and
    setup-rust references move to a single repo-wide pin
    927edd45ae77be4251a8a18ca9eb5613a2e32cbd; coverage generation is
    guarded to pull_request (the workflow also triggers on push, now
    owned by coverage-main.yml) and enables with-ratchet: 'true'; the
    bespoke CodeScene CLI install and cs-coverage upload steps are
    removed from the pull-request job in favour of a deferred-gate note.
    Python coverage stays format: cobertura / output-path: coverage.xml
    because the shared action rejects lcov for non-Rust projects.
  • New templated coverage-main.yml (template/.github/workflows/coverage-main.yml.jinja):
    triggers on push to main plus workflow_dispatch (mandatory,
    since automerge pushes do not fire push-event workflows); sets up
    Python and uv explicitly; generates cobertura coverage with the
    ratchet; and uploads to CodeScene through the guarded shared
    upload-codescene-coverage action (mode: upload default, skipped
    when CS_ACCESS_TOKEN is empty).
  • New codescene_project_id copier variable (copier.yml),
    default empty, surfaced in the deferred-gate note. Token-less,
    id-less generated repos stay green; onboarding is a matter of setting
    the secret and the id.

Review walkthrough

  • The PR job never uploads to CodeScene; only pushes to main (and
    manual dispatches) do. This matches the estate rule that
    cs-coverage upload is accepted solely from analysed branches, and
    avoids duplicate uploads per commit.
  • The changed-line cs-coverage check gate is intentionally not
    wired in. CodeScene rejects cs-coverage check for any project whose
    coverage-gates configuration is absent — a per-project, UI-side
    setting rather than a CI defect. The deferred-gate note records how to
    add the guarded mode: check step once a project is onboarded.
  • The Rust-extension variant (use_rust) keeps Python detection: its
    crate lives under rust_extension/ with no root Cargo.toml, so the
    shared action's detector still classifies the repo as Python
    (cobertura). Both workflows pass cargo-manifest: rust_extension/Cargo.toml and set up Rust for that variant so the
    extension is built and measured, mirroring the existing coverage step.
  • pytest-workers is deliberately left at its default (xdist): the
    template's own test target already runs pytest -v -n, so the suite
    is xdist-native and needs no serial pin.
  • Contract tests are updated in the same commit: the CI coverage
    contract now asserts the new pin, the pull_request guard, and the
    ratchet input; a new assert_coverage_main_workflow_contract helper
    validates the push-to-main upload workflow (triggers, guarded upload,
    ratchet, and Rust manifest wiring), exercised by both the render tests
    and focused unit tests.

Validation

  • make check-fmt, make lint (ruff + interrogate 100%), and
    make typecheck (ty) all pass.
  • pytest tests/test_helpers.py tests/test_parent_ci.py — 19 passed.
  • pytest tests/test_template.py — 11 passed, 3 snapshots unchanged
    (both pure-Python and Rust variants render valid YAML for ci.yml
    and coverage-main.yml).
  • Copier renders cleanly for the pure, Rust, and onboarded
    (codescene_project_id set) variants; all rendered workflows parse as
    valid YAML.
  • Pre-existing, unrelated:
    test_typos_rollout::test_committed_config_matches_current_shared_dictionary
    fails identically on pristine main (shared oxendict-base dictionary
    drift, environment-dependent); main's CI is green, confirming it
    regenerates a matching config in CI. Not touched by this PR.

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

Copy link
Copy Markdown

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: 24 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: 9e67cdab-4fcf-433c-aff3-71b666a33df1

📥 Commits

Reviewing files that changed from the base of the PR and between c8be1ae and f90bd4c.

📒 Files selected for processing (8)
  • copier.yml
  • template/.github/workflows/ci.yml.jinja
  • template/.github/workflows/coverage-main.yml.jinja
  • tests/helpers/ci_contracts.py
  • tests/helpers/tooling_contracts.py
  • tests/test_helpers.py
  • tests/test_template.py
  • typos.toml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codescene-coverage-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: 682f4e701c

ℹ️ 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".

output-path: coverage.xml
format: cobertura
artefact-name-suffix: {{ package_name | lower | replace("_", "-") }}
with-ratchet: 'true'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Fix the ratchet pin before enabling it

With with-ratchet enabled here, generated repos rely on the pinned generate-coverage action to restore the main-branch baseline before PR checks. I checked the pinned action at 927edd45ae77be4251a8a18ca9eb5613a2e32cbd: it restores with key: ratchet-baseline-${{ runner.os }}-${{ github.run_id }} and restore-keys: ratchet-baseline-${{ runner.os }}-, but saves with key: ratchet-baseline-${{ runner.os }}. Because GitHub cache restore keys are prefix matches, the saved cache does not start with the restore prefix, so the baseline is never restored and coverage drops compare against the freshly-created 0 baseline. Please bump/fix the action pin or leave the ratchet disabled until the cache keys align.

Useful? React with 👍 / 👎.

Bring generated projects into line with the proven estate coverage
recipe (the Python leg pathfound in cmd-mox#190) so repos are born with
the CodeScene wiring rather than needing a later onboarding PR.

Templated ci.yml (pull-request coverage):
- Check out with fetch-depth 0 so a future changed-line cs-coverage
  check can reach the merge base.
- Bump the shared generate-coverage and setup-rust references to
  927edd45ae77be4251a8a18ca9eb5613a2e32cbd, keeping a single repo-wide
  pin.
- Guard coverage generation to pull requests (ci.yml also triggers on
  push, and coverage-main.yml now owns the push-to-main run) and enable
  the coverage ratchet.
- Retain cobertura and coverage.xml, which the shared action mandates
  for Python and mixed projects.
- Drop the bespoke CodeScene CLI install and cs-coverage upload steps
  from the pull-request job; leave a deferred-gate note explaining that
  the changed-line check awaits per-project CodeScene enablement.

New templated coverage-main.yml (push-to-main upload):
- Trigger on push to main plus workflow_dispatch, the latter being
  mandatory because automerge pushes do not fire push-event workflows.
- Set up Python and uv explicitly, generate cobertura coverage with the
  ratchet, and upload to CodeScene through the guarded shared action so
  token-less repos skip the upload rather than fail.

Add a codescene_project_id copier variable (default empty) surfaced in
the deferred-gate note, so the pattern degrades gracefully until a
generated repo is onboarded to CodeScene.

Update the CI and coverage-main workflow contract tests and their
synthetic fixtures to match the new pin, pull-request guard, ratchet
input, and push-to-main upload wiring.

Incidentally regenerate the committed typos.toml from the current shared
en-GB-oxendict dictionary. The upstream dictionary had drifted, which
left the required test gate latently red on main and would otherwise
block this pull request; the regeneration is what `make spelling`
produces in CI.
@leynos
leynos force-pushed the codescene-coverage-template branch from 682f4e7 to f90bd4c Compare July 14, 2026 00:27
@leynos

leynos commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Incidental fix folded into this PR: regenerated the committed typos.toml from the current shared en-GB-oxendict dictionary. The upstream dictionary had drifted, leaving the required test gate latently red on main (it fails identically on pristine main), which would otherwise block this PR. The regeneration is exactly what make spelling produces in CI; no coverage-related behaviour depends on it.

@leynos
leynos enabled auto-merge (squash) July 14, 2026 00:27
@leynos
leynos merged commit ab5ec28 into main Jul 14, 2026
6 checks passed
@leynos
leynos deleted the codescene-coverage-template branch July 14, 2026 00:48
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.

1 participant