Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/skills/agentic-workflows/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Load these files from `github/gh-aw` (they are not available locally).
- `.github/aw/debug-agentic-workflow.md`
- `.github/aw/dependabot.md`
- `.github/aw/deployment-status.md`
- `.github/aw/designer-mappings.md`
- `.github/aw/designer.md`
- `.github/aw/evals.md`
- `.github/aw/experiments.md`
Expand Down Expand Up @@ -100,4 +101,3 @@ After loading the matching workflow prompt or skill, follow it directly:
- Design long-running multi-agent research workflows: `.github/aw/multi-agent-research.md`

When the task involves OTEL, OTLP, traces, observability backends, or telemetry-driven analysis, also read and follow `skills/otel-queries/SKILL.md` after loading the matching workflow prompt or skill.

24 changes: 13 additions & 11 deletions actions/setup/js/pr_review_buffer.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -352,17 +352,19 @@ function createReviewBuffer() {

// Add footer to review body if we should and we have footer context
if (shouldAddFooter && footerContext) {
body += generateFooterWithMessages(
footerContext.workflowName,
footerContext.runUrl,
footerContext.workflowSource,
footerContext.workflowSourceURL,
footerContext.triggeringIssueNumber,
footerContext.triggeringPRNumber,
footerContext.triggeringDiscussionNumber,
undefined,
{ skipDetectionCaution: true }
);
body +=
"\n\n" +
generateFooterWithMessages(
footerContext.workflowName,
footerContext.runUrl,
footerContext.workflowSource,
footerContext.workflowSourceURL,
footerContext.triggeringIssueNumber,
footerContext.triggeringPRNumber,
footerContext.triggeringDiscussionNumber,
undefined,
{ skipDetectionCaution: true }
);

const callerWorkflowId = process.env.GH_AW_CALLER_WORKFLOW_ID || "";
if (callerWorkflowId) {
Expand Down
33 changes: 33 additions & 0 deletions actions/setup/js/pr_review_buffer.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,39 @@ describe("pr_review_buffer (factory pattern)", () => {
expect(callArgs.body).toContain("test-workflow");
});

it("should separate body from footer with a blank line for proper markdown rendering", async () => {
buffer.addComment({ path: "test.js", line: 1, body: "comment" });
buffer.setReviewMetadata("Review body content", "COMMENT");
buffer.setReviewContext({
repo: "owner/repo",
repoParts: { owner: "owner", repo: "repo" },
pullRequestNumber: 42,
pullRequest: { head: { sha: "abc123" } },
});
buffer.setFooterContext({
workflowName: "test-workflow",
runUrl: "https://github.com/owner/repo/actions/runs/123",
workflowSource: "owner/repo/workflows/test.md@v1",
workflowSourceURL: "https://github.com/owner/repo/blob/main/test.md",
});

mockGithub.rest.pulls.createReview.mockResolvedValue({
data: {
id: 403,
html_url: "https://github.com/owner/repo/pull/42#pullrequestreview-403",
},
});

const result = await buffer.submitReview();

expect(result.success).toBe(true);
const callArgs = mockGithub.rest.pulls.createReview.mock.calls[0][0];
// The footer blockquote must be preceded by at least one blank line
// so Markdown parses the "> Generated by" quote section correctly.
expect(callArgs.body).toMatch(/\n\n> /);
expect(callArgs.body).not.toMatch(/[^\n]\n> /);
});

it("should retry with COMMENT when APPROVE is rejected on own PR", async () => {
buffer.addComment({ path: "test.js", line: 1, body: "comment" });
buffer.setReviewMetadata("LGTM", "APPROVE");
Expand Down