fix: allow multiple agent assignments to same issue when pull_request_repo differs#25916
fix: allow multiple agent assignments to same issue when pull_request_repo differs#25916
Conversation
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b4681576-a2d6-406e-982c-95c92bc37bd7 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…pecified When assign_to_agent is called for an issue where the agent is already assigned, allow re-assignment if a pull_request_repo is specified. This enables multi-platform workflows where the same issue triggers Copilot sessions in different target repositories. Fixes #6587 Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b4681576-a2d6-406e-982c-95c92bc37bd7 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates the agent-assignment logic so a second Copilot session can be triggered on the same issue when targeting a different pull_request_repo, and adjusts the maintenance workflow output.
Changes:
- Adjusted the “already assigned” dedup guard in
assign_to_agent.cjsto allow re-assignment when a PR target repo is involved. - Added a test for re-assignment behavior when an item specifies a different
pull_request_repo. - Updated the maintenance workflow (runner label + removed Docker daemon startup step) and modified related generator comments.
Show a summary per file
| File | Description |
|---|---|
actions/setup/js/assign_to_agent.cjs |
Changes dedup logic for already-assigned agent to permit cross-repo PR targeting. |
actions/setup/js/assign_to_agent.test.cjs |
Adds coverage for re-assignment when an item specifies a different pull_request_repo. |
pkg/workflow/maintenance_workflow.go |
Updates documentation comments for generated workflow conditions (currently introduces incorrect smart-quote literals). |
.github/workflows/agentics-maintenance.yml |
Changes validate_workflows runner label and removes Docker daemon startup step. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
pkg/workflow/maintenance_workflow.go:757
- Same issue here: the comment uses a smart quote in
operation != ”, which is misleading and doesn’t match the actual condition built (BuildStringLiteral("")). Update the comment to the correct empty-string literal for clarity.
// buildRunOperationCondition creates the condition for the unified run_operation
// job that handles all dispatch operations except the ones with dedicated jobs.
// Condition: dispatch && operation != ” && operation != each excluded && !fork.
func buildRunOperationCondition(excludedOperations ...string) ConditionNode {
- Files reviewed: 4/4 changed files
- Comments generated: 4
actions/setup/js/assign_to_agent.cjs
Outdated
| // Skip if agent is already assigned and no explicit pull_request_repo is specified. | ||
| // When a different pull_request_repo is provided, allow re-assignment so Copilot | ||
| // can be triggered for a different target repository on the same issue. | ||
| if (currentAssignees.some(a => a.id === agentId) && !effectivePullRequestRepoId) { |
There was a problem hiding this comment.
The dedup guard is checking !effectivePullRequestRepoId, but effectivePullRequestRepoId is also set when a global pull-request-repo is configured (see initialization from pullRequestRepoId). That means if an agent is already assigned and a global PR repo is configured, this will no longer skip and will attempt to re-assign every time, which can unintentionally trigger duplicate Copilot sessions. Consider keying the skip condition off whether a per-item message.pull_request_repo override was provided (and/or whether it differs from the global repo), rather than whether the resolved repo ID is non-null.
| // Skip if agent is already assigned and no explicit pull_request_repo is specified. | |
| // When a different pull_request_repo is provided, allow re-assignment so Copilot | |
| // can be triggered for a different target repository on the same issue. | |
| if (currentAssignees.some(a => a.id === agentId) && !effectivePullRequestRepoId) { | |
| const hasPerItemPullRequestRepoOverride = !!message.pull_request_repo; | |
| // Skip if agent is already assigned and no explicit per-item pull_request_repo is specified. | |
| // When a different pull_request_repo is provided on the message, allow re-assignment | |
| // so Copilot can be triggered for a different target repository on the same issue. | |
| if (currentAssignees.some(a => a.id === agentId) && !hasPerItemPullRequestRepoOverride) { |
| it("should allow re-assignment when agent is already assigned but pull_request_repo differs", async () => { | ||
| process.env.GH_AW_AGENT_PULL_REQUEST_REPO = "test-owner/default-pr-repo"; | ||
| process.env.GH_AW_AGENT_ALLOWED_PULL_REQUEST_REPOS = "test-owner/other-platform-repo"; | ||
| setAgentOutput({ | ||
| items: [ | ||
| { | ||
| type: "assign_to_agent", | ||
| issue_number: 42, | ||
| agent: "copilot", |
There was a problem hiding this comment.
This new test covers the per-item pull_request_repo override case, but it doesn’t cover the regression risk introduced by the updated dedup guard when a global pull-request-repo is configured and no per-item override is present. Add a test asserting that when the agent is already assigned and pull_request_repo is not provided, the handler still logs the "already assigned" message and does not call the assignment mutation, even if GH_AW_AGENT_PULL_REQUEST_REPO is set.
| // buildNotForkAndScheduledOrOperation creates a condition for jobs that run on | ||
| // schedule (or empty operation) AND when a specific operation is selected. | ||
| // Condition: !fork && (not_dispatch || operation == '' || operation == op) | ||
| // Condition: !fork && (not_dispatch || operation == ” || operation == op) | ||
| func buildNotForkAndScheduledOrOperation(operation string) ConditionNode { |
There was a problem hiding this comment.
The condition in this comment is now documented as operation == ” (smart quote) which no longer represents an empty-string check and is likely a copy/paste/encoding mistake. Update it to use the correct empty-string literal (consistent with the surrounding code/other comments).
This issue also appears on line 754 of the same file.
| validate_workflows: | ||
| if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.operation == 'validate' && !github.event.repository.fork }} | ||
| runs-on: ubuntu-latest | ||
| runs-on: ubuntu-slim | ||
| permissions: | ||
| contents: read |
There was a problem hiding this comment.
This PR includes workflow changes (runner label change and removal of the Docker-daemon step) that aren’t mentioned in the PR title/description, which currently describes only the assign_to_agent dedup behavior. Either update the PR description to cover these workflow changes, or split them into a separate PR to keep the change set focused and easier to review.
🧪 Test Quality Sentinel ReportTest Quality Score: 80/100✅ Excellent test quality
Test Classification Details
Test Analysis✅
|
There was a problem hiding this comment.
✅ Test Quality Sentinel: 80/100. Test quality is acceptable — 0% of new tests are implementation tests (threshold: 30%). The new test directly verifies the behavioral contract of the fix with 5 assertions covering both the skip-prevention and the correct GraphQL mutation parameters.
|
@copilot review all comments. Revert agentic maintenance validation job |
…ce changes Address PR review feedback: - Use message.pull_request_repo (per-item override) instead of effectivePullRequestRepoId (which includes global config) for the already-assigned dedup guard - Add test for global pull-request-repo with already-assigned agent (no per-item override) to verify dedup still works - Revert unrelated agentics-maintenance.yml and maintenance_workflow.go changes Agent-Logs-Url: https://github.com/github/gh-aw/sessions/9202ff8f-8030-4a1e-835d-f6ed3e77b236 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Addressed in 001ba4e:
|
The already-assigned guard in
assign_to_agent.cjsunconditionally short-circuits when the agent is already an assignee, preventing a second Copilot session from being triggered against a differentpull_request_repo(e.g., iOS repo + Android repo on the same issue).Change: Only skip when no per-item
pull_request_repooverride is provided:This keys the dedup guard off
message.pull_request_repo(the per-item override) rather than the resolvedeffectivePullRequestRepoId, which would also be set when a globalpull-request-repois configured. This preserves no-op dedup behavior for plain re-assignments and global config, while allowing Copilot to be triggered for a second platform (differentpull_request_repo) on the same issue.assign_to_agent.cjs— AddedhasPerItemPullRequestRepoOverridecheck to the dedup guard so assignments with a per-item target repo proceedassign_to_agent.test.cjs— Added test case verifying re-assignment proceeds when agent is already assigned but a per-itempull_request_repois specified; added regression test verifying dedup still skips when only a globalGH_AW_AGENT_PULL_REQUEST_REPOis set with no per-item override