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
1 change: 1 addition & 0 deletions .github/workflows/smoke-copilot-arm.lock.yml

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

1 change: 1 addition & 0 deletions .github/workflows/smoke-copilot.lock.yml

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

1 change: 1 addition & 0 deletions actions/setup/js/create_pr_review_comment.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ async function main(config = {}) {
return {
success: false,
error: "Not in pull request context",
skipped: true,
};
}

Expand Down
2 changes: 2 additions & 0 deletions actions/setup/js/create_pr_review_comment.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ describe("create_pr_review_comment.cjs", () => {

expect(result.success).toBe(false);
expect(result.error).toContain("Not in pull request context");
expect(result.skipped).toBe(true);
expect(buffer.getBufferedCount()).toBe(0);
});

Expand Down Expand Up @@ -409,6 +410,7 @@ describe("create_pr_review_comment.cjs", () => {

expect(result.success).toBe(false);
expect(result.error).toContain("Not in pull request context");
expect(result.skipped).toBe(true);
expect(buffer.getBufferedCount()).toBe(0);
});

Expand Down
1 change: 1 addition & 0 deletions actions/setup/js/reply_to_pr_review_comment.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ async function main(config = {}) {
return {
success: false,
error: "Cannot reply to review comments outside of a pull request context",
skipped: true,
};
}
targetPRNumber = triggeringPRNumber;
Expand Down
1 change: 1 addition & 0 deletions actions/setup/js/reply_to_pr_review_comment.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ describe("reply_to_pr_review_comment", () => {

expect(result.success).toBe(false);
expect(result.error).toContain("pull request context");
expect(result.skipped).toBe(true);
});

it("should work when triggered from issue_comment on a PR", async () => {
Expand Down
6 changes: 3 additions & 3 deletions pkg/workflow/action_pins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,9 @@ func TestApplyActionPinToStep(t *testing.T) {
func TestGetActionPinsSorting(t *testing.T) {
pins := getActionPins()

// Verify we got all the pins (38 as of March 2026)
if len(pins) != 38 {
t.Errorf("getActionPins() returned %d pins, expected 38", len(pins))
// Verify we got all the pins (39 as of March 2026)
if len(pins) != 39 {
t.Errorf("getActionPins() returned %d pins, expected 39", len(pins))
}

// Verify they are sorted by version (descending) then by repository name (ascending)
Expand Down
25 changes: 23 additions & 2 deletions pkg/workflow/notify_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,23 @@ func (c *Compiler) buildConclusionJob(data *WorkflowData, mainJobName string, sa
return job, nil
}

// systemSafeOutputJobNames contains job names that are built-in system jobs and should not be
// treated as custom safe output job types in the GH_AW_SAFE_OUTPUT_JOBS mapping.
// The safe output handler manager uses this mapping to determine which message types are
// handled by custom job steps (and therefore should be silently skipped rather than flagged
// as "no handler loaded").
var systemSafeOutputJobNames = map[string]bool{
"safe_outputs": true, // consolidated safe outputs job
"upload_assets": true, // upload assets job
}

// buildSafeOutputJobsEnvVars creates environment variables for safe output job URLs
// Returns both a JSON mapping and the actual environment variable declarations
// Returns both a JSON mapping and the actual environment variable declarations.
// The mapping includes:
// - Built-in jobs with known URL outputs (e.g., create_issue → issue_url)
// - Custom safe-output jobs (from safe-outputs.jobs) with an empty URL key, so the handler
// manager knows those message types are handled by a dedicated job step and should be
// skipped gracefully rather than reported as "No handler loaded".
func buildSafeOutputJobsEnvVars(jobNames []string) (string, []string) {
// Map job names to their expected URL output keys
jobOutputMapping := make(map[string]string)
Expand Down Expand Up @@ -462,7 +477,13 @@ func buildSafeOutputJobsEnvVars(jobNames []string) (string, []string) {
case "push_to_pull_request_branch":
urlKey = "commit_url"
default:
// Skip jobs that don't have URL outputs
if systemSafeOutputJobNames[jobName] {
// Skip known system jobs — they are not custom safe output types
continue
}
// Custom safe-output job: include in the mapping with an empty URL key so the
// handler manager can silently skip messages of this type.
jobOutputMapping[jobName] = ""
continue
}

Expand Down
19 changes: 16 additions & 3 deletions pkg/workflow/notify_comment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -608,14 +608,27 @@ func TestBuildSafeOutputJobsEnvVars(t *testing.T) {
checkJSONKeys: []string{"push_to_pull_request_branch"},
},
{
name: "skips jobs without URL outputs",
jobNames: []string{"create_issue", "detection", "some_custom_job"},
name: "includes custom jobs and skips system jobs",
jobNames: []string{"create_issue", "safe_outputs", "some_custom_job"},
expectJSON: true,
expectEnvVars: 1,
checkEnvVars: []string{
"GH_AW_OUTPUT_CREATE_ISSUE_ISSUE_URL: ${{ needs.create_issue.outputs.issue_url }}",
},
checkJSONKeys: []string{"create_issue"},
checkJSONKeys: []string{"create_issue", "some_custom_job"},
},
{
name: "custom-only jobs produce JSON without URL env vars",
jobNames: []string{"safe_outputs", "send_slack_message"},
expectJSON: true,
expectEnvVars: 0,
checkJSONKeys: []string{"send_slack_message"},
},
{
name: "system jobs are excluded from JSON",
jobNames: []string{"safe_outputs", "upload_assets"},
expectJSON: false,
expectEnvVars: 0,
},
{
name: "handles empty job list",
Expand Down