From abc2ba0d82d4c9e115c328b1da2cb7b95ace1f0c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 17:43:58 +0000 Subject: [PATCH 01/12] Initial plan From 631dad098f664e3d43bf9d39b5de2ab2d1dbd219 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 18:30:26 +0000 Subject: [PATCH 02/12] fix: add ensureSafeDirectoryTrust to bridge path to fix dubious ownership Extract ensureSafeDirectoryTrust from safe_outputs_handlers.cjs to git_helpers.cjs so it is available to the bridge (Process Safe Outputs step) as well as the MCP server container. The bridge runs outside the Docker container as a potentially different user/HOME, so the in-container `git config --global safe.directory` never reaches it. Using GIT_CONFIG_* env vars in the bridge process directly ensures git trusts the checkout regardless of HOME or uid. - Extract ensureSafeDirectoryTrust to git_helpers.cjs (uses core.debug, no server param), export it - Update safe_outputs_handlers.cjs to import from git_helpers.cjs and remove local definition; update 3 call sites to drop server param - Call ensureSafeDirectoryTrust in push_to_pull_request_branch.cjs: - In main() factory with GITHUB_WORKSPACE (covers all messages) - Per-message for cross-repo repoCwd subdirectory checkouts - Fix bundle apply error message to include actual error text - Add 8 new unit tests for ensureSafeDirectoryTrust Closes #46028 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/git_helpers.cjs | 37 ++++++ actions/setup/js/git_helpers.test.cjs | 108 ++++++++++++++++++ .../setup/js/push_to_pull_request_branch.cjs | 17 ++- actions/setup/js/safe_outputs_handlers.cjs | 41 +------ 4 files changed, 164 insertions(+), 39 deletions(-) diff --git a/actions/setup/js/git_helpers.cjs b/actions/setup/js/git_helpers.cjs index 66f711d2977..0b95833b74b 100644 --- a/actions/setup/js/git_helpers.cjs +++ b/actions/setup/js/git_helpers.cjs @@ -37,6 +37,42 @@ function getGitAuthEnv(token) { }; } +/** + * Ensure the given directory is trusted for git in the current process context. + * Injects safe.directory via GIT_CONFIG_COUNT/KEY/VALUE env vars so that all + * subsequent git commands in this process inherit the trust without writing to + * ~/.gitconfig (no persistent global git config side effects). + * + * This is specifically needed for the "bridge" path (the Process Safe Outputs step + * running outside the Docker container) where HOME or the uid may differ from the + * in-container user that originally configured safe.directory in ~/.gitconfig. + * + * GIT_CONFIG_COUNT/KEY/VALUE is supported since git 2.31. + * + * @param {string} gitCwd - The directory to trust (e.g. GITHUB_WORKSPACE or a repo checkout path) + * @returns {void} + */ +function ensureSafeDirectoryTrust(gitCwd) { + if (!gitCwd) return; + + // Check if gitCwd is already present in the injected env-var config to avoid + // duplicate entries when the handler is called more than once in the same process. + // The `|| 0` guard converts NaN (from a malformed pre-existing GIT_CONFIG_COUNT) to 0, + // preventing GIT_CONFIG_KEY_NaN/VALUE_NaN entries that would corrupt the env-var config chain. + const existingCount = parseInt(process.env.GIT_CONFIG_COUNT || "0", 10) || 0; + for (let i = 0; i < existingCount; i++) { + if (process.env[`GIT_CONFIG_KEY_${i}`] === "safe.directory" && process.env[`GIT_CONFIG_VALUE_${i}`] === gitCwd) { + return; + } + } + + const idx = existingCount; + process.env.GIT_CONFIG_COUNT = String(existingCount + 1); + process.env[`GIT_CONFIG_KEY_${idx}`] = "safe.directory"; + process.env[`GIT_CONFIG_VALUE_${idx}`] = gitCwd; + core.debug(`Configured git safe.directory for bridge context: ${gitCwd}`); +} + /** * Safely execute git command using spawnSync with args array to prevent shell injection. * @@ -603,6 +639,7 @@ async function linearizeRangeAsCommit(baseRef, commitMessage, execApi, opts = {} } module.exports = { + ensureSafeDirectoryTrust, execGitSync, backfillCommitObjects, ensureFullHistoryForBundle, diff --git a/actions/setup/js/git_helpers.test.cjs b/actions/setup/js/git_helpers.test.cjs index 6f4035901a1..dd22861c8f5 100644 --- a/actions/setup/js/git_helpers.test.cjs +++ b/actions/setup/js/git_helpers.test.cjs @@ -282,6 +282,114 @@ describe("git_helpers.cjs", () => { }); }); + describe("ensureSafeDirectoryTrust", () => { + let originalEnv; + + beforeEach(() => { + originalEnv = { ...process.env }; + // Clean up GIT_CONFIG_* vars injected by a previous test + for (const key of Object.keys(process.env)) { + if (key.startsWith("GIT_CONFIG_")) { + delete process.env[key]; + } + } + }); + + afterEach(() => { + // Restore to original, removing any vars added during the test + for (const key of Object.keys(process.env)) { + if (!(key in originalEnv)) { + delete process.env[key]; + } + } + Object.assign(process.env, originalEnv); + }); + + it("should export ensureSafeDirectoryTrust function", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + expect(typeof ensureSafeDirectoryTrust).toBe("function"); + }); + + it("should set GIT_CONFIG_* env vars for the given directory", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + + ensureSafeDirectoryTrust("/workspace/repo"); + + expect(process.env.GIT_CONFIG_COUNT).toBe("1"); + expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); + expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo"); + }); + + it("should not add a duplicate entry when called twice with the same directory", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + + ensureSafeDirectoryTrust("/workspace/repo"); + ensureSafeDirectoryTrust("/workspace/repo"); + + expect(process.env.GIT_CONFIG_COUNT).toBe("1"); + }); + + it("should append a new entry when called with a different directory", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + + ensureSafeDirectoryTrust("/workspace/repo-a"); + ensureSafeDirectoryTrust("/workspace/repo-b"); + + expect(process.env.GIT_CONFIG_COUNT).toBe("2"); + expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); + expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo-a"); + expect(process.env.GIT_CONFIG_KEY_1).toBe("safe.directory"); + expect(process.env.GIT_CONFIG_VALUE_1).toBe("/workspace/repo-b"); + }); + + it("should be a no-op when called with an empty string", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + + ensureSafeDirectoryTrust(""); + + expect(process.env.GIT_CONFIG_COUNT).toBeUndefined(); + }); + + it("should be a no-op when called with undefined/falsy", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + + ensureSafeDirectoryTrust(undefined); + + expect(process.env.GIT_CONFIG_COUNT).toBeUndefined(); + }); + + it("should preserve existing GIT_CONFIG_* entries set by getGitAuthEnv", async () => { + const { ensureSafeDirectoryTrust, getGitAuthEnv } = await import("./git_helpers.cjs"); + + // Simulate what getGitAuthEnv returns being already applied via env + const authEnv = getGitAuthEnv("test-token"); + Object.assign(process.env, authEnv); + + ensureSafeDirectoryTrust("/workspace/repo"); + + // The count should be incremented by 1 (from 1 to 2) + expect(parseInt(process.env.GIT_CONFIG_COUNT, 10)).toBe(2); + // Existing auth entry preserved + expect(process.env.GIT_CONFIG_KEY_0).toBe(authEnv.GIT_CONFIG_KEY_0); + expect(process.env.GIT_CONFIG_VALUE_0).toBe(authEnv.GIT_CONFIG_VALUE_0); + // New safe.directory entry appended + expect(process.env.GIT_CONFIG_KEY_1).toBe("safe.directory"); + expect(process.env.GIT_CONFIG_VALUE_1).toBe("/workspace/repo"); + }); + + it("should handle a malformed GIT_CONFIG_COUNT gracefully", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + + process.env.GIT_CONFIG_COUNT = "not-a-number"; + + ensureSafeDirectoryTrust("/workspace/repo"); + + expect(process.env.GIT_CONFIG_COUNT).toBe("1"); + expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); + expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo"); + }); + }); + describe("ensureFullHistoryForBundle", () => { it("should unshallow the repository when the repository is shallow", async () => { const { ensureFullHistoryForBundle } = await import("./git_helpers.cjs"); diff --git a/actions/setup/js/push_to_pull_request_branch.cjs b/actions/setup/js/push_to_pull_request_branch.cjs index 2dee8698930..2bbe325f29d 100644 --- a/actions/setup/js/push_to_pull_request_branch.cjs +++ b/actions/setup/js/push_to_pull_request_branch.cjs @@ -18,7 +18,7 @@ const { checkFileProtection, checkFileProtectionPostApply } = require("./manifes const { buildWorkflowRunUrl } = require("./workflow_metadata_helpers.cjs"); const { renderTemplateFromFile, buildProtectedFileList, getPromptPath } = require("./messages_core.cjs"); const { overridePersistedExtraheader, restorePersistedExtraheader } = require("./git_auth_helpers.cjs"); -const { ensureFullHistoryForBundle, extractBundlePrerequisiteCommits, isShallowOrSparseCheckout, linearizeRangeAsCommit } = require("./git_helpers.cjs"); +const { ensureFullHistoryForBundle, extractBundlePrerequisiteCommits, isShallowOrSparseCheckout, linearizeRangeAsCommit, ensureSafeDirectoryTrust } = require("./git_helpers.cjs"); const { normalizeCommitSHA } = require("./commit_sha_helpers.cjs"); const { findRepoCheckout } = require("./find_repo_checkout.cjs"); const { getThreatDetectedMarker } = require("./threat_detection_warning.cjs"); @@ -326,6 +326,13 @@ async function main(config = {}) { const { defaultTargetRepo, allowedRepos } = resolveTargetRepoConfig(config); const githubClient = await createAuthenticatedGitHubClient(config); + // Ensure the workspace is trusted in the bridge process (Process Safe Outputs step). + // The bridge runs outside the Docker container as a potentially different user/HOME, + // so the in-container `git config --global safe.directory` may not be visible here. + // Using GIT_CONFIG_* env vars avoids relying on ~/.gitconfig and covers cases where + // the conditional "Configure Git credentials" step was skipped or HOME differs. + ensureSafeDirectoryTrust(process.env.GITHUB_WORKSPACE || process.cwd()); + // Git network operations authenticate using the credentials actions/checkout // persisted into .git/config for the safe_outputs job (persist-credentials: true, // using the resolved push token). We intentionally do NOT inject an additional @@ -667,6 +674,12 @@ async function main(config = {}) { // Base options for all git exec calls - includes cwd when running in a subdirectory checkout const baseGitOpts = repoCwd ? { cwd: repoCwd } : {}; + + // For cross-repo checkouts, also trust the specific subdirectory. The factory-level call + // covers GITHUB_WORKSPACE; this per-message call covers subdirectory checkout paths. + if (repoCwd) { + ensureSafeDirectoryTrust(repoCwd); + } let pullRequest; try { const response = await githubClient.rest.pulls.get({ @@ -1106,7 +1119,7 @@ async function main(config = {}) { } catch { // Ignore } - return { success: false, error: "Failed to apply bundle" }; + return { success: false, error: `Failed to apply bundle: ${getErrorMessage(bundleError)}` }; } } else { // Patch transport (non-default): git am --3way diff --git a/actions/setup/js/safe_outputs_handlers.cjs b/actions/setup/js/safe_outputs_handlers.cjs index aa0e06e7e1b..b107fc0e449 100644 --- a/actions/setup/js/safe_outputs_handlers.cjs +++ b/actions/setup/js/safe_outputs_handlers.cjs @@ -13,7 +13,7 @@ const { getBaseBranch } = require("./get_base_branch.cjs"); const { lookupCheckout } = require("./checkout_manifest.cjs"); const { generateGitPatch } = require("./generate_git_patch.cjs"); const { generateGitBundle } = require("./generate_git_bundle.cjs"); -const { hasMergeCommitsInRange, execGitSync } = require("./git_helpers.cjs"); +const { hasMergeCommitsInRange, execGitSync, ensureSafeDirectoryTrust } = require("./git_helpers.cjs"); const { enforceCommentLimits } = require("./comment_limit_helpers.cjs"); const { getErrorMessage } = require("./error_helpers.cjs"); const { ERR_CONFIG, ERR_SYSTEM, ERR_VALIDATION } = require("./error_codes.cjs"); @@ -200,39 +200,6 @@ function resolvePatchWorkspacePath(workspacePath) { return { success: true, absolutePath: resolved }; } -/** - * Ensure the current git checkout path is trusted in this process context. - * Injects safe.directory via GIT_CONFIG_COUNT/KEY/VALUE env vars so that all - * subsequent git commands in this process inherit the trust without writing to - * ~/.gitconfig (no persistent global git config side effects). - * - * GIT_CONFIG_COUNT/KEY/VALUE is supported since git 2.31. - * - * @param {string} gitCwd - * @param {{ debug: (message: string) => void }} server - * @returns {void} - */ -function ensureSafeDirectoryTrust(gitCwd, server) { - if (!gitCwd) return; - - // Check if gitCwd is already present in the injected env-var config to avoid - // duplicate entries when the handler is called more than once in the same process. - // The `|| 0` guard converts NaN (from a malformed pre-existing GIT_CONFIG_COUNT) to 0, - // preventing GIT_CONFIG_KEY_NaN/VALUE_NaN entries that would corrupt the env-var config chain. - const existingCount = parseInt(process.env.GIT_CONFIG_COUNT || "0", 10) || 0; - for (let i = 0; i < existingCount; i++) { - if (process.env[`GIT_CONFIG_KEY_${i}`] === "safe.directory" && process.env[`GIT_CONFIG_VALUE_${i}`] === gitCwd) { - return; - } - } - - const idx = existingCount; - process.env.GIT_CONFIG_COUNT = String(existingCount + 1); - process.env[`GIT_CONFIG_KEY_${idx}`] = "safe.directory"; - process.env[`GIT_CONFIG_VALUE_${idx}`] = gitCwd; - server.debug(`Configured git safe.directory for bridge context: ${gitCwd}`); -} - /** * Create handlers for safe output tools * @param {Object} server - The MCP server instance for logging @@ -244,7 +211,7 @@ function createHandlers(server, appendSafeOutput, config = {}) { // Ensure the workspace is trusted for the lifetime of this server process. // This covers all current and future handlers automatically; per-handler calls // additionally cover per-request checkout paths that differ from GITHUB_WORKSPACE. - ensureSafeDirectoryTrust(process.env.GITHUB_WORKSPACE || process.cwd(), server); + ensureSafeDirectoryTrust(process.env.GITHUB_WORKSPACE || process.cwd()); const TOKEN_THRESHOLD = 16000; @@ -802,7 +769,7 @@ function createHandlers(server, appendSafeOutput, config = {}) { // This prevents TOCTOU races where the agent flips the ref between patch and bundle // generation, causing the two to represent different commit sets. const gitCwd = repoCwd || process.env.GITHUB_WORKSPACE || process.cwd(); - ensureSafeDirectoryTrust(gitCwd, server); + ensureSafeDirectoryTrust(gitCwd); let pinnedSha; try { pinnedSha = execGitSync(["rev-parse", "--verify", `refs/heads/${entry.branch}^{commit}`], { cwd: gitCwd }) @@ -1238,7 +1205,7 @@ function createHandlers(server, appendSafeOutput, config = {}) { // This prevents TOCTOU races where the agent flips the ref between patch and bundle // generation, causing the two to represent different commit sets. const pushGitCwd = repoCwd || process.env.GITHUB_WORKSPACE || process.cwd(); - ensureSafeDirectoryTrust(pushGitCwd, server); + ensureSafeDirectoryTrust(pushGitCwd); let pushPinnedSha; try { pushPinnedSha = execGitSync(["rev-parse", "--verify", `refs/heads/${entry.branch}^{commit}`], { cwd: pushGitCwd }) From c0efbf66bf44fe4bf1ecd1e1a887e6f78fb6bbca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 21:33:23 +0000 Subject: [PATCH 03/12] Fix safe directory env count parsing Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/git_helpers.cjs | 10 ++++++---- actions/setup/js/git_helpers.test.cjs | 13 ++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/actions/setup/js/git_helpers.cjs b/actions/setup/js/git_helpers.cjs index 0b95833b74b..3adfdcf67c5 100644 --- a/actions/setup/js/git_helpers.cjs +++ b/actions/setup/js/git_helpers.cjs @@ -57,9 +57,11 @@ function ensureSafeDirectoryTrust(gitCwd) { // Check if gitCwd is already present in the injected env-var config to avoid // duplicate entries when the handler is called more than once in the same process. - // The `|| 0` guard converts NaN (from a malformed pre-existing GIT_CONFIG_COUNT) to 0, - // preventing GIT_CONFIG_KEY_NaN/VALUE_NaN entries that would corrupt the env-var config chain. - const existingCount = parseInt(process.env.GIT_CONFIG_COUNT || "0", 10) || 0; + // Malformed pre-existing GIT_CONFIG_COUNT values (NaN, negative, fractional, + // or unsafe integers) fall back to 0 to avoid corrupting the env-var config chain. + const rawCount = process.env.GIT_CONFIG_COUNT || "0"; + const parsedCount = Number(rawCount); + const existingCount = Number.isSafeInteger(parsedCount) && parsedCount >= 0 ? parsedCount : 0; for (let i = 0; i < existingCount; i++) { if (process.env[`GIT_CONFIG_KEY_${i}`] === "safe.directory" && process.env[`GIT_CONFIG_VALUE_${i}`] === gitCwd) { return; @@ -70,7 +72,7 @@ function ensureSafeDirectoryTrust(gitCwd) { process.env.GIT_CONFIG_COUNT = String(existingCount + 1); process.env[`GIT_CONFIG_KEY_${idx}`] = "safe.directory"; process.env[`GIT_CONFIG_VALUE_${idx}`] = gitCwd; - core.debug(`Configured git safe.directory for bridge context: ${gitCwd}`); + globalThis.core?.debug?.(`Configured git safe.directory for bridge context: ${gitCwd}`); } /** diff --git a/actions/setup/js/git_helpers.test.cjs b/actions/setup/js/git_helpers.test.cjs index dd22861c8f5..2c608994185 100644 --- a/actions/setup/js/git_helpers.test.cjs +++ b/actions/setup/js/git_helpers.test.cjs @@ -380,7 +380,7 @@ describe("git_helpers.cjs", () => { it("should handle a malformed GIT_CONFIG_COUNT gracefully", async () => { const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); - process.env.GIT_CONFIG_COUNT = "not-a-number"; + process.env.GIT_CONFIG_COUNT = "-1"; ensureSafeDirectoryTrust("/workspace/repo"); @@ -388,6 +388,17 @@ describe("git_helpers.cjs", () => { expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo"); }); + + it("should not require a shimmed core global", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + + global.core = undefined; + + expect(() => ensureSafeDirectoryTrust("/workspace/repo")).not.toThrow(); + expect(process.env.GIT_CONFIG_COUNT).toBe("1"); + expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); + expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo"); + }); }); describe("ensureFullHistoryForBundle", () => { From 6077c7beca6ed126e4c9d05de9d3c35dc2339dec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Jul 2026 21:34:03 +0000 Subject: [PATCH 04/12] Expand safe directory trust tests Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/git_helpers.test.cjs | 33 +++++++++++++++++++-------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/actions/setup/js/git_helpers.test.cjs b/actions/setup/js/git_helpers.test.cjs index 2c608994185..26a74646292 100644 --- a/actions/setup/js/git_helpers.test.cjs +++ b/actions/setup/js/git_helpers.test.cjs @@ -377,27 +377,40 @@ describe("git_helpers.cjs", () => { expect(process.env.GIT_CONFIG_VALUE_1).toBe("/workspace/repo"); }); - it("should handle a malformed GIT_CONFIG_COUNT gracefully", async () => { + it("should handle malformed GIT_CONFIG_COUNT values gracefully", async () => { const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); - process.env.GIT_CONFIG_COUNT = "-1"; + for (const malformedCount of ["not-a-number", "-1", "1.5", String(Number.MAX_SAFE_INTEGER + 1)]) { + for (const key of Object.keys(process.env)) { + if (key.startsWith("GIT_CONFIG_")) { + delete process.env[key]; + } + } - ensureSafeDirectoryTrust("/workspace/repo"); + process.env.GIT_CONFIG_COUNT = malformedCount; - expect(process.env.GIT_CONFIG_COUNT).toBe("1"); - expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); - expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo"); + ensureSafeDirectoryTrust("/workspace/repo"); + + expect(process.env.GIT_CONFIG_COUNT).toBe("1"); + expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); + expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo"); + } }); it("should not require a shimmed core global", async () => { const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + const originalCore = global.core; global.core = undefined; - expect(() => ensureSafeDirectoryTrust("/workspace/repo")).not.toThrow(); - expect(process.env.GIT_CONFIG_COUNT).toBe("1"); - expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); - expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo"); + try { + expect(() => ensureSafeDirectoryTrust("/workspace/repo")).not.toThrow(); + expect(process.env.GIT_CONFIG_COUNT).toBe("1"); + expect(process.env.GIT_CONFIG_KEY_0).toBe("safe.directory"); + expect(process.env.GIT_CONFIG_VALUE_0).toBe("/workspace/repo"); + } finally { + global.core = originalCore; + } }); }); From d4d78ebaf0c709aab5a61327201677c55422a26a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Jul 2026 03:36:13 +0000 Subject: [PATCH 05/12] Restore safe.directory bridge debug logging Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/git_helpers.cjs | 14 ++++++++-- actions/setup/js/git_helpers.test.cjs | 32 +++++++++++++++++----- actions/setup/js/safe_outputs_handlers.cjs | 6 ++-- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/actions/setup/js/git_helpers.cjs b/actions/setup/js/git_helpers.cjs index 3adfdcf67c5..ecd14f41291 100644 --- a/actions/setup/js/git_helpers.cjs +++ b/actions/setup/js/git_helpers.cjs @@ -50,9 +50,11 @@ function getGitAuthEnv(token) { * GIT_CONFIG_COUNT/KEY/VALUE is supported since git 2.31. * * @param {string} gitCwd - The directory to trust (e.g. GITHUB_WORKSPACE or a repo checkout path) + * @param {Object|Function} [logger] - Optional logger object + * with a debug method (for example the MCP server) or a direct debug function. * @returns {void} */ -function ensureSafeDirectoryTrust(gitCwd) { +function ensureSafeDirectoryTrust(gitCwd, logger) { if (!gitCwd) return; // Check if gitCwd is already present in the injected env-var config to avoid @@ -72,7 +74,15 @@ function ensureSafeDirectoryTrust(gitCwd) { process.env.GIT_CONFIG_COUNT = String(existingCount + 1); process.env[`GIT_CONFIG_KEY_${idx}`] = "safe.directory"; process.env[`GIT_CONFIG_VALUE_${idx}`] = gitCwd; - globalThis.core?.debug?.(`Configured git safe.directory for bridge context: ${gitCwd}`); + let debug; + if (typeof logger === "function") { + debug = logger; + } else if (typeof logger?.debug === "function") { + debug = logger.debug.bind(logger); + } else if (typeof globalThis.core?.debug === "function") { + debug = globalThis.core.debug.bind(globalThis.core); + } + debug?.(`Configured git safe.directory for bridge context: ${gitCwd}`); } /** diff --git a/actions/setup/js/git_helpers.test.cjs b/actions/setup/js/git_helpers.test.cjs index 26a74646292..aa6574b8bb1 100644 --- a/actions/setup/js/git_helpers.test.cjs +++ b/actions/setup/js/git_helpers.test.cjs @@ -364,17 +364,20 @@ describe("git_helpers.cjs", () => { // Simulate what getGitAuthEnv returns being already applied via env const authEnv = getGitAuthEnv("test-token"); Object.assign(process.env, authEnv); + const existingConfigCount = parseInt(authEnv.GIT_CONFIG_COUNT, 10); ensureSafeDirectoryTrust("/workspace/repo"); - // The count should be incremented by 1 (from 1 to 2) - expect(parseInt(process.env.GIT_CONFIG_COUNT, 10)).toBe(2); - // Existing auth entry preserved - expect(process.env.GIT_CONFIG_KEY_0).toBe(authEnv.GIT_CONFIG_KEY_0); - expect(process.env.GIT_CONFIG_VALUE_0).toBe(authEnv.GIT_CONFIG_VALUE_0); + // The count should be incremented by 1. + expect(parseInt(process.env.GIT_CONFIG_COUNT, 10)).toBe(existingConfigCount + 1); + // Existing auth entries preserved + for (let i = 0; i < existingConfigCount; i++) { + expect(process.env[`GIT_CONFIG_KEY_${i}`]).toBe(authEnv[`GIT_CONFIG_KEY_${i}`]); + expect(process.env[`GIT_CONFIG_VALUE_${i}`]).toBe(authEnv[`GIT_CONFIG_VALUE_${i}`]); + } // New safe.directory entry appended - expect(process.env.GIT_CONFIG_KEY_1).toBe("safe.directory"); - expect(process.env.GIT_CONFIG_VALUE_1).toBe("/workspace/repo"); + expect(process.env[`GIT_CONFIG_KEY_${existingConfigCount}`]).toBe("safe.directory"); + expect(process.env[`GIT_CONFIG_VALUE_${existingConfigCount}`]).toBe("/workspace/repo"); }); it("should handle malformed GIT_CONFIG_COUNT values gracefully", async () => { @@ -412,6 +415,21 @@ describe("git_helpers.cjs", () => { global.core = originalCore; } }); + + it("should use a provided logger when core is not shimmed", async () => { + const { ensureSafeDirectoryTrust } = await import("./git_helpers.cjs"); + const originalCore = global.core; + const logger = { debug: vi.fn() }; + + global.core = undefined; + + try { + ensureSafeDirectoryTrust("/workspace/repo", logger); + expect(logger.debug).toHaveBeenCalledWith("Configured git safe.directory for bridge context: /workspace/repo"); + } finally { + global.core = originalCore; + } + }); }); describe("ensureFullHistoryForBundle", () => { diff --git a/actions/setup/js/safe_outputs_handlers.cjs b/actions/setup/js/safe_outputs_handlers.cjs index b107fc0e449..b467cc25773 100644 --- a/actions/setup/js/safe_outputs_handlers.cjs +++ b/actions/setup/js/safe_outputs_handlers.cjs @@ -211,7 +211,7 @@ function createHandlers(server, appendSafeOutput, config = {}) { // Ensure the workspace is trusted for the lifetime of this server process. // This covers all current and future handlers automatically; per-handler calls // additionally cover per-request checkout paths that differ from GITHUB_WORKSPACE. - ensureSafeDirectoryTrust(process.env.GITHUB_WORKSPACE || process.cwd()); + ensureSafeDirectoryTrust(process.env.GITHUB_WORKSPACE || process.cwd(), server); const TOKEN_THRESHOLD = 16000; @@ -769,7 +769,7 @@ function createHandlers(server, appendSafeOutput, config = {}) { // This prevents TOCTOU races where the agent flips the ref between patch and bundle // generation, causing the two to represent different commit sets. const gitCwd = repoCwd || process.env.GITHUB_WORKSPACE || process.cwd(); - ensureSafeDirectoryTrust(gitCwd); + ensureSafeDirectoryTrust(gitCwd, server); let pinnedSha; try { pinnedSha = execGitSync(["rev-parse", "--verify", `refs/heads/${entry.branch}^{commit}`], { cwd: gitCwd }) @@ -1205,7 +1205,7 @@ function createHandlers(server, appendSafeOutput, config = {}) { // This prevents TOCTOU races where the agent flips the ref between patch and bundle // generation, causing the two to represent different commit sets. const pushGitCwd = repoCwd || process.env.GITHUB_WORKSPACE || process.cwd(); - ensureSafeDirectoryTrust(pushGitCwd); + ensureSafeDirectoryTrust(pushGitCwd, server); let pushPinnedSha; try { pushPinnedSha = execGitSync(["rev-parse", "--verify", `refs/heads/${entry.branch}^{commit}`], { cwd: pushGitCwd }) From b7fd8e0ee1733f9d1a5deed67eabb16a2aa1de5c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Jul 2026 07:49:07 +0000 Subject: [PATCH 06/12] chore: start final PR finisher pass Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@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 092aada6f01..3d6eb6ec67f 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 7fbc3953765..4c96d7c4a51 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 279d407502e..b670dfbb32e 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":"2d6e82aec6fea9061e1ef1cbb085324e6ed6c079230d70bbbb96611bb18cf7cf","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 @@ -1949,7 +1949,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 8d7320c75be..81a6ce1825b 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 06ce5804857b5cb4f842036eabd921401b3429d5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Jul 2026 08:04:03 +0000 Subject: [PATCH 07/12] fix: clean stale awf chroot temp dirs Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- actions/setup/clean.sh | 23 +++++-- actions/setup/js/chroot_home_cleanup.test.js | 36 ++++++++++- actions/setup/post.js | 66 ++++++++------------ actions/setup/sh/install_copilot_cli.sh | 12 ++-- 4 files changed, 87 insertions(+), 50 deletions(-) diff --git a/actions/setup/clean.sh b/actions/setup/clean.sh index 3f3cd511f85..19bd60691c0 100755 --- a/actions/setup/clean.sh +++ b/actions/setup/clean.sh @@ -41,10 +41,11 @@ if [ -d "${tmpDir}" ]; then fi fi -# Remove AWF chroot home directories under /tmp (e.g. /tmp/awf-*-chroot-home). -# These are created by AWF when running with --enable-host-access on GitHub-hosted runners. -# Files inside may be owned by root (written by Docker containers or privileged AWF processes), -# causing EACCES failures if cleanup is attempted without sudo. +# Remove AWF chroot directories under /tmp (e.g. /tmp/awf-*-chroot-home and +# /tmp/awf-chroot-*). These are created by AWF when running with +# --enable-host-access on GitHub-hosted runners. Files inside may be owned by +# root (written by Docker containers or privileged AWF processes), causing +# EACCES failures if cleanup is attempted without sudo. if awf_chroot_home_dirs="$(sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d -print 2>/dev/null)"; then if [ -n "${awf_chroot_home_dirs}" ]; then if sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d -exec rm -rf -- {} + 2>/dev/null; then @@ -58,3 +59,17 @@ if awf_chroot_home_dirs="$(sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' else echo "Warning: unable to inspect /tmp/awf-*-chroot-home directories with sudo" >&2 fi + +if awf_chroot_dirs="$(sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d -print 2>/dev/null)"; then + if [ -n "${awf_chroot_dirs}" ]; then + if sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d -exec rm -rf -- {} + 2>/dev/null; then + echo "Cleaned up /tmp/awf-chroot-* directories (sudo)" + else + echo "Warning: failed to clean /tmp/awf-chroot-* directories" >&2 + fi + else + echo "No /tmp/awf-chroot-* directories found" + fi +else + echo "Warning: unable to inspect /tmp/awf-chroot-* directories with sudo" >&2 +fi diff --git a/actions/setup/js/chroot_home_cleanup.test.js b/actions/setup/js/chroot_home_cleanup.test.js index 77e15492ad0..a1eb7b3c57a 100644 --- a/actions/setup/js/chroot_home_cleanup.test.js +++ b/actions/setup/js/chroot_home_cleanup.test.js @@ -100,6 +100,19 @@ describe("post.js chroot-home cleanup", () => { expect(result.stdout).toContain("Cleaned up 2 /tmp/awf-*-chroot-home directories"); expect(fs.readFileSync(logPath, "utf8")).toContain("-exec rm -rf -- {} +"); }); + + it("logs count of cleaned chroot directories", () => { + const { fakeBin, logPath } = createFakeSudoEnvironment(); + const result = runPostScript({ + PATH: `${fakeBin}:${process.env.PATH}`, + FAKE_SUDO_LOG: logPath, + FAKE_FIND_PRINT_OUTPUT: "/tmp/awf-chroot-a\n/tmp/awf-chroot-b\n", + }); + + expect(result.status).toBe(0); + expect(result.stdout).toContain("Cleaned up 2 /tmp/awf-chroot-* directories"); + expect(fs.readFileSync(logPath, "utf8")).toContain("-name awf-chroot-* -type d -exec rm -rf -- {} +"); + }); }); describe("clean.sh chroot-home cleanup", () => { @@ -136,6 +149,23 @@ describe("clean.sh chroot-home cleanup", () => { expect(result.stdout).toContain("Cleaned up /tmp/awf-*-chroot-home directories (sudo)"); expect(fs.readFileSync(logPath, "utf8")).toContain("-exec rm -rf -- {} +"); }); + + it("logs successful cleanup when chroot directories are found", () => { + const { fakeBin, logPath, root } = createFakeSudoEnvironment(); + const destination = path.join(root, "destination"); + fs.mkdirSync(destination, { recursive: true }); + + const result = runCleanScript({ + PATH: `${fakeBin}:${process.env.PATH}`, + FAKE_SUDO_LOG: logPath, + FAKE_FIND_PRINT_OUTPUT: "/tmp/awf-chroot-a\n", + INPUT_DESTINATION: destination, + }); + + expect(result.status).toBe(0); + expect(result.stdout).toContain("Cleaned up /tmp/awf-chroot-* directories (sudo)"); + expect(fs.readFileSync(logPath, "utf8")).toContain("-name awf-chroot-* -type d -exec rm -rf -- {} +"); + }); }); describe("install_copilot_cli.sh chroot-home cleanup", () => { @@ -143,13 +173,17 @@ describe("install_copilot_cli.sh chroot-home cleanup", () => { const script = fs.readFileSync(INSTALL_COPILOT_CLI_SCRIPT_PATH, "utf8"); const ownershipFixIndex = script.indexOf('sudo chown -R "$(id -u):$(id -g)" "$COPILOT_DIR"'); - const cleanupBannerIndex = script.indexOf('echo "Cleaning up stale AWF chroot home directories..."'); + const cleanupBannerIndex = script.indexOf('echo "Cleaning up stale AWF chroot directories..."'); const cleanupCommandIndex = script.indexOf( "sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d -exec rm -rf -- {} + 2>/dev/null || true" ); + const cleanupChrootCommandIndex = script.indexOf( + "sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d -exec rm -rf -- {} + 2>/dev/null || true" + ); expect(ownershipFixIndex).toBeGreaterThanOrEqual(0); expect(cleanupBannerIndex).toBeGreaterThan(ownershipFixIndex); expect(cleanupCommandIndex).toBeGreaterThan(cleanupBannerIndex); + expect(cleanupChrootCommandIndex).toBeGreaterThan(cleanupCommandIndex); }); }); diff --git a/actions/setup/post.js b/actions/setup/post.js index c20bf339eda..89bac6b41d9 100644 --- a/actions/setup/post.js +++ b/actions/setup/post.js @@ -120,51 +120,37 @@ function listTmpGhAwFiles(tmpDir, maxDepth, maxFiles) { } } - // Clean up AWF chroot home directories under /tmp (e.g. /tmp/awf-*-chroot-home). - // These are created by AWF when running with --enable-host-access on GitHub-hosted runners. - // Files inside may be owned by root (written by Docker containers or privileged AWF processes), + // Clean up AWF chroot directories under /tmp (e.g. /tmp/awf-*-chroot-home + // and /tmp/awf-chroot-*). These are created by AWF when running with + // --enable-host-access on GitHub-hosted runners. Files inside may be owned + // by root (written by Docker containers or privileged AWF processes), // causing EACCES failures if cleanup is attempted without sudo. - const awfChrootHomeFindResult = spawnSync( - "sudo", - ["find", "/tmp", "-maxdepth", "1", "-name", "awf-*-chroot-home", "-type", "d", "-print"], - { encoding: "utf8" } - ); - if (awfChrootHomeFindResult.status !== 0) { - console.log("Failed to inspect /tmp/awf-*-chroot-home directories"); - } else { - const awfChrootHomeDirs = awfChrootHomeFindResult.stdout + for (const pattern of ["awf-*-chroot-home", "awf-chroot-*"]) { + const awfChrootFindResult = spawnSync("sudo", ["find", "/tmp", "-maxdepth", "1", "-name", pattern, "-type", "d", "-print"], { encoding: "utf8" }); + if (awfChrootFindResult.status !== 0) { + console.log(`Failed to inspect /tmp/${pattern} directories`); + continue; + } + + const awfChrootDirs = awfChrootFindResult.stdout .split("\n") .map(line => line.trim()) .filter(Boolean); - if (awfChrootHomeDirs.length === 0) { - console.log("No /tmp/awf-*-chroot-home directories found"); + if (awfChrootDirs.length === 0) { + console.log(`No /tmp/${pattern} directories found`); + continue; + } + + const awfChrootCleanupResult = spawnSync( + "sudo", + ["find", "/tmp", "-maxdepth", "1", "-name", pattern, "-type", "d", "-exec", "rm", "-rf", "--", "{}", "+"], + { stdio: "inherit" } + ); + if (awfChrootCleanupResult.status === 0) { + const awfChrootNoun = awfChrootDirs.length === 1 ? "directory" : "directories"; + console.log(`Cleaned up ${awfChrootDirs.length} /tmp/${pattern} ${awfChrootNoun}`); } else { - const awfChrootHomeCleanupResult = spawnSync( - "sudo", - [ - "find", - "/tmp", - "-maxdepth", - "1", - "-name", - "awf-*-chroot-home", - "-type", - "d", - "-exec", - "rm", - "-rf", - "--", - "{}", - "+" - ], - { stdio: "inherit" } - ); - if (awfChrootHomeCleanupResult.status === 0) { - const awfChrootHomeNoun = awfChrootHomeDirs.length === 1 ? "directory" : "directories"; - console.log(`Cleaned up ${awfChrootHomeDirs.length} /tmp/awf-*-chroot-home ${awfChrootHomeNoun}`); - } else { - console.log("Failed to clean /tmp/awf-*-chroot-home directories"); - } + console.log(`Failed to clean /tmp/${pattern} directories`); } } })(); diff --git a/actions/setup/sh/install_copilot_cli.sh b/actions/setup/sh/install_copilot_cli.sh index d3ba2452ee7..191d0e79f87 100755 --- a/actions/setup/sh/install_copilot_cli.sh +++ b/actions/setup/sh/install_copilot_cli.sh @@ -43,14 +43,16 @@ echo "Ensuring correct ownership of $COPILOT_DIR..." mkdir -p "$COPILOT_DIR" sudo chown -R "$(id -u):$(id -g)" "$COPILOT_DIR" -# Clean up any stale AWF chroot home directories left by previous runs. +# Clean up any stale AWF chroot directories left by previous runs. # When AWF ran with `sudo -E awf --enable-host-access`, it created -# /tmp/awf-*-chroot-home directories with root-owned files. These cause -# EACCES failures in the Copilot CLI cleanup path (rimrafSync) on the same or -# subsequent runs, which reports as "engine terminated unexpectedly". +# /tmp/awf-*-chroot-home and /tmp/awf-chroot-* directories with root-owned +# files. These cause EACCES failures in the Copilot CLI cleanup path +# (rimrafSync) or AWF writeConfigs on the same or subsequent runs, which +# reports as "engine terminated unexpectedly" or fatal EACCES errors. # Remove them here before the agent starts so the runner is in a clean state. -echo "Cleaning up stale AWF chroot home directories..." +echo "Cleaning up stale AWF chroot directories..." sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d -exec rm -rf -- {} + 2>/dev/null || true +sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d -exec rm -rf -- {} + 2>/dev/null || true # Detect OS and architecture OS="$(uname -s)" From 634cba0bbcc2c98f458bbddd6fae204ef9131a44 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Jul 2026 09:39:02 +0000 Subject: [PATCH 08/12] fix: preclean stale awf chroot dirs before awf install Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- actions/setup/js/chroot_home_cleanup.test.js | 23 ++++++++++++++++++++ actions/setup/sh/install_awf_binary.sh | 8 +++++++ 2 files changed, 31 insertions(+) diff --git a/actions/setup/js/chroot_home_cleanup.test.js b/actions/setup/js/chroot_home_cleanup.test.js index a1eb7b3c57a..4841a1fb968 100644 --- a/actions/setup/js/chroot_home_cleanup.test.js +++ b/actions/setup/js/chroot_home_cleanup.test.js @@ -9,6 +9,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); const POST_SCRIPT_PATH = path.join(__dirname, "..", "post.js"); const CLEAN_SCRIPT_PATH = path.join(__dirname, "..", "clean.sh"); const INSTALL_COPILOT_CLI_SCRIPT_PATH = path.join(__dirname, "..", "sh", "install_copilot_cli.sh"); +const INSTALL_AWF_BINARY_SCRIPT_PATH = path.join(__dirname, "..", "sh", "install_awf_binary.sh"); const tempDirs = []; @@ -187,3 +188,25 @@ describe("install_copilot_cli.sh chroot-home cleanup", () => { expect(cleanupChrootCommandIndex).toBeGreaterThan(cleanupCommandIndex); }); }); + +describe("install_awf_binary.sh chroot-home cleanup", () => { + it("cleans stale chroot directories before starting AWF installation", () => { + const script = fs.readFileSync(INSTALL_AWF_BINARY_SCRIPT_PATH, "utf8"); + + const rootlessPreflightIndex = script.indexOf("# Rootless mode preflight"); + const cleanupBannerIndex = script.indexOf('echo "Cleaning up stale AWF chroot directories..."'); + const cleanupHomeCommandIndex = script.indexOf( + "sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d -exec rm -rf -- {} + 2>/dev/null || true" + ); + const cleanupChrootCommandIndex = script.indexOf( + "sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d -exec rm -rf -- {} + 2>/dev/null || true" + ); + const downloadUrlIndex = script.indexOf("# Download URLs"); + + expect(rootlessPreflightIndex).toBeGreaterThanOrEqual(0); + expect(cleanupBannerIndex).toBeGreaterThan(rootlessPreflightIndex); + expect(cleanupHomeCommandIndex).toBeGreaterThan(cleanupBannerIndex); + expect(cleanupChrootCommandIndex).toBeGreaterThan(cleanupHomeCommandIndex); + expect(downloadUrlIndex).toBeGreaterThan(cleanupChrootCommandIndex); + }); +}); diff --git a/actions/setup/sh/install_awf_binary.sh b/actions/setup/sh/install_awf_binary.sh index ff642fc0bbc..7226074d797 100755 --- a/actions/setup/sh/install_awf_binary.sh +++ b/actions/setup/sh/install_awf_binary.sh @@ -85,6 +85,14 @@ if [ "$ROOTLESS" = "true" ]; then fi fi +# Clean up any stale AWF chroot directories left by previous runs before we +# execute awf. Rootless AWF can fail its writeConfigs startup path with EACCES +# when stale /tmp/awf-*-chroot-home or /tmp/awf-chroot-* directories remain +# from earlier jobs on the same runner. +echo "Cleaning up stale AWF chroot directories..." +sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d -exec rm -rf -- {} + 2>/dev/null || true +sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d -exec rm -rf -- {} + 2>/dev/null || true + # Download URLs BASE_URL="https://github.com/${AWF_REPO}/releases/download/${AWF_VERSION}" CHECKSUMS_URL="${BASE_URL}/checksums.txt" From 6469a66ff280830954fb749dcc15c55223fe40e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Jul 2026 10:03:11 +0000 Subject: [PATCH 09/12] fix: preclean stale awf dirs before awf startup Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- actions/setup/js/chroot_home_cleanup.test.js | 12 ++++++++---- actions/setup/sh/install_awf_binary.sh | 12 +++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/actions/setup/js/chroot_home_cleanup.test.js b/actions/setup/js/chroot_home_cleanup.test.js index 4841a1fb968..170fbed4e36 100644 --- a/actions/setup/js/chroot_home_cleanup.test.js +++ b/actions/setup/js/chroot_home_cleanup.test.js @@ -193,20 +193,24 @@ describe("install_awf_binary.sh chroot-home cleanup", () => { it("cleans stale chroot directories before starting AWF installation", () => { const script = fs.readFileSync(INSTALL_AWF_BINARY_SCRIPT_PATH, "utf8"); - const rootlessPreflightIndex = script.indexOf("# Rootless mode preflight"); + const rootlessPreflightIndex = script.indexOf('if ! { mkdir -p "${AWF_INSTALL_DIR}" && [ -w "${AWF_INSTALL_DIR}" ]; }; then'); const cleanupBannerIndex = script.indexOf('echo "Cleaning up stale AWF chroot directories..."'); + const sudoGuardIndex = script.indexOf("if command -v sudo >/dev/null 2>&1; then"); const cleanupHomeCommandIndex = script.indexOf( - "sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d -exec rm -rf -- {} + 2>/dev/null || true" + `sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d \\( -user root -o -user "$(id -un)" \\) -exec rm -rf -- {} + || true` ); const cleanupChrootCommandIndex = script.indexOf( - "sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d -exec rm -rf -- {} + 2>/dev/null || true" + `sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d \\( -user root -o -user "$(id -un)" \\) -exec rm -rf -- {} + || true` ); + const sudoWarningIndex = script.indexOf('echo "Warning: sudo is unavailable; skipping stale AWF chroot cleanup" >&2'); const downloadUrlIndex = script.indexOf("# Download URLs"); expect(rootlessPreflightIndex).toBeGreaterThanOrEqual(0); expect(cleanupBannerIndex).toBeGreaterThan(rootlessPreflightIndex); - expect(cleanupHomeCommandIndex).toBeGreaterThan(cleanupBannerIndex); + expect(sudoGuardIndex).toBeGreaterThan(cleanupBannerIndex); + expect(cleanupHomeCommandIndex).toBeGreaterThan(sudoGuardIndex); expect(cleanupChrootCommandIndex).toBeGreaterThan(cleanupHomeCommandIndex); + expect(sudoWarningIndex).toBeGreaterThan(cleanupChrootCommandIndex); expect(downloadUrlIndex).toBeGreaterThan(cleanupChrootCommandIndex); }); }); diff --git a/actions/setup/sh/install_awf_binary.sh b/actions/setup/sh/install_awf_binary.sh index 7226074d797..c62afcab532 100755 --- a/actions/setup/sh/install_awf_binary.sh +++ b/actions/setup/sh/install_awf_binary.sh @@ -88,10 +88,16 @@ fi # Clean up any stale AWF chroot directories left by previous runs before we # execute awf. Rootless AWF can fail its writeConfigs startup path with EACCES # when stale /tmp/awf-*-chroot-home or /tmp/awf-chroot-* directories remain -# from earlier jobs on the same runner. +# from earlier jobs on the same runner. Limit cleanup to directories owned by +# root or the current runner user so we do not delete unrelated /tmp entries +# that happen to match the name pattern. echo "Cleaning up stale AWF chroot directories..." -sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d -exec rm -rf -- {} + 2>/dev/null || true -sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d -exec rm -rf -- {} + 2>/dev/null || true +if command -v sudo >/dev/null 2>&1; then + sudo find /tmp -maxdepth 1 -name 'awf-*-chroot-home' -type d \( -user root -o -user "$(id -un)" \) -exec rm -rf -- {} + || true + sudo find /tmp -maxdepth 1 -name 'awf-chroot-*' -type d \( -user root -o -user "$(id -un)" \) -exec rm -rf -- {} + || true +else + echo "Warning: sudo is unavailable; skipping stale AWF chroot cleanup" >&2 +fi # Download URLs BASE_URL="https://github.com/${AWF_REPO}/releases/download/${AWF_VERSION}" From 2e6b2f274000791ca6533afd4437276559aa6ffc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Jul 2026 23:21:57 +0000 Subject: [PATCH 10/12] Apply remaining changes Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/workflows/agentic-auto-upgrade.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/agentic-auto-upgrade.yml b/.github/workflows/agentic-auto-upgrade.yml index e169cea32b6..7035101ee35 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: "11 4 * * 6" # Weekly (auto-upgrade) + - cron: "21 3 * * 5" # Weekly (auto-upgrade) workflow_dispatch: permissions: From 04095c330f8ec34b3bf4be44dd04ea5107e5bee6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Jul 2026 03:29:26 +0000 Subject: [PATCH 11/12] Plan merge-conflict resolution Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/agentic-auto-upgrade.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: From ab66c06bd209383c7e922c20fa3908a9a4ec11a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Jul 2026 07:57:10 +0000 Subject: [PATCH 12/12] docs: add trimleftright to linter README Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/linters/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/linters/README.md b/pkg/linters/README.md index 2af2f13dc91..dc35a7c93da 100644 --- a/pkg/linters/README.md +++ b/pkg/linters/README.md @@ -55,6 +55,7 @@ This package currently provides custom Go analyzers in the following subpackages - `timeafterleak` — reports `time.After` calls used as the channel-receive expression in a `select` case inside a `for` or `range` loop that leak a timer channel on each iteration when another case fires first. - `timesleepnocontext` — reports `time.Sleep` calls inside functions that already receive a `context.Context`, where a context-aware `select` should be used instead. - `tolowerequalfold` — reports case-insensitive string comparisons using `strings.ToLower`/`ToUpper` that should use `strings.EqualFold`. +- `trimleftright` — reports `strings.TrimLeft` / `strings.TrimRight` calls with a multi-character literal cutset where `strings.TrimPrefix` / `strings.TrimSuffix` was likely intended. - `uncheckedtypeassertion` — reports single-value type assertions where unchecked panics are possible. - `wgdonenotdeferred` — reports non-deferred `sync.WaitGroup.Done()` calls that can deadlock on panics or early returns. - `writebytestring` — reports `w.Write([]byte(s))` calls where `s` is a string, which can be replaced with `io.WriteString` to avoid an unnecessary `[]byte` allocation. @@ -115,6 +116,7 @@ This package currently provides custom Go analyzers in the following subpackages | `timeafterleak` | Custom `go/analysis` analyzer that flags `time.After` in `select` cases inside loops that leak a timer channel on each iteration when another case fires first | | `timesleepnocontext` | Custom `go/analysis` analyzer that flags `time.Sleep` calls in context-aware functions | | `tolowerequalfold` | Custom `go/analysis` analyzer that flags case-insensitive comparisons via `strings.ToLower`/`ToUpper` that should use `strings.EqualFold` | +| `trimleftright` | Custom `go/analysis` analyzer that flags `strings.TrimLeft` / `strings.TrimRight` calls with a multi-character literal cutset where `strings.TrimPrefix` / `strings.TrimSuffix` was likely intended | | `uncheckedtypeassertion` | Custom `go/analysis` analyzer that flags unchecked single-value type assertions | | `wgdonenotdeferred` | Custom `go/analysis` analyzer that flags non-deferred `sync.WaitGroup.Done()` calls | | `writebytestring` | Custom `go/analysis` analyzer that flags `w.Write([]byte(s))` calls where `s` is a string that can be replaced with `io.WriteString` | @@ -234,6 +236,7 @@ _ = timesleepnocontext.Analyzer - `github.com/github/gh-aw/pkg/linters/timeafterleak` — time-after-leak analyzer subpackage - `github.com/github/gh-aw/pkg/linters/timesleepnocontext` — time-sleep-no-context analyzer subpackage - `github.com/github/gh-aw/pkg/linters/tolowerequalfold` — to-lower-equal-fold analyzer subpackage +- `github.com/github/gh-aw/pkg/linters/trimleftright` — trim-left-right analyzer subpackage - `github.com/github/gh-aw/pkg/linters/uncheckedtypeassertion` — unchecked-type-assertion analyzer subpackage - `github.com/github/gh-aw/pkg/linters/wgdonenotdeferred` — wg-done-not-deferred analyzer subpackage - `github.com/github/gh-aw/pkg/linters/writebytestring` — write-byte-string analyzer subpackage