Skip to content

Label unassigned Copilot-authored PRs - #19989

Merged
Ella Hathaway (ellahathaway) merged 8 commits into
mainfrom
ellahathaway-copilot-pr-attribution
Oct 14, 2026
Merged

Ella Hathaway (ellahathaway) merged 8 commits into
mainfrom
ellahathaway-copilot-pr-attribution

Conversation

@ellahathaway

@ellahathaway Ella Hathaway (ellahathaway) commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Description

Copilot-authored pull requests need a deterministic way to enter the Aspire team's ownership flow without inferring ownership from commit text or posting potentially unsafe mentions.

This extends the existing pull request labeler to:

  • Add needs-assignee when a Copilot-authored pull request is opened or reopened without a human assignee.
  • Remove or restore the label as human assignees are added or removed.
  • Remove the label when the pull request is closed.
  • Serialize updates per pull request and tolerate a label that was removed concurrently.
  • Keep area-label prediction limited to the original opened event.

The Aspire Team App also recognizes GitHub's GraphQL copilot-swe-agent identities. A Copilot-authored pull request with one human assignee is therefore attributed to <assignee>/copilot and appears in that person's existing queue.

Important: This does not automate assignment or review. Someone still needs to notice the label, assign an owner, and move the pull request through the normal review flow. This is intended as a visibility and ownership signal—one step toward resolving the broader issue of team-created Copilot pull requests being missed.

The needs-assignee repository label has been created. Existing open Copilot pull requests are intentionally not backfilled.

Security considerations

The label job runs on pull_request_target with pull-requests: write and contents: read. It sparsely checks out only .github/workflows/labeler-predict-pulls.js from the trusted default-branch event SHA with credentials disabled, then executes that module through the pinned actions/github-script action. It never checks out or executes pull request content, and uses fixed label and account values plus GitHub API metadata. It does not generate comments or mentions.

Validation:

  • LabelerPredictPullsWorkflowTests: 10 passed.
  • Aspire Team App GitHub tests: 7 passed.
  • Workflow YAML parsed successfully; lifecycle trigger and trusted-checkout assertions passed.
  • The live needs-assignee repository label exists.

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0fa7758d-f1e9-490d-b611-9c151d6206e1
Copilot AI balanced review requested due to automatic review settings September 8, 2026 20:04
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19989

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19989"

@github-actions github-actions Bot added the area-engineering-systems infrastructure helix infra engineering repo stuff label Sep 8, 2026
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new workflow job likely lacks the required GitHub Actions token permissions to add/remove labels via the Issues API, which can cause runtime failures and prevent the feature from working.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR extends the pull-request labeler workflow to keep a needs-assignee label in sync for Copilot-authored PRs (based on assignee lifecycle events), and updates the Aspire Team App’s Copilot attribution to recognize the copilot-swe-agent identity. It also adds workflow-focused infrastructure tests (with a Node-based harness) to validate the new behavior.

Changes:

  • Add a new update-copilot-assignee-label job to .github/workflows/labeler-predict-pulls.yml and limit area-label prediction to the original opened event.
  • Add an Infrastructure.Tests harness + tests to execute and validate the workflow’s inline github-script logic.
  • Update Aspire Team App logic and tests to treat copilot-swe-agent as a Copilot identity for attribution.
File summaries
File Description
tests/Infrastructure.Tests/WorkflowScripts/LabelerPredictPullsWorkflowTests.cs Adds tests asserting workflow triggers/guards and validating needs-assignee label behavior via a Node harness.
tests/Infrastructure.Tests/WorkflowScripts/labeler-predict-pulls.harness.js Adds a Node harness that emulates actions/github-script execution and records label mutations/API calls.
.github/workflows/labeler-predict-pulls.yml Adds a new job to sync needs-assignee on Copilot-authored PRs and gates area prediction to opened.
.github/extensions/aspire-team-app/github.test.mjs Adds a test ensuring copilot-swe-agent PRs with one human assignee attribute to {assignee}/copilot.
.github/extensions/aspire-team-app/github.mjs Updates Copilot identity detection to include copilot-swe-agent.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0fa7758d-f1e9-490d-b611-9c151d6206e1
Copilot AI review requested due to automatic review settings September 8, 2026 20:13
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The Team App’s Copilot login detection omits the copilot-swe-agent[bot] variant, which can prevent intended assignee-based attribution for some Copilot-authored PRs.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0fa7758d-f1e9-490d-b611-9c151d6206e1
Copilot AI review requested due to automatic review settings September 8, 2026 20:21
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

It changes a pull_request_target workflow with write permissions, so it warrants final human security review even though tests are present.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@ellahathaway
Ella Hathaway (ellahathaway) marked this pull request as ready for review September 8, 2026 20:29
Preserve assignment lifecycle triggers alongside upstream workflow security annotations.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The implementation matches the described lifecycle and includes focused coverage for identities, event gating, and concurrent removal.

Review effort: Balanced
Findings: None

@radical Ankit Jain (radical) left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[automated] Updated feedback supersedes my original recommendation: test a standalone label-sync script behaviorally, without testing YAML-only configuration or parsing YAML to extract scripts. The inline comment has been updated in place; the earlier suggestion to evaluate workflow conditions is withdrawn.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: aa9ef5ea-73f9-4188-9661-0d564de95bb8
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The Team App can misclassify copilot-swe-agent itself as the sole human assignee.

0 open findings

Previously missed (1)

In code that hasn't changed since last review

Medium severity Exclude copilot-swe-agent from human assignee attribution

.github/​extensions/​aspire-team-app/​github.mjs:199

Adding the non-suffixed copilot-swe-agent identity exposes an inconsistency in resolveAuthor: its “human” assignee filter excludes only [bot] logins and exact copilot. If that Copilot identity is the sole assignee, the app incorrectly attributes the PR to copilot-swe-agent/copilot instead of treating it as unassigned by a human. Filter assignees through isCopilotLogin (or fetch their GraphQL __typename) and cover this case in the regression test.

🧠 Review effort: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: aa9ef5ea-73f9-4188-9661-0d564de95bb8
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Release-targeted PRs cannot load the script, and closed/reopened events do not synchronize the label.

0 open findings

Previously missed (2)

In code that hasn't changed since last review

Medium severity Handle closed and reopened PR events for label management

.github/​workflows/​labeler-predict-pulls.yml:18

The script and regression test remove needs-assignee from a closed PR, but this workflow never runs for closed, so an unassigned Copilot PR keeps the label after closure. Subscribe to both closed and reopened; the latter is needed to restore the label when that PR becomes open again.

Medium severity Checkout default-branch SHA for pull_request_target script

.github/​workflows/​labeler-predict-pulls.yml:65

This checkout breaks the new job for pull requests targeting release/**. pull_request_target loads the workflow from the default branch, but github.event.pull_request.base.sha is the target release branch's commit; existing release branches do not contain this newly added script, so sparse checkout (or the subsequent require) will fail. Checkout the trusted default-branch event SHA instead so the script is available without executing PR content.

🧠 Review effort: Balanced

@radical

This comment has been minimized.

@radical

Copy link
Copy Markdown
Member

CI confidence report

Audited commit: 68499fba2a87e5c88d0e59a357d51457f1855d33

🔴 BLOCKED — fix before merge: the required needs-assignee label is absent, release-targeted runs cannot load the new module, and the privileged workflow lacks qualifying final-definition execution.

Required validation: 🔴 3 missing · 🟡 0 attention · 🟢 7 verified · ⚪ 0 not applicable

Independent review: completed

Material limits

  • 🔴 Repository label needs-assignee exists — Repository label needs-assignee is absent (REST lookup returns 404), so label addition cannot succeed. Expected: the label exists before addLabels is called. Observed: the PR description also says it must be created before enabling the workflow; the workflow calls addLabels.
  • 🔴 Release-targeted job loads trusted label module — The job checks out pull_request.base.sha, but supported release branches do not contain the newly added module. The workflow listens for release/** targets; the release/13.6 tree does not contain the newly added module. Expected: the trusted checkout contains .github/workflows/labeler-predict-pulls.js. Observed: that path is absent on the release branch, so require cannot load it (checkout ref).
  • 🔴 labeler-predict-pulls.yml final-definition execution — No qualifying run of the final labeler-predict-pulls.yml definition was found for the audited head. Expected: an authorized run of the final workflow definition proves the module loads and the assignment event produces the intended label effect. Observed: the only discovered run for this workflow used stale SHA a0392c87073edc067111a6c1b777aea2d8b7171b (run).

Reviewer actions

  • Required before merge: Satisfy Repository label needs-assignee exists by creating that label in microsoft/aspire.
    Done when: the repository label lookup returns the label and the workflow can add it to a test pull request.
  • Required before merge: Satisfy Release-targeted job loads trusted label module by making the label job's trusted checkout provide the module on every supported target branch, including release/**, without checking out pull-request code.
    Done when: a release-targeted run loads the module from a trusted ref and reaches the label API call.
  • Required before merge: Satisfy labeler-predict-pulls.yml final-definition execution by establishing authorized supported execution of the final workflow for assignment changes, or record qualifying non-author maintainer acceptance of the remaining unrun behavior.
    Done when: a final-definition run demonstrates the expected label effect, or a linked qualifying acceptance names the unsafe-to-run behavior and alternative checks; accepted unrun remains yellow.
    The job has pull-requests: write and changes repository labels; do not run it against a live PR without explicit owner authorization.

Validation coverage

  • 🔴 Workflow execution and runtime prerequisites — the three named workflow requirements above remain missing.
  • 🟢 CI security scanning — final-head CI ran zizmor 1.30.1 with online audits enabled and reported no new alerts; the paired local scan's online mode remains unknown and its coverage incomplete.
  • 🟢 Tests and static review — Infrastructure.Tests and Copilot extension validation passed; the final-head handwritten workflow actionlint scan passed; the targeted CI trust-boundary review and both added action-pin provenance checks passed.

🟢 Verified requirements and scanner receipts
  • Infrastructure.Tests behavior tests — the final-head PR CI run used the merge tree containing the audited commit; the Infrastructure test job completed with Test run summary: Passed!. The job's selector named tests/Infrastructure.Tests/Infrastructure.Tests.csproj. CI run.
  • Copilot extension validation and tests — node .github/extensions/validate-extensions.mjs completed and reported Validated 1 manifest(s), 25 module(s), imported 11 safe module(s), ran 11 test file(s). This includes the changed extension test file. Validation run.
  • Handwritten workflow actionlint scan — final-head CI used actionlint 1.7.12 and the lint job succeeded. The paired local actionlint command exited 1 on both trees: it reported an apparent new parser warning on untouched .github/workflows/tests.yml and a matching resolved warning on untouched .github/workflows/deployment-tests.yml, both for enumerate-tests metadata. This is an unrelated path shift, not a PR-introduced finding; the changed workflow had no diagnostics. CI run.
  • Paired online zizmor 1.30.1 coverage — final-head CI ran zizmor 1.30.1 with online-audits=true and reported no new alerts. The paired local scan exited 0 on base and head but did not establish online mode or complete changed-definition coverage, so its empty delta is not treated as blanket-clean. CI job.
  • Targeted CI trust-boundary review — reviewed pull_request_target, its write permission, checkout ref and sparse path, credential persistence, pinned action use, and the JavaScript API inputs. No additional injection or privilege-boundary defect was found; the release-branch path failure is reported above. Workflow.
  • actions/checkout v7.0.1 pin provenance and metadata — v7.0.1 resolves to the exact 40-character SHA in the workflow; the referenced action.yml exists. This is a first-party actions/* pin.
  • actions/github-script v9.0.0 pin provenance and metadata — annotated v9.0.0 resolves to the exact 40-character SHA in the workflow; the referenced action.yml exists and supports the configured script input. This is a first-party actions/* pin.
  • Paired scanner details — local zizmor 1.30.1 exited 0 on base and head, with no new/worsened findings and no blocking candidates or notes, but it reported no changed definitions and unknown network mode; this incomplete receipt is not treated as blanket-clean. Separately, final-head CI ran zizmor with online audits enabled and reported no new alerts. ShellCheck found no changed standalone shell inputs. The paired manual source review found no changed or added shell/PowerShell block in the PR diff, so no changed embedded-script input required execution; this applicability review does not upgrade the helper's incomplete scanner-coverage status. No PSScriptAnalyzer input applies.
Scope, method, and reconciliation
  • Scope: GitHub workflow/runtime behavior, the standalone label script, and Aspire Team App attribution. Pinned base: f2528c5248e8b3fa0d1ec6675cb00bb7a4222f9f.
  • Method: used the globally installed self-workflow skill at origin/main 6faab32ed101824dc25c40318e4c3fc90a8d8166; collected pinned PR facts and workflow-run candidates; reviewed the PR diff, source, discussion, final-head checks, release-branch source availability, label configuration, action tags and scanner receipts. No code, PR, label, or workflow state was changed; no remote run was started.
  • Finding reconciliation: the close/reopen suggestion is excluded from this report: the stated contract is assignment changes, and a closed-state helper test does not establish a closure-event requirement. The release-branch module failure and missing repository label remain supported by the current source/configuration checks. The final-head CI job confirms online zizmor 1.30.1 ran with online-audits=true and no new alerts, so that requirement is verified. The paired local scan's unknown online mode and incomplete changed-definition coverage remain disclosed as limitations; its empty delta is not treated as blanket-clean.
  • Local scanner status: the paired helper exited 1 because actionlint reported the apparent warning path shift described above. Per-tool status: actionlint completed with the unrelated warning and outstanding embedded-analysis coverage (base/head exit 1); ShellCheck had no standalone inputs and no ShellCheck command, with embedded-script coverage not established by this tool; local zizmor completed with unknown online mode (base/head exit 0). coverage_complete was false. Separately, final-head CI ran online zizmor and actionlint successfully.
  • Unchanged shell scope: the helper's conservative embedded-script warning remains documented; no inline shell/PowerShell source changed in the PR diff. No local report URL or artifact location is included.
Runs and links consulted (6)
  • Final-head CI — success; Infrastructure.Tests and handwritten workflow lint passed on the merge tree containing the audited head.
  • Copilot extension validation — success; 11 test files executed.
  • Final-head zizmor job — success; the log shows online-audits: true and no new alerts.
  • Older labeler workflow run — success at stale head a0392c87073edc067111a6c1b777aea2d8b7171b; does not verify the audited workflow definition.
  • PR description — says the label must be created manually before workflow enablement; no such repository label is currently present.
  • GitHub label lookup — 404 at audit time.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: aa9ef5ea-73f9-4188-9661-0d564de95bb8
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Regression coverage is missing for the workflow contract and bot-only assignee behavior.

1 open finding
Previously missed (1)

In code that hasn't changed since last review

Medium severity Test bot-only assignee handling for needs-assignee label

.github/​workflows/​labeler-predict-pulls.js:22

The tests cover no assignee and a User assignee, but not the Bot-only case that this human-assignee distinction is meant to support. A regression that treats any assignee as ownership would still pass while failing to add or retain needs-assignee; add a case with only a type: "Bot" assignee and assert the label remains present.

🧠 Review effort: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aa9ef5ea-73f9-4188-9661-0d564de95bb8
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Tests selector

1 / 98 PR test projects · 0 PR jobs, from 4 changed files.

Selected PR test projects (1 / 98)

Infrastructure.Tests

Selected PR jobs (0)

none


How these were chosen — grouped by what changed

📄 .github/workflows/labeler-predict-pulls.js (changed)
→ 1 directly: Infrastructure.Tests

📄 .github/workflows/labeler-predict-pulls.yml (changed)
→ 1 directly: Infrastructure.Tests

🧪 tests/Infrastructure.Tests/WorkflowScripts/LabelerPredictPullsWorkflowTests.cs (changed test)
→ 1 directly: Infrastructure.Tests

🧪 tests/Infrastructure.Tests/WorkflowScripts/labeler-predict-pulls.harness.js (changed test)
→ 1 directly: Infrastructure.Tests

Job reasons

none


Selection computed for commit d363dcc.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The lifecycle logic, trusted checkout, permissions, CI routing, identity handling, and focused regression coverage are consistent and complete.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

@radical Ankit Jain (radical) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[automated] Reviewed the changes since the last CI confidence report, through d363dccc098ab720dd29273d2ee736af6c0e1b57. No blocking code issues remain from that review.

The needs-assignee repository label now exists, and the checkout uses the trusted default-branch event SHA, addressing the release-targeted helper-loading issue. Current-head CI passed, including behavioral tests, workflow lint, extension validation, and security scanning.

I accept the remaining pre-merge runtime validation limitation: the new label-sync job requires pull_request_target, which loads the published default-branch workflow; manual dispatch skips this job. Its live behavior therefore remains unverified, rather than passed.

After merge, please inspect a subsequent qualifying Copilot PR event and its update-copilot-assignee-label job to confirm the helper loads and needs-assignee is added or removed as expected. Assignment and close/reopen events should also leave area-label prediction skipped. A green overall run with the label-sync job skipped would not establish that this works.

@ellahathaway
Ella Hathaway (ellahathaway) merged commit dbaaddc into main Oct 14, 2026
53 checks passed
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 17.0 milestone Oct 14, 2026
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

✅ No documentation update needed.

Step 5 branch taken: docs_optional → build_or_ci_only (overlapping with test_only for the test files).

Triggered signals: none (signal_count: 0, recommendation: "docs_optional").

Allowlist justification: All 6 changed files are internal CI/engineering automation, none under src/ or user-facing doc-relevant paths:

  • .github/extensions/aspire-team-app/github.mjs (modified) — internal GitHub App helper logic
  • .github/extensions/aspire-team-app/github.test.mjs (modified) — test file for the above
  • .github/workflows/labeler-predict-pulls.js (added) — new trusted workflow script
  • .github/workflows/labeler-predict-pulls.yml (modified) — workflow trigger/config
  • tests/Infrastructure.Tests/WorkflowScripts/LabelerPredictPullsWorkflowTests.cs (added) — test file
  • tests/Infrastructure.Tests/WorkflowScripts/labeler-predict-pulls.harness.js (added) — test harness

This PR adds a needs-assignee label to Copilot-authored PRs lacking a human assignee, purely as internal repository-maintenance automation (pull_request_target workflow with pull-requests: write). It does not change any public API, CLI, dashboard, hosting/client integration, package, or other content that microsoft/aspire.dev documents. No docs PR is warranted.

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

Labels

area-engineering-systems infrastructure helix infra engineering repo stuff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants