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
4 changes: 2 additions & 2 deletions actions/setup/js/add_comment.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const { replaceTemporaryIdReferences, loadTemporaryIdMapFromResolved, resolveRep
const { getTrackerID } = require("./get_tracker_id.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
const { parseBoolTemplatable } = require("./templatable.cjs");
const { resolveTarget } = require("./safe_output_helpers.cjs");
const { resolveTarget, isStagedMode } = require("./safe_output_helpers.cjs");
const { resolveTargetRepoConfig, resolveAndValidateRepo } = require("./repo_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { getMissingInfoSections } = require("./missing_messages_helper.cjs");
Expand Down Expand Up @@ -312,7 +312,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

// Check if append-only-comments is enabled in messages config
const messagesConfig = getMessages();
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/add_labels.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const { getErrorMessage } = require("./error_helpers.cjs");
const { resolveTargetRepoConfig, resolveAndValidateRepo } = require("./repo_helpers.cjs");
const { tryEnforceArrayLimit } = require("./limit_enforcement_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { resolveRepoIssueTarget, loadTemporaryIdMapFromResolved } = require("./temporary_id.cjs");
const { MAX_LABELS } = require("./constants.cjs");
Expand All @@ -31,7 +32,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Add labels configuration: max=${maxCount}`);
if (allowedLabels.length > 0) {
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/add_reviewer.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { processItems } = require("./safe_output_processor.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
const { getPullRequestNumber } = require("./pr_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { COPILOT_REVIEWER_BOT } = require("./constants.cjs");

Expand All @@ -24,7 +25,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Add reviewer configuration: max=${maxCount}`);
if (allowedReviewers.length > 0) {
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/assign_milestone.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

const { getErrorMessage } = require("./error_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { loadTemporaryIdMapFromResolved, resolveRepoIssueTarget } = require("./temporary_id.cjs");

Expand All @@ -25,7 +26,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Assign milestone configuration: max=${maxCount}`);
if (allowedMilestones.length > 0) {
Expand Down
4 changes: 2 additions & 2 deletions actions/setup/js/assign_to_user.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
const { processItems } = require("./safe_output_processor.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
const { resolveTargetRepoConfig, resolveAndValidateRepo } = require("./repo_helpers.cjs");
const { resolveIssueNumber, extractAssignees } = require("./safe_output_helpers.cjs");
const { resolveIssueNumber, extractAssignees, isStagedMode } = require("./safe_output_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { parseBoolTemplatable } = require("./templatable.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
Expand All @@ -31,7 +31,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Assign to user configuration: max=${maxCount}, unassign_first=${unassignFirst}`);
if (allowedAssignees.length > 0) {
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/autofix_code_scanning_alert.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

const { getErrorMessage } = require("./error_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");

/**
* @typedef {import('./types/handler-factory').HandlerFactoryFunction} HandlerFactoryFunction
Expand All @@ -19,7 +20,7 @@ const HANDLER_TYPE = "autofix_code_scanning_alert";
async function main(config = {}) {
// Extract configuration
const maxCount = config.max || 10;
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Add code scanning autofix configuration: max=${maxCount}`);
if (isStaged) logStagedPreviewInfo("no changes will be written");
Expand Down
14 changes: 14 additions & 0 deletions actions/setup/js/call_workflow.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
const HANDLER_TYPE = "call_workflow";

const { getErrorMessage } = require("./error_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");

/**
* Main handler factory for call_workflow.
Expand All @@ -31,6 +33,7 @@ async function main(config = {}) {

// Track how many items we've processed for max limit
let processedCount = 0;
const isStaged = isStagedMode(config);

/**
* Message handler function that processes a single call_workflow message.
Expand Down Expand Up @@ -85,6 +88,17 @@ async function main(config = {}) {
const inputs = message.inputs && typeof message.inputs === "object" ? message.inputs : {};
const payloadJson = JSON.stringify(inputs);

// If in staged mode, preview the workflow call without executing it
if (isStaged) {
logStagedPreviewInfo(`Would call workflow: ${workflowName} with payload: ${payloadJson}`);
return {
success: true,
staged: true,
workflow_name: workflowName,
payload: payloadJson,
};
}

// Set the step outputs that the conditional `uses:` jobs check
core.setOutput("call_workflow_name", workflowName);
core.setOutput("call_workflow_payload", payloadJson);
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/close_discussion.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
const { getErrorMessage } = require("./error_helpers.cjs");
const { sanitizeContent } = require("./sanitize_content.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { ERR_NOT_FOUND } = require("./error_codes.cjs");

Expand Down Expand Up @@ -163,7 +164,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Close discussion configuration: max=${maxCount}`);
if (requiredLabels.length > 0) {
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/close_entity_helpers.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { getRepositoryUrl } = require("./get_repository_url.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
const { sanitizeContent } = require("./sanitize_content.cjs");
const { buildWorkflowRunUrl } = require("./workflow_metadata_helpers.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");

/**
* @typedef {'issue' | 'pull_request'} EntityType
Expand Down Expand Up @@ -212,7 +213,7 @@ function escapeMarkdownTitle(title) {
*/
async function processCloseEntityItems(config, callbacks, handlerConfig = {}) {
// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(handlerConfig);

const result = loadAgentOutput();
if (!result.success) {
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/close_issue.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { getErrorMessage } = require("./error_helpers.cjs");
const { resolveTargetRepoConfig, resolveAndValidateRepo } = require("./repo_helpers.cjs");
const { sanitizeContent } = require("./sanitize_content.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { ERR_NOT_FOUND } = require("./error_codes.cjs");

Expand Down Expand Up @@ -91,7 +92,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Close issue configuration: max=${maxCount}, state_reason=${configStateReason}`);
if (requiredLabels.length > 0) {
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/close_pull_request.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const { getTrackerID } = require("./get_tracker_id.cjs");
const { generateFooterWithMessages } = require("./messages_footer.cjs");
const { sanitizeContent } = require("./sanitize_content.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { ERR_NOT_FOUND } = require("./error_codes.cjs");
const { buildWorkflowRunUrl } = require("./workflow_metadata_helpers.cjs");
Expand Down Expand Up @@ -90,7 +91,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode (either globally or per-handler config)
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true" || config.staged === true;
const isStaged = isStagedMode(config);

core.info(`Close pull request configuration: max=${maxCount}`);
if (requiredLabels.length > 0) {
Expand Down
14 changes: 14 additions & 0 deletions actions/setup/js/create_code_scanning_alert.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/

const { getErrorMessage } = require("./error_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const fs = require("fs");
const path = require("path");

Expand All @@ -29,6 +31,7 @@ async function main(config = {}) {

// Track how many items we've processed for max limit
let processedCount = 0;
const isStaged = isStagedMode(config);

// Collect valid findings across all messages
const validFindings = [];
Expand Down Expand Up @@ -235,6 +238,17 @@ async function main(config = {}) {

core.info(`Added security finding ${validFindings.length}: ${finding.severity} in ${finding.file}:${finding.line}`);

// If in staged mode, preview the finding without writing the SARIF file
if (isStaged) {
logStagedPreviewInfo(`Would create code scanning alert: ${finding.severity} in ${finding.file}:${finding.line} - ${finding.message}`);
return {
success: true,
staged: true,
finding: finding,
findingsCount: validFindings.length,
};
}
Comment on lines +241 to +250
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

The staged-mode branch is new, but the existing test suite for this handler doesn’t include assertions for staged mode. Adding a test that sets config.staged = true (and/or GH_AW_SAFE_OUTPUTS_STAGED=true) and verifies no SARIF file is written while returning { staged: true } would help lock in the intended behavior.

Copilot uses AI. Check for mistakes.

// Generate/update SARIF file after each finding
try {
generateSarifFile();
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/create_discussion.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const { generateWorkflowIdMarker, generateWorkflowCallIdMarker, generateCloseKey
const { sanitizeLabelContent } = require("./sanitize_label_content.cjs");
const { tryEnforceArrayLimit } = require("./limit_enforcement_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { closeOlderDiscussions: closeOlderDiscussionsFunc } = require("./close_older_discussions.cjs");
const { parseBoolTemplatable } = require("./templatable.cjs");
const { buildWorkflowRunUrl } = require("./workflow_metadata_helpers.cjs");
Expand Down Expand Up @@ -318,7 +319,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

// Parse labels from config
const labelsConfig = config.labels || [];
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/create_issue.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const { closeOlderIssues } = require("./close_older_issues.cjs");
const { parseBoolTemplatable } = require("./templatable.cjs");
const { tryEnforceArrayLimit } = require("./limit_enforcement_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { buildWorkflowRunUrl } = require("./workflow_metadata_helpers.cjs");
const { MAX_LABELS, MAX_ASSIGNEES } = require("./constants.cjs");

Expand Down Expand Up @@ -218,7 +219,7 @@ async function main(config = {}) {
const assignCopilot = process.env.GH_AW_ASSIGN_COPILOT === "true";

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Default target repo: ${defaultTargetRepo}`);
if (allowedRepos.size > 0) {
Expand Down
5 changes: 5 additions & 0 deletions actions/setup/js/create_pr_review_comment.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ async function main(config = {}) {
core.info(`Allowed repos: ${Array.from(allowedRepos).join(", ")}`);
}

// Propagate per-handler staged flag to the shared PR review buffer
if (config.staged === true) {
buffer.setStaged(true);
}

// Track how many items we've processed for max limit
let processedCount = 0;

Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/create_project.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { loadAgentOutput } = require("./load_agent_output.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
const { normalizeTemporaryId, isTemporaryId, generateTemporaryId, getOrGenerateTemporaryId } = require("./temporary_id.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { ERR_CONFIG, ERR_NOT_FOUND, ERR_VALIDATION } = require("./error_codes.cjs");

/**
Expand Down Expand Up @@ -298,7 +299,7 @@ async function main(config = {}, githubClient = null) {
const configuredViews = Array.isArray(config.views) ? config.views : [];

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

// Use the provided github client, or fall back to the global github object
// The global github object is available when running via github-script action
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/create_project_status_update.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { loadAgentOutput } = require("./load_agent_output.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
const { sanitizeContent } = require("./sanitize_content.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { isTemporaryId, normalizeTemporaryId } = require("./temporary_id.cjs");
const { ERR_CONFIG, ERR_NOT_FOUND, ERR_PARSE, ERR_VALIDATION } = require("./error_codes.cjs");

Expand Down Expand Up @@ -288,7 +289,7 @@ async function main(config = {}, githubClient = null) {
const maxCount = config.max || 10;

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

// Use the provided github client, or fall back to the global github object
// @ts-ignore - global.github is set by setupGlobals() from github-script context
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/create_pull_request.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const { buildWorkflowRunUrl } = require("./workflow_metadata_helpers.cjs");
const { checkFileProtection } = require("./manifest_file_helpers.cjs");
const { renderTemplateFromFile } = require("./messages_core.cjs");
const { COPILOT_REVIEWER_BOT, FAQ_CREATE_PR_PERMISSIONS_URL } = require("./constants.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");

/**
* @typedef {import('./types/handler-factory').HandlerFactoryFunction} HandlerFactoryFunction
Expand Down Expand Up @@ -160,7 +161,7 @@ async function main(config = {}) {
const triggeringIssueNumber = typeof context !== "undefined" && context.payload?.issue?.number && !context.payload?.issue?.pull_request ? context.payload.issue.number : undefined;

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Base branch: ${configBaseBranch || "(dynamic - resolved per target repo)"}`);
core.info(`Default target repo: ${defaultTargetRepo}`);
Expand Down
14 changes: 14 additions & 0 deletions actions/setup/js/dispatch_workflow.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const HANDLER_TYPE = "dispatch_workflow";
const { getErrorMessage } = require("./error_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { resolveTargetRepoConfig, parseRepoSlug, validateTargetRepo } = require("./repo_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");

/**
* Main handler factory for dispatch_workflow
Expand Down Expand Up @@ -73,6 +75,7 @@ async function main(config = {}) {
// Track how many items we've processed for max limit
let processedCount = 0;
let lastDispatchTime = 0;
const isStaged = isStagedMode(config);

// Helper function to get the default branch of the dispatch target repository
const getDefaultBranchRef = async () => {
Expand Down Expand Up @@ -197,6 +200,17 @@ async function main(config = {}) {
const workflowFile = `${workflowName}${extension}`;
core.info(`Dispatching workflow: ${workflowFile}`);

// If in staged mode, preview the dispatch without executing it
if (isStaged) {
logStagedPreviewInfo(`Would dispatch workflow: ${workflowFile} in ${resolvedRepoSlug} with ref: ${ref}`);
return {
success: true,
staged: true,
workflow_name: workflowName,
inputs: inputs,
};
}
Comment on lines 200 to +212
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

Staged-mode behavior was added here, but there doesn’t appear to be test coverage asserting that config.staged === true (and/or the global env var) triggers the preview path and avoids dispatching. Adding a unit test for the staged branch would help prevent regressions (e.g., ensure it returns { staged: true } and does not call the GitHub API).

Copilot uses AI. Check for mistakes.

// Dispatch the workflow using the resolved file.
// Request return_run_details for newer GitHub API support; fall back without it
// for older GitHub Enterprise Server deployments that don't support the parameter.
Expand Down
3 changes: 2 additions & 1 deletion actions/setup/js/hide_comment.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

const { getErrorMessage } = require("./error_helpers.cjs");
const { logStagedPreviewInfo } = require("./staged_preview.cjs");
const { isStagedMode } = require("./safe_output_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");

/**
Expand Down Expand Up @@ -52,7 +53,7 @@ async function main(config = {}) {
const githubClient = await createAuthenticatedGitHubClient(config);

// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
const isStaged = isStagedMode(config);

core.info(`Hide comment configuration: max=${maxCount}`);
if (allowedReasons.length > 0) {
Expand Down
Loading
Loading