Skip to content

tools: claude: update workflow with systemd changes#472

Draft
pzmarzly wants to merge 1 commit intofacebook:mainfrom
pzmarzly:push-prrkmotnxqmo
Draft

tools: claude: update workflow with systemd changes#472
pzmarzly wants to merge 1 commit intofacebook:mainfrom
pzmarzly:push-prrkmotnxqmo

Conversation

@pzmarzly
Copy link
Contributor

systemd project recently adopted this workflow, improving it in the process.
New workflow is more secure, and has more stable output format.

Thanks @daandemeyer!

I kept some of the differences:

  • we want to re-use /review-pr skill as much as possible
  • we don't mind burning tokens on 3rd party PRs automatically
  • we're using openrouter backend

Demo:

systemd recently adopted this workflow, improving it in the process.
New workflow is more secure, and has more stable output format.
@pzmarzly pzmarzly requested a review from qdeslandes as a code owner March 12, 2026 23:21
@meta-cla meta-cla bot added the cla signed label Mar 12, 2026
owner,
repo,
issue_number: prNumber,
per_page: 100,

Choose a reason for hiding this comment

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

Claude: suggestion: listComments uses per_page: 100 without pagination. On a long-lived PR with 100+ top-level comments, the tracking comment could be missed, causing a duplicate. Consider using github.paginate():

Suggested change
per_page: 100,
const issueComments = await github.paginate(
github.rest.issues.listComments,
{ owner, repo, issue_number: prNumber, per_page: 100 }
);

Then use issueComments directly (it returns a flat array, no .data wrapper).

if (typeof review.summary === "string")
summary = review.summary;
} catch (e) {
console.log(`Failed to parse structured output: ${e.message}`);

Choose a reason for hiding this comment

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

Claude: suggestion: When JSON.parse fails, the error is logged but execution continues silently — the tracking comment ends up saying "no issues found" which hides the real problem. Consider using core.warning() so the workflow run status reflects the parse failure:

Suggested change
console.log(`Failed to parse structured output: ${e.message}`);
} catch (e) {
core.warning(`Failed to parse structured output: ${e.message}`);
}

"description": "Path relative to repo root"
},
"line": {
"type": "integer",

Choose a reason for hiding this comment

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

Claude: suggestion: The schema requires line as a non-nullable integer. Issues that aren't tied to a specific line (commit message problems, general documentation observations, CLAUDE.md improvement suggestions) can't be represented — Claude will either fabricate a line number or drop the finding.

Consider making line optional by removing it from the required array and adding a guard in the post job to skip createReviewComment when line is absent (those findings would still appear in the tracking comment summary).

Comment on lines +54 to +59
const prevBody = existing.body.replace(/\n\n\[Workflow run\]\([^)]*\)$/, "");
await github.rest.issues.updateComment({
owner,
repo,
comment_id: existing.id,
body: `> **Claude is re-reviewing this PR…** ([workflow run](${runUrl}))\n\n${prevBody}`,

Choose a reason for hiding this comment

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

Claude: nit: When a re-run is triggered while a previous "re-reviewing" banner is already present, the new update prepends another > **Claude is re-reviewing…** on top of the previous one. Multiple rapid synchronize events (e.g. force-push + immediate amend) will accumulate layers of nested blockquote headers.

Consider stripping any existing re-reviewing prefix from prevBody before wrapping again, or replacing the body with just the status line + the last actual review content.

Copy link
Contributor Author

@pzmarzly pzmarzly Mar 12, 2026

Choose a reason for hiding this comment

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

It should eventually fix itself though, once workflow succeeds


/* If the review job failed or was cancelled, update the tracking
* comment to reflect that and bail out. */
if ("${{ needs.review.result }}" !== "success") {

Choose a reason for hiding this comment

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

Claude: nit: "${{ needs.review.result }}" is injected directly into the JavaScript source via GitHub Actions expression expansion. While needs.*.result is a GitHub-controlled enum and safe here, the rest of the file consistently uses environment variables for expression values (e.g. process.env.PR_NUMBER, process.env.HEAD_SHA). For consistency:

env:
    REVIEW_RESULT: ${{ needs.review.result }}
if (process.env.REVIEW_RESULT !== "success") {

@github-actions
Copy link

Claude: review of facebook/bpfilter #472 (8ac27f6)

Suggestions

  • Marker injection fails for single-line summaries.github/workflows/claude-pr-review.yaml:388 — If Claude's summary has no newline, replace(/\n/, ...) never matches and the <!-- claude-pr-review --> marker is never inserted, causing duplicate tracking comments on re-runs
  • Setup comment search not paginated.github/workflows/claude-pr-review.yaml:46listComments uses per_page: 100 without pagination; PRs with 100+ comments will miss the tracking comment
  • JSON parse failure silently swallowed.github/workflows/claude-pr-review.yaml:345 — When JSON.parse fails, the error is logged but the workflow reports "no issues found" instead of signaling a warning
  • Schema requires line as non-nullable integer.github/workflows/claude-pr-review.yaml:120 — Issues not tied to a specific line (commit messages, CLAUDE.md suggestions) can't be represented; consider making line optional

Nits

  • Re-review banner nests on repeated triggers.github/workflows/claude-pr-review.yaml:54-59 — Multiple rapid synchronize events accumulate nested blockquote "re-reviewing" headers
  • Expression interpolation in JS source.github/workflows/claude-pr-review.yaml:319${{ needs.review.result }} injected directly into JS; rest of file uses process.env.* pattern for consistency

@pzmarzly pzmarzly marked this pull request as draft March 12, 2026 23:47
@pzmarzly
Copy link
Contributor Author

@daandemeyer do you mind taking a look at the issues that the bot found?

Copy link
Contributor

@qdeslandes qdeslandes left a comment

Choose a reason for hiding this comment

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

Reviewing AI instructions really is not fun. I had a quick look and it LGTM, letting it run on PRs will be the proper way to actually check if it does what we expect it to do. I'll let @daandemeyer have a look at your comment if he wants to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants