From 024c16349d6e4a5c4d5801b6e25bb4cba7250f4d Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 30 Jan 2026 15:58:21 -0500 Subject: [PATCH] Auto-add "Fixes #N" closing keyword to PR body when triggered from issue When a workflow is triggered by an issue (e.g., Copilot SWE agent assigned to fix an issue), the created PR should include a GitHub closing keyword so the issue auto-closes on merge. Agents are instructed to include "Fixes #N" in PR descriptions, but they don't reliably follow this instruction. This change adds automatic injection of the closing keyword when: 1. The workflow was triggered from an issue context 2. The PR body doesn't already contain a closing keyword (fix/close/resolve) Uses the same `triggeringIssueNumber` pattern already established in `create_issue.cjs` and `create_pr_review_comment.cjs`. Fixes githubnext/gh-aw#12822 Co-Authored-By: Claude Opus 4.5 Signed-off-by: Andrew Anderson --- actions/setup/js/create_pull_request.cjs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/actions/setup/js/create_pull_request.cjs b/actions/setup/js/create_pull_request.cjs index 7de251c91df..ce35dd07a72 100644 --- a/actions/setup/js/create_pull_request.cjs +++ b/actions/setup/js/create_pull_request.cjs @@ -81,6 +81,11 @@ async function main(config = {}) { throw new Error("base_branch configuration is required"); } + // Extract triggering issue number from context (for auto-linking PRs to issues) + const triggeringIssueNumber = context.payload?.issue?.number && !context.payload?.issue?.pull_request + ? context.payload.issue.number + : undefined; + // Check if we're in staged mode const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true"; @@ -328,6 +333,17 @@ async function main(config = {}) { // Remove duplicate title from description if it starts with a header matching the title processedBody = removeDuplicateTitleFromDescription(title, processedBody); + // Auto-add "Fixes #N" closing keyword if triggered from an issue and not already present. + // This ensures the triggering issue is auto-closed when the PR is merged. + // Agents are instructed to include this but don't reliably do so. + if (triggeringIssueNumber) { + const hasClosingKeyword = /(?:fix|fixes|fixed|close|closes|closed|resolve|resolves|resolved)\s+#\d+/i.test(processedBody); + if (!hasClosingKeyword) { + processedBody = processedBody.trimEnd() + `\n\nFixes #${triggeringIssueNumber}`; + core.info(`Auto-added "Fixes #${triggeringIssueNumber}" closing keyword to PR body`); + } + } + let bodyLines = processedBody.split("\n"); let branchName = pullRequestItem.branch ? pullRequestItem.branch.trim() : null;