From a877f3cbc4b1dda2639b2dd3b2c4ea8beb15afba Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 4 Apr 2026 23:13:15 +0000
Subject: [PATCH 1/5] Initial plan
From e5e5ddd134254de9bf722d32d02e26174f8d0ce1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 4 Apr 2026 23:21:42 +0000
Subject: [PATCH 2/5] Initial plan for duplicate token step fix
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/96ee3670-b890-4866-8874-41dfc5bf92ec
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.../copilot-token-optimizer.lock.yml | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/.github/workflows/copilot-token-optimizer.lock.yml b/.github/workflows/copilot-token-optimizer.lock.yml
index 19d48acb675..53c0976a49d 100644
--- a/.github/workflows/copilot-token-optimizer.lock.yml
+++ b/.github/workflows/copilot-token-optimizer.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"86a159c3ff0374493fa651d638eab96762e4dad20a9b47e1cd175c3d768437be","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"80ad5c2ec213174bfae14e58c80ce530e5744bbb27b8538ef71c64a67f94778c","strict":true,"agent_id":"copilot"}
# ___ _ _
# / _ \ | | (_)
# | |_| | __ _ ___ _ __ | |_ _ ___
@@ -152,16 +152,16 @@ jobs:
run: |
bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
{
- cat << 'GH_AW_PROMPT_822a6d37b217ea93_EOF'
+ cat << 'GH_AW_PROMPT_8574d6695fabe0ee_EOF'
- GH_AW_PROMPT_822a6d37b217ea93_EOF
+ GH_AW_PROMPT_8574d6695fabe0ee_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/agentic_workflows_guide.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/repo_memory_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_822a6d37b217ea93_EOF'
+ cat << 'GH_AW_PROMPT_8574d6695fabe0ee_EOF'
Tools: create_issue, missing_tool, missing_data, noop
@@ -193,14 +193,14 @@ jobs:
{{/if}}
- GH_AW_PROMPT_822a6d37b217ea93_EOF
+ GH_AW_PROMPT_8574d6695fabe0ee_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_822a6d37b217ea93_EOF'
+ cat << 'GH_AW_PROMPT_8574d6695fabe0ee_EOF'
{{#runtime-import .github/workflows/shared/mcp/gh-aw.md}}
{{#runtime-import .github/workflows/shared/reporting.md}}
{{#runtime-import .github/workflows/copilot-token-optimizer.md}}
- GH_AW_PROMPT_822a6d37b217ea93_EOF
+ GH_AW_PROMPT_8574d6695fabe0ee_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
@@ -429,12 +429,12 @@ jobs:
mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_0b64c8e56368c0ae_EOF'
- {"create_issue":{"expires":168,"max":1,"title_prefix":"[copilot-token-optimizer] "},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":51200}]}}
- GH_AW_SAFE_OUTPUTS_CONFIG_0b64c8e56368c0ae_EOF
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_a69d7382b73926ca_EOF'
+ {"create_issue":{"close_older_issues":true,"expires":168,"max":1,"title_prefix":"[copilot-token-optimizer] "},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":51200}]}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_a69d7382b73926ca_EOF
- name: Write Safe Outputs Tools
run: |
- cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_fa1fbe008d87589d_EOF'
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_df17b016774b9777_EOF'
{
"description_suffixes": {
"create_issue": " CONSTRAINTS: Maximum 1 issue(s) can be created. Title will be prefixed with \"[copilot-token-optimizer] \"."
@@ -442,8 +442,8 @@ jobs:
"repo_params": {},
"dynamic_tools": []
}
- GH_AW_SAFE_OUTPUTS_TOOLS_META_fa1fbe008d87589d_EOF
- cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_3faae8610bd35d4c_EOF'
+ GH_AW_SAFE_OUTPUTS_TOOLS_META_df17b016774b9777_EOF
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_16d37360fe894c1f_EOF'
{
"create_issue": {
"defaultMax": 1,
@@ -536,7 +536,7 @@ jobs:
}
}
}
- GH_AW_SAFE_OUTPUTS_VALIDATION_3faae8610bd35d4c_EOF
+ GH_AW_SAFE_OUTPUTS_VALIDATION_16d37360fe894c1f_EOF
node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
- name: Generate Safe Outputs MCP Server Config
id: safe-outputs-config
@@ -607,7 +607,7 @@ jobs:
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.12'
mkdir -p /home/runner/.copilot
- cat << GH_AW_MCP_CONFIG_f021b11b7f2e027d_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
+ cat << GH_AW_MCP_CONFIG_972eeb306fdf4f5d_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
{
"mcpServers": {
"agenticworkflows": {
@@ -667,7 +667,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_f021b11b7f2e027d_EOF
+ GH_AW_MCP_CONFIG_972eeb306fdf4f5d_EOF
- name: Download activation artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
@@ -1302,7 +1302,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"expires\":168,\"max\":1,\"title_prefix\":\"[copilot-token-optimizer] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"close_older_issues\":true,\"expires\":168,\"max\":1,\"title_prefix\":\"[copilot-token-optimizer] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
From f9e53d4925baaf4917f5c17297a7ef9b87b48266 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 4 Apr 2026 23:33:54 +0000
Subject: [PATCH 3/5] fix: rename duplicate checkout app token steps to have
unique names
When multiple checkout entries fall back to the top-level github-app,
GenerateCheckoutAppTokenSteps previously used the same step name
'Generate GitHub App token' for all minting steps. The duplicate-name
validator then rejected the workflow with a compiler error.
Fix: add the checkout index to each minting step name so every step
has a unique name ('Generate GitHub App token for checkout (N)').
This mirrors the pattern already used for invalidation steps.
Also add integration test to ensure this combination compiles cleanly.
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/96ee3670-b890-4866-8874-41dfc5bf92ec
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
pkg/workflow/checkout_step_generator.go | 4 +
...licate_step_validation_integration_test.go | 98 +++++++++++++++++++
2 files changed, 102 insertions(+)
diff --git a/pkg/workflow/checkout_step_generator.go b/pkg/workflow/checkout_step_generator.go
index 6216c8cbc99..993593f17c6 100644
--- a/pkg/workflow/checkout_step_generator.go
+++ b/pkg/workflow/checkout_step_generator.go
@@ -25,6 +25,10 @@ func (cm *CheckoutManager) GenerateCheckoutAppTokenSteps(c *Compiler, permission
stepID := fmt.Sprintf("checkout-app-token-%d", i)
for _, step := range appSteps {
modified := strings.ReplaceAll(step, "id: safe-outputs-app-token", "id: "+stepID)
+ // Rename the step to make it unique when multiple checkouts use app auth.
+ // This prevents duplicate step name errors when more than one checkout entry
+ // falls back to the top-level github-app (or has its own github-app configured).
+ modified = strings.ReplaceAll(modified, "name: Generate GitHub App token", fmt.Sprintf("name: Generate GitHub App token for checkout (%d)", i))
steps = append(steps, modified)
}
}
diff --git a/pkg/workflow/duplicate_step_validation_integration_test.go b/pkg/workflow/duplicate_step_validation_integration_test.go
index 92283543ff3..0a7fcd6d219 100644
--- a/pkg/workflow/duplicate_step_validation_integration_test.go
+++ b/pkg/workflow/duplicate_step_validation_integration_test.go
@@ -89,3 +89,101 @@ This workflow tests that duplicate checkout steps are properly deduplicated.
t.Logf("✓ Duplicate step validation working correctly: found %d checkout step(s) in safe_outputs job (deduplicated)", checkoutCount)
}
+
+// TestDuplicateStepValidation_CheckoutPlusGitHubApp_Integration tests that combining
+// a top-level github-app with multiple cross-repo checkouts and tools.github does not
+// produce duplicate 'Generate GitHub App token' steps in the activation job.
+//
+// Regression test for: https://github.com/github/gh-aw/issues/
+// When multiple checkout entries all fall back to the top-level github-app,
+// each minting step previously received the same name, triggering the duplicate
+// step validation error ("compiler bug: duplicate step 'Generate GitHub App token'").
+func TestDuplicateStepValidation_CheckoutPlusGitHubApp_Integration(t *testing.T) {
+ tmpDir := testutil.TempDir(t, "duplicate-checkout-token-test")
+
+ // Workflow that combines all three conditions that triggered the bug:
+ // 1. Top-level github-app: (used as fallback for all token-minting operations)
+ // 2. Two cross-repo checkout: entries (both fall back to the top-level github-app)
+ // 3. tools.github: with mode: remote
+ mdContent := `---
+on:
+ issues:
+ types: [opened]
+engine:
+ id: claude
+strict: false
+permissions:
+ contents: read
+ issues: read
+ pull-requests: read
+
+github-app:
+ app-id: ${{ secrets.APP_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
+ repositories: ["side-repo", "target-repo"]
+
+checkout:
+ - repository: myorg/target-repo
+ ref: main
+ - repository: myorg/side-repo
+ ref: main
+
+tools:
+ github:
+ mode: remote
+ toolsets: [default]
+---
+
+# Test Workflow
+
+This workflow tests that multiple checkouts + top-level github-app + tools.github
+compile without duplicate 'Generate GitHub App token' step errors in the activation job.
+`
+
+ mdFile := filepath.Join(tmpDir, "test-checkout-github-app.md")
+ err := os.WriteFile(mdFile, []byte(mdContent), 0644)
+ if err != nil {
+ t.Fatalf("Failed to create test file: %v", err)
+ }
+
+ // Compile workflow — must succeed without a duplicate step error
+ compiler := NewCompiler()
+ err = compiler.CompileWorkflow(mdFile)
+ if err != nil {
+ if strings.Contains(err.Error(), "duplicate step") {
+ t.Fatalf("Regression: duplicate step error when combining multiple checkouts + top-level github-app: %v", err)
+ }
+ // Other errors are acceptable for this regression test
+ t.Logf("Compilation failed with non-duplicate-step error (acceptable): %v", err)
+ return
+ }
+
+ // Read the generated lock file and verify the activation job has unique step names
+ lockFile := stringutil.MarkdownToLockFile(mdFile)
+ lockContent, err := os.ReadFile(lockFile)
+ if err != nil {
+ t.Fatalf("Failed to read lock file: %v", err)
+ }
+ lockContentStr := string(lockContent)
+
+ // Both checkout token minting steps should be present with unique names.
+ // The step names are "Generate GitHub App token for checkout (N)" — one per checkout entry.
+ count0 := strings.Count(lockContentStr, "name: Generate GitHub App token for checkout (0)")
+ count1 := strings.Count(lockContentStr, "name: Generate GitHub App token for checkout (1)")
+ if count0 != 1 {
+ t.Errorf("Expected exactly 1 'Generate GitHub App token for checkout (0)' step, got %d", count0)
+ }
+ if count1 != 1 {
+ t.Errorf("Expected exactly 1 'Generate GitHub App token for checkout (1)' step, got %d", count1)
+ }
+
+ // Exactly one generic "Generate GitHub App token" step is expected — for the GitHub MCP server
+ // in the agent job (id: github-mcp-app-token). If more than one appears, that means a
+ // checkout minting step was not renamed, which would cause a duplicate-name error.
+ genericCount := strings.Count(lockContentStr, "name: Generate GitHub App token\n")
+ if genericCount > 1 {
+ t.Errorf("Found %d generic 'Generate GitHub App token' steps; checkout steps must use unique names to avoid duplicates", genericCount)
+ }
+
+ t.Logf("✓ No duplicate token steps: checkout (0) count=%d, checkout (1) count=%d, generic=%d", count0, count1, genericCount)
+}
From 88d5f517adf9bf384bc7d4f24963016993379a26 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 4 Apr 2026 23:37:55 +0000
Subject: [PATCH 4/5] fix review: use correct engine format and remove issue
placeholder in test
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/96ee3670-b890-4866-8874-41dfc5bf92ec
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
pkg/workflow/duplicate_step_validation_integration_test.go | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/pkg/workflow/duplicate_step_validation_integration_test.go b/pkg/workflow/duplicate_step_validation_integration_test.go
index 0a7fcd6d219..3f300e7f09c 100644
--- a/pkg/workflow/duplicate_step_validation_integration_test.go
+++ b/pkg/workflow/duplicate_step_validation_integration_test.go
@@ -94,7 +94,6 @@ This workflow tests that duplicate checkout steps are properly deduplicated.
// a top-level github-app with multiple cross-repo checkouts and tools.github does not
// produce duplicate 'Generate GitHub App token' steps in the activation job.
//
-// Regression test for: https://github.com/github/gh-aw/issues/
// When multiple checkout entries all fall back to the top-level github-app,
// each minting step previously received the same name, triggering the duplicate
// step validation error ("compiler bug: duplicate step 'Generate GitHub App token'").
@@ -109,8 +108,7 @@ func TestDuplicateStepValidation_CheckoutPlusGitHubApp_Integration(t *testing.T)
on:
issues:
types: [opened]
-engine:
- id: claude
+engine: claude
strict: false
permissions:
contents: read
From d17c0456336f2824f5b82413cd93d698ae08349b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 4 Apr 2026 23:56:36 +0000
Subject: [PATCH 5/5] fix review: revert unrelated lockfile changes; fail test
on any compile error
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/41b76e6d-2d10-4dc7-aa68-2ac94e6dffb5
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.../copilot-token-optimizer.lock.yml | 34 +++++++++----------
...licate_step_validation_integration_test.go | 6 ++--
2 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/.github/workflows/copilot-token-optimizer.lock.yml b/.github/workflows/copilot-token-optimizer.lock.yml
index 53c0976a49d..19d48acb675 100644
--- a/.github/workflows/copilot-token-optimizer.lock.yml
+++ b/.github/workflows/copilot-token-optimizer.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"80ad5c2ec213174bfae14e58c80ce530e5744bbb27b8538ef71c64a67f94778c","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"86a159c3ff0374493fa651d638eab96762e4dad20a9b47e1cd175c3d768437be","strict":true,"agent_id":"copilot"}
# ___ _ _
# / _ \ | | (_)
# | |_| | __ _ ___ _ __ | |_ _ ___
@@ -152,16 +152,16 @@ jobs:
run: |
bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
{
- cat << 'GH_AW_PROMPT_8574d6695fabe0ee_EOF'
+ cat << 'GH_AW_PROMPT_822a6d37b217ea93_EOF'
- GH_AW_PROMPT_8574d6695fabe0ee_EOF
+ GH_AW_PROMPT_822a6d37b217ea93_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/agentic_workflows_guide.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/repo_memory_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_8574d6695fabe0ee_EOF'
+ cat << 'GH_AW_PROMPT_822a6d37b217ea93_EOF'
Tools: create_issue, missing_tool, missing_data, noop
@@ -193,14 +193,14 @@ jobs:
{{/if}}
- GH_AW_PROMPT_8574d6695fabe0ee_EOF
+ GH_AW_PROMPT_822a6d37b217ea93_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_8574d6695fabe0ee_EOF'
+ cat << 'GH_AW_PROMPT_822a6d37b217ea93_EOF'
{{#runtime-import .github/workflows/shared/mcp/gh-aw.md}}
{{#runtime-import .github/workflows/shared/reporting.md}}
{{#runtime-import .github/workflows/copilot-token-optimizer.md}}
- GH_AW_PROMPT_8574d6695fabe0ee_EOF
+ GH_AW_PROMPT_822a6d37b217ea93_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
@@ -429,12 +429,12 @@ jobs:
mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_a69d7382b73926ca_EOF'
- {"create_issue":{"close_older_issues":true,"expires":168,"max":1,"title_prefix":"[copilot-token-optimizer] "},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":51200}]}}
- GH_AW_SAFE_OUTPUTS_CONFIG_a69d7382b73926ca_EOF
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_0b64c8e56368c0ae_EOF'
+ {"create_issue":{"expires":168,"max":1,"title_prefix":"[copilot-token-optimizer] "},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":51200}]}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_0b64c8e56368c0ae_EOF
- name: Write Safe Outputs Tools
run: |
- cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_df17b016774b9777_EOF'
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_fa1fbe008d87589d_EOF'
{
"description_suffixes": {
"create_issue": " CONSTRAINTS: Maximum 1 issue(s) can be created. Title will be prefixed with \"[copilot-token-optimizer] \"."
@@ -442,8 +442,8 @@ jobs:
"repo_params": {},
"dynamic_tools": []
}
- GH_AW_SAFE_OUTPUTS_TOOLS_META_df17b016774b9777_EOF
- cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_16d37360fe894c1f_EOF'
+ GH_AW_SAFE_OUTPUTS_TOOLS_META_fa1fbe008d87589d_EOF
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_3faae8610bd35d4c_EOF'
{
"create_issue": {
"defaultMax": 1,
@@ -536,7 +536,7 @@ jobs:
}
}
}
- GH_AW_SAFE_OUTPUTS_VALIDATION_16d37360fe894c1f_EOF
+ GH_AW_SAFE_OUTPUTS_VALIDATION_3faae8610bd35d4c_EOF
node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
- name: Generate Safe Outputs MCP Server Config
id: safe-outputs-config
@@ -607,7 +607,7 @@ jobs:
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.12'
mkdir -p /home/runner/.copilot
- cat << GH_AW_MCP_CONFIG_972eeb306fdf4f5d_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
+ cat << GH_AW_MCP_CONFIG_f021b11b7f2e027d_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
{
"mcpServers": {
"agenticworkflows": {
@@ -667,7 +667,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_972eeb306fdf4f5d_EOF
+ GH_AW_MCP_CONFIG_f021b11b7f2e027d_EOF
- name: Download activation artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
@@ -1302,7 +1302,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"close_older_issues\":true,\"expires\":168,\"max\":1,\"title_prefix\":\"[copilot-token-optimizer] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"expires\":168,\"max\":1,\"title_prefix\":\"[copilot-token-optimizer] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/pkg/workflow/duplicate_step_validation_integration_test.go b/pkg/workflow/duplicate_step_validation_integration_test.go
index 3f300e7f09c..d8a4ceed56f 100644
--- a/pkg/workflow/duplicate_step_validation_integration_test.go
+++ b/pkg/workflow/duplicate_step_validation_integration_test.go
@@ -144,16 +144,14 @@ compile without duplicate 'Generate GitHub App token' step errors in the activat
t.Fatalf("Failed to create test file: %v", err)
}
- // Compile workflow — must succeed without a duplicate step error
+ // Compile workflow — must succeed so the generated lock file can be validated.
compiler := NewCompiler()
err = compiler.CompileWorkflow(mdFile)
if err != nil {
if strings.Contains(err.Error(), "duplicate step") {
t.Fatalf("Regression: duplicate step error when combining multiple checkouts + top-level github-app: %v", err)
}
- // Other errors are acceptable for this regression test
- t.Logf("Compilation failed with non-duplicate-step error (acceptable): %v", err)
- return
+ t.Fatalf("Compilation failed unexpectedly before lock-file assertions could run: %v", err)
}
// Read the generated lock file and verify the activation job has unique step names