Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Feb 12, 2026

Problem

remove_labels.cjs and assign_to_user.cjs hardcoded context.repo in API calls, ignoring the target-repo configuration. This blocked cross-repository workflows that need to operate on issues/PRs in external repos (e.g., triage workflows in a side repo managing issues in the main repo).

Changes

Applied the same pattern from #15027 (add_labels.cjs, close_issue.cjs) to both handlers:

remove_labels.cjs

  • Import and use resolveTargetRepoConfig / resolveAndValidateRepo from repo_helpers.cjs
  • Replace ...context.repo with explicit repoParts.owner / repoParts.repo in removeLabel API calls
  • Add per-message repository validation with allowed_repos support

assign_to_user.cjs

  • Import and use resolveTargetRepoConfig / resolveAndValidateRepo from repo_helpers.cjs
  • Replace context.repo.owner / context.repo.repo with repoParts.owner / repoParts.repo in addAssignees API calls
  • Add per-message repository validation with allowed_repos support

Tests

  • Added 4 test cases per handler: target-repo config, cross-repo messages, unauthorized repo rejection, bare repo name qualification

Usage

safe-outputs:
  remove-labels:
    allowed: ["triage-needed"]
    target-repo: "microsoft/vscode"
    allowed_repos: ["microsoft/vscode"]
  assign-to-user:
    max: 1
    target-repo: "microsoft/vscode"
    allowed_repos: ["microsoft/vscode"]

The upstream plumbing (Go compiler, config generation, MCP schema) was already wired correctly - the handlers just weren't reading the config.

Original prompt

This section details on the original issue you should resolve

<issue_title>remove_labels and assign_to_user safe output handlers do not support target-repo for cross-repository operations</issue_title>
<issue_description>🤖: Bug report submitted by AI

Summary

Follow-up to #15027 — the same context.repo hardcoding bug that was fixed in add_labels.cjs and close_issue.cjs also exists in remove_labels.cjs and assign_to_user.cjs. Both handlers ignore the target-repo config and always operate against the workflow's own repository.

Affected Files

actions/setup/js/remove_labels.cjs

  • Lines 11-12: Only imports safe_output_validator.cjs and error_helpers.cjs — does NOT import repo_helpers.cjs
  • Line 124: Hardcoded ...context.repo in the removeLabel API call:
    await github.rest.issues.removeLabel({
      ...context.repo,
      issue_number: itemNumber,
      name: label,
    });

actions/setup/js/assign_to_user.cjs

  • Lines 8-9: Only imports safe_output_processor.cjs and error_helpers.cjs — does NOT import repo_helpers.cjs
  • Lines 104-105: Hardcoded context.repo.owner / context.repo.repo in the addAssignees API call:
    await github.rest.issues.addAssignees({
      owner: context.repo.owner,
      repo: context.repo.repo,
      issue_number: issueNumber,
      assignees: uniqueAssignees,
    });

Root Cause

When #15027 was fixed, add_labels.cjs and close_issue.cjs were updated to use resolveTargetRepoConfig / resolveAndValidateRepo from repo_helpers.cjs. The same fix was not applied to remove_labels.cjs and assign_to_user.cjs.

The Plumbing Already Works

Everything upstream of the handler JS is wired correctly:

  1. Go compiler structs: Both RemoveLabelsConfig and AssignToUserConfig embed SafeOutputTargetConfig (which provides TargetRepoSlug and AllowedRepos)
  2. Config generation (compiler_safe_outputs_config.go): The remove_labels builder calls AddIfNotEmpty("target-repo", c.TargetRepoSlug) and AddStringSlice("allowed_repos", c.AllowedRepos). The assign_to_user builder similarly extracts the config via addRepoParameterIfNeeded in safe_outputs_config_generation.go (line 894-898).
  3. Docs (.github/aw/github-agentic-workflows.md): Both remove-labels and assign-to-user document target-repo as a supported field.
  4. MCP tool schema: The compiler correctly adds the repo parameter to the safe-outputs MCP tool description when allowed-repos is configured.

The config IS passed correctly at runtime — it's just never read by the handlers.

Fix

Apply the exact same pattern from add_labels.cjs (the fix from #15027):

For each handler:

  1. Add the import:

    const { resolveTargetRepoConfig, resolveAndValidateRepo } = require("./repo_helpers.cjs");
  2. In the main() factory function, resolve the target repo from config:

    const { defaultTargetRepo, allowedRepos } = resolveTargetRepoConfig(config);
  3. In the message handler function, resolve and validate per-message:

    const repoResult = resolveAndValidateRepo(message, defaultTargetRepo, allowedRepos, "label"); // or "assignee"
    if (!repoResult.success) {
      core.warning(`Skipping: ${repoResult.error}`);
      return { success: false, error: repoResult.error };
    }
    const { repo: itemRepo, repoParts } = repoResult;
  4. Replace context.repo / ...context.repo with repoParts.owner / repoParts.repo in the API call.

Reference implementation: actions/setup/js/add_labels.cjs lines 13, 24, 57, 65, 127-128

Use Case

We're building a stale-issue re-triage workflow in a side repo (gh-aw-test) that will eventually run cross-repo from microsoft/vscode-engineering against microsoft/vscode. The workflow needs to:

Reproduction

  1. Create a workflow with target-repo set to an external repo:
    safe-outputs:
      remove-labels:
        allowed: ["triage-needed"]
        target-repo: "org/other-repo"
      assign-to-user:
        max: 1
        target-repo: "org/other-repo"
  2. Trigger the workflow and have the agent call remove_labels or assign_to_user on an issue in the external repo
  3. Both will 404 because they operate on context.repo instead of the configured target repo</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.


Changeset

  • Type: patch
  • Description: Ensure remove_labels and assign_to_user safe-output handlers honor target-repo and allowed_repos configs for cross-repository workflows.

Generated by Changeset Generator

…lers

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix output handlers to support target-repo for cross-repository operations Fix cross-repository support in remove_labels and assign_to_user handlers Feb 12, 2026
Copilot AI requested a review from pelikhan February 12, 2026 18:38
@pelikhan pelikhan marked this pull request as ready for review February 12, 2026 18:39
Copilot AI review requested due to automatic review settings February 12, 2026 18:39
@pelikhan pelikhan added the smoke label Feb 12, 2026
@github-actions
Copy link
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 12, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 12, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Contributor

🧪 Smoke Project is now testing project operations...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 12, 2026

Changeset Generator completed successfully!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes cross-repository behavior in the remove_labels and assign_to_user safe-output handlers by honoring target-repo and validating per-message repo overrides via the shared repo_helpers.cjs utilities, aligning them with the existing cross-repo pattern used by other handlers.

Changes:

  • Updated remove_labels.cjs and assign_to_user.cjs to resolve the effective repo via resolveTargetRepoConfig / resolveAndValidateRepo and to use repoParts.owner / repoParts.repo in GitHub API calls.
  • Added cross-repo test coverage for both handlers (target-repo, per-message repo, allowed repo rejection, bare repo qualification).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
actions/setup/js/remove_labels.cjs Uses repo resolution/validation helpers and calls issues.removeLabel against the resolved target repo.
actions/setup/js/assign_to_user.cjs Uses repo resolution/validation helpers and calls issues.addAssignees against the resolved target repo.
actions/setup/js/remove_labels.test.cjs Adds tests covering target-repo and allowed repo behaviors for remove_labels.
actions/setup/js/assign_to_user.test.cjs Adds tests covering target-repo and allowed repo behaviors for assign_to_user.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Contributor

Agent Container Tool Check ✅

All development tools are available in the agent container:

Tool Status Version
bash 5.2.21
sh available
git available
jq 1.7
yq 4.52.2
curl available
gh 2.86.0
node available
python3 available
go 1.24.13
java available
dotnet available

Result: 12/12 tools available ✅

All required development tools passed verification.

AI generated by Agent Container Smoke Test

@github-actions
Copy link
Contributor

Smoke Project completed successfully. All project operations validated.

@github-actions
Copy link
Contributor

PRs: #15211 "[docs] Unbloat CLI commands reference documentation", #15210 "Add sanitized title and body activation outputs"
GitHub MCP ✅
Serena MCP ❌ (MCP connection closed)
Playwright ✅
File write ✅
Bash cat ✅
Build gh-aw ✅
Overall: FAIL

AI generated by Smoke Codex

@github-actions
Copy link
Contributor

Smoke Test Results - ⚠️ PARTIAL PASS (8/9)

PRs tested: #15221, #15219

Test Result
GitHub MCP
Safe Inputs GH CLI
Serena MCP
Playwright
File Ops
Build
Discussion
Workflow Dispatch

Status: 8/9 tests passed (Serena MCP tool unavailable)

§21959564629

@pelikhan @Copilot

AI generated by Smoke Copilot

@github-actions github-actions bot removed the smoke label Feb 12, 2026
@github-actions
Copy link
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@pelikhan pelikhan merged commit e717c2d into main Feb 12, 2026
1 check passed
@pelikhan pelikhan deleted the copilot/fix-output-handlers-repo-support branch February 12, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

remove_labels and assign_to_user safe output handlers do not support target-repo for cross-repository operations

2 participants