Skip to content

Commit 2a45faf

Browse files
edburnsCopilot
andcommitted
Use agent_assignment API to guarantee base branch on Copilot assignment
Replace the body-prepend workaround with the REST API's agent_assignment.base_branch field when assigning issues to Copilot. This is the programmatic equivalent of selecting the branch in the GitHub UI and guarantees Copilot creates its topic branch from BASE_BRANCH instead of defaulting to main. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c8c20cb commit 2a45faf

1 file changed

Lines changed: 28 additions & 52 deletions

File tree

  • .github/skills/shepherd-task-from-assignment-to-ready

‎.github/skills/shepherd-task-from-assignment-to-ready/SKILL.md‎

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,73 +25,49 @@ Automate the lifecycle of a child **Task** issue from "assigned to Copilot" thro
2525

2626
## Procedure
2727

28-
### Step 1: Assign the task to @Copilot
28+
### Step 1: Assign the task to @Copilot with `base_branch`
2929

30-
First, prepend an instruction to the issue body telling Copilot which base branch to use. This must happen **before** assignment to avoid a race condition where Copilot targets `main` instead.
31-
32-
**Idempotency:** If the issue body already starts with `**Base branch:**`, skip the prepend (it was already done in a prior run).
30+
Use the REST API's `agent_assignment` object to assign the issue to Copilot **and** specify the base branch in a single atomic call. This guarantees Copilot branches from `$BASE_BRANCH` (equivalent to selecting the branch in the GitHub UI).
3331

3432
```bash
35-
# Check if already prepended (idempotency guard)
36-
CURRENT_BODY=$(gh issue view $TASK_ISSUE -R $REPO --json body --jq '.body')
37-
if echo "$CURRENT_BODY" | head -1 | grep -q '^\*\*Base branch:\*\*'; then
38-
echo "Base branch instruction already present — skipping prepend."
39-
else
40-
# Prepend base branch instruction (use --body-file to preserve markdown formatting)
41-
gh issue view $TASK_ISSUE -R $REPO --json body --jq '.body' > /tmp/issue-body-$TASK_ISSUE.md
42-
cat > /tmp/issue-body-$TASK_ISSUE-new.md <<HEADER
43-
**Base branch:** Create your PR targeting \`$BASE_BRANCH\` (not \`main\`).
44-
45-
**Requirement:** When you open the PR, the very first thing you put in the description must be \`Fixes #$TASK_ISSUE\` where the issue number is this issue for which the PR aims to implement the work.
46-
47-
--------
48-
49-
HEADER
50-
cat /tmp/issue-body-$TASK_ISSUE.md >> /tmp/issue-body-$TASK_ISSUE-new.md
51-
gh issue edit $TASK_ISSUE -R $REPO --body-file /tmp/issue-body-$TASK_ISSUE-new.md
52-
rm -f /tmp/issue-body-$TASK_ISSUE.md /tmp/issue-body-$TASK_ISSUE-new.md
53-
fi
33+
gh api --method POST \
34+
-H "Accept: application/vnd.github+json" \
35+
-H "X-GitHub-Api-Version: 2022-11-28" \
36+
/repos/$REPO/issues/$TASK_ISSUE/assignees \
37+
--input - <<EOF
38+
{
39+
"assignees": ["copilot-swe-agent[bot]"],
40+
"agent_assignment": {
41+
"base_branch": "$BASE_BRANCH",
42+
"custom_instructions": "When you open the PR, the very first thing you put in the description must be \`Fixes #$TASK_ISSUE\`."
43+
}
44+
}
45+
EOF
5446
```
5547

5648
> **PowerShell equivalent** (when running on Windows):
5749
> ```powershell
58-
> $body = gh issue view $TASK_ISSUE -R $REPO --json body --jq '.body' | Out-String
59-
> if ($body.TrimStart().StartsWith("**Base branch:**")) {
60-
> Write-Host "Base branch instruction already present - skipping prepend."
61-
> } else {
62-
> $instruction = @"
63-
> **Base branch:** Create your PR targeting ``$BASE_BRANCH`` (not ``main``).
64-
>
65-
> **Requirement:** When you open the PR, the very first thing you put in the description must be ``Fixes #$TASK_ISSUE`` where the issue number is this issue for which the PR aims to implement the work.
66-
>
67-
> --------
68-
>
69-
> "@
70-
> $newBody = $instruction + $body
71-
> $tmpFile = [System.IO.Path]::GetTempFileName()
72-
> Set-Content -Path $tmpFile -Value $newBody -NoNewline
73-
> gh issue edit $TASK_ISSUE -R $REPO --body-file $tmpFile
74-
> Remove-Item $tmpFile
50+
> $json = @"
51+
> {
52+
> "assignees": ["copilot-swe-agent[bot]"],
53+
> "agent_assignment": {
54+
> "base_branch": "$BASE_BRANCH",
55+
> "custom_instructions": "When you open the PR, the very first thing you put in the description must be ``Fixes #$TASK_ISSUE``."
56+
> }
7557
> }
58+
> "@
59+
> $json | gh api --method POST `
60+
> -H "Accept: application/vnd.github+json" `
61+
> -H "X-GitHub-Api-Version: 2022-11-28" `
62+
> "/repos/$REPO/issues/$TASK_ISSUE/assignees" `
63+
> --input -
7664
> ```
7765
78-
Then assign:
79-
80-
```bash
81-
gh issue edit $TASK_ISSUE --add-assignee "@copilot" -R $REPO
82-
```
83-
8466
This triggers Copilot to:
8567
1. Create a topic branch from `$BASE_BRANCH`.
8668
2. Open a draft PR targeting `$BASE_BRANCH`.
8769
3. Push initial commits.
8870
89-
**Fallback:** After the PR is created (Step 2), verify it targets `$BASE_BRANCH`. If Copilot ignored the instruction, fix the base:
90-
91-
```bash
92-
gh pr edit $PR_NUMBER -R $REPO --base "$BASE_BRANCH"
93-
```
94-
9571
### Step 2: Find the corresponding PR
9672
9773
Use **all three** of the following strategies (in order) each polling iteration. Copilot often creates PRs whose title or branch name does NOT contain the issue number — it may use a descriptive name instead. Therefore, relying on title/branch regex alone is insufficient.

0 commit comments

Comments
 (0)