Skip to content

feat: open (or update) an issue when a publish run fails - #326

Merged
d-morrison merged 7 commits into
mainfrom
feat/open-failure-issue
Jul 27, 2026
Merged

feat: open (or update) an issue when a publish run fails#326
d-morrison merged 7 commits into
mainfrom
feat/open-failure-issue

Conversation

@d-morrison

@d-morrison d-morrison commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Closes #325.

A workflow that runs where no pull request carries its result --- a push to the default branch, a schedule, a release --- fails silently. The red run shows up in the Actions tab and nowhere else, so a broken deploy can sit for days while the published site goes stale. That is what prompted this: d-morrison/altdoc's deploy went red four times in three days on an unrelated upstream outage (d-morrison/altdoc#60), and every occurrence was found by a person going looking.

What this adds

report-failure.yml --- a reusable workflow filing an issue when a watched job fails. Consumers add it as a final job gated on the job they want watched:

  report-failure:
    needs: publish
    if: always() && needs.publish.result == 'failure' && github.event_name != 'pull_request'
    permissions:
      issues: write
    uses: d-morrison/gha/.github/workflows/report-failure.yml@v2
    with:
      title: Publish workflow is failing

open-failure-issue --- the composite doing the work, so the logic has one home rather than being copied to each caller. It wraps two scripts: scripts/select-existing-issue.sh, where the deduplication rule lives, and scripts/split-csv-list.sh, which splits and trims the labels input. Both are unit-tested offline.

Three design points worth review

It is a separate workflow, not a job inside quarto-publish.yml. That was the first approach and it is unshippable: a reusable workflow's jobs can only hold permissions the caller granted, and the docs are explicit that permissions "can only be maintained or reduced---not elevated." A failure-reporting job living inside quarto-publish.yml would therefore make issues: write mandatory for every existing caller of that workflow, wanted or not --- and examples/quarto-publish.yml's own comment records that this repo has already learned a caller must grant a job's permissions even when that job is skipped, so defaulting the feature off would not have avoided it. Kept separate, the permission is granted only by callers that opt in, and any workflow can be watched rather than only publishing.

The reporting job holds issues: write and nothing else, and performs no checkout. Naming any scope in a permissions: block zeroes the rest, so a job that checked the repository out would also need contents: read --- and without it the checkout fails on a private or internal repo, exactly when the job exists to report a failure. Instead the composite names the repository through GH_REPO and carries its own files via github.action_path. That also removes a silent dependency on the caller having checked out the repo being reported against, which need not be the same one (relevant to #327).

Repeat failures comment rather than pile up. check-links.yml's existing copy of this pattern calls gh issue create unconditionally, so a recurring failure files an identical issue every run. This matches on the title first and comments on the open report instead. The match is exact and case-sensitive on purpose: Publish failed: website and Publish failed: website preview are different problems, and folding the second onto the first would bury its evidence.

A label the calling repository does not define is dropped with a warning and the issue filed anyway --- losing a failure report over a missing label is the worse outcome, and check-links.yml's hard-coded bug,automated,copilot shows how easily a consumer repo ends up without one.

Deferred to #327, with a finding worth recording

The two intended call sites --- migrating check-links.yml onto the composite, and dogfooding report-failure in website-publish.yml --- were both cut from this PR and moved to #327.

A uses: ref resolves when the job is prepared, before any step runs and before any step-level if: is evaluated. So check-links.yml referring to open-failure-issue@v2 failed links / link-checker outright (run 30251435485) on a step gated behind failure() that could never have executed --- and _selftest.yml drives check-links.yml through a local ./ ref, so it went red on every PR. Nothing inside this PR could fix it: the action does not exist at @v2 until this merges and the tag slides, and a relative local path is not a workaround (#284: inside a reusable workflow it resolves against the caller's checkout).

CLAUDE.md gains this as a distinction its existing bootstrapping note misses. That note calls the gap a coverage footnote, which is true for request-dependabot-review because it only runs on Dependabot PRs; when the new caller is dogfooded here on every PR, the same gap is a red check instead.

Verification

  • run-select-existing-issue-tests.sh covers the matching rule offline: no-match, prefix-is-not-a-match, case sensitivity, converging on the oldest when duplicates already exist, a title carrying shell and jq metacharacters, and an empty title failing loudly rather than matching arbitrarily.
  • run-split-csv-list-tests.sh covers the splitter: the space-after-comma case that motivated it, tabs, empty and comma-only inputs, and a label whose internal spaces must survive trimming (good first issue is a real label, which is why xargs is the wrong tool here).
  • build-reviewer-args.sh now delegates to that same splitter rather than carrying a second copy; its five pre-existing tests pass unchanged.
  • _selftest.yml's failure-issue job calls the composite through a real uses: step, proving it resolves its helpers via github.action_path --- the wiring gha#196 showed a unit test alone does not cover. dry-run exists for this: without it the only end-to-end call would file an issue on this repo every selftest run, so the job needs just issues: read.
  • Docs synced per CLAUDE.md: README.md's workflow table and permissions list, website/workflows.qmd, website/permissions.qmd, the new website/reference/report-failure.qmd, website/_quarto.yml's nav, and every @v2 enumeration in README.md, website/versioning.qmd, website/workflows.qmd, and CLAUDE.md itself.

report-failure.yml's own @v2 reference to the composite is the ordinary convention here (quarto-publish.yml refers to quarto-publish@v2 the same way) and resolves once the tag advances. No workflow in this repo calls it yet, which is why it does not reproduce the problem above.

Copilot AI review requested due to automatic review settings July 27, 2026 08:42

Copilot AI 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.

Copilot wasn't able to review any files in this pull request.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…e action

A workflow that runs where no PR carries its result -- a push to the default
branch, a schedule, a release -- fails silently: the red run is visible only
in the Actions tab, so a broken deploy can sit unnoticed while the published
site goes stale.

report-failure.yml files an issue for that, or comments on the issue already
open for the same title rather than filing a duplicate on every failing run.
Consumers add it as a final job gated on the job they want watched.

It is its own workflow rather than a job inside quarto-publish.yml because a
reusable workflow's jobs can only hold permissions the caller granted: folding
it in would have made issues: write mandatory for every existing caller of
that workflow. As a separate workflow the permission is opt-in, and any
workflow can be watched.

The lookup and issue calls live in a shared open-failure-issue composite,
which check-links.yml now uses in place of its own inline gh issue create --
so the dedupe and the missing-label tolerance apply there too.

Closes #325
Copilot AI review requested due to automatic review settings July 27, 2026 08:50

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

A uses: ref resolves when the job is prepared, before any step-level if: is
evaluated, so check-links.yml's reference to open-failure-issue@v2 failed
link-checker outright -- on a step gated behind failure() that could never
have run. _selftest.yml drives check-links through a local ./ ref, so this
went red on every PR, and no change inside this PR could fix it: the action
does not exist at @v2 until this merges and the tag slides.

website-publish.yml's dogfood job carries the same dependency and is deferred
with it. Both land in #327, once @v2 includes the action.

CLAUDE.md records the distinction the existing bootstrapping note misses:
whether this gap is a coverage footnote or a red check depends on whether the
new caller is dogfooded here on every PR.
Copilot AI review requested due to automatic review settings July 27, 2026 08:52

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@d-morrison
d-morrison marked this pull request as ready for review July 27, 2026 08:53
Comment thread .github/workflows/report-failure.yml
Comment thread .github/actions/open-failure-issue/action.yml
Comment thread .github/workflows/_selftest.yml Outdated
Comment thread examples/report-failure.yml
@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Code review

Reviewed the report-failure capability added by this PR (new open-failure-issue composite, report-failure.yml reusable workflow, select-existing-issue.sh dedup helper + offline tests, _selftest.yml coverage, and the docs/changelog sync). The design itself is sound — dedup via exact title match with lowest-number convergence is well-reasoned and well-tested, untrusted values (title/body/labels) are passed through env:/a temp file rather than interpolated into run: (no shell-injection vector), and the doc-sync sweep (@v1/@v2 blanket prose, the three input-doc sites, changelog fragment) is thorough and accurate everywhere I checked.

Four issues found, posted as inline comments, most significant first:

  1. .github/workflows/report-failure.yml — the report job's permissions: block grants only issues: write but also runs actions/checkout, which zeroes contents to none and can fail the checkout on private/internal repos. High confidence; verified against GitHub's own permissions-scoping docs and against this repo's sibling workflows (check-links.yml, summary.yml, and this PR's own _selftest.yml job), which all grant contents: read for the identical checkout + gh issue pattern.
  2. .github/actions/open-failure-issue/action.yml — the labels input is handed to gh issue create --label unsplit/untrimmed, so a natural "bug, automated" (space after comma) silently drops all labels via the fallback retry, not just the malformed one. Verified against gh's actual flag-parsing behavior (Cobra StringSliceVar → Go csv.Reader, no leading-space trim) and empirically against a live repo. This is the same bug class this repo already fixed in build-reviewer-args.sh for gha#253.
  3. .github/workflows/_selftest.yml — the new job's comment claims the action is "shared by quarto-publish.yml and check-links.yml," but neither is true yet; only report-failure.yml calls it in this PR, and the PR's own new CLAUDE.md prose confirms the check-links.yml migration was deferred to gha#327.
  4. examples/report-failure.yml — minor/cosmetic: the && github.event_name != 'pull_request' clause in the example's if: is unreachable given the stub's own on: push/workflow_dispatch triggers.

One additional finding not tied to a specific diff line: website/permissions.qmd has its own independently-worded "Per-workflow grants" list (already covering check-links, summary, request-dependabot-review, etc.) that this PR doesn't update with a report-failure entry, even though README.md's parallel Permissions section was correctly updated. CLAUDE.md doesn't explicitly name this file as a required sync site the way it does for the three workflow-input doc locations, so this is a lower-confidence, by-analogy gap rather than a stated-rule violation — but it's the same "convention restated in multiple independently-worded spots, one of them missed" pattern CLAUDE.md calls out elsewhere (gha#161, gha#181), and worth a one-line addition for consistency.

Verdict

Needs more work — primarily finding 1 (missing contents: read), which is a real correctness bug likely to break this capability's first real-world use on a private/internal consumer repo. Findings 2-4 and the permissions.qmd gap are lower-severity and don't block merge on their own, but are worth fixing in the same pass.

@github-actions

Copy link
Copy Markdown
Contributor

Claude finished reviewView run


Review posted on PR #326.

Summary: Four issues found and posted as inline comments (most severe first):

  1. report-failure.yml — the report job grants only issues: write but also does actions/checkout, zeroing contents to none, which can fail checkout on private/internal repos. High confidence, cross-verified against GitHub Actions docs and this repo's own sibling workflows.
  2. open-failure-issue/action.yml — the labels input isn't split/trimmed before gh issue create --label, so "bug, automated" (space after comma) silently drops all labels via the fallback retry — verified against gh's actual flag-parsing source and a live repo. Same bug class as gha#253's already-fixed build-reviewer-args.sh.
  3. _selftest.yml — a new comment falsely claims the action is already shared by quarto-publish.yml/check-links.yml, contradicted by the PR's own diff and CLAUDE.md addition (migration deferred to gha#327).
  4. examples/report-failure.yml — minor: a dead != 'pull_request' condition given the stub's own triggers.

Also flagged (not tied to a diff line): website/permissions.qmd's parallel per-workflow permissions list wasn't updated for report-failure, unlike its README.md counterpart.

Verdict: Needs more work — the missing contents: read permission is a real correctness bug.

@github-actions

Copy link
Copy Markdown
Contributor

💰 Cost: $12.9702 (review) — run

Two real bugs from review, plus three doc-accuracy fixes.

1. report-failure.yml's report job granted issues: write and then ran
   actions/checkout. Naming any scope zeroes the rest, so contents was none
   and the checkout would fail on a private or internal repo -- at the moment
   the job exists to report a failure. Rather than widen the grant, the
   checkout is gone: the composite already carries its own files via
   github.action_path, and now names the repository through GH_REPO instead
   of inferring it from a git remote. issues: write alone is now true rather
   than aspirational, and the composite no longer silently depends on the
   caller having checked out the repo being reported against.

2. The labels input went to a single --label unsplit. That flag is a Cobra
   StringSlice, which splits on commas without trimming, so a natural
   "bug, automated" yields " automated", matches no label, and fails the
   create -- and the fallback then drops the valid "bug" too, warning about
   a missing label when the real cause was a space. Same shape as gha#253.
   split-csv-list.sh now splits and trims, one --label per name, with tests
   including the internal-space case ("good first issue" is a real label).

3. _selftest.yml's comment claimed the action was already shared with
   quarto-publish.yml and check-links.yml; neither is true in this PR.
4. The examples' pull_request clause is inert as those stubs stand; say so
   rather than leaving it looking load-bearing.
5. website/permissions.qmd's own per-workflow list was missed when README's
   parallel section was updated.
Copilot AI review requested due to automatic review settings July 27, 2026 09:13

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copy link
Copy Markdown
Collaborator Author

ARD round 1 --- all five addressed in 0d90314

# Finding Disposition
1 report job checks out with contents: none Address --- checkout removed entirely
2 labels not split/trimmed before --label Address --- new split-csv-list.sh, one --label per name
3 _selftest.yml comment claims wiring that does not exist Address --- reworded
4 Inert pull_request clause in the examples Address --- kept, comment reworded in both copies
5 website/permissions.qmd list missed (not tied to a diff line) Address --- entry added

Two of these were real bugs, and both would have surfaced first in a consumer repo rather than here, which is the worst place to find them. Worth recording what each one actually was:

Finding 1 was a permissions bug with a design smell underneath it. The fix took the reviewer's cheaper option --- GH_REPO in the composite's env:, checkout deleted --- because the checkout was not just costing a contents: read grant, it was how gh was learning which repository to file against. That made the composite silently dependent on the caller having checked out the right repo, which is precisely the assumption gha#327's check-links.yml migration would have broken.

Finding 2 is worse than it first reads, and the review's diagnosis is what showed it: a space after a comma fails the create, the fallback then drops the valid labels too, and the warning blames a missing label. Three steps between cause and symptom. It is also the same shape as gha#253, in a repo that had already fixed it once --- so the fix went into a shared, tested script rather than inline.

On the website/permissions.qmd gap, worth noting for its own sake: CLAUDE.md names three doc-sync sites for a new workflow input, and permissions.qmd is not among them because it is not an inputs table. It is still a per-workflow list that drifts independently of its README.md counterpart, and it was missed for exactly that reason. I have not added it to CLAUDE.md's list in this PR --- that is a convention change worth its own change rather than a side effect of this one --- but it is a real gap in the stated procedure.

Verification for the two code fixes:

  • run-split-csv-list-tests.sh covers ten cases, including the space-after-comma case that motivated it, tabs, empty and comma-only inputs, and a label with internal spaces (good first issue is a real GitHub label, so trimming must not use xargs). Also confirmed the built argument vector directly: --label bug --label automated --label 'good first issue'.
  • The fallback's guard moved from -z "$LABELS" to ${#labels[@]} -eq 0, which fixes an adjacent case the reviewer did not raise: " , " is a non-empty input yielding no labels, and the old guard would have warned about labels being dropped that never existed.

Generated by Claude Code

Comment thread .github/workflows/scripts/split-csv-list.sh
Comment thread CLAUDE.md Outdated
@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Code review

Re-reviewed after the follow-up commit (0d90314, "fix: drop the checkout, and split/trim labels before passing them to gh") that addressed all four issues from the prior review round:

  1. report-failure.yml missing contents: read - fixed by removing the checkout entirely; the composite now resolves its own scripts via github.action_path and names the target repo via GH_REPO: ${{ github.repository }}. issues: write alone is now genuinely sufficient.
  2. Unsplit/untrimmed LABELS - fixed with a new split-csv-list.sh helper plus one --label flag per trimmed item, with an offline test suite covering the space-after-comma case.
  3. Stale _selftest.yml comment - fixed; the comment now correctly states report-failure.yml is the only caller so far, with check-links.yml's migration deferred to gha#327.
  4. website/permissions.qmd gap - fixed; a report-failure entry was added, consistent with README.md's.

The fifth item (examples/report-failure.yml's dead pull_request clause) was cosmetic/non-blocking in the original review; the author left the clause in place and added a comment explaining it's inert for this stub but relevant for consumers who add a pull_request trigger - a reasonable disposition for a non-blocking finding.

Two new, non-blocking findings from this round, posted inline:

  1. .github/workflows/scripts/split-csv-list.sh - the new script duplicates build-reviewer-args.sh's split/trim logic rather than sharing it (CLAUDE.md guideline 14 "Don't reinvent the wheel" / guideline 10 "Question redundant content"). Confirmed on independent verification: both scripts solve the identical split-and-trim problem, build-reviewer-args.sh could delegate to the new script with no loss of behavior, and the new script's own header comment documents xargs (still used by build-reviewer-args.sh) as the wrong tool for this - without a "checked existing options, nothing fit" note. Fine to defer to a follow-up so this PR doesn't have to touch the already-released build-reviewer-args.sh.
  2. CLAUDE.md - the new Layout bullet for .github/actions/open-failure-issue/ names select-existing-issue.sh but omits split-csv-list.sh, even though the composite wraps both symmetrically via github.action_path and the bullet even describes the label-dropping behavior that split-csv-list.sh implements. This repo's own convention (e.g. the generate-altdoc-landing-page bullet) is to enumerate every script a multi-script composite wraps.

I also re-checked (and found no new issues with) the items this round's fix commit touched: shell-injection safety of the new GH_REPO/label/title/body handling (all routed through env:, never interpolated into run:), the mapfile < <(...) pattern used for labels (a real "exit status is swallowed" gotcha, but not reachable under any realistic input since SPLIT_SCRIPT's path resolution is proven by the same github.action_path mechanism the sibling SELECT_SCRIPT call already exercises end-to-end), and the dry-run gating logic (correctly exits before any real gh issue call).

Verdict heading below.

Verdict

Ready for merge - the blocking issue from the prior round (missing contents: read) is resolved, and the two new findings in this round are non-blocking DRY/documentation suggestions, not correctness bugs.

build-reviewer-args.sh now delegates its split/trim to split-csv-list.sh and
only reshapes the result into JSON, instead of carrying a second copy of the
same loop in the same directory. Its five existing tests pass unchanged.

That also retires its `xargs` trim, which interprets quotes and backslashes
as shell syntax -- harmless for usernames, but the wrong tool, and the reason
the new script did not use it in the first place.

The CLAUDE.md Layout bullet named only select-existing-issue.sh. The edit
adding the second script was made but never reached a commit: the Tests
section's half landed and the Layout section's did not, so the file described
a one-script composite while the Tests section below it named both.
@github-actions

Copy link
Copy Markdown
Contributor

Claude finished reviewView run


gh pr comment 326 --repo d-morrison/gha --body "## Code review

Re-reviewed after the follow-up commit (`0d90314`, "fix: drop the checkout, and split/trim labels before passing them to gh") that addressed all four issues from the prior review round:

  1. `report-failure.yml` missing `contents: read` — fixed by removing the checkout entirely; the composite now resolves its own scripts via `github.action_path` and names the target repo via `GH_REPO: ${{ github.repository }}`. `issues: write` alone is now genuinely sufficient.
  2. Unsplit/untrimmed `LABELS` — fixed with a new `split-csv-list.sh` helper plus one `--label` flag per trimmed item, with an offline test suite covering the space-after-comma case.
  3. Stale `_selftest.yml` comment — fixed; the comment now correctly states `report-failure.yml` is the only caller so far, with `check-links.yml`'s migration deferred to gha#327.
  4. `website/permissions.qmd` gap — fixed; a `report-failure` entry was added, consistent with `README.md`'s.

The fifth item (`examples/report-failure.yml`'s dead `pull_request` clause) was cosmetic/non-blocking in the original review; the author left the clause in place and added a comment explaining it's inert for this stub but relevant for consumers who add a `pull_request` trigger — a reasonable disposition for a non-blocking finding.

Two new, non-blocking findings from this round, posted inline:

  1. `.github/workflows/scripts/split-csv-list.sh` — the new script duplicates `build-reviewer-args.sh`'s split/trim logic rather than sharing it (CLAUDE.md §14 "Don't reinvent the wheel" / §10 "Question redundant content"). Confirmed on independent verification: both scripts solve the identical split-and-trim problem, `build-reviewer-args.sh` could delegate to the new script with no loss of behavior, and the new script's own header comment documents `xargs` (still used by `build-reviewer-args.sh`) as the wrong tool for this — without a "checked existing options, nothing fit" note. Fine to defer to a follow-up so this PR doesn't have to touch the already-released `build-reviewer-args.sh`.
  2. `CLAUDE.md` — the new Layout bullet for `.github/actions/open-failure-issue/` names `select-existing-issue.sh` but omits `split-csv-list.sh`, even though the composite wraps both symmetrically via `github.action_path` and the bullet even describes the label-dropping behavior that `split-csv-list.sh` implements. This repo's own convention (e.g. the `generate-altdoc-landing-page` bullet) is to enumerate every script a multi-script composite wraps.

I also re-checked (and found no new issues with) the items this round's fix commit touched: shell-injection safety of the new `GH_REPO`/label/title/body handling (all routed through `env:`, never interpolated into `run:`), the `mapfile < <(...)` pattern used for labels (a real "exit status is swallowed" gotcha, but not reachable under any realistic input since `SPLIT_SCRIPT`'s path resolution is proven by the same `github.action_path` mechanism the sibling `SELECT_SCRIPT` call already exercises end-to-end — not flagging per this review's "don't flag issues that depend on specific/unreachable state" bar), and the `dry-run` gating logic (correctly exits before any real `gh issue` call).

Verdict

Ready for merge — the blocking issue from the prior round (missing `contents: read`) is resolved, and the two new findings in this round are non-blocking DRY/documentation suggestions, not correctness bugs."

@github-actions

Copy link
Copy Markdown
Contributor

💰 Cost: $13.3279 (review) — run

Copilot AI review requested due to automatic review settings July 27, 2026 09:32

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

The CLAUDE.md bullet illustrated the untrimmed label by putting it in a code
span that begins with a space, which is what markdownlint's no-space-in-code
rule exists to catch. Say it in prose instead.

Ironically this only surfaced now: lint-markdown was green on the previous
commit because the bullet itself had never landed.
Copilot AI review requested due to automatic review settings July 27, 2026 09:34

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread CLAUDE.md Outdated
…udo-quote

The paragraph cited the Layout section for a gap the Tests section describes,
and put quotation marks around a phrase that appears nowhere in the file --
it was a paraphrase dressed as a quotation. Both are the kind of claim this
repo's own review guidelines ask to be checked against what the document
actually says, and neither survived that check.
Copilot AI review requested due to automatic review settings July 27, 2026 09:43

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

test comment - please ignore, will be replaced

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.

2026-07-27 18:21 UTC

@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Code review

Confirming review — the previous verdict was Ready for merge, posted here, after commit 0d90314 fixed the round-1 blocking issue (report-failure.yml's missing contents: read) and the label-splitting bug. That round also flagged two non-blocking follow-ups (split-csv-list.sh duplicating build-reviewer-args.sh's logic, and CLAUDE.md's Layout bullet omitting split-csv-list.sh), and a subsequent pass flagged one more doc-accuracy issue in CLAUDE.md's new bootstrapping-gap paragraph (misattributed section, plus a paraphrase dressed as a quotation).

I re-verified the current head (609a2a6) against all of that prior feedback and confirm every item is now resolved:

  • report-failure.yml's report job no longer checks out the repo; it names the target via GH_REPO: ${{ github.repository }} and holds issues: write only — genuinely sufficient now, verified against the composite's env: block.
  • Label splittingsplit-csv-list.sh now does the split/trim, with one --label per name; its test suite covers the space-after-comma case, internal-space labels (good first issue), and all-blank input.
  • _selftest.yml's comment now accurately states report-failure.yml is the only caller so far, with check-links.yml's migration deferred to gha#327 — matches the diff.
  • split-csv-list.sh duplicationbuild-reviewer-args.sh now delegates to it (bash "$script_dir/split-csv-list.sh" "$REVIEWERS" | jq -R -s -c '...') rather than carrying a second copy; confirmed its five pre-existing behavioral test cases still pass unchanged under the new implementation.
  • CLAUDE.md's Layout bullet for .github/actions/open-failure-issue/ now names both select-existing-issue.sh and split-csv-list.sh, with the label-dropping behavior correctly attributed to the latter.
  • CLAUDE.md's bootstrapping-gap paragraph now correctly points at "The Tests section's build-reviewer-args paragraph" (verified against that paragraph's actual text) rather than the wrong Layout-section bullet, and the pseudo-quote is gone — the text is a plain paraphrase now.

I also re-swept doc-sync completeness (README.md, website/workflows.qmd, website/versioning.qmd, website/permissions.qmd, website/reference/report-failure.qmd, website/_quarto.yml nav, the changelog.d/ fragment) and found no gaps — all consistent with the actual composite/workflow behavior (no checkout, GH_REPO-based repo targeting, issues: write-only permissions).

No new issues found in the commits since the last review round (5acfd9d, c82ed2af, 609a2a6).

Verdict

Ready for merge — the prior verdict stands; all outstanding findings (blocking and non-blocking) have been addressed.

@github-actions

Copy link
Copy Markdown
Contributor

Claude finished reviewView run


Posted the confirming review: #326 (comment)

Summary: All findings from prior review rounds — the report-failure.yml checkout/permissions bug, the unsplit LABELS bug, the stale _selftest.yml comment, the split-csv-list.sh/build-reviewer-args.sh duplication, CLAUDE.md's missing script mention, and CLAUDE.md's bootstrapping-gap misattribution/pseudo-quote — are confirmed fixed in the current head (609a2a6). I independently re-verified each fix against the actual diff content rather than trusting the commit messages, re-swept all doc-sync sites, and found no new issues introduced by the latest three commits.

Verdict

Ready for merge

@github-actions

Copy link
Copy Markdown
Contributor

💰 Cost: $2.6100 (review) — run

Copy link
Copy Markdown
Collaborator Author

Ready for merge

Fully clean at 609a2a6.

Checks --- all 30 completed, none failing, including codecov/patch. Re-read after the verdict posted rather than before: claude-review commented at 09:50 and its own job did not finish until 09:50:55, with require-review following at 09:51:02. A verdict landing is not the same as the check finishing.

Review --- Ready for merge, confirming the round-2 verdict and re-verifying each earlier finding against the current head. All 7 inline threads resolved.

Merge state --- git merge-tree against current origin/main: no conflicts.

What the four rounds actually caught

Worth recording, because only the first round found a bug in the feature itself:

  1. A permissions bug that would have failed on any private consumer --- issues: write plus a checkout means contents: none. Fixed by deleting the checkout rather than widening the grant, which also removed the composite's silent dependency on the caller having checked out the right repo.
  2. A label bug three steps removed from its symptom --- an untrimmed bug, automated fails the create, the fallback then drops the valid label too, and the warning blames a missing label.
  3. DRY --- the label fix had created a second CSV splitter beside build-reviewer-args.sh. Consolidated instead of deferred.
  4. Two doc-accuracy findings, both on prose asserting things about files without checking them: a comment claiming a wiring that did not exist, and a cross-reference naming the wrong section with a paraphrase in quotation marks.

The last two rounds found nothing but documentation defects, which is the shape of a PR converging rather than churning.

Not merging

Leaving that to you. Two notes for when you do:


Generated by Claude Code

@d-morrison
d-morrison merged commit fee46d9 into main Jul 27, 2026
30 checks passed
@d-morrison
d-morrison deleted the feat/open-failure-issue branch July 27, 2026 18:21
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.

quarto-publish should open an issue when a publish run fails

3 participants