feat(anvil): publish scheduled failures as issues - #65
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project status has failed because the head coverage (99.9%) is below the target coverage (100.0%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #65 +/- ##
=====================================
Coverage 99.9% 99.9%
=====================================
Files 135 135
Lines 17449 17449
=====================================
Hits 17448 17448
Misses 1 1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR extends cargo-anvil’s generated scheduled GitHub Actions workflows to publish recurring scheduled failures as a single upserted GitHub issue, and updates the crate docs/design docs accordingly.
Changes:
- Add a
publish-failurejob to the scheduled reusable workflow to create/comment on a stable “[Anvil] Scheduled checks failed” issue when any scheduled group fails. - Grant
issues: writeto the scheduled root workflow’s reusable-workflow call to enable issue publishing, with an opt-out viaANVIL_PUBLISH_FAILURE_ISSUE=false. - Document the new behavior and permission model in crate docs and the GitHub design doc; update templates and snapshots/tests to match.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/anvil-scheduled.yml |
Grants issues: write on the scheduled reusable-workflow call job. |
.github/workflows/anvil-scheduled-impl.yml |
Adds publish-failure job that creates/comments on a stable incident issue based on needs results. |
crates/cargo-anvil/templates/github/scheduled-root-workflow.yml |
Template update to grant issues: write for adopters’ scheduled root workflow. |
crates/cargo-anvil/templates/github/scheduled-impl-workflow.yml |
Template update adding the publish-failure job and issue upsert logic. |
crates/cargo-anvil/tests/snapshots/snapshots__github_backend.snap |
Snapshot update reflecting the new scheduled workflow job and permissions. |
crates/cargo-anvil/src/anvil/artifacts/github.rs |
Tightens tests to assert the new workflow fragments are present (job, condition, actions/github-script, issue APIs). |
crates/cargo-anvil/src/lib.rs |
Rustdoc updates describing scheduled failure issue publication and how to disable it. |
crates/cargo-anvil/README.md |
Regenerated README including the new scheduled failure issue publication documentation. |
crates/cargo-anvil/docs/design/github.md |
Design doc updates covering workflow shape, permissions, and the new “scheduled failure issues” behavior. |
.anvil.lock |
Updates catalog checksum and managed-region checksums to reflect regenerated artifacts. |
Suppressed comments (1)
.github/workflows/anvil-scheduled-impl.yml:160
- Fetching all open issues via
paginate(listForRepo)can be very expensive on large repositories (extra API calls + more data than needed). Since you only need to know whether a single title exists, prefer the Search API scoped tois:issue is:openand the title string, then exact-match the returned items.
const openIssues = await github.paginate(
github.rest.issues.listForRepo,
{
owner: context.repo.owner,
repo: context.repo.repo,
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.
Suppressed comments (4)
.github/workflows/anvil-scheduled-impl.yml:130
- Because the calling job in
anvil-scheduled.ymlgrantsissues: writeand this reusable workflow does not set restrictive default permissions, all jobs here (scheduled-test/advisories/runtime-analysis/exhaustive) will run withissues: write, not justpublish-failure. To keep least privilege, setpermissions: { contents: read }at the reusable-workflow level (or add per-jobpermissionsfor the scheduled-* jobs) and grantissues: writeonly onpublish-failure.
if: ${{ always() && vars.ANVIL_PUBLISH_FAILURE_ISSUE != 'false'
&& contains(needs.*.result, 'failure') }}
runs-on: ${{ inputs.linux_runner }}
permissions:
contents: read
issues: write
crates/cargo-anvil/docs/design/github.md:678
- This bullet implies
issues: writeis effectively scoped only to the publisher. In reusable workflows, permissions granted on the calling job are inherited by all jobs in the called workflow unless the called workflow sets restrictive defaults / per-job permissions. The recommendation should call that out so adopters understand how to keep least privilege.
- `permissions: contents: read` at the workflow level. anvil's default ships with
this.
- The scheduled reusable-workflow call grants `issues: write` at job scope so its
publisher can create or comment on the failure issue. The PR workflow never receives
this permission.
crates/cargo-anvil/docs/design/github.md:750
- This paragraph currently states
issues: writeis granted only to the scheduled root call and publishing job, but the generated reusable workflow does not set restrictive defaults—so the scheduled-* jobs would also inherit that permission. Either tighten the generated workflow permissions, or update this section to describe the actual inheritance behavior and the recommended restriction mechanism.
The publisher uses the workflow's short-lived `GITHUB_TOKEN`, with `issues: write`
granted only to the scheduled root call and publishing job. It does not receive repository
contents beyond read access and does not forward logs or environment data into the issue.
This narrow GitHub-native path also lets GitHub's Teams app relay issue notifications
without an external webhook or additional secret.
crates/cargo-anvil/templates/github/scheduled-impl-workflow.yml:130
- Same least-privilege concern in the template: callers grant
issues: writeon the reusable-workflow call job, and without restrictive default/job permissions in the called workflow, all scheduled jobs inherit it. Consider adding workflow-levelpermissions: { contents: read }(or explicit per-job permissions) so onlypublish-failurereceivesissues: write.
if: ${{ always() && vars.ANVIL_PUBLISH_FAILURE_ISSUE != 'false'
&& contains(needs.*.result, 'failure') }}
runs-on: ${{ inputs.linux_runner }}
permissions:
contents: read
issues: write
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.
Suppressed comments (4)
crates/cargo-anvil/docs/design/github.md:758
- This claims
issues: writeis granted only to the scheduled root call and the publishing job. In GitHub Actions, theGITHUB_TOKENpermissions granted on the reusable-workflow call are inherited by all jobs in the called workflow unless that workflow (or each job) further restricts them. As the generated scheduled reusable workflow only setspermissionsonpublish-failure, the other scheduled jobs will also run withissues: write, so the doc currently overstates least-privilege.
The publisher uses the workflow's short-lived `GITHUB_TOKEN`, with `issues: write`
granted only to the scheduled root call and publishing job. It does not receive repository
contents beyond read access and does not forward logs or environment data into the issue.
This narrow GitHub-native path also lets GitHub's Teams app relay issue notifications
without an external webhook or additional secret.
.github/workflows/anvil-scheduled-impl.yml:130
- Job-level
permissionsare set only onpublish-failure, but the scheduled root workflow grantsissues: writeon the reusable-workflow call. Unless this reusable workflow defines restrictive default permissions (workflow-level or per-job), the other scheduled jobs will also inheritissues: write, expanding token scope beyond what’s needed.
permissions:
contents: read
issues: write
crates/cargo-anvil/src/anvil/artifacts/github.rs:327
- The new JavaScript harness only asserts that the search query contains
in:body, so it wouldn’t catch a regression where the query can never match the marker/issue body (which would lead to duplicate issues). Tighten the assertion to require the marker term used for identity.
assert.equal(created.search.length, 1);
assert.match(created.search[0].q, /in:body/);
assert.equal(created.create.length, 1);
crates/cargo-anvil/src/anvil/artifacts/github.rs:365
- This test hard-requires a
nodebinary at runtime; in environments where contributors runcargo testwithout Node installed, it will fail even though the Rust code is fine. Consider skipping this test when Node is unavailable to keep the crate’s unit tests runnable in minimal Rust-only setups.
let output = Command::new("node")
.arg(&path)
.output()
.expect("Node.js is required to test the generated github-script");
assert!(
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.
Suppressed comments (4)
.github/workflows/anvil-scheduled-impl.yml:130
anvil-scheduled.ymlgrantsissues: writeon the reusable-workflow call. In a reusable workflow, jobs without an explicitpermissionsblock inherit those caller permissions; sincescheduled-test/scheduled-advisories/etc. have nopermissionshere, they will also run withissues: writeeven though onlypublish-failureneeds it. To keep least-privilege, add restrictive defaultpermissionsat the reusable-workflow level (or per scheduled job) and leaveissues: writeonly onpublish-failure.
permissions:
contents: read
issues: write
crates/cargo-anvil/docs/design/github.md:678
- This bullet reads as if
issues: writeis effectively scoped to only the publisher, but with reusable workflows the caller's token permissions are inherited by jobs that don't set their ownpermissions. Either update the workflows to restrict defaults (so onlypublish-failuregetsissues: write) or clarify here that adopters must do that to achieve least-privilege.
- The scheduled reusable-workflow call grants `issues: write` at job scope so its
publisher can create or comment on the failure issue. The PR workflow never receives
this permission.
crates/cargo-anvil/templates/github/scheduled-impl-workflow.yml:130
- The template adds
issues: writeforpublish-failure, but the calling workflow grantsissues: writeon the reusable-workflow call. Unless this reusable workflow sets restrictive defaultpermissions, every job in the reusable workflow inherits that permission. If the intent is least-privilege, set workflow-levelpermissions: { contents: read }(or per scheduled job) and keepissues: writeonly forpublish-failure.
permissions:
contents: read
issues: write
crates/cargo-anvil/src/anvil/artifacts/github.rs:364
- This test unconditionally requires an external
nodebinary. That makescargo test -p cargo-anvilfail in environments that don't have Node installed (even though the feature being tested is a YAML template string). Consider treating missing Node as a skipped test instead of a hard failure.
let output = Command::new("node")
.arg(&path)
.output()
.expect("Node.js is required to test the generated github-script");
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.
Suppressed comments (7)
crates/cargo-anvil/docs/design/github.md:756
- This paragraph says
issues: writeis granted only to the root call and publishing job, but the current reusable workflow does not restrict default permissions. Unless the called workflow sets minimal defaults (and onlypublish-failureoverrides them), other jobs will also inheritissues: writewhen the caller grants it.
The publisher uses the workflow's short-lived `GITHUB_TOKEN`, with `issues: write`
granted only to the scheduled root call and publishing job. It does not receive repository
contents beyond read access and does not forward logs or environment data into the issue.
crates/cargo-anvil/docs/design/github.md:678
- This bullet implies
issues: writeis effectively scoped only to the publisher, but in GitHub reusable workflows the caller-grantedGITHUB_TOKENpermissions are inherited by all jobs unless the called workflow sets restrictive defaults. The doc should either explain that inheritance, or state that adopters should set minimal default permissions in the reusable workflow and grantissues: writeonly topublish-failure.
- The scheduled reusable-workflow call grants `issues: write` at job scope so its
publisher can create or comment on the failure issue. The PR workflow never receives
this permission.
.github/workflows/anvil-scheduled-impl.yml:130
- The caller grants
issues: writeto this reusable workflow, and since this workflow does not set restrictive default permissions for the other jobs,scheduled-test/scheduled-advisories/etc will likely inheritissues: writetoo. Consider setting minimal default permissions (e.g. workflow-levelpermissions: { contents: read }) and only grantingissues: writeonpublish-failureto keep least-privilege.
permissions:
contents: read
issues: write
.github/workflows/anvil-scheduled.yml:22
issues: writeis granted on the reusable-workflow call here, andanvil-scheduled-impl.ymldoes not set restrictive default permissions. That means all jobs in the called reusable workflow will likely inheritissues: write, even though onlypublish-failureneeds it. Consider updating the reusable workflow (and its template) to set a minimal default likepermissions: { contents: read }and then grantissues: writeonly on thepublish-failurejob, so this call can remain the upper bound without widening privilege for the scheduled jobs.
uses: ./.github/workflows/anvil-scheduled-impl.yml
permissions:
contents: read
issues: write
secrets: inherit
crates/cargo-anvil/templates/github/scheduled-root-workflow.yml:22
- Granting
issues: writeon the reusable-workflow call here widens the effectiveGITHUB_TOKENpermissions for all jobs in the called reusable workflow unless that workflow sets restrictive defaults. To keep least-privilege, consider adding minimal default permissions (e.g.permissions: { contents: read }) to the scheduled reusable workflow template and only givingissues: writeto thepublish-failurejob.
uses: ./.github/workflows/anvil-scheduled-impl.yml
permissions:
contents: read
issues: write
secrets: inherit
crates/cargo-anvil/src/anvil/artifacts/github.rs:365
- This unit test hard-requires
nodeto be installed; in environments where Rust tooling is available but Node.js is not (some CI runners / constrained dev boxes),cargo testwill fail even though the Rust code is otherwise fine. Consider skipping this test whennodeis not present, and only failing on actual script-behavior mismatches.
let output = Command::new("node")
.arg(&path)
.output()
.expect("Node.js is required to test the generated github-script");
crates/cargo-anvil/templates/github/scheduled-impl-workflow.yml:130
- This template assumes
issues: writeis only needed forpublish-failure, but when adopters grantissues: writeon the reusable-workflow call, other jobs will inherit it unless this workflow sets restrictive defaults. Consider adding minimal default permissions (workflow-level or per-job) and only grantingissues: writeonpublish-failure.
permissions:
contents: read
issues: write
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.
Suppressed comments (4)
.github/workflows/anvil-scheduled-impl.yml:130
- Least-privilege concern:
anvil-scheduled.ymlgrantsissues: writeon the reusable-workflow call job, and this reusable workflow doesn’t set a restrictive workflow-levelpermissions:. As a result, all jobs in this called workflow (e.g.scheduled-test,scheduled-advisories, etc.) will also run withissues: write, even though onlypublish-failureneeds it. Consider adding a top-levelpermissions: { contents: read }in the reusable workflow and leavingissues: writeonly onpublish-failure.
&& contains(needs.*.result, 'failure') }}
runs-on: ${{ inputs.linux_runner }}
permissions:
contents: read
issues: write
crates/cargo-anvil/docs/design/github.md:756
- This description doesn’t match the effective GitHub Actions permission model:
issues: writegranted on the reusable-workflow call is inherited by all jobs in the called workflow unless the called workflow sets a restrictive workflow-levelpermissions:. As written, readers may assume onlypublish-failurecan write issues even though the current workflow YAML grants that scope to the other scheduled jobs too.
The publisher uses the workflow's short-lived `GITHUB_TOKEN`, with `issues: write`
granted only to the scheduled root call and publishing job. It does not receive repository
contents beyond read access and does not forward logs or environment data into the issue.
crates/cargo-anvil/src/anvil/artifacts/github.rs:366
- This unit test hard-requires
nodeand fails withNotFoundon developer machines/environments that don’t have Node installed. Othercargo-anviltests that rely on external validators (e.g.actionlint,taplo,just) explicitly skip when the tool isn’t present, so it would be more consistent to degrade gracefully here too.
let output = Command::new("node")
.arg(&path)
.output()
.expect("Node.js is required to test the generated github-script");
crates/cargo-anvil/templates/github/scheduled-impl-workflow.yml:130
- Least-privilege concern: the scheduled root workflow now grants
issues: writeon the reusable-workflow call job, and this reusable workflow template doesn’t set a restrictive workflow-levelpermissions:. That means all scheduled jobs in the called workflow inheritissues: write, even though onlypublish-failureneeds it. Consider adding a top-levelpermissions: { contents: read }in this template and keepingissues: writeonly onpublish-failure.
&& contains(needs.*.result, 'failure') }}
runs-on: ${{ inputs.linux_runner }}
permissions:
contents: read
issues: write
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
Apply the least-privilege workflow change after confirming the restriction only reduces scheduled check job permissions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
Default reusable PR workflow jobs to read-only and grant pull-request write access only to pr-fast, where advisory comments are managed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
Prevent cargo-binstall from compiling before Anvil's source prerequisite gate, and provision libclang only for GitHub-hosted Linux ARM64 jobs that install cargo-spellcheck. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
Update the local and ADO artifact snapshots for the shared cargo-binstall strategy change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
cargo-spellcheck 0.15.1 cannot compile on current Linux ARM64 and crashes on Windows ARM64. Skip its setup, validation, and execution on ARM64 while retaining x64 coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
Upgrade cargo-spellcheck to 0.15.7, remove the 0.15.1 ARM64 skip policy and version tripwire, and regenerate Anvil workflows, justfiles, lock metadata, and snapshots. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
28e3ab1 to
3d22490
Compare
Explain that the 0.15.7 tokenization change is deliberately accommodated by spellcheck.toml instead of describing the now-pinned release as an unhandled regression. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 21 changed files in this pull request and generated no new comments.
Suppressed comments (5)
crates/cargo-anvil/docs/design/github.md:674
- The root-workflow examples earlier in this document (the
anvil-pr.ymlandanvil-scheduled.ymlsnippets around lines 226–252) still omit these required job-level permissions. Following those examples now produces 403s for both the scheduled issue publisher and PR advisory comments, despite this section saying they are part of the recommended shape. Update the snippets alongside this permission-model change, or explicitly show the requiredpermissionsblocks there.
- The scheduled reusable-workflow call grants `issues: write` at job scope so its
publisher can create or comment on the failure issue. The called workflow resets its
default permissions to `contents: read`, then restores `issues: write` only on the
publishing job; scheduled check jobs do not inherit write access. The PR workflow
never receives this permission.
crates/cargo-anvil/docs/design/local.md:286
- This new design text presents
--disable-strategies compileas the install path for every binstall tool, but the shared helper is also used by ordinary tools that have nosource_prereq. That broadens the behavior beyond the prerequisite-ordering fix and conflicts with the stated requirement to preserve ordinary tools' strategy; revise this section to describe the flag only for prerequisite-bearing fallbacks once the helper is scoped accordingly.
- `binstall` -- `cargo binstall --no-confirm --locked --disable-strategies compile
<tool> --version '=<pin>'`. Downloads a prebuilt binary from each tool's GitHub
Releases when available. If no binary is available, Anvil runs the tool's source
prerequisite before invoking `cargo install` itself; disabling binstall's compile
strategy prevents an uncontrolled source build from bypassing that check. The
binary path cuts the cold-runner install phase from ~30 min to ~1 min.
crates/cargo-anvil/docs/design/github.md:674
- The earlier scheduled root-workflow example in this document (around lines 239–252) still omits the
issues: writepermission that this section now requires. An adopter copying that example will invoke the publisher with a read-only token and get a 403 instead of an incident issue; update the example to show the caller job grantingcontents: readandissues: write.
- The scheduled reusable-workflow call grants `issues: write` at job scope so its
publisher can create or comment on the failure issue. The called workflow resets its
default permissions to `contents: read`, then restores `issues: write` only on the
publishing job; scheduled check jobs do not inherit write access. The PR workflow
never receives this permission.
crates/cargo-anvil/templates/justfiles/anvil/tools.just:229
- This shared helper is used by every
installer == 'binstall'recipe, so disablingcompilehere changes ordinary tools such ascargo-deltaandcargo-nextestas well: they no longer use binstall's original source strategy and instead always fall through tocargo installwhen no binary is available. That contradicts the stated goal of leaving ordinary tools' install strategy unchanged; apply the disabled strategy only when$sourcePrereqis set, preserving the original binstall invocation otherwise.
cargo binstall --no-confirm --locked --disable-strategies compile $name --version "=$version"
justfiles/anvil/tools.just:229
- This shared helper is used by every
installer == 'binstall'recipe, so disablingcompilehere changes ordinary tools such ascargo-deltaandcargo-nextestas well: they no longer use binstall's original source strategy and instead always fall through tocargo installwhen no binary is available. That contradicts the stated goal of leaving ordinary tools' install strategy unchanged; apply the disabled strategy only when$sourcePrereqis set, preserving the original binstall invocation otherwise.
cargo binstall --no-confirm --locked --disable-strategies compile $name --version "=$version"
Disable binstall compilation only for tools with source prerequisites and restore executable coverage for fallback ordering, exact pins, prerequisite failures, and ordinary-tool strategy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
Sander Saares (sandersaares)
left a comment
There was a problem hiding this comment.
[Copilot speaking]
Published 10 findings. 3 findings follow up on existing discussion threads.
See diagnostics
| Diagnostic | Value |
|---|---|
| Cache | Hit |
Clarify bounded issue identity and manual lifecycle, converge legacy mutation failures on the shared incident, tighten publisher permissions, document reusable-workflow boundaries, and explain focused test harness behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1c90ffee-5127-4069-8bb1-cef1492a400c
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 24 changed files in this pull request and generated no new comments.
Suppressed comments (9)
.github/workflows/anvil-pr-impl.yml:36
- This generated workflow comment hard-codes the numbered design-doc reference
docs/design/github.md §9. Embedding a section number in emitted workflow source will become stale when the design is renumbered and couples every adopter's generated file to the document layout; keep the permission explanation but remove the section citation.
# request scope below. See docs/design/github.md §9.
.github/workflows/anvil-pr.yml:24
- This generated workflow comment hard-codes the numbered design-doc reference
docs/design/github.md §9. Embedding a section number in emitted workflow source will become stale when the design is renumbered and couples every adopter's generated file to the document layout; keep the permission explanation but remove the section citation.
# only on pr-fast. See docs/design/github.md §9.
.github/workflows/anvil-scheduled-impl.yml:36
- This generated workflow comment hard-codes the numbered design-doc reference
docs/design/github.md §9. Embedding a section number in emitted workflow source will become stale when the design is renumbered and couples every adopter's generated file to the document layout; keep the permission explanation but remove the section citation.
# issues scope below. See docs/design/github.md §9.
.github/workflows/anvil-scheduled.yml:21
- This generated workflow comment hard-codes the numbered design-doc reference
docs/design/github.md §9. Embedding a section number in emitted workflow source will become stale when the design is renumbered and couples every adopter's generated file to the document layout; keep the permission explanation but remove the section citation.
# publish-failure. See docs/design/github.md §9.
.github/workflows/nightly.yml:75
- This jq filter assumes every returned issue has a string body. GitHub can return
body: nullfor bodyless issues, in which casecontains(...)errors; with the Actions shell'spipefail, the failure-publication step can fail instead of finding or creating the incident. Coalesce the body to an empty string before callingcontains.
--jq '.[] | select(.body | contains("<!-- anvil scheduled failure -->")) | .number' \
crates/cargo-anvil/templates/github/pr-impl-workflow.yml:36
- This generated-workflow comment links to a numbered design-doc section. The repository guideline prohibits code comments from coupling to design-document structure, so section renumbering will make this stale; keep the permission explanation but remove the
See docs/design/github.md §9citation.
# request scope below. See docs/design/github.md §9.
crates/cargo-anvil/templates/github/pr-root-workflow.yml:24
- This generated-workflow comment links to a numbered design-doc section. The repository guideline prohibits code comments from coupling to design-document structure, so section renumbering will make this stale; keep the permission explanation but remove the
See docs/design/github.md §9citation.
# only on pr-fast. See docs/design/github.md §9.
crates/cargo-anvil/templates/github/scheduled-impl-workflow.yml:36
- This generated-workflow comment links to a numbered design-doc section. The repository guideline prohibits code comments from coupling to design-document structure, so section renumbering will make this stale; keep the permission explanation but remove the
See docs/design/github.md §9citation.
# issues scope below. See docs/design/github.md §9.
crates/cargo-anvil/templates/github/scheduled-root-workflow.yml:21
- This generated-workflow comment links to a numbered design-doc section. The repository guideline prohibits code comments from coupling to design-document structure, so section renumbering will make this stale; keep the permission explanation but remove the
See docs/design/github.md §9citation.
# publish-failure. See docs/design/github.md §9.
| [View workflow run]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID)" | ||
| # Share Anvil's marker-owned incident so overlapping mutation | ||
| # failures produce one durable issue and one notification stream. | ||
| EXISTING_ISSUE=$(gh issue list \ |
There was a problem hiding this comment.
🤖: Non-blocking — I think the goal is right: a nightly mutation failure and an Anvil scheduled failure are one incident operationally, so converging on one durable issue and one notification owner beats two Teams posts.
The part worth weighing is the mechanism's other effect: <!-- anvil scheduled failure --> stops being an Anvil-private key and becomes a repo-wide protocol with two independent implementations — the github-script publisher in templates/github/scheduled-impl-workflow.yml:145+, which is executably tested (src/anvil/artifacts/github.rs runs the extracted script under node and pins the exact search query), and this gh-CLI version, which is hand-maintained, not emitted from a template, not tracked in .anvil.lock, and has no test at all. Three things have to stay identical across the pair — the marker text, the title, and the effective query semantics — and nothing enforces that. If a later change to the template's marker or title lands (it is generated artifact text, so it can move with an anvil update), this file keeps publishing under the old identity and the incident stream silently splits back into two, which is precisely the outcome this change exists to prevent. The failure mode is quiet: two open issues rather than an error.
Two cheap guards would close it, either or both:
- assert in the existing contract test that
SCHEDULED_IMPL_WORKFLOW's marker/title literals also appear in this workflow's text — or at minimum a comment here naming the template as the canonical owner of the marker, so the next person editing either side knows the other exists; - extract this failure step and run it against a fake
gh: in the convergence case,gh issue listexposes an open issue carrying Anvil's exact marker and the step must comment on it without creating another; in the absent-marker case it must create with the shared title/marker and the current run URL. Have the fake assert the marker-scoped list arguments too — otherwise the two implementations can drift while each stays internally plausible.
Separately, and out of scope for this PR: sharing the output while deliberately keeping the inputs distinct means the repo now runs mutation testing twice (scripts/mutants.rs here, Anvil's scheduled-exhaustive there) under one incident identity. Is folding this config into scheduled-exhaustive and retiring nightly.yml the intended end-state, or is a second hand-maintained publisher of Anvil's protocol something this repo carries permanently? Worth writing the answer down, because it decides whether the duplication above is temporary or not.
| @@ -57,19 +58,26 @@ jobs: | |||
| env: | |||
There was a problem hiding this comment.
🤖: Non-blocking — this is about .github/workflows/nightly.yml:56, the if: on this step (nearest commentable line). Now that this job publishes into Anvil's marker-owned incident (same title, same <!-- anvil scheduled failure --> marker), it should mirror the publisher's kill switch. anvil-scheduled-impl.yml:139 gates publish-failure on vars.ANVIL_PUBLISH_FAILURE_ISSUE != 'false', and the README / src/lib.rs / docs/design/github.md §11 all advertise that variable as the way to disable failure-issue publication. With the two publishers sharing one identity, setting it to false no longer stops the incident stream in this repo — nightly keeps creating/commenting on the same issue. Suggest adding && vars.ANVIL_PUBLISH_FAILURE_ISSUE != 'false' to this step's if: so both halves of the shared contract respect the same switch.
…lisher #65 landed the generic `publish-failure` job, so `scheduled-benchmarks` joins its `needs:` list -- without that a benchmark regression fails the scheduled run and never reaches the tracking issue. A test pins the dependency, since this is exactly the wiring that rots silently. The permission grants compose rather than replace: the root workflow keeps `actions: read` for the history-artifact restore alongside #65's `issues: write`. The test harness merge keeps main's helpers (including its new versions.just guard in `fixture`) and adopts its `FAKE_CARGO_PS1` naming, while retaining the bench-history and git stand-ins; both branches had hoisted the same script into a const under different names. Docs no longer say anvil ships no notifier for this -- with #65 merged it does. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a3ecc845-0526-499a-a233-6b82909c4517
Integrate #65 (publish scheduled failures as issues) with the local-impact work: - recipe_contracts.rs: adopt main's FAKE_CARGO_PS1 const refactor (script hoisted out of `fixture` + new binstall/install branches) and its conditional `versions`/`rust_nightly` guard, while re-applying this branch's `seed_include` helper and keeping `set allow-duplicate-recipes` (scoped check fixtures legitimately import impact.just alongside an anvil-impact stub, so duplicate recipe names must be tolerated). Main's shorter fixture no longer trips too_many_lines, so the #[expect] is dropped. - github.md: keep this branch's accurate ANVIL_IMPACT=off description of the scheduled path and fold in main's non-executable-schematic / canonical-YAML note. Generated artifacts (.anvil.lock, README, snapshots) reconciled from the merged sources. Full cargo-anvil suite, workspace clippy (-D warnings), fmt, spellcheck green. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 37923be4-ff18-4207-bf8c-8a49849a657b
🤖
Summary
ANVIL_PUBLISH_FAILURE_ISSUE=falseActions repository variableValidation
cargo test -p cargo-anvil --test recipe_contractscargo test -p cargo-anvil anvil::artifacts::cargo test -p cargo-anvil --test snapshotscargo run -p cargo-anvil -- --backend github --dry-runcargo +nightly fmt --all --checkcargo clippy -p cargo-anvil --all-targets -- -D warningscargo doc2readme --check --lib --template ../README.j2just anvil-spellcheck