From 72a976c4c2ffc45a300d612d4096989ebe4db717 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 13:22:31 +0000 Subject: [PATCH 01/14] Initial plan From e136e17307fa33e8f2b551d6745ed2b79734d697 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 13:41:48 +0000 Subject: [PATCH 02/14] Fix safe-outputs handler step token precedence Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/compiler_safe_outputs_steps.go | 16 ++++------- ...safe_outputs_handler_manager_token_test.go | 28 +++++++++++++++---- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/pkg/workflow/compiler_safe_outputs_steps.go b/pkg/workflow/compiler_safe_outputs_steps.go index f714c56d3a4..d90e2ca3bd2 100644 --- a/pkg/workflow/compiler_safe_outputs_steps.go +++ b/pkg/workflow/compiler_safe_outputs_steps.go @@ -272,24 +272,18 @@ func (c *Compiler) buildHandlerManagerStep(data *WorkflowData) ([]string, error) } // With section for github-token - // Use the standard safe outputs token for all operations. - // If project operations are configured, prefer the project token for the github-script client. - // Rationale: update_project/create_project_status_update call the Projects v2 GraphQL API, which - // cannot be accessed with the default GITHUB_TOKEN. GH_AW_PROJECT_GITHUB_TOKEN is the required - // token for Projects v2 operations. + // Use the standard safe-outputs token for the shared github-script client. + // Project operations use GH_AW_PROJECT_GITHUB_TOKEN from env with dedicated handler logic. steps = append(steps, " with:\n") // Token precedence for the handler manager step: - // 1. Project token (if project operations are configured) - already set above - // 2. Safe-outputs level token (so.GitHubToken) - // 3. Magic secret fallback via getEffectiveSafeOutputGitHubToken() + // 1. Safe-outputs level token (so.GitHubToken) + // 2. Magic secret fallback via getEffectiveSafeOutputGitHubToken() // // Note: We do NOT fall back to per-output tokens (add-comment, create-issue, etc.) // because those are specific to their operations. The handler manager needs a // general-purpose token for the github-script client. configToken := "" - if projectToken != "" { - configToken = projectToken - } else if data.SafeOutputs != nil && data.SafeOutputs.GitHubToken != "" { + if data.SafeOutputs != nil && data.SafeOutputs.GitHubToken != "" { configToken = data.SafeOutputs.GitHubToken } c.addSafeOutputGitHubTokenForConfig(&steps, data, configToken) diff --git a/pkg/workflow/safe_outputs_handler_manager_token_test.go b/pkg/workflow/safe_outputs_handler_manager_token_test.go index c001ab7b4ab..8bfab091981 100644 --- a/pkg/workflow/safe_outputs_handler_manager_token_test.go +++ b/pkg/workflow/safe_outputs_handler_manager_token_test.go @@ -194,7 +194,23 @@ func TestHandlerManagerProjectGitHubTokenEnvVar(t *testing.T) { }, }, expectedEnvVarValue: "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.PROJECTS_PAT }}", - expectedWithToken: "github-token: ${{ secrets.PROJECTS_PAT }}", + expectedWithToken: "github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}", + shouldHaveToken: true, + }, + { + name: "update-project with custom github-token and safe-outputs github-token", + frontmatter: map[string]any{ + "name": "Test Workflow", + "safe-outputs": map[string]any{ + "github-token": "${{ secrets.SAFE_OUTPUTS_TOKEN }}", + "update-project": map[string]any{ + "github-token": "${{ secrets.PROJECTS_PAT }}", + "project": "https://github.com/orgs/myorg/projects/1", + }, + }, + }, + expectedEnvVarValue: "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.PROJECTS_PAT }}", + expectedWithToken: "github-token: ${{ secrets.SAFE_OUTPUTS_TOKEN }}", shouldHaveToken: true, }, { @@ -208,7 +224,7 @@ func TestHandlerManagerProjectGitHubTokenEnvVar(t *testing.T) { }, }, expectedEnvVarValue: "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}", - expectedWithToken: "github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}", + expectedWithToken: "github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}", shouldHaveToken: true, }, { @@ -238,7 +254,7 @@ func TestHandlerManagerProjectGitHubTokenEnvVar(t *testing.T) { }, }, expectedEnvVarValue: "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.STATUS_PAT }}", - expectedWithToken: "github-token: ${{ secrets.STATUS_PAT }}", + expectedWithToken: "github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}", shouldHaveToken: true, }, { @@ -252,7 +268,7 @@ func TestHandlerManagerProjectGitHubTokenEnvVar(t *testing.T) { }, }, expectedEnvVarValue: "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.CREATE_PAT }}", - expectedWithToken: "github-token: ${{ secrets.CREATE_PAT }}", + expectedWithToken: "github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}", shouldHaveToken: true, }, { @@ -274,7 +290,7 @@ func TestHandlerManagerProjectGitHubTokenEnvVar(t *testing.T) { }, }, expectedEnvVarValue: "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.UPDATE_PAT }}", - expectedWithToken: "github-token: ${{ secrets.UPDATE_PAT }}", + expectedWithToken: "github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}", shouldHaveToken: true, }, { @@ -312,7 +328,7 @@ func TestHandlerManagerProjectGitHubTokenEnvVar(t *testing.T) { "Expected environment variable %q to be set in handler manager step", tt.expectedEnvVarValue) - // Check that the github-script token matches the effective project token + // Check that the github-script token uses safe-outputs token precedence. assert.Contains(t, yamlStr, tt.expectedWithToken, "Expected github-script token %q to be set in handler manager step", tt.expectedWithToken) From 9ae4b9383b950f9ce2d5d22c8a583c6e0cdd0bfd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 13:48:25 +0000 Subject: [PATCH 03/14] chore: outline plan for safe-output token pollution tests Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/smoke-project.lock.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index dd2c2acb155..3dcba967766 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -2195,7 +2195,7 @@ jobs: GH_AW_PROJECT_URL: "https://github.com/orgs/github/projects/24068" GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} with: - github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); setupGlobals(core, github, context, exec, io, getOctokit); From 65dfd4e210e09221a1b13f16c47dd31d4f7fdf46 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 14:00:55 +0000 Subject: [PATCH 04/14] test: cover handler-manager token isolation across safe outputs Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- ...safe_outputs_handler_manager_token_test.go | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/pkg/workflow/safe_outputs_handler_manager_token_test.go b/pkg/workflow/safe_outputs_handler_manager_token_test.go index 8bfab091981..0eaa986d23a 100644 --- a/pkg/workflow/safe_outputs_handler_manager_token_test.go +++ b/pkg/workflow/safe_outputs_handler_manager_token_test.go @@ -3,6 +3,7 @@ package workflow import ( + "sort" "strings" "testing" @@ -340,3 +341,50 @@ func TestHandlerManagerProjectGitHubTokenEnvVar(t *testing.T) { }) } } + +// TestHandlerManagerGitHubTokenIsolationAcrossSafeOutputHandlers verifies that the shared +// github-script client token remains sourced from safe-outputs.github-token regardless of which +// safe-output handler is configured alongside project-specific token settings. +func TestHandlerManagerGitHubTokenIsolationAcrossSafeOutputHandlers(t *testing.T) { + handlerNames := make([]string, 0, len(handlerRegistry)) + for handlerName := range handlerRegistry { + handlerNames = append(handlerNames, handlerName) + } + sort.Strings(handlerNames) + + for _, handlerName := range handlerNames { + t.Run(handlerName, func(t *testing.T) { + safeOutputs := map[string]any{ + "github-token": "${{ secrets.SAFE_OUTPUTS_TOKEN }}", + "update-project": map[string]any{ + "github-token": "${{ secrets.PROJECTS_PAT }}", + "project": "https://github.com/orgs/myorg/projects/1", + }, + } + + safeOutputKey := strings.ReplaceAll(handlerName, "_", "-") + if safeOutputKey != "update-project" { + safeOutputs[safeOutputKey] = map[string]any{} + } + + frontmatter := map[string]any{ + "name": "Test Workflow", + "safe-outputs": safeOutputs, + } + + compiler := NewCompiler() + workflowData := &WorkflowData{ + Name: "test-workflow", + SafeOutputs: compiler.extractSafeOutputsConfig(frontmatter), + } + + steps, err := compiler.buildHandlerManagerStep(workflowData) + require.NoError(t, err) + + yamlStr := strings.Join(steps, "") + assert.Contains(t, yamlStr, "github-token: ${{ secrets.SAFE_OUTPUTS_TOKEN }}") + assert.NotContains(t, yamlStr, "github-token: ${{ secrets.PROJECTS_PAT }}") + assert.Contains(t, yamlStr, "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.PROJECTS_PAT }}") + }) + } +} From ea7118ff8c321f5dee259febc60302f2493cb1ba Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:18:30 +0000 Subject: [PATCH 05/14] fix: preserve project handler token isolation at runtime Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/handler_auth.cjs | 2 +- .../setup/js/safe_output_handler_manager.cjs | 25 ++++- .../js/safe_output_handler_manager.test.cjs | 91 +++++++++++++++++++ ...safe_outputs_handler_manager_token_test.go | 7 +- 4 files changed, 121 insertions(+), 4 deletions(-) diff --git a/actions/setup/js/handler_auth.cjs b/actions/setup/js/handler_auth.cjs index a6cfacdfa3b..f5135dc3b4e 100644 --- a/actions/setup/js/handler_auth.cjs +++ b/actions/setup/js/handler_auth.cjs @@ -14,7 +14,7 @@ * 2. global github — step-level token set in the github-script with.github-token * * The step-level token itself follows (as set by the Go compiler): - * project token > global safe-outputs.github-token > magic secrets + * global safe-outputs.github-token > magic secrets */ /** diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index 2520014ae46..3e4c82ef9f8 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -101,6 +101,9 @@ const STANDALONE_STEP_TYPES = new Set(["upload_asset", "noop"]); */ const CODE_PUSH_TYPES = new Set(["push_to_pull_request_branch", "create_pull_request"]); +/** @type {Set} Project-safe-output handlers that should default to GH_AW_PROJECT_GITHUB_TOKEN when no per-handler github-token is configured. */ +const PROJECT_HANDLER_TYPES = new Set(["create_project", "create_project_status_update", "update_project"]); + // Threat-detection warn-mode requirement IDs from safe-outputs specification: // - WTD2: Convertible outputs must be mapped to a reviewable type. // - WTD3: Non-reviewable outputs must be aborted. @@ -306,6 +309,10 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti // Call the factory function with config to get the message handler const handlerConfig = { ...(config[type] || {}) }; + if (PROJECT_HANDLER_TYPES.has(type) && !handlerConfig["github-token"] && process.env.GH_AW_PROJECT_GITHUB_TOKEN) { + handlerConfig["github-token"] = process.env.GH_AW_PROJECT_GITHUB_TOKEN; + } + // Pass top-level mentions policy through so handlers can preserve // the same allowed mention aliases used during collection. if (handlerConfig.mentions == null && config.mentions != null) { @@ -320,7 +327,8 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti handlerConfig._prReviewBufferRegistry = prReviewBufferRegistry; } - const messageHandler = await handlerModule.main(handlerConfig); + const handlerGithubClient = handlerConfig["github-token"] && typeof global.getOctokit === "function" ? global.getOctokit(handlerConfig["github-token"]) : null; + const messageHandler = await handlerModule.main(handlerConfig, handlerGithubClient); if (typeof messageHandler !== "function") { // This is a fatal error - the handler is misconfigured @@ -330,7 +338,20 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti throw error; } - messageHandlers.set(type, messageHandler); + const wrappedMessageHandler = + PROJECT_HANDLER_TYPES.has(type) && handlerGithubClient + ? async (...args) => { + const previousGithub = global.github; + global.github = handlerGithubClient; + try { + return await messageHandler(...args); + } finally { + global.github = previousGithub; + } + } + : messageHandler; + + messageHandlers.set(type, wrappedMessageHandler); core.info(`✓ Loaded and initialized handler for: ${type}`); } else { core.warning(`Handler module ${type} does not export a main function`); diff --git a/actions/setup/js/safe_output_handler_manager.test.cjs b/actions/setup/js/safe_output_handler_manager.test.cjs index a5c5260fe45..5dced16d632 100644 --- a/actions/setup/js/safe_output_handler_manager.test.cjs +++ b/actions/setup/js/safe_output_handler_manager.test.cjs @@ -291,6 +291,97 @@ describe("Safe Output Handler Manager", () => { createIssueMainSpy.mockRestore(); } }); + + it("injects GH_AW_PROJECT_GITHUB_TOKEN for project handlers when github-token is missing", async () => { + process.env.GH_AW_PROJECT_GITHUB_TOKEN = "projects-token"; + global.getOctokit = vi.fn().mockReturnValue({ client: "project-client" }); + + const updateProjectModule = require("./update_project.cjs"); + const updateProjectMainSpy = vi.spyOn(updateProjectModule, "main").mockImplementation(async () => async () => ({ success: true })); + + try { + const handlers = await loadHandlers({ + update_project: { project: "https://github.com/orgs/myorg/projects/1" }, + }); + + expect(handlers.has("update_project")).toBe(true); + expect(global.getOctokit).toHaveBeenCalledWith("projects-token"); + expect(updateProjectMainSpy).toHaveBeenCalledWith( + expect.objectContaining({ + project: "https://github.com/orgs/myorg/projects/1", + "github-token": "projects-token", + }), + expect.objectContaining({ client: "project-client" }) + ); + } finally { + updateProjectMainSpy.mockRestore(); + delete process.env.GH_AW_PROJECT_GITHUB_TOKEN; + delete global.getOctokit; + } + }); + + it("preserves explicit project handler github-token over GH_AW_PROJECT_GITHUB_TOKEN fallback", async () => { + process.env.GH_AW_PROJECT_GITHUB_TOKEN = "fallback-project-token"; + global.getOctokit = vi.fn().mockReturnValue({ client: "project-client" }); + + const updateProjectModule = require("./update_project.cjs"); + const updateProjectMainSpy = vi.spyOn(updateProjectModule, "main").mockImplementation(async () => async () => ({ success: true })); + + try { + await loadHandlers({ + update_project: { + project: "https://github.com/orgs/myorg/projects/1", + "github-token": "explicit-project-token", + }, + }); + + expect(global.getOctokit).toHaveBeenCalledWith("explicit-project-token"); + expect(updateProjectMainSpy).toHaveBeenCalledWith( + expect.objectContaining({ + "github-token": "explicit-project-token", + }), + expect.objectContaining({ client: "project-client" }) + ); + } finally { + updateProjectMainSpy.mockRestore(); + delete process.env.GH_AW_PROJECT_GITHUB_TOKEN; + delete global.getOctokit; + } + }); + + it("wraps project handlers so global.github is set to the project client during execution", async () => { + process.env.GH_AW_PROJECT_GITHUB_TOKEN = "projects-token"; + const projectClient = { client: "project-client" }; + global.getOctokit = vi.fn().mockReturnValue(projectClient); + + const previousGithub = { client: "shared-client" }; + global.github = previousGithub; + let seenGithub = null; + + const updateProjectModule = require("./update_project.cjs"); + const updateProjectMainSpy = vi.spyOn(updateProjectModule, "main").mockImplementation(async () => async () => { + seenGithub = global.github; + return { success: true }; + }); + + try { + const handlers = await loadHandlers({ + update_project: { project: "https://github.com/orgs/myorg/projects/1" }, + }); + const handler = handlers.get("update_project"); + expect(typeof handler).toBe("function"); + + await handler({ type: "update_project" }); + + expect(seenGithub).toBe(projectClient); + expect(global.github).toBe(previousGithub); + } finally { + updateProjectMainSpy.mockRestore(); + delete process.env.GH_AW_PROJECT_GITHUB_TOKEN; + delete global.getOctokit; + global.github = previousGithub; + } + }); }); describe("loadHandlers - path traversal sanitization", () => { diff --git a/pkg/workflow/safe_outputs_handler_manager_token_test.go b/pkg/workflow/safe_outputs_handler_manager_token_test.go index 0eaa986d23a..c65c4f9cab2 100644 --- a/pkg/workflow/safe_outputs_handler_manager_token_test.go +++ b/pkg/workflow/safe_outputs_handler_manager_token_test.go @@ -382,9 +382,14 @@ func TestHandlerManagerGitHubTokenIsolationAcrossSafeOutputHandlers(t *testing.T require.NoError(t, err) yamlStr := strings.Join(steps, "") + if !strings.Contains(yamlStr, handlerName) { + t.Skipf("handler %q not materialized from minimal config; skipping isolation assertions", handlerName) + } assert.Contains(t, yamlStr, "github-token: ${{ secrets.SAFE_OUTPUTS_TOKEN }}") assert.NotContains(t, yamlStr, "github-token: ${{ secrets.PROJECTS_PAT }}") - assert.Contains(t, yamlStr, "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.PROJECTS_PAT }}") + if handlerName == "update_project" { + assert.Contains(t, yamlStr, "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.PROJECTS_PAT }}") + } }) } } From bb6e74cf226b301dc694df19c129812449a4a5b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:24:00 +0000 Subject: [PATCH 06/14] test: clarify project token handler assertions and mocks Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/safe_output_handler_manager.cjs | 5 ++++- actions/setup/js/safe_output_handler_manager.test.cjs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index 3e4c82ef9f8..a252dd4c0ce 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -327,7 +327,10 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti handlerConfig._prReviewBufferRegistry = prReviewBufferRegistry; } - const handlerGithubClient = handlerConfig["github-token"] && typeof global.getOctokit === "function" ? global.getOctokit(handlerConfig["github-token"]) : null; + let handlerGithubClient = null; + if (handlerConfig["github-token"] && typeof global.getOctokit === "function") { + handlerGithubClient = global.getOctokit(handlerConfig["github-token"]); + } const messageHandler = await handlerModule.main(handlerConfig, handlerGithubClient); if (typeof messageHandler !== "function") { diff --git a/actions/setup/js/safe_output_handler_manager.test.cjs b/actions/setup/js/safe_output_handler_manager.test.cjs index 5dced16d632..b7c5e4a2ab4 100644 --- a/actions/setup/js/safe_output_handler_manager.test.cjs +++ b/actions/setup/js/safe_output_handler_manager.test.cjs @@ -360,6 +360,7 @@ describe("Safe Output Handler Manager", () => { const updateProjectModule = require("./update_project.cjs"); const updateProjectMainSpy = vi.spyOn(updateProjectModule, "main").mockImplementation(async () => async () => { + // outer function: handler factory at loadHandlers() time; inner function: message handler at processMessages() time seenGithub = global.github; return { success: true }; }); From 8866a063b53f07f4ac05f9556371e6028244ae62 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:29:27 +0000 Subject: [PATCH 07/14] fix: restore global github state in project handler wrapper Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../setup/js/safe_output_handler_manager.cjs | 7 ++++- .../js/safe_output_handler_manager.test.cjs | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index a252dd4c0ce..89820f1e272 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -344,12 +344,17 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti const wrappedMessageHandler = PROJECT_HANDLER_TYPES.has(type) && handlerGithubClient ? async (...args) => { + const hadGithub = Object.prototype.hasOwnProperty.call(global, "github"); const previousGithub = global.github; global.github = handlerGithubClient; try { return await messageHandler(...args); } finally { - global.github = previousGithub; + if (hadGithub) { + global.github = previousGithub; + } else { + delete global.github; + } } } : messageHandler; diff --git a/actions/setup/js/safe_output_handler_manager.test.cjs b/actions/setup/js/safe_output_handler_manager.test.cjs index b7c5e4a2ab4..d5df7b3e165 100644 --- a/actions/setup/js/safe_output_handler_manager.test.cjs +++ b/actions/setup/js/safe_output_handler_manager.test.cjs @@ -383,6 +383,33 @@ describe("Safe Output Handler Manager", () => { global.github = previousGithub; } }); + + it("restores global.github to absent state after wrapped project handler execution", async () => { + process.env.GH_AW_PROJECT_GITHUB_TOKEN = "projects-token"; + const projectClient = { client: "project-client" }; + global.getOctokit = vi.fn().mockReturnValue(projectClient); + delete global.github; + + const updateProjectModule = require("./update_project.cjs"); + const updateProjectMainSpy = vi.spyOn(updateProjectModule, "main").mockImplementation(async () => async () => ({ success: true })); + + try { + const handlers = await loadHandlers({ + update_project: { project: "https://github.com/orgs/myorg/projects/1" }, + }); + const handler = handlers.get("update_project"); + expect(typeof handler).toBe("function"); + + await handler({ type: "update_project" }); + + expect("github" in global).toBe(false); + } finally { + updateProjectMainSpy.mockRestore(); + delete process.env.GH_AW_PROJECT_GITHUB_TOKEN; + delete global.getOctokit; + delete global.github; + } + }); }); describe("loadHandlers - path traversal sanitization", () => { From 5af8ac4264818ab54e525111974b2488e407e6ff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:36:00 +0000 Subject: [PATCH 08/14] refactor: extract project github client rebinding helper Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../setup/js/safe_output_handler_manager.cjs | 49 ++++++++++++------- ...safe_outputs_handler_manager_token_test.go | 3 +- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index 89820f1e272..c8b57613331 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -286,6 +286,35 @@ function loadConfig() { /** @type {Set} Handler types that participate in the PR review buffer */ const PR_REVIEW_HANDLER_TYPES = new Set(["create_pull_request_review_comment", "submit_pull_request_review"]); +/** + * Wrap a handler so project-safe-output execution can temporarily bind global.github + * to the handler-specific authenticated client. + * + * @param {string} type - Safe-output handler type + * @param {Function} messageHandler - Loaded handler function + * @param {Object|null} handlerGithubClient - Optional per-handler GitHub client + * @returns {Function} Wrapped handler function + */ +function wrapWithClientRebinding(type, messageHandler, handlerGithubClient) { + if (!PROJECT_HANDLER_TYPES.has(type) || !handlerGithubClient) { + return messageHandler; + } + return async (...args) => { + const hadGithub = Object.prototype.hasOwnProperty.call(global, "github"); + const previousGithub = global.github; + global.github = handlerGithubClient; + try { + return await messageHandler(...args); + } finally { + if (hadGithub) { + global.github = previousGithub; + } else { + delete global.github; + } + } + }; +} + /** * Load and initialize handlers for enabled safe output types * Calls each handler's factory function (main) to get message processors @@ -341,25 +370,7 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti throw error; } - const wrappedMessageHandler = - PROJECT_HANDLER_TYPES.has(type) && handlerGithubClient - ? async (...args) => { - const hadGithub = Object.prototype.hasOwnProperty.call(global, "github"); - const previousGithub = global.github; - global.github = handlerGithubClient; - try { - return await messageHandler(...args); - } finally { - if (hadGithub) { - global.github = previousGithub; - } else { - delete global.github; - } - } - } - : messageHandler; - - messageHandlers.set(type, wrappedMessageHandler); + messageHandlers.set(type, wrapWithClientRebinding(type, messageHandler, handlerGithubClient)); core.info(`✓ Loaded and initialized handler for: ${type}`); } else { core.warning(`Handler module ${type} does not export a main function`); diff --git a/pkg/workflow/safe_outputs_handler_manager_token_test.go b/pkg/workflow/safe_outputs_handler_manager_token_test.go index c65c4f9cab2..76a3a05a0e7 100644 --- a/pkg/workflow/safe_outputs_handler_manager_token_test.go +++ b/pkg/workflow/safe_outputs_handler_manager_token_test.go @@ -382,7 +382,8 @@ func TestHandlerManagerGitHubTokenIsolationAcrossSafeOutputHandlers(t *testing.T require.NoError(t, err) yamlStr := strings.Join(steps, "") - if !strings.Contains(yamlStr, handlerName) { + handlerConfigKey := "\\\"" + handlerName + "\\\":" + if !strings.Contains(yamlStr, handlerConfigKey) { t.Skipf("handler %q not materialized from minimal config; skipping isolation assertions", handlerName) } assert.Contains(t, yamlStr, "github-token: ${{ secrets.SAFE_OUTPUTS_TOKEN }}") From 60abf429468c12c6483838c262c7113e36939f29 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:41:18 +0000 Subject: [PATCH 09/14] refactor: centralize project handler github-token config key Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/safe_output_handler_manager.cjs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index c8b57613331..f40d0efed55 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -29,6 +29,7 @@ const { checkRateLimitHeadroom } = require("./rate_limit_helpers.cjs"); const { redactSensitiveConfig } = require("./safe_outputs_config_redact.cjs"); const nodePath = require("path"); const fs = require("fs"); +const GITHUB_TOKEN_CONFIG_KEY = "github-token"; /** * Handler map configuration @@ -338,8 +339,8 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti // Call the factory function with config to get the message handler const handlerConfig = { ...(config[type] || {}) }; - if (PROJECT_HANDLER_TYPES.has(type) && !handlerConfig["github-token"] && process.env.GH_AW_PROJECT_GITHUB_TOKEN) { - handlerConfig["github-token"] = process.env.GH_AW_PROJECT_GITHUB_TOKEN; + if (PROJECT_HANDLER_TYPES.has(type) && !handlerConfig[GITHUB_TOKEN_CONFIG_KEY] && process.env.GH_AW_PROJECT_GITHUB_TOKEN) { + handlerConfig[GITHUB_TOKEN_CONFIG_KEY] = process.env.GH_AW_PROJECT_GITHUB_TOKEN; } // Pass top-level mentions policy through so handlers can preserve @@ -357,8 +358,8 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti } let handlerGithubClient = null; - if (handlerConfig["github-token"] && typeof global.getOctokit === "function") { - handlerGithubClient = global.getOctokit(handlerConfig["github-token"]); + if (handlerConfig[GITHUB_TOKEN_CONFIG_KEY] && typeof global.getOctokit === "function") { + handlerGithubClient = global.getOctokit(handlerConfig[GITHUB_TOKEN_CONFIG_KEY]); } const messageHandler = await handlerModule.main(handlerConfig, handlerGithubClient); From 0b13b43029ff4ef9042f191c9c424a76e65d0e82 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:06:07 +0000 Subject: [PATCH 10/14] test: tighten safe-output handler token isolation coverage Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- ...safe_outputs_handler_manager_token_test.go | 143 +++++++++++++++--- 1 file changed, 118 insertions(+), 25 deletions(-) diff --git a/pkg/workflow/safe_outputs_handler_manager_token_test.go b/pkg/workflow/safe_outputs_handler_manager_token_test.go index 76a3a05a0e7..a4cae47f012 100644 --- a/pkg/workflow/safe_outputs_handler_manager_token_test.go +++ b/pkg/workflow/safe_outputs_handler_manager_token_test.go @@ -3,6 +3,8 @@ package workflow import ( + "encoding/json" + "reflect" "sort" "strings" "testing" @@ -346,6 +348,15 @@ func TestHandlerManagerProjectGitHubTokenEnvVar(t *testing.T) { // github-script client token remains sourced from safe-outputs.github-token regardless of which // safe-output handler is configured alongside project-specific token settings. func TestHandlerManagerGitHubTokenIsolationAcrossSafeOutputHandlers(t *testing.T) { + const safeOutputsToken = "${{ secrets.SAFE_OUTPUTS_TOKEN }}" + const handlerToken = "${{ secrets.HANDLER_TOKEN }}" + + projectHandlers := map[string]bool{ + "update_project": true, + "create_project_status_update": true, + "create_project": true, + } + handlerNames := make([]string, 0, len(handlerRegistry)) for handlerName := range handlerRegistry { handlerNames = append(handlerNames, handlerName) @@ -354,43 +365,125 @@ func TestHandlerManagerGitHubTokenIsolationAcrossSafeOutputHandlers(t *testing.T for _, handlerName := range handlerNames { t.Run(handlerName, func(t *testing.T) { - safeOutputs := map[string]any{ - "github-token": "${{ secrets.SAFE_OUTPUTS_TOKEN }}", - "update-project": map[string]any{ - "github-token": "${{ secrets.PROJECTS_PAT }}", - "project": "https://github.com/orgs/myorg/projects/1", - }, - } - - safeOutputKey := strings.ReplaceAll(handlerName, "_", "-") - if safeOutputKey != "update-project" { - safeOutputs[safeOutputKey] = map[string]any{} - } - - frontmatter := map[string]any{ - "name": "Test Workflow", - "safe-outputs": safeOutputs, + safeOutputs := &SafeOutputsConfig{ + GitHubToken: safeOutputsToken, } + enableHandlerForIsolationTest(t, safeOutputs, handlerName, handlerToken) compiler := NewCompiler() workflowData := &WorkflowData{ Name: "test-workflow", - SafeOutputs: compiler.extractSafeOutputsConfig(frontmatter), + SafeOutputs: safeOutputs, } steps, err := compiler.buildHandlerManagerStep(workflowData) require.NoError(t, err) yamlStr := strings.Join(steps, "") - handlerConfigKey := "\\\"" + handlerName + "\\\":" - if !strings.Contains(yamlStr, handlerConfigKey) { - t.Skipf("handler %q not materialized from minimal config; skipping isolation assertions", handlerName) - } - assert.Contains(t, yamlStr, "github-token: ${{ secrets.SAFE_OUTPUTS_TOKEN }}") - assert.NotContains(t, yamlStr, "github-token: ${{ secrets.PROJECTS_PAT }}") - if handlerName == "update_project" { - assert.Contains(t, yamlStr, "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.PROJECTS_PAT }}") + handlerConfig := extractHandlerManagerConfigFromYAML(t, yamlStr) + _, ok := handlerConfig[handlerName] + assert.True(t, ok, "expected handler %q to be present in GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG", handlerName) + + assert.Contains(t, yamlStr, "github-token: "+safeOutputsToken) + assert.NotContains(t, yamlStr, "github-token: "+handlerToken) + if projectHandlers[handlerName] { + assert.Contains(t, yamlStr, "GH_AW_PROJECT_GITHUB_TOKEN: "+handlerToken) + } else { + assert.NotContains(t, yamlStr, "GH_AW_PROJECT_GITHUB_TOKEN:") } }) } } + +func enableHandlerForIsolationTest(t *testing.T, safeOutputs *SafeOutputsConfig, handlerName, token string) { + t.Helper() + + switch handlerName { + case "dispatch_repository": + safeOutputs.DispatchRepository = &DispatchRepositoryConfig{ + Tools: map[string]*DispatchRepositoryToolConfig{ + "default": { + Workflow: "safe-outputs-dispatch", + EventType: "safe-outputs-dispatch", + Repository: "github/gh-aw", + Max: strPtr("1"), + GitHubToken: token, + }, + }, + } + return + case "create_report_incomplete_issue": + safeOutputs.ReportIncomplete = &ReportIncompleteConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: strPtr("1"), + GitHubToken: token, + }, + } + return + } + + configValue := reflect.ValueOf(safeOutputs).Elem() + configType := configValue.Type() + + for i := range configType.NumField() { + field := configType.Field(i) + yamlTag := strings.Split(field.Tag.Get("yaml"), ",")[0] + if yamlTag == "" || yamlTag == "-" { + continue + } + if strings.ReplaceAll(yamlTag, "-", "_") != handlerName { + continue + } + + require.Equal(t, reflect.Pointer, field.Type.Kind(), "handler field %s must be a pointer type", field.Name) + handlerValue := reflect.New(field.Type.Elem()) + initializeHandlerConfigForIsolationTest(handlerValue.Elem(), token) + configValue.Field(i).Set(handlerValue) + return + } + + require.Failf(t, "missing handler field", "no SafeOutputsConfig field found for handler %q", handlerName) +} + +func initializeHandlerConfigForIsolationTest(handlerStruct reflect.Value, token string) { + baseField := handlerStruct.FieldByName("BaseSafeOutputConfig") + if baseField.IsValid() { + if maxField := baseField.FieldByName("Max"); maxField.IsValid() && maxField.CanSet() { + maxField.Set(reflect.ValueOf(strPtr("1"))) + } + if tokenField := baseField.FieldByName("GitHubToken"); tokenField.IsValid() && tokenField.CanSet() { + tokenField.SetString(token) + } + } + if tokenField := handlerStruct.FieldByName("GitHubToken"); tokenField.IsValid() && tokenField.CanSet() && tokenField.Kind() == reflect.String { + tokenField.SetString(token) + } + + // project URL is required for update-project and create-project-status-update + if projectField := handlerStruct.FieldByName("Project"); projectField.IsValid() && projectField.CanSet() && projectField.Kind() == reflect.String { + projectField.SetString("https://github.com/orgs/myorg/projects/1") + } +} + +func extractHandlerManagerConfigFromYAML(t *testing.T, yamlStr string) map[string]map[string]any { + t.Helper() + + const prefix = "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: " + for line := range strings.SplitSeq(yamlStr, "\n") { + trimmed := strings.TrimSpace(line) + if !strings.HasPrefix(trimmed, prefix) { + continue + } + + configJSON := strings.TrimPrefix(trimmed, prefix) + configJSON = strings.Trim(configJSON, "\"") + configJSON = strings.ReplaceAll(configJSON, "\\\"", "\"") + + var config map[string]map[string]any + require.NoError(t, json.Unmarshal([]byte(configJSON), &config), "handler config JSON should be valid") + return config + } + + require.Fail(t, "missing GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG in compiled YAML") + return nil +} From 454e9c1d7fd7024cd331bfb5ef1b87287e4f42c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:10:30 +0000 Subject: [PATCH 11/14] test: avoid vacuous handler iteration assertions Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/workflow/safe_outputs_handler_manager_token_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/workflow/safe_outputs_handler_manager_token_test.go b/pkg/workflow/safe_outputs_handler_manager_token_test.go index a4cae47f012..5348d83e1d2 100644 --- a/pkg/workflow/safe_outputs_handler_manager_token_test.go +++ b/pkg/workflow/safe_outputs_handler_manager_token_test.go @@ -425,7 +425,8 @@ func enableHandlerForIsolationTest(t *testing.T, safeOutputs *SafeOutputsConfig, configValue := reflect.ValueOf(safeOutputs).Elem() configType := configValue.Type() - for i := range configType.NumField() { + //nolint:intrange // explicit bounds loop keeps compatibility with reviewers/tools that don't accept range-over-int + for i := 0; i < configType.NumField(); i++ { field := configType.Field(i) yamlTag := strings.Split(field.Tag.Get("yaml"), ",")[0] if yamlTag == "" || yamlTag == "-" { From a653044a727fdfe2f5fea2a6597100c0614c40c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:20:52 +0000 Subject: [PATCH 12/14] chore: start CI failure triage Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/agentic-auto-upgrade.yml | 2 +- .github/workflows/avenger.lock.yml | 5 ++--- .github/workflows/hourly-ci-cleaner.lock.yml | 5 ++--- .github/workflows/release.lock.yml | 6 +++--- .github/workflows/skillet.lock.yml | 5 ++--- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/agentic-auto-upgrade.yml b/.github/workflows/agentic-auto-upgrade.yml index 7035101ee35..e169cea32b6 100644 --- a/.github/workflows/agentic-auto-upgrade.yml +++ b/.github/workflows/agentic-auto-upgrade.yml @@ -34,7 +34,7 @@ name: Agentic Auto-Upgrade on: schedule: - - cron: "21 3 * * 5" # Weekly (auto-upgrade) + - cron: "11 4 * * 6" # Weekly (auto-upgrade) workflow_dispatch: permissions: diff --git a/.github/workflows/avenger.lock.yml b/.github/workflows/avenger.lock.yml index c1462431878..759bba75c28 100644 --- a/.github/workflows/avenger.lock.yml +++ b/.github/workflows/avenger.lock.yml @@ -1,5 +1,5 @@ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"6807590fb97b42c0858f3b0e068f5f2b823e6d3a5a873b1a1652f5658361eb44","body_hash":"e5fd04fe008ba327d939d9aee395ffb802836e30fd1f3772ca36984bdd1478f4","strict":true,"agent_id":"claude","agent_model":"claude-haiku-4.5","engine_versions":{"claude":"2.1.210"}} -# gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} +# gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ @@ -44,7 +44,6 @@ # Custom actions used: # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 -# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1146,7 +1145,7 @@ jobs: GH_HOST="${GH_HOST#http://}" echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Check last CI workflow run status on main branch diff --git a/.github/workflows/hourly-ci-cleaner.lock.yml b/.github/workflows/hourly-ci-cleaner.lock.yml index ca0f005228e..430262a8018 100644 --- a/.github/workflows/hourly-ci-cleaner.lock.yml +++ b/.github/workflows/hourly-ci-cleaner.lock.yml @@ -1,5 +1,5 @@ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"8b86cc12904088cf1b7630e0faa28299f64081df184a028b6293cb4f8bfdd07d","body_hash":"8eb6f8fd1e8e3d63cfd268226d09333129d49634435ae9a3c88debb099521ed5","strict":true,"agent_id":"claude","engine_versions":{"claude":"2.1.210"}} -# gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} +# gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ @@ -45,7 +45,6 @@ # Custom actions used: # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 -# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1153,7 +1152,7 @@ jobs: GH_HOST="${GH_HOST#http://}" echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Check last CI workflow run status on main branch diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 5ffc07c471f..c3e4b45dede 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -1,5 +1,5 @@ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"2b85ad1e6c3e13e577935d3841133c8c2d72ba5ad9c46e4116d3d60d49ee875b","body_hash":"646353d7bb4e5523bc85349c2cce38188190095a303f83cc95961ff145a47043","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.70"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"anchore/sbom-action","sha":"e22c389904149dbc22b58101806040fa8d37a610","version":"v0.24.0"},{"repo":"docker/build-push-action","sha":"53b7df96c91f9c12dcc8a07bcb9ccacbed38856a","version":"v7.3.0"},{"repo":"docker/login-action","sha":"af1e73f918a031802d376d3c8bbc3fe56130a9b0","version":"v4.4.0"},{"repo":"docker/metadata-action","sha":"dc802804100637a589fabce1cb79ff13a1411302","version":"v6.2.0"},{"repo":"docker/setup-buildx-action","sha":"bb05f3f5519dd87d3ba754cc423b652a5edd6d2c","version":"v4.2.0"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"anchore/sbom-action","sha":"e22c389904149dbc22b58101806040fa8d37a610","version":"v0.24.0"},{"repo":"docker/build-push-action","sha":"53b7df96c91f9c12dcc8a07bcb9ccacbed38856a","version":"v7.3.0"},{"repo":"docker/login-action","sha":"af1e73f918a031802d376d3c8bbc3fe56130a9b0","version":"v4.4.0"},{"repo":"docker/metadata-action","sha":"dc802804100637a589fabce1cb79ff13a1411302","version":"v6.2.0"},{"repo":"docker/setup-buildx-action","sha":"bb05f3f5519dd87d3ba754cc423b652a5edd6d2c","version":"v4.2.0"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ @@ -47,7 +47,7 @@ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) -# - actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # b7ad1dad31e06c5925ef5d2fc7ad053ef454303e +# - actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 # - anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 # - docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 @@ -1944,7 +1944,7 @@ jobs: env: RELEASE_TAG: ${{ needs.config.outputs.release_tag }} - name: Setup Go - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # b7ad1dad31e06c5925ef5d2fc7ad053ef454303e + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: cache: false go-version-file: go.mod diff --git a/.github/workflows/skillet.lock.yml b/.github/workflows/skillet.lock.yml index 2c83c89a672..d718a6999b3 100644 --- a/.github/workflows/skillet.lock.yml +++ b/.github/workflows/skillet.lock.yml @@ -1,5 +1,5 @@ # gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"2b7791e73899163b45a0881db45f5747495a6a7dbd2dc4e17f3f31af4ecf6898","body_hash":"ff6f6b1fbf4788ce998b5ddca9ed8f907259189ec1db98a5cd9768e4e0ed2f50","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.70"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"3a2844b7e9c422d3c10d287c895573f7108da1b3"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"3a2844b7e9c422d3c10d287c895573f7108da1b3"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35","digest":"sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.35@sha256:2202f63e8650b2b8b0d38033b44a05387b2b71ad3e690c4d23a34786f5462aed"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35","digest":"sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.35@sha256:755b79d0dfda82bd6b43a208d68666721e504110c5d342a4eeb199802644ff04"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35","digest":"sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.35@sha256:fe83cd274636efa9de3f456e2b078fae137328b9bb6ee4986ae510acaef0cec5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35","digest":"sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.35@sha256:f69282ec7b1326ba53891c399cf5b10475c0d3ccf4e1519b33d234a5427b57d3"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.1","digest":"sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.1@sha256:ad2a979c2cd8b50098e84938ca9c9c1580eb8e91526f101a90adfba7859b2c32"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ @@ -45,7 +45,6 @@ # Custom actions used: # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 -# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 @@ -1728,7 +1727,7 @@ jobs: GH_AW_INFO_AWF_VERSION: "v0.27.35" GH_AW_INFO_ENGINE_ID: "copilot" - name: Checkout skills directory - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false sparse-checkout: | From e21b4d9b7d1ef8f0a7056a82586e63e7724ed692 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:33:26 +0000 Subject: [PATCH 13/14] fix cjs typecheck for handler manager global github binding Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../setup/js/safe_output_handler_manager.cjs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/actions/setup/js/safe_output_handler_manager.cjs b/actions/setup/js/safe_output_handler_manager.cjs index f40d0efed55..538cac42408 100644 --- a/actions/setup/js/safe_output_handler_manager.cjs +++ b/actions/setup/js/safe_output_handler_manager.cjs @@ -301,16 +301,18 @@ function wrapWithClientRebinding(type, messageHandler, handlerGithubClient) { return messageHandler; } return async (...args) => { - const hadGithub = Object.prototype.hasOwnProperty.call(global, "github"); - const previousGithub = global.github; - global.github = handlerGithubClient; + /** @type {any} */ + const globalState = global; + const hadGithub = Object.prototype.hasOwnProperty.call(globalState, "github"); + const previousGithub = globalState.github; + globalState.github = handlerGithubClient; try { return await messageHandler(...args); } finally { if (hadGithub) { - global.github = previousGithub; + globalState.github = previousGithub; } else { - delete global.github; + delete globalState.github; } } }; @@ -357,9 +359,12 @@ async function loadHandlers(config, prReviewBufferRegistry, resolvedAllowedMenti handlerConfig._prReviewBufferRegistry = prReviewBufferRegistry; } + /** @type {any|null} */ let handlerGithubClient = null; - if (handlerConfig[GITHUB_TOKEN_CONFIG_KEY] && typeof global.getOctokit === "function") { - handlerGithubClient = global.getOctokit(handlerConfig[GITHUB_TOKEN_CONFIG_KEY]); + /** @type {any} */ + const globalState = global; + if (handlerConfig[GITHUB_TOKEN_CONFIG_KEY] && typeof globalState.getOctokit === "function") { + handlerGithubClient = globalState.getOctokit(handlerConfig[GITHUB_TOKEN_CONFIG_KEY]); } const messageHandler = await handlerModule.main(handlerConfig, handlerGithubClient); From 6e445b0e05f364505b2d6c02d62948a6d00ac15b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 19:06:13 +0000 Subject: [PATCH 14/14] test: align mentions config spy expectations with handler client arg Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/safe_output_handler_manager.test.cjs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/actions/setup/js/safe_output_handler_manager.test.cjs b/actions/setup/js/safe_output_handler_manager.test.cjs index d5df7b3e165..8fd1750adf9 100644 --- a/actions/setup/js/safe_output_handler_manager.test.cjs +++ b/actions/setup/js/safe_output_handler_manager.test.cjs @@ -277,14 +277,16 @@ describe("Safe Output Handler Manager", () => { max: 1, mentions: mentionsConfig, allowedMentionAliases: ["copilot", "octocat"], - }) + }), + null ); expect(createIssueMainSpy).toHaveBeenCalledWith( expect.objectContaining({ max: 1, mentions: mentionsConfig, allowedMentionAliases: ["copilot", "octocat"], - }) + }), + null ); } finally { addCommentMainSpy.mockRestore();