Skip to content

Commit 65de811

Browse files
arilivigniCopilot
andcommitted
Step 3: accept app <copilot-ref> issue links in merge check
The Copilot App rewrites a plain 'Closes #2' in the PR body as a <copilot-ref ... target-id=".../issues/2"> chip, which GitHub does not parse as a closing keyword. As a result closingIssuesReferences was empty and the terminal Step 3 check false-failed even though the learner linked and closed the correct issue. Harden check-issue-closed to also scan the PR body for referenced issue numbers (bare #N and .../issues/N URLs, covering the app's chip) and pass when any non-walkthrough referenced issue is closed. Clarify in the step troubleshooting that the linked-issue chip is expected. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a9ddd07b-77bf-43e0-a5d9-c6426a067e0e
1 parent d089c37 commit 65de811

2 files changed

Lines changed: 42 additions & 15 deletions

File tree

.github/steps/3-step.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ Review the diff agent merge staged, then merge it. Watch this issue for **two re
170170
171171
- If the merge check hasn't posted, make sure agent merge actually **merged** the PR (not just opened it).
172172
- The exercise won't advance if the merged app fails to build. If the build row is red, fix the code on `main` (usually a `localStorage` call outside the `client:load` / `<script>` boundary) and push the fix.
173-
- If the app issue stays open, confirm the PR body used `Closes https://github.com/{{full_repo_name}}/issues/2` (your **Build the bookmarks app** issue) — not the walkthrough issue — then close it manually if needed.
173+
- If the app issue stays open, confirm the PR body used `Closes https://github.com/{{full_repo_name}}/issues/2` (your **Build the bookmarks app** issue) — not the walkthrough issue — then close it manually if needed. The app may render the closing reference as a linked **Issue #2** chip; that's expected — the check accepts it as long as issue **#2** ends up closed.
174174
- Still stuck on the app itself? See [Getting started with the Copilot App](https://docs.github.com/en/copilot/how-tos/github-copilot-app/getting-started).
175175
176176
</details>

.github/workflows/3-step.yml

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,43 +185,70 @@ jobs:
185185
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
186186
PR_NUMBER: ${{ github.event.pull_request.number }}
187187
WALKTHROUGH_ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
188+
OWNER: ${{ github.repository_owner }}
189+
REPO_NAME: ${{ github.event.repository.name }}
188190
run: |
189191
if [ -z "$PR_NUMBER" ]; then
190192
echo "No pull request in context (manual dispatch); skipping linked-issue check."
191193
exit 0
192194
fi
193195
194-
# Merging closes the linked issue asynchronously, so poll a few times
195-
# to avoid a false failure from reading the state too early.
196-
CLOSED_LINKED=0
197-
for attempt in 1 2 3 4 5; do
198-
CLOSED_LINKED=$(gh api graphql \
196+
# Gather every issue this PR intends to resolve, from two sources:
197+
# 1. GitHub's own closing references — populated only when the body
198+
# uses a plain-text closing keyword like "Closes #2".
199+
# 2. Issue numbers embedded in the PR body — including the Copilot
200+
# App's <copilot-ref ... target-id=".../issues/N"> chips, which
201+
# GitHub does NOT parse as closing keywords. Without this the
202+
# check false-fails when the learner referenced the issue
203+
# correctly but the app encoded it as a rich reference.
204+
collect_candidates() {
205+
gh api graphql \
199206
-f query='query($owner:String!,$repo:String!,$pr:Int!){
200207
repository(owner:$owner,name:$repo){
201208
pullRequest(number:$pr){
202-
closingIssuesReferences(first:20){ nodes { number state } }
209+
closingIssuesReferences(first:20){ nodes { number } }
203210
}
204211
}
205212
}' \
206-
-f owner="${{ github.repository_owner }}" \
207-
-f repo="${{ github.event.repository.name }}" \
213+
-f owner="$OWNER" \
214+
-f repo="$REPO_NAME" \
208215
-F pr="$PR_NUMBER" \
209-
--jq "[.data.repository.pullRequest.closingIssuesReferences.nodes[]
210-
| select(.number != ($WALKTHROUGH_ISSUE_NUMBER|tonumber))
211-
| select(.state == \"CLOSED\")] | length")
216+
--jq '.data.repository.pullRequest.closingIssuesReferences.nodes[].number' \
217+
2>/dev/null || true
218+
219+
gh api "repos/$OWNER/$REPO_NAME/pulls/$PR_NUMBER" --jq '.body // ""' 2>/dev/null \
220+
| grep -oiE '(#[0-9]+|/issues/[0-9]+)' \
221+
| grep -oE '[0-9]+' || true
222+
}
212223
213-
echo "Attempt $attempt: linked work item issues now closed by this PR: $CLOSED_LINKED"
224+
# Merging closes the linked issue asynchronously, so poll a few times
225+
# to avoid a false failure from reading the state too early.
226+
CLOSED_LINKED=0
227+
for attempt in 1 2 3 4 5; do
228+
CLOSED_LINKED=0
229+
for num in $(collect_candidates | sort -un); do
230+
if [ "$num" = "$WALKTHROUGH_ISSUE_NUMBER" ]; then
231+
continue
232+
fi
233+
STATE=$(gh api "repos/$OWNER/$REPO_NAME/issues/$num" --jq '.state' 2>/dev/null || echo "")
234+
if [ "$STATE" = "closed" ]; then
235+
echo "Referenced work item issue #$num is closed."
236+
CLOSED_LINKED=1
237+
fi
238+
done
239+
240+
echo "Attempt $attempt: linked (non-walkthrough) work item issues closed by this PR: $CLOSED_LINKED"
214241
if [ "$CLOSED_LINKED" -ge 1 ]; then
215242
break
216243
fi
217244
sleep 3
218245
done
219246
220247
if [ "$CLOSED_LINKED" -ge 1 ]; then
221-
echo "The merged pull request closed its linked work item issue."
248+
echo "The merged pull request resolved its linked work item issue."
222249
exit 0
223250
else
224-
echo "No linked work item issue was closed. Ensure the PR body used a closing keyword (e.g. 'Closes #<app-issue-number>') pointing at your bookmarks issue, not the walkthrough issue."
251+
echo "No linked work item issue was closed. In the pull request body, reference your bookmarks issue with a closing keyword (e.g. 'Closes #<app-issue-number>') pointing at that issue, not the walkthrough issue, and make sure the issue is closed."
225252
exit 1
226253
fi
227254

0 commit comments

Comments
 (0)