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
26 changes: 13 additions & 13 deletions .github/workflows/security-alert-burndown.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 41 additions & 1 deletion actions/setup/js/create_issue.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
// @ts-check
/// <reference types="@actions/github-script" />

/**
* Module-level storage for issues that need copilot assignment
* This is populated by the create_issue handler when GH_AW_ASSIGN_COPILOT is true
* and consumed by the handler manager to set the issues_to_assign_copilot output
* @type {Array<string>}
*/
let issuesToAssignCopilotGlobal = [];

/**
* Get the list of issues that need copilot assignment
* @returns {Array<string>} Array of "repo:number" strings
*/
function getIssuesToAssignCopilot() {
return issuesToAssignCopilotGlobal;
}

/**
* Reset the list of issues that need copilot assignment
* Used for testing
*/
function resetIssuesToAssignCopilot() {
issuesToAssignCopilotGlobal = [];
}

const { sanitizeLabelContent } = require("./sanitize_label_content.cjs");
const { generateFooter, generateWorkflowIdMarker } = require("./generate_footer.cjs");
const { getTrackerID } = require("./get_tracker_id.cjs");
Expand Down Expand Up @@ -174,6 +198,9 @@ async function main(config = {}) {
const groupEnabled = config.group === true || config.group === "true";
const closeOlderIssuesEnabled = config.close_older_issues === true || config.close_older_issues === "true";

// Check if copilot assignment is enabled
const assignCopilot = process.env.GH_AW_ASSIGN_COPILOT === "true";

core.info(`Default target repo: ${defaultTargetRepo}`);
if (allowedRepos.size > 0) {
core.info(`Allowed repos: ${Array.from(allowedRepos).join(", ")}`);
Expand Down Expand Up @@ -347,6 +374,13 @@ async function main(config = {}) {
.filter(assignee => assignee)
.filter((assignee, index, arr) => arr.indexOf(assignee) === index);

// Check if copilot is in the assignees list
const hasCopilot = assignees.includes("copilot");

// Filter out "copilot" from assignees - it will be assigned separately using GraphQL
// Copilot is not a valid GitHub user and must be assigned via the agent assignment API
assignees = assignees.filter(assignee => assignee !== "copilot");

let title = createIssueItem.title ? createIssueItem.title.trim() : "";

// Replace temporary ID references in the body using already-created issues
Expand Down Expand Up @@ -428,6 +462,12 @@ async function main(config = {}) {
temporaryIdMap.set(normalizeTemporaryId(temporaryId), { repo: qualifiedItemRepo, number: issue.number });
core.info(`Stored temporary ID mapping: ${temporaryId} -> ${qualifiedItemRepo}#${issue.number}`);

// Track issue for copilot assignment if needed
if (hasCopilot && assignCopilot) {
issuesToAssignCopilotGlobal.push(`${qualifiedItemRepo}:${issue.number}`);
core.info(`Queued issue ${qualifiedItemRepo}#${issue.number} for copilot assignment`);
}

// Close older issues if enabled
if (closeOlderIssuesEnabled) {
if (workflowId) {
Expand Down Expand Up @@ -591,4 +631,4 @@ async function main(config = {}) {
};
}

module.exports = { main, createParentIssueTemplate, searchForExistingParent, getSubIssueCount };
module.exports = { main, createParentIssueTemplate, searchForExistingParent, getSubIssueCount, getIssuesToAssignCopilot, resetIssuesToAssignCopilot };
16 changes: 16 additions & 0 deletions actions/setup/js/safe_output_handler_manager.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const { hasUnresolvedTemporaryIds, replaceTemporaryIdReferences, normalizeTempor
const { generateMissingInfoSections } = require("./missing_info_formatter.cjs");
const { setCollectedMissings } = require("./missing_messages_helper.cjs");
const { writeSafeOutputSummaries } = require("./safe_output_summary.cjs");
const { getIssuesToAssignCopilot } = require("./create_issue.cjs");

const DEFAULT_AGENTIC_CAMPAIGN_LABEL = "agentic-campaign";

Expand Down Expand Up @@ -793,6 +794,11 @@ async function main() {
try {
core.info("Safe Output Handler Manager starting...");

// Reset create_issue handler's global state to ensure clean state for this run
// This prevents stale data accumulation if the module is reused
const { resetIssuesToAssignCopilot } = require("./create_issue.cjs");
resetIssuesToAssignCopilot();

// Load configuration
const config = loadConfig();
core.debug(`Configuration: ${JSON.stringify(Object.keys(config))}`);
Expand Down Expand Up @@ -885,6 +891,16 @@ async function main() {
// Export processed count for consistency with project handler
core.setOutput("processed_count", successCount);

// Export issues that need copilot assignment (if any)
const issuesToAssignCopilot = getIssuesToAssignCopilot();
if (issuesToAssignCopilot.length > 0) {
const issuesToAssignStr = issuesToAssignCopilot.join(",");
core.setOutput("issues_to_assign_copilot", issuesToAssignStr);
core.info(`Exported ${issuesToAssignCopilot.length} issue(s) for copilot assignment: ${issuesToAssignStr}`);
} else {
core.setOutput("issues_to_assign_copilot", "");
}

core.info("Safe Output Handler Manager completed");
} catch (error) {
core.setFailed(`Handler manager failed: ${getErrorMessage(error)}`);
Expand Down
Loading