Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions actions/setup/js/assign_to_agent.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ async function main() {

// Process each agent assignment
const results = [];
for (let i = 0; i < itemsToProcess.length; i++) {
const item = itemsToProcess[i];
for (const [i, item] of itemsToProcess.entries()) {
const agentName = item.agent ?? defaultAgent;
// Model, custom agent, and custom instructions are only configurable via frontmatter defaults
// They are NOT available as per-item overrides in the tool call
Expand Down Expand Up @@ -478,12 +477,7 @@ async function main() {
let errorMessage = getErrorMessage(error);

// Check if this is a token authentication error
const isAuthError =
errorMessage.includes("Bad credentials") ||
errorMessage.includes("Not Authenticated") ||
errorMessage.includes("Resource not accessible") ||
errorMessage.includes("Insufficient permissions") ||
errorMessage.includes("requires authentication");
const isAuthError = ["Bad credentials", "Not Authenticated", "Resource not accessible", "Insufficient permissions", "requires authentication"].some(msg => errorMessage.includes(msg));

// If ignore-if-error is enabled and this is an auth error, log warning and skip
if (ignoreIfError && isAuthError) {
Expand Down
29 changes: 29 additions & 0 deletions actions/setup/js/assign_to_agent.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,35 @@ describe("assign_to_agent", () => {
expect(lastGraphQLCall[1].targetRepoId).toBe("item-pull-request-repo-id");
});

it("should reject per-item pull_request_repo not in allowed list", 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/allowed-pr-repo";
setAgentOutput({
items: [
{
type: "assign_to_agent",
issue_number: 42,
agent: "copilot",
pull_request_repo: "test-owner/not-allowed-repo",
},
],
errors: [],
});

// Mock global PR repo lookup
mockGithub.graphql.mockResolvedValueOnce({
repository: {
id: "default-pr-repo-id",
defaultBranchRef: { name: "main" },
},
});

await eval(`(async () => { ${assignToAgentScript}; await main(); })()`);

expect(mockCore.error).toHaveBeenCalledWith(expect.stringContaining("E004:"));
expect(mockCore.warning).toHaveBeenCalledWith(expect.stringContaining("Failed to assign 1 agent(s)"));
});

it("should allow pull-request-repo without it being in allowed-pull-request-repos", async () => {
// Set pull-request-repo but DO NOT set allowed-pull-request-repos
// This tests that pull-request-repo is automatically allowed (like target-repo behavior)
Expand Down