From b9e5595b481c4fe731938e3808d909b06c0bcb5c Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 19 Apr 2026 23:45:03 +0000
Subject: [PATCH 01/10] chore: start update-pull-request merge-base support
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/340b546b-743d-45b6-ac7e-8ec5735124d3
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/requirements.txt | 1 +
.../smoke-create-cross-repo-pr.lock.yml | 52 ++++++++--------
.../workflows/smoke-create-cross-repo-pr.md | 10 ++--
.../smoke-update-cross-repo-pr.lock.yml | 50 ++++++++--------
.../workflows/smoke-update-cross-repo-pr.md | 8 +--
.../src/content/docs/agent-factory-status.mdx | 5 ++
.../docs/reference/frontmatter-full.md | 59 ++++++++++++++++---
7 files changed, 118 insertions(+), 67 deletions(-)
diff --git a/.github/workflows/requirements.txt b/.github/workflows/requirements.txt
index 56829fdbd0f..abcda1723e7 100644
--- a/.github/workflows/requirements.txt
+++ b/.github/workflows/requirements.txt
@@ -1,3 +1,4 @@
+"mempalace==3.2.0"
markitdown-mcp
numpy
scikit-learn
diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml
index abdd7ed4c2c..8ea587dbaf8 100644
--- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml
+++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"86acca80f30c2c8b5c2f2acfcd36ccdf20eeb732a678a64f2db35dd5e1f6425a","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"55e430e79f4d85abfe9d63d9335d30f2e95aeb486662520e010facf5d69dde96","strict":true,"agent_id":"copilot"}
# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GH_AW_SIDE_REPO_PAT","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.25"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.25"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.25"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.25"},{"image":"ghcr.io/github/github-mcp-server:v1.0.0"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]}
# ___ _ _
# / _ \ | | (_)
@@ -22,7 +22,7 @@
#
# For more information: https://github.github.com/gh-aw/introduction/overview/
#
-# Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo
+# Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo
#
# Resolved workflow manifest:
# Imports:
@@ -190,7 +190,7 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
GH_AW_WORKFLOW_NAME: "Smoke Create Cross-Repo PR"
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -214,19 +214,19 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_a4d7ae5e3561acd9_EOF'
+ cat << 'GH_AW_PROMPT_0420ea7924b34dcb_EOF'
- GH_AW_PROMPT_a4d7ae5e3561acd9_EOF
+ GH_AW_PROMPT_0420ea7924b34dcb_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/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_a4d7ae5e3561acd9_EOF'
+ cat << 'GH_AW_PROMPT_0420ea7924b34dcb_EOF'
Tools: add_comment(max:2), create_issue, create_pull_request, missing_tool, missing_data, noop
- GH_AW_PROMPT_a4d7ae5e3561acd9_EOF
+ GH_AW_PROMPT_0420ea7924b34dcb_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
- cat << 'GH_AW_PROMPT_a4d7ae5e3561acd9_EOF'
+ cat << 'GH_AW_PROMPT_0420ea7924b34dcb_EOF'
The following GitHub context information is available for this workflow:
@@ -255,17 +255,17 @@ jobs:
- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
{{/if}}
- **checkouts**: The following repositories have been checked out and are available in the workspace:
- - `$GITHUB_WORKSPACE` → `githubnext/gh-aw-side-repo` (cwd) [shallow clone, fetch-depth=1 (default)]
+ - `$GITHUB_WORKSPACE` → `github/gh-aw-side-repo` (cwd) [shallow clone, fetch-depth=1 (default)]
- **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches).
- GH_AW_PROMPT_a4d7ae5e3561acd9_EOF
+ GH_AW_PROMPT_0420ea7924b34dcb_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_a4d7ae5e3561acd9_EOF'
+ cat << 'GH_AW_PROMPT_0420ea7924b34dcb_EOF'
{{#runtime-import .github/workflows/shared/observability-otlp.md}}
{{#runtime-import .github/workflows/smoke-create-cross-repo-pr.md}}
- GH_AW_PROMPT_a4d7ae5e3561acd9_EOF
+ GH_AW_PROMPT_0420ea7924b34dcb_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -396,11 +396,11 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- - name: Checkout githubnext/gh-aw-side-repo
+ - name: Checkout github/gh-aw-side-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- repository: githubnext/gh-aw-side-repo
+ repository: github/gh-aw-side-repo
token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
- name: Create gh-aw temp directory
run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
@@ -460,9 +460,9 @@ 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_2a41d056264725d2_EOF
- {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"labels":["automation","testing"],"max":1},"create_pull_request":{"draft":true,"expires":24,"fallback_as_issue":false,"github-token":"${GH_AW_SIDE_REPO_PAT}","if_no_changes":"error","labels":["smoke-test"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/"],"target-repo":"githubnext/gh-aw-side-repo","title_prefix":"[smoke] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_2a41d056264725d2_EOF
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << GH_AW_SAFE_OUTPUTS_CONFIG_6f9e329493efc8a8_EOF
+ {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"labels":["automation","testing"],"max":1},"create_pull_request":{"draft":true,"expires":24,"fallback_as_issue":false,"github-token":"${GH_AW_SIDE_REPO_PAT}","if_no_changes":"error","labels":["smoke-test"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/"],"target-repo":"github/gh-aw-side-repo","title_prefix":"[smoke] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_6f9e329493efc8a8_EOF
- name: Write Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -726,7 +726,7 @@ jobs:
mkdir -p /home/runner/.copilot
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_bc036f9a74cfcfbb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_cc43158393ecf2ed_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
@@ -773,7 +773,7 @@ jobs:
}
}
}
- GH_AW_MCP_CONFIG_bc036f9a74cfcfbb_EOF
+ GH_AW_MCP_CONFIG_cc43158393ecf2ed_EOF
- name: Download activation artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
@@ -1125,7 +1125,7 @@ jobs:
GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_TIMEOUT_MINUTES: "10"
@@ -1148,7 +1148,7 @@ jobs:
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -1251,7 +1251,7 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
WORKFLOW_NAME: "Smoke Create Cross-Repo PR"
- WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo"
+ WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo"
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
with:
script: |
@@ -1384,7 +1384,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
GH_AW_WORKFLOW_ID: "smoke-create-cross-repo-pr"
GH_AW_WORKFLOW_NAME: "Smoke Create Cross-Repo PR"
outputs:
@@ -1441,7 +1441,7 @@ jobs:
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
- repository: githubnext/gh-aw-side-repo
+ repository: github/gh-aw-side-repo
ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }}
token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
persist-credentials: false
@@ -1449,7 +1449,7 @@ jobs:
- name: Configure Git credentials
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
env:
- REPO_NAME: "githubnext/gh-aw-side-repo"
+ REPO_NAME: "github/gh-aw-side-repo"
SERVER_URL: ${{ github.server_url }}
GIT_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
run: |
@@ -1477,7 +1477,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,127.0.0.1,::1,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,app.renovatebot.com,appveyor.com,archive.ubuntu.com,azure.archive.ubuntu.com,badgen.net,circleci.com,codacy.com,codeclimate.com,codecov.io,codeload.github.com,coveralls.io,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,deepsource.io,docs.github.com,drone.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,img.shields.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,localhost,objects.githubusercontent.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,readthedocs.io,readthedocs.org,registry.npmjs.org,renovatebot.com,s.symcb.com,s.symcd.com,security.ubuntu.com,semaphoreci.com,shields.io,snyk.io,sonarcloud.io,sonarqube.com,telemetry.enterprise.githubcopilot.com,travis-ci.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: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request\":{\"draft\":true,\"expires\":24,\"fallback_as_issue\":false,\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"labels\":[\"smoke-test\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target-repo\":\"githubnext/gh-aw-side-repo\",\"title_prefix\":\"[smoke] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request\":{\"draft\":true,\"expires\":24,\"fallback_as_issue\":false,\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"labels\":[\"smoke-test\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target-repo\":\"github/gh-aw-side-repo\",\"title_prefix\":\"[smoke] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
with:
diff --git a/.github/workflows/smoke-create-cross-repo-pr.md b/.github/workflows/smoke-create-cross-repo-pr.md
index 554d38b1e8a..1464954c09f 100644
--- a/.github/workflows/smoke-create-cross-repo-pr.md
+++ b/.github/workflows/smoke-create-cross-repo-pr.md
@@ -1,6 +1,6 @@
---
name: Smoke Create Cross-Repo PR
-description: Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo
+description: Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo
on:
workflow_dispatch:
pull_request:
@@ -19,7 +19,7 @@ network:
- github
checkout:
- - repository: githubnext/gh-aw-side-repo
+ - repository: github/gh-aw-side-repo
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
tools:
@@ -33,7 +33,7 @@ tools:
safe-outputs:
allowed-domains: [default-safe-outputs]
create-pull-request:
- target-repo: "githubnext/gh-aw-side-repo"
+ target-repo: "github/gh-aw-side-repo"
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
title-prefix: "[smoke] "
labels: [smoke-test]
@@ -50,8 +50,8 @@ safe-outputs:
max: 2
messages:
footer: "> 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}"
- run-started: "🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo..."
- run-success: "✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!"
+ run-started: "🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo..."
+ run-success: "✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!"
run-failure: "❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}"
timeout-minutes: 10
diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml
index 7d76d117232..0875fda71f4 100644
--- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml
+++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"72e74209f519ac8a58429a763b6209ce0cfc5f4400a65afc569d4000defeb89a","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5b785f55ba2a16a818befb3d75af99bead1554141d32d0929c26c762b0075dd6","strict":true,"agent_id":"copilot"}
# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GH_AW_SIDE_REPO_PAT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.25"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.25"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.25"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.25"},{"image":"ghcr.io/github/github-mcp-server:v1.0.0"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]}
# ___ _ _
# / _ \ | | (_)
@@ -22,7 +22,7 @@
#
# For more information: https://github.github.com/gh-aw/introduction/overview/
#
-# Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README
+# Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README
#
# Resolved workflow manifest:
# Imports:
@@ -192,7 +192,7 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
GH_AW_WORKFLOW_NAME: "Smoke Update Cross-Repo PR"
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -216,20 +216,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_4524bd3388c5bf7b_EOF'
+ cat << 'GH_AW_PROMPT_95b80c043e2e7005_EOF'
- GH_AW_PROMPT_4524bd3388c5bf7b_EOF
+ GH_AW_PROMPT_95b80c043e2e7005_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/cache_memory_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_4524bd3388c5bf7b_EOF'
+ cat << 'GH_AW_PROMPT_95b80c043e2e7005_EOF'
Tools: add_comment(max:2), create_issue, push_to_pull_request_branch, missing_tool, missing_data, noop
- GH_AW_PROMPT_4524bd3388c5bf7b_EOF
+ GH_AW_PROMPT_95b80c043e2e7005_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md"
- cat << 'GH_AW_PROMPT_4524bd3388c5bf7b_EOF'
+ cat << 'GH_AW_PROMPT_95b80c043e2e7005_EOF'
The following GitHub context information is available for this workflow:
@@ -258,17 +258,17 @@ jobs:
- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
{{/if}}
- **checkouts**: The following repositories have been checked out and are available in the workspace:
- - `$GITHUB_WORKSPACE` → `githubnext/gh-aw-side-repo` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: main, refs/pulls/open/*]
+ - `$GITHUB_WORKSPACE` → `github/gh-aw-side-repo` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: main, refs/pulls/open/*]
- **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches).
- GH_AW_PROMPT_4524bd3388c5bf7b_EOF
+ GH_AW_PROMPT_95b80c043e2e7005_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_4524bd3388c5bf7b_EOF'
+ cat << 'GH_AW_PROMPT_95b80c043e2e7005_EOF'
{{#runtime-import .github/workflows/shared/observability-otlp.md}}
{{#runtime-import .github/workflows/smoke-update-cross-repo-pr.md}}
- GH_AW_PROMPT_4524bd3388c5bf7b_EOF
+ GH_AW_PROMPT_95b80c043e2e7005_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -405,14 +405,14 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- - name: Checkout githubnext/gh-aw-side-repo
+ - name: Checkout github/gh-aw-side-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- repository: githubnext/gh-aw-side-repo
+ repository: github/gh-aw-side-repo
token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
fetch-depth: 0
- - name: Fetch additional refs for githubnext/gh-aw-side-repo
+ - name: Fetch additional refs for github/gh-aw-side-repo
env:
GH_AW_FETCH_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
run: |
@@ -491,9 +491,9 @@ 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_fa6946bcf33a49e7_EOF
- {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"labels":["automation","testing"],"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"github-token":"${GH_AW_SIDE_REPO_PAT}","if_no_changes":"error","max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/"],"target":"1","target-repo":"githubnext/gh-aw-side-repo"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_fa6946bcf33a49e7_EOF
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << GH_AW_SAFE_OUTPUTS_CONFIG_e4863e5cb9b826e6_EOF
+ {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"labels":["automation","testing"],"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"github-token":"${GH_AW_SIDE_REPO_PAT}","if_no_changes":"error","max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/"],"target":"1","target-repo":"github/gh-aw-side-repo"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_e4863e5cb9b826e6_EOF
- name: Write Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -735,7 +735,7 @@ jobs:
mkdir -p /home/runner/.copilot
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_c5bec9ad3d1e0dc9_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_770e0ca1bdd5fb05_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
@@ -782,7 +782,7 @@ jobs:
}
}
}
- GH_AW_MCP_CONFIG_c5bec9ad3d1e0dc9_EOF
+ GH_AW_MCP_CONFIG_770e0ca1bdd5fb05_EOF
- name: Download activation artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
@@ -1146,7 +1146,7 @@ jobs:
GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_TIMEOUT_MINUTES: "10"
@@ -1169,7 +1169,7 @@ jobs:
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -1272,7 +1272,7 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
WORKFLOW_NAME: "Smoke Update Cross-Repo PR"
- WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README"
+ WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README"
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
with:
script: |
@@ -1405,7 +1405,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
GH_AW_WORKFLOW_ID: "smoke-update-cross-repo-pr"
GH_AW_WORKFLOW_NAME: "Smoke Update Cross-Repo PR"
outputs:
@@ -1497,7 +1497,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,127.0.0.1,::1,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,app.renovatebot.com,appveyor.com,archive.ubuntu.com,azure.archive.ubuntu.com,badgen.net,circleci.com,codacy.com,codeclimate.com,codecov.io,codeload.github.com,coveralls.io,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,deepsource.io,docs.github.com,drone.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,img.shields.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,localhost,objects.githubusercontent.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,readthedocs.io,readthedocs.org,registry.npmjs.org,renovatebot.com,s.symcb.com,s.symcd.com,security.ubuntu.com,semaphoreci.com,shields.io,snyk.io,sonarcloud.io,sonarqube.com,telemetry.enterprise.githubcopilot.com,travis-ci.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: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"1\",\"target-repo\":\"githubnext/gh-aw-side-repo\"},\"report_incomplete\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"1\",\"target-repo\":\"github/gh-aw-side-repo\"},\"report_incomplete\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
with:
diff --git a/.github/workflows/smoke-update-cross-repo-pr.md b/.github/workflows/smoke-update-cross-repo-pr.md
index be40456a6a2..1eea5a5482c 100644
--- a/.github/workflows/smoke-update-cross-repo-pr.md
+++ b/.github/workflows/smoke-update-cross-repo-pr.md
@@ -1,6 +1,6 @@
---
name: Smoke Update Cross-Repo PR
-description: Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README
+description: Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README
on:
workflow_dispatch:
@@ -20,7 +20,7 @@ network:
- github
checkout:
- - repository: githubnext/gh-aw-side-repo
+ - repository: github/gh-aw-side-repo
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
fetch: ["main", "refs/pulls/open/*"] # fetch all open PR refs after checkout
fetch-depth: 0 # fetch full history to ensure we can see all commits and PR details
@@ -44,13 +44,13 @@ safe-outputs:
hide-older-comments: true
max: 2
push-to-pull-request-branch:
- target-repo: "githubnext/gh-aw-side-repo"
+ target-repo: "github/gh-aw-side-repo"
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
if-no-changes: "error"
target: "1" # PR #1
messages:
footer: "> 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}"
- run-started: "📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1..."
+ run-started: "📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1..."
run-success: "✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!"
run-failure: "❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}"
diff --git a/docs/src/content/docs/agent-factory-status.mdx b/docs/src/content/docs/agent-factory-status.mdx
index 00921406afe..a7b60fd0fb1 100644
--- a/docs/src/content/docs/agent-factory-status.mdx
+++ b/docs/src/content/docs/agent-factory-status.mdx
@@ -9,6 +9,7 @@ These are experimental agentic workflows used by the GitHub Next team to learn,
| Workflow | Agent | Status | Schedule | Command |
|:---------|:-----:|:------:|:--------:|:-------:|
+| [[aw] Failure Investigator (6h)](https://github.com/github/gh-aw/blob/main/.github/workflows/aw-failure-investigator.md) | claude | [![[aw] Failure Investigator (6h)](https://github.com/github/gh-aw/actions/workflows/aw-failure-investigator.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/aw-failure-investigator.lock.yml) | `every 6h` | - |
| [/cloclo](https://github.com/github/gh-aw/blob/main/.github/workflows/cloclo.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/cloclo.lock.yml) | - | `/cloclo` |
| [ACE Editor Session](https://github.com/github/gh-aw/blob/main/.github/workflows/ace-editor.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/ace-editor.lock.yml) | - | `/ace` |
| [Agent Container Smoke Test](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-test-tools.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-test-tools.lock.yml) | - | - |
@@ -47,10 +48,12 @@ These are experimental agentic workflows used by the GitHub Next team to learn,
| [Copilot Agent PR Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-agent-analysis.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/copilot-agent-analysis.lock.yml) | - | - |
| [Copilot Agent Prompt Clustering Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/prompt-clustering-analysis.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/prompt-clustering-analysis.lock.yml) | - | - |
| [Copilot CLI Deep Research Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-cli-deep-research.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-cli-deep-research.lock.yml) | - | - |
+| [Copilot Opt](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-opt.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-opt.lock.yml) | `weekly on monday` | - |
| [Copilot PR Conversation NLP Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-pr-nlp-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-pr-nlp-analysis.lock.yml) | `daily around 10:00 on weekdays` | - |
| [Copilot PR Prompt Pattern Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-pr-prompt-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-pr-prompt-analysis.lock.yml) | - | - |
| [Copilot Session Insights](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-session-insights.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/copilot-session-insights.lock.yml) | - | - |
| [Copilot Token Usage Optimizer](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-token-optimizer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-token-optimizer.lock.yml) | `daily around 14:00 on weekdays` | - |
+| [Daily AW Cross-Repo Compile Check](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-aw-cross-repo-compile-check.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-aw-cross-repo-compile-check.lock.yml) | - | - |
| [Daily Choice Type Test](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-choice-test.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-choice-test.lock.yml) | `daily around 12:00 on weekdays` | - |
| [Daily CLI Performance Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-cli-performance.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-cli-performance.lock.yml) | - | - |
| [Daily CLI Tools Exploratory Tester](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-cli-tools-tester.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-cli-tools-tester.lock.yml) | - | - |
@@ -159,11 +162,13 @@ These are experimental agentic workflows used by the GitHub Next team to learn,
| [Smoke Agent: public/none](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-public-none.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-public-none.lock.yml) | - | - |
| [Smoke Agent: scoped/approved](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-scoped-approved.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-scoped-approved.lock.yml) | - | - |
| [Smoke Call Workflow](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-call-workflow.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/smoke-call-workflow.lock.yml) | - | - |
+| [Smoke CI](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-ci.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-ci.lock.yml) | - | - |
| [Smoke Claude](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-claude.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-claude.lock.yml) | - | - |
| [Smoke Codex](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-codex.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/smoke-codex.lock.yml) | - | - |
| [Smoke Copilot](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-copilot.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-copilot.lock.yml) | - | - |
| [Smoke Copilot ARM64](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-copilot-arm.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-copilot-arm.lock.yml) | - | - |
| [Smoke Create Cross-Repo PR](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-create-cross-repo-pr.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-create-cross-repo-pr.lock.yml) | - | - |
+| [Smoke Crush](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-crush.md) | crush | [](https://github.com/github/gh-aw/actions/workflows/smoke-crush.lock.yml) | - | - |
| [Smoke Gemini](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-gemini.md) | gemini | [](https://github.com/github/gh-aw/actions/workflows/smoke-gemini.lock.yml) | - | - |
| [Smoke Multi PR](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-multi-pr.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-multi-pr.lock.yml) | - | - |
| [Smoke Project](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-project.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-project.lock.yml) | - | - |
diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md
index e29e729d7a6..04c81d72c0d 100644
--- a/docs/src/content/docs/reference/frontmatter-full.md
+++ b/docs/src/content/docs/reference/frontmatter-full.md
@@ -34,6 +34,13 @@ description: "Description of the workflow"
# (optional)
source: "example-value"
+# Optional workflow location redirect for updates. Format: workflow spec or GitHub
+# URL (e.g., owner/repo/path@ref or
+# https://github.com/owner/repo/blob/main/path.md). When present, update follows
+# this location and rewrites source.
+# (optional)
+redirect: "example-value"
+
# Optional tracker identifier to tag all created assets (issues, discussions,
# comments, pull requests). Must be at least 8 characters and contain only
# alphanumeric characters, hyphens, and underscores. This identifier will be
@@ -820,9 +827,10 @@ on:
# (optional)
# This field supports multiple formats (oneOf):
- # Option 1: Allow any authenticated user to trigger the workflow (⚠️ disables
- # permission checking entirely - use with caution)
- roles: "all"
+ # Option 1: Single repository permission level that can trigger the workflow. Use
+ # 'all' to allow any authenticated user (⚠️ disables permission checking entirely
+ # - use with caution)
+ roles: "admin"
# Option 2: List of repository permission levels that can trigger the workflow.
# Permission checks are automatically applied to potentially unsafe triggers.
@@ -1530,8 +1538,8 @@ engine: "example-value"
# Option 2: Extended engine configuration object with advanced options for model
# selection, turn limiting, environment variables, and custom steps
engine:
- # AI engine identifier: built-in ('claude', 'codex', 'copilot', 'gemini',
- # 'crush') or a named catalog entry
+ # AI engine identifier: built-in ('claude', 'codex', 'copilot', 'gemini', 'crush')
+ # or a named catalog entry
id: "example-value"
# Optional version of the AI engine action (e.g., 'beta', 'stable', 20). Has
@@ -1764,8 +1772,7 @@ engine:
# Option 4: Engine definition: full declarative metadata for a named engine entry
# (used in builtin engine shared workflow files such as @builtin:engines/*.md)
engine:
- # Unique engine identifier (e.g. 'copilot', 'claude', 'codex', 'gemini',
- # 'crush')
+ # Unique engine identifier (e.g. 'copilot', 'claude', 'codex', 'gemini', 'crush')
id: "example-value"
# Human-readable display name for the engine
@@ -3407,6 +3414,18 @@ safe-outputs:
reviewers: []
# Array items: string
+ # Optional team reviewer(s) to assign to the pull request. Accepts either a single
+ # string or an array of team slugs.
+ # (optional)
+ # This field supports multiple formats (oneOf):
+
+ # Option 1: Single team slug to assign as a reviewer to the pull request.
+ team-reviewers: "example-value"
+
+ # Option 2: List of team slugs to assign as reviewers to the pull request.
+ team-reviewers: []
+ # Array items: string
+
# Optional assignee(s) for a fallback issue created when pull request creation
# cannot proceed, including protected-files fallback-to-issue and pull request
# creation or push failures. Accepts either a single string or an array of
@@ -3485,6 +3504,14 @@ safe-outputs:
# (optional)
base-branch: "example-value"
+ # Optional list of allowed base branch patterns (glob syntax, e.g. 'main',
+ # 'release/*'). When configured, the agent may provide a `base` field in
+ # create_pull_request output to override base-branch for a single run, but only if
+ # it matches one of these patterns.
+ # (optional)
+ allowed-base-branches: []
+ # Array of strings
+
# Controls whether AI-generated footer is added to the pull request. When false,
# the visible footer content is omitted but XML markers (workflow-id, tracker-id,
# metadata) are still included for searchability. Defaults to true.
@@ -4036,6 +4063,18 @@ safe-outputs:
reviewers: []
# Array of strings
+ # Optional allowed team reviewer or list of allowed team reviewers. If omitted,
+ # any team reviewers are allowed.
+ # (optional)
+ # This field supports multiple formats (oneOf):
+
+ # Option 1: string
+ team-reviewers: "example-value"
+
+ # Option 2: array
+ team-reviewers: []
+ # Array items: string
+
# Optional maximum number of reviewers to add (default: 3) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
@@ -4576,6 +4615,12 @@ safe-outputs:
# (optional)
if-no-changes: "warn"
+ # When true, treat deleted/missing pull request branch errors as a skipped push
+ # instead of a hard failure. Useful when the PR branch may be deleted before safe
+ # outputs run.
+ # (optional)
+ ignore-missing-branch-failure: true
+
# Optional suffix to append to generated commit titles (e.g., ' [skip ci]' to
# prevent triggering CI on the commit)
# (optional)
From f0386edddf5463435bd5cf6e0fe57f54124c0619 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 19 Apr 2026 23:47:22 +0000
Subject: [PATCH 02/10] feat: add merge-base support to update-pull-request
safe output
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/340b546b-743d-45b6-ac7e-8ec5735124d3
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
actions/setup/js/safe_outputs_tools.json | 4 +
actions/setup/js/types/safe-outputs.d.ts | 2 +
actions/setup/js/update_pull_request.cjs | 29 ++++++-
actions/setup/js/update_pull_request.test.cjs | 87 +++++++++++++++++++
pkg/parser/schemas/main_workflow_schema.json | 4 +
.../compiler_safe_outputs_config_test.go | 59 +++++++++++++
.../compiler_safe_outputs_handlers.go | 1 +
pkg/workflow/js/safe_outputs_tools.json | 4 +
.../safe_output_validation_config_test.go | 16 ++++
.../safe_outputs_validation_config.go | 3 +-
pkg/workflow/update_pull_request_helpers.go | 2 +
11 files changed, 209 insertions(+), 2 deletions(-)
diff --git a/actions/setup/js/safe_outputs_tools.json b/actions/setup/js/safe_outputs_tools.json
index 3d87db2ed1d..58990088bf3 100644
--- a/actions/setup/js/safe_outputs_tools.json
+++ b/actions/setup/js/safe_outputs_tools.json
@@ -783,6 +783,10 @@
"enum": ["replace", "append", "prepend"],
"description": "How to update the PR body: 'replace' (default - completely overwrite), 'append' (add to end with separator), or 'prepend' (add to start with separator). Title is always replaced."
},
+ "merge_base": {
+ "type": "boolean",
+ "description": "When true, update the pull request branch with the latest base branch changes before applying other updates. Defaults to false."
+ },
"pull_request_number": {
"type": ["number", "string"],
"description": "Pull request number to update. This is the numeric ID from the GitHub URL (e.g., 234 in github.com/owner/repo/pull/234). Required when the workflow target is '*' (any PR)."
diff --git a/actions/setup/js/types/safe-outputs.d.ts b/actions/setup/js/types/safe-outputs.d.ts
index b57933516c0..fb5ff47438c 100644
--- a/actions/setup/js/types/safe-outputs.d.ts
+++ b/actions/setup/js/types/safe-outputs.d.ts
@@ -235,6 +235,8 @@ interface UpdatePullRequestItem extends BaseSafeOutputItem {
body?: string;
/** Update operation for body: 'replace' (default), 'append', or 'prepend' */
operation?: "replace" | "append" | "prepend";
+ /** When true, merges the latest base branch changes into the pull request branch before other updates */
+ merge_base?: boolean;
/** Optional pull request number for target "*" */
pull_request_number?: number | string;
/** Whether the PR should be a draft (true) or ready for review (false) */
diff --git a/actions/setup/js/update_pull_request.cjs b/actions/setup/js/update_pull_request.cjs
index 9400f174490..804b0ddc28b 100644
--- a/actions/setup/js/update_pull_request.cjs
+++ b/actions/setup/js/update_pull_request.cjs
@@ -32,6 +32,17 @@ async function executePRUpdate(github, context, prNumber, updateData) {
// Remove internal fields
const { _operation, _rawBody, _includeFooter, _workflowRepo, ...apiData } = updateData;
+ const mergeBase = apiData.merge_base === true;
+ delete apiData.merge_base;
+
+ if (mergeBase) {
+ core.info(`Updating pull request #${prNumber} branch with base branch changes`);
+ await github.rest.pulls.updateBranch({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: prNumber,
+ });
+ }
// If we have a body, process it with the appropriate operation
if (rawBody !== undefined) {
@@ -77,6 +88,15 @@ async function executePRUpdate(github, context, prNumber, updateData) {
core.info(`Will update body (length: ${apiData.body.length})`);
}
+ if (Object.keys(apiData).length === 0) {
+ const { data: pr } = await github.rest.pulls.get({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: prNumber,
+ });
+ return pr;
+ }
+
const { data: pr } = await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -141,6 +161,12 @@ function buildPRUpdateData(item, config) {
hasUpdates = true;
}
+ const mergeBase = item.merge_base !== undefined ? item.merge_base === true : config.merge_base === true;
+ if (mergeBase) {
+ updateData.merge_base = true;
+ hasUpdates = true;
+ }
+
if (!hasUpdates) {
return {
success: true,
@@ -181,7 +207,8 @@ const main = createUpdateHandlerFactory({
additionalConfig: {
allow_title: true,
allow_body: true,
+ merge_base: false,
},
});
-module.exports = { main };
+module.exports = { main, buildPRUpdateData };
diff --git a/actions/setup/js/update_pull_request.test.cjs b/actions/setup/js/update_pull_request.test.cjs
index 522d66bddc4..c63532b5196 100644
--- a/actions/setup/js/update_pull_request.test.cjs
+++ b/actions/setup/js/update_pull_request.test.cjs
@@ -23,6 +23,7 @@ const mockGithub = {
pulls: {
get: vi.fn(),
update: vi.fn(),
+ updateBranch: vi.fn(),
},
},
};
@@ -81,6 +82,11 @@ describe("update_pull_request.cjs - executePRUpdate function", () => {
html_url: "https://github.com/testowner/testrepo/pull/100",
},
});
+ mockGithub.rest.pulls.updateBranch.mockResolvedValue({
+ data: {
+ message: "Branch updated",
+ },
+ });
});
describe("Replace operation", () => {
@@ -738,3 +744,84 @@ describe("update_pull_request.cjs - executePRUpdate function", () => {
});
});
});
+
+describe("update_pull_request.cjs - merge_base behavior", () => {
+ beforeEach(async () => {
+ vi.clearAllMocks();
+ vi.resetModules();
+
+ updatePRModule = await import("./update_pull_request.cjs");
+
+ mockGithub.rest.pulls.get.mockResolvedValue({
+ data: {
+ number: 100,
+ title: "Test PR",
+ body: "Original body content",
+ html_url: "https://github.com/testowner/testrepo/pull/100",
+ },
+ });
+
+ mockGithub.rest.pulls.update.mockResolvedValue({
+ data: {
+ number: 100,
+ title: "Updated PR",
+ body: "Original body content",
+ html_url: "https://github.com/testowner/testrepo/pull/100",
+ },
+ });
+
+ mockGithub.rest.pulls.updateBranch.mockResolvedValue({
+ data: {
+ message: "Branch updated",
+ },
+ });
+ });
+
+ it("should include merge_base when item requests it", () => {
+ const result = updatePRModule.buildPRUpdateData({ merge_base: true }, {});
+
+ expect(result.success).toBe(true);
+ expect(result.data.merge_base).toBe(true);
+ });
+
+ it("should inherit merge_base from config when item does not set it", () => {
+ const result = updatePRModule.buildPRUpdateData({}, { merge_base: true });
+
+ expect(result.success).toBe(true);
+ expect(result.data.merge_base).toBe(true);
+ });
+
+ it("should call updateBranch when merge_base is enabled and no other fields are updated", async () => {
+ const handlerFactory = await updatePRModule.main();
+ const handler = await handlerFactory({ merge_base: true });
+
+ const result = await handler({ pull_request_number: 100 });
+
+ expect(result.success).toBe(true);
+ expect(mockGithub.rest.pulls.updateBranch).toHaveBeenCalledWith({
+ owner: "testowner",
+ repo: "testrepo",
+ pull_number: 100,
+ });
+ expect(mockGithub.rest.pulls.update).not.toHaveBeenCalled();
+ });
+
+ it("should call updateBranch before pulls.update when merge_base and title update are both requested", async () => {
+ const handlerFactory = await updatePRModule.main();
+ const handler = await handlerFactory({});
+
+ await handler({
+ pull_request_number: 100,
+ title: "Updated PR",
+ merge_base: true,
+ });
+
+ expect(mockGithub.rest.pulls.updateBranch).toHaveBeenCalled();
+ expect(mockGithub.rest.pulls.update).toHaveBeenCalledWith({
+ owner: "testowner",
+ repo: "testrepo",
+ pull_number: 100,
+ title: "Updated PR",
+ });
+ });
+});
diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json
index 23994195e59..89e9395fb40 100644
--- a/pkg/parser/schemas/main_workflow_schema.json
+++ b/pkg/parser/schemas/main_workflow_schema.json
@@ -6976,6 +6976,10 @@
"type": "boolean",
"description": "Allow updating pull request body - defaults to true, set to false to disable"
},
+ "merge-base": {
+ "type": "boolean",
+ "description": "When true, update the pull request branch with the latest base branch changes before applying other updates. Defaults to false."
+ },
"operation": {
"type": "string",
"description": "Default operation for body updates: 'append' (add to end), 'prepend' (add to start), or 'replace' (overwrite completely). Defaults to 'replace' if not specified.",
diff --git a/pkg/workflow/compiler_safe_outputs_config_test.go b/pkg/workflow/compiler_safe_outputs_config_test.go
index 23666116af1..8759f6cfb56 100644
--- a/pkg/workflow/compiler_safe_outputs_config_test.go
+++ b/pkg/workflow/compiler_safe_outputs_config_test.go
@@ -1203,6 +1203,65 @@ func TestHandlerConfigUpdateFields(t *testing.T) {
}
}
+func TestUpdatePullRequestMergeBaseHandlerConfig(t *testing.T) {
+ tests := []struct {
+ name string
+ mergeBase *bool
+ expected bool
+ }{
+ {
+ name: "defaults merge_base to false",
+ mergeBase: nil,
+ expected: false,
+ },
+ {
+ name: "sets merge_base true when configured",
+ mergeBase: testBoolPtr(true),
+ expected: true,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ compiler := NewCompiler()
+
+ workflowData := &WorkflowData{
+ Name: "Test Workflow",
+ SafeOutputs: &SafeOutputsConfig{
+ UpdatePullRequests: &UpdatePullRequestsConfig{
+ MergeBase: tt.mergeBase,
+ },
+ },
+ }
+
+ var steps []string
+ compiler.addHandlerManagerConfigEnvVar(&steps, workflowData)
+
+ for _, step := range steps {
+ if strings.Contains(step, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG") {
+ parts := strings.Split(step, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: ")
+ if len(parts) == 2 {
+ jsonStr := strings.TrimSpace(parts[1])
+ jsonStr = strings.Trim(jsonStr, "\"")
+ jsonStr = strings.ReplaceAll(jsonStr, "\\\"", "\"")
+
+ var config map[string]map[string]any
+ err := json.Unmarshal([]byte(jsonStr), &config)
+ require.NoError(t, err)
+
+ updatePRConfig, ok := config["update_pull_request"]
+ require.True(t, ok, "Expected update_pull_request config")
+
+ mergeBaseValue, ok := updatePRConfig["merge_base"]
+ require.True(t, ok, "Expected merge_base key in update_pull_request config")
+ assert.Equal(t, tt.expected, mergeBaseValue)
+ }
+ }
+ }
+ })
+ }
+}
+
// TestEmptySafeOutputsConfig tests behavior with no safe outputs
func TestEmptySafeOutputsConfig(t *testing.T) {
compiler := NewCompiler()
diff --git a/pkg/workflow/compiler_safe_outputs_handlers.go b/pkg/workflow/compiler_safe_outputs_handlers.go
index c42bb7abc61..9469324e105 100644
--- a/pkg/workflow/compiler_safe_outputs_handlers.go
+++ b/pkg/workflow/compiler_safe_outputs_handlers.go
@@ -437,6 +437,7 @@ var handlerRegistry = map[string]handlerBuilder{
AddIfNotEmpty("target", c.Target).
AddBoolPtrOrDefault("allow_title", c.Title, true).
AddBoolPtrOrDefault("allow_body", c.Body, true).
+ AddBoolPtrOrDefault("merge_base", c.MergeBase, false).
AddStringPtr("default_operation", c.Operation).
AddTemplatableBool("footer", getEffectiveFooterForTemplatable(c.Footer, cfg.Footer)).
AddIfNotEmpty("target-repo", c.TargetRepoSlug).
diff --git a/pkg/workflow/js/safe_outputs_tools.json b/pkg/workflow/js/safe_outputs_tools.json
index c640af9a387..fdb5b110788 100644
--- a/pkg/workflow/js/safe_outputs_tools.json
+++ b/pkg/workflow/js/safe_outputs_tools.json
@@ -935,6 +935,10 @@
],
"description": "How to update the PR body: 'replace' (default - completely overwrite), 'append' (add to end with separator), or 'prepend' (add to start with separator). Title is always replaced."
},
+ "merge_base": {
+ "type": "boolean",
+ "description": "When true, update the pull request branch with the latest base branch changes before applying other updates. Defaults to false."
+ },
"pull_request_number": {
"type": [
"number",
diff --git a/pkg/workflow/safe_output_validation_config_test.go b/pkg/workflow/safe_output_validation_config_test.go
index c90b706ff68..9ae1fa97dfe 100644
--- a/pkg/workflow/safe_output_validation_config_test.go
+++ b/pkg/workflow/safe_output_validation_config_test.go
@@ -188,11 +188,27 @@ func TestUpdateDiscussionValidationConfig(t *testing.T) {
}
}
+func TestUpdatePullRequestValidationConfig(t *testing.T) {
+ config, ok := ValidationConfig["update_pull_request"]
+ if !ok {
+ t.Fatal("update_pull_request not found in ValidationConfig")
+ }
+
+ if config.CustomValidation != "requiresOneOf:title,body,merge_base" {
+ t.Errorf("update_pull_request customValidation = %q, want %q", config.CustomValidation, "requiresOneOf:title,body,merge_base")
+ }
+
+ if _, ok := config.Fields["merge_base"]; !ok {
+ t.Error("update_pull_request Fields is missing the 'merge_base' field")
+ }
+}
+
func TestValidationConfigConsistency(t *testing.T) {
// Verify that all types with customValidation have valid validation rules
validCustomValidations := map[string]bool{
"requiresOneOf:status,title,body": true,
"requiresOneOf:title,body": true,
+ "requiresOneOf:title,body,merge_base": true,
"requiresOneOf:title,body,labels": true,
"requiresOneOf:issue_number,pull_number": true,
"requiresOneOf:reviewers,team_reviewers": true,
diff --git a/pkg/workflow/safe_outputs_validation_config.go b/pkg/workflow/safe_outputs_validation_config.go
index 98cc8729e56..5a9692245da 100644
--- a/pkg/workflow/safe_outputs_validation_config.go
+++ b/pkg/workflow/safe_outputs_validation_config.go
@@ -154,11 +154,12 @@ var ValidationConfig = map[string]TypeValidationConfig{
},
"update_pull_request": {
DefaultMax: 1,
- CustomValidation: "requiresOneOf:title,body",
+ CustomValidation: "requiresOneOf:title,body,merge_base",
Fields: map[string]FieldValidation{
"title": {Type: "string", Sanitize: true, MaxLength: 256},
"body": {Type: "string", Sanitize: true, MaxLength: MaxBodyLength},
"operation": {Type: "string", Enum: []string{"replace", "append", "prepend"}},
+ "merge_base": {Type: "boolean"},
"draft": {Type: "boolean"},
"pull_request_number": {IssueOrPRNumber: true},
"repo": {Type: "string", MaxLength: 256}, // Optional: target repository in format "owner/repo"
diff --git a/pkg/workflow/update_pull_request_helpers.go b/pkg/workflow/update_pull_request_helpers.go
index 058e783e524..3140a20f55d 100644
--- a/pkg/workflow/update_pull_request_helpers.go
+++ b/pkg/workflow/update_pull_request_helpers.go
@@ -14,6 +14,7 @@ type UpdatePullRequestsConfig struct {
UpdateEntityConfig `yaml:",inline"`
Title *bool `yaml:"title,omitempty"` // Allow updating PR title - defaults to true, set to false to disable
Body *bool `yaml:"body,omitempty"` // Allow updating PR body - defaults to true, set to false to disable
+ MergeBase *bool `yaml:"merge-base,omitempty"` // When true, update PR branch with latest base branch changes before applying other updates. Defaults to false.
Operation *string `yaml:"operation,omitempty"` // Default operation for body updates: "append", "prepend", or "replace" (defaults to "replace")
Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted.
}
@@ -28,6 +29,7 @@ func (c *Compiler) parseUpdatePullRequestsConfig(outputMap map[string]any) *Upda
return []UpdateEntityFieldSpec{
{Name: "title", Mode: FieldParsingBoolValue, Dest: &cfg.Title},
{Name: "body", Mode: FieldParsingBoolValue, Dest: &cfg.Body},
+ {Name: "merge-base", Mode: FieldParsingBoolValue, Dest: &cfg.MergeBase},
{Name: "footer", Mode: FieldParsingTemplatableBool, StringDest: &cfg.Footer},
}
}, func(configMap map[string]any, cfg *UpdatePullRequestsConfig) {
From 0405d9ec7aa1fda3370c97bbd127112951d43fab Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 19 Apr 2026 23:54:23 +0000
Subject: [PATCH 03/10] chore: keep PR scoped and finalize merge-base
validation updates
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/340b546b-743d-45b6-ac7e-8ec5735124d3
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/changeset.lock.yml | 9 ++--
.github/workflows/requirements.txt | 1 -
.github/workflows/smoke-claude.lock.yml | 9 ++--
.../smoke-create-cross-repo-pr.lock.yml | 52 +++++++++----------
.../workflows/smoke-create-cross-repo-pr.md | 10 ++--
.../smoke-update-cross-repo-pr.lock.yml | 50 +++++++++---------
.../workflows/smoke-update-cross-repo-pr.md | 8 +--
actions/setup/js/update_pull_request.test.cjs | 6 +--
.../src/content/docs/agent-factory-status.mdx | 5 --
.../docs/reference/frontmatter-full.md | 5 ++
pkg/workflow/update_pull_request_helpers.go | 8 +--
11 files changed, 83 insertions(+), 80 deletions(-)
diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml
index f7b01ce4e57..43498f5df12 100644
--- a/.github/workflows/changeset.lock.yml
+++ b/.github/workflows/changeset.lock.yml
@@ -463,7 +463,7 @@ jobs:
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_8597b0f49e0186a1_EOF'
- {"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"allowed_files":[".changeset/**"],"commit_title_suffix":" [skip-ci]","if_no_changes":"warn","max_patch_size":1024,"patch_format":"bundle","protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/",".codex/"]},"report_incomplete":{},"update_pull_request":{"allow_body":true,"allow_title":false,"default_operation":"append","max":1}}
+ {"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"allowed_files":[".changeset/**"],"commit_title_suffix":" [skip-ci]","if_no_changes":"warn","max_patch_size":1024,"patch_format":"bundle","protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/",".codex/"]},"report_incomplete":{},"update_pull_request":{"allow_body":true,"allow_title":false,"default_operation":"append","max":1,"merge_base":false}}
GH_AW_SAFE_OUTPUTS_CONFIG_8597b0f49e0186a1_EOF
- name: Write Safe Outputs Tools
env:
@@ -581,6 +581,9 @@ jobs:
"draft": {
"type": "boolean"
},
+ "merge_base": {
+ "type": "boolean"
+ },
"operation": {
"type": "string",
"enum": [
@@ -602,7 +605,7 @@ jobs:
"maxLength": 256
}
},
- "customValidation": "requiresOneOf:title,body"
+ "customValidation": "requiresOneOf:title,body,merge_base"
}
}
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -1208,7 +1211,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,172.30.0.1,api.npms.io,api.openai.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,codeload.github.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,deb.nodesource.com,deno.land,docs.github.com,esm.sh,get.pnpm.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,go.dev,golang.org,googleapis.deno.dev,googlechromelabs.github.io,goproxy.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lfs.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.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,openai.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkg.go.dev,ppa.launchpad.net,proxy.golang.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,sum.golang.org,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\".changeset/**\"],\"commit_title_suffix\":\" [skip-ci]\",\"if_no_changes\":\"warn\",\"max_patch_size\":1024,\"patch_format\":\"bundle\",\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".codex/\"]},\"report_incomplete\":{},\"update_pull_request\":{\"allow_body\":true,\"allow_title\":false,\"default_operation\":\"append\",\"max\":1}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\".changeset/**\"],\"commit_title_suffix\":\" [skip-ci]\",\"if_no_changes\":\"warn\",\"max_patch_size\":1024,\"patch_format\":\"bundle\",\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".codex/\"]},\"report_incomplete\":{},\"update_pull_request\":{\"allow_body\":true,\"allow_title\":false,\"default_operation\":\"append\",\"max\":1,\"merge_base\":false}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/requirements.txt b/.github/workflows/requirements.txt
index abcda1723e7..56829fdbd0f 100644
--- a/.github/workflows/requirements.txt
+++ b/.github/workflows/requirements.txt
@@ -1,4 +1,3 @@
-"mempalace==3.2.0"
markitdown-mcp
numpy
scikit-learn
diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml
index a4eeb2e1933..18f4d34504f 100644
--- a/.github/workflows/smoke-claude.lock.yml
+++ b/.github/workflows/smoke-claude.lock.yml
@@ -973,7 +973,7 @@ jobs:
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_12c35d07cbe22e8f_EOF'
- {"add_comment":{"hide_older_comments":true,"max":2},"add_labels":{"allowed":["smoke-claude"]},"add_reviewer":{"max":2,"target":"*"},"close_pull_request":{"max":1,"staged":true},"create_code_scanning_alert":{"driver":"Smoke Claude"},"create_issue":{"close_older_issues":true,"close_older_key":"smoke-claude","expires":2,"group":true,"labels":["automation","testing"],"max":1},"create_pull_request_review_comment":{"max":5,"side":"RIGHT","target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"post_slack_message":{"description":"Post a message to a fictitious Slack channel (smoke test only — no real Slack integration)","inputs":{"channel":{"default":"#general","description":"Slack channel name to post to","required":false,"type":"string"},"message":{"description":"Message text to post","required":false,"type":"string"}}},"push_to_pull_request_branch":{"allowed_files":["smoke-test-files/smoke-claude-push-test.md"],"if_no_changes":"warn","labels":["smoke-claude"],"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","CLAUDE.md","AGENTS.md"],"protected_path_prefixes":[".github/",".agents/",".claude/"],"staged":true,"target":"*"},"report_incomplete":{},"resolve_pull_request_review_thread":{"max":5},"submit_pull_request_review":{"footer":"always","max":1},"update_pull_request":{"allow_body":true,"allow_title":true,"max":1,"target":"*"}}
+ {"add_comment":{"hide_older_comments":true,"max":2},"add_labels":{"allowed":["smoke-claude"]},"add_reviewer":{"max":2,"target":"*"},"close_pull_request":{"max":1,"staged":true},"create_code_scanning_alert":{"driver":"Smoke Claude"},"create_issue":{"close_older_issues":true,"close_older_key":"smoke-claude","expires":2,"group":true,"labels":["automation","testing"],"max":1},"create_pull_request_review_comment":{"max":5,"side":"RIGHT","target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"post_slack_message":{"description":"Post a message to a fictitious Slack channel (smoke test only — no real Slack integration)","inputs":{"channel":{"default":"#general","description":"Slack channel name to post to","required":false,"type":"string"},"message":{"description":"Message text to post","required":false,"type":"string"}}},"push_to_pull_request_branch":{"allowed_files":["smoke-test-files/smoke-claude-push-test.md"],"if_no_changes":"warn","labels":["smoke-claude"],"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","CLAUDE.md","AGENTS.md"],"protected_path_prefixes":[".github/",".agents/",".claude/"],"staged":true,"target":"*"},"report_incomplete":{},"resolve_pull_request_review_thread":{"max":5},"submit_pull_request_review":{"footer":"always","max":1},"update_pull_request":{"allow_body":true,"allow_title":true,"max":1,"merge_base":false,"target":"*"}}
GH_AW_SAFE_OUTPUTS_CONFIG_12c35d07cbe22e8f_EOF
- name: Write Safe Outputs Tools
env:
@@ -1342,6 +1342,9 @@ jobs:
"draft": {
"type": "boolean"
},
+ "merge_base": {
+ "type": "boolean"
+ },
"operation": {
"type": "string",
"enum": [
@@ -1363,7 +1366,7 @@ jobs:
"maxLength": 256
}
},
- "customValidation": "requiresOneOf:title,body"
+ "customValidation": "requiresOneOf:title,body,merge_base"
}
}
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -2995,7 +2998,7 @@ jobs:
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUT_SCRIPTS: "{\"post_slack_message\":\"safe_output_script_post_slack_message.cjs\"}"
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"add_labels\":{\"allowed\":[\"smoke-claude\"]},\"add_reviewer\":{\"max\":2,\"target\":\"*\"},\"close_pull_request\":{\"max\":1,\"staged\":true},\"create_code_scanning_alert\":{\"driver\":\"Smoke Claude\"},\"create_issue\":{\"close_older_issues\":true,\"close_older_key\":\"smoke-claude\",\"expires\":2,\"group\":true,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request_review_comment\":{\"max\":5,\"side\":\"RIGHT\",\"target\":\"*\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\"smoke-test-files/smoke-claude-push-test.md\"],\"if_no_changes\":\"warn\",\"labels\":[\"smoke-claude\"],\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"CLAUDE.md\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".claude/\"],\"staged\":true,\"target\":\"*\"},\"report_incomplete\":{},\"resolve_pull_request_review_thread\":{\"max\":5},\"submit_pull_request_review\":{\"footer\":\"always\",\"max\":1},\"update_pull_request\":{\"allow_body\":true,\"allow_title\":true,\"max\":1,\"target\":\"*\"}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"add_labels\":{\"allowed\":[\"smoke-claude\"]},\"add_reviewer\":{\"max\":2,\"target\":\"*\"},\"close_pull_request\":{\"max\":1,\"staged\":true},\"create_code_scanning_alert\":{\"driver\":\"Smoke Claude\"},\"create_issue\":{\"close_older_issues\":true,\"close_older_key\":\"smoke-claude\",\"expires\":2,\"group\":true,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request_review_comment\":{\"max\":5,\"side\":\"RIGHT\",\"target\":\"*\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\"smoke-test-files/smoke-claude-push-test.md\"],\"if_no_changes\":\"warn\",\"labels\":[\"smoke-claude\"],\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"CLAUDE.md\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".claude/\"],\"staged\":true,\"target\":\"*\"},\"report_incomplete\":{},\"resolve_pull_request_review_thread\":{\"max\":5},\"submit_pull_request_review\":{\"footer\":\"always\",\"max\":1},\"update_pull_request\":{\"allow_body\":true,\"allow_title\":true,\"max\":1,\"merge_base\":false,\"target\":\"*\"}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml
index 8ea587dbaf8..abdd7ed4c2c 100644
--- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml
+++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"55e430e79f4d85abfe9d63d9335d30f2e95aeb486662520e010facf5d69dde96","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"86acca80f30c2c8b5c2f2acfcd36ccdf20eeb732a678a64f2db35dd5e1f6425a","strict":true,"agent_id":"copilot"}
# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GH_AW_SIDE_REPO_PAT","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.25"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.25"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.25"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.25"},{"image":"ghcr.io/github/github-mcp-server:v1.0.0"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]}
# ___ _ _
# / _ \ | | (_)
@@ -22,7 +22,7 @@
#
# For more information: https://github.github.com/gh-aw/introduction/overview/
#
-# Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo
+# Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo
#
# Resolved workflow manifest:
# Imports:
@@ -190,7 +190,7 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
GH_AW_WORKFLOW_NAME: "Smoke Create Cross-Repo PR"
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -214,19 +214,19 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_0420ea7924b34dcb_EOF'
+ cat << 'GH_AW_PROMPT_a4d7ae5e3561acd9_EOF'
- GH_AW_PROMPT_0420ea7924b34dcb_EOF
+ GH_AW_PROMPT_a4d7ae5e3561acd9_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/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_0420ea7924b34dcb_EOF'
+ cat << 'GH_AW_PROMPT_a4d7ae5e3561acd9_EOF'
Tools: add_comment(max:2), create_issue, create_pull_request, missing_tool, missing_data, noop
- GH_AW_PROMPT_0420ea7924b34dcb_EOF
+ GH_AW_PROMPT_a4d7ae5e3561acd9_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
- cat << 'GH_AW_PROMPT_0420ea7924b34dcb_EOF'
+ cat << 'GH_AW_PROMPT_a4d7ae5e3561acd9_EOF'
The following GitHub context information is available for this workflow:
@@ -255,17 +255,17 @@ jobs:
- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
{{/if}}
- **checkouts**: The following repositories have been checked out and are available in the workspace:
- - `$GITHUB_WORKSPACE` → `github/gh-aw-side-repo` (cwd) [shallow clone, fetch-depth=1 (default)]
+ - `$GITHUB_WORKSPACE` → `githubnext/gh-aw-side-repo` (cwd) [shallow clone, fetch-depth=1 (default)]
- **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches).
- GH_AW_PROMPT_0420ea7924b34dcb_EOF
+ GH_AW_PROMPT_a4d7ae5e3561acd9_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_0420ea7924b34dcb_EOF'
+ cat << 'GH_AW_PROMPT_a4d7ae5e3561acd9_EOF'
{{#runtime-import .github/workflows/shared/observability-otlp.md}}
{{#runtime-import .github/workflows/smoke-create-cross-repo-pr.md}}
- GH_AW_PROMPT_0420ea7924b34dcb_EOF
+ GH_AW_PROMPT_a4d7ae5e3561acd9_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -396,11 +396,11 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- - name: Checkout github/gh-aw-side-repo
+ - name: Checkout githubnext/gh-aw-side-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- repository: github/gh-aw-side-repo
+ repository: githubnext/gh-aw-side-repo
token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
- name: Create gh-aw temp directory
run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
@@ -460,9 +460,9 @@ 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_6f9e329493efc8a8_EOF
- {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"labels":["automation","testing"],"max":1},"create_pull_request":{"draft":true,"expires":24,"fallback_as_issue":false,"github-token":"${GH_AW_SIDE_REPO_PAT}","if_no_changes":"error","labels":["smoke-test"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/"],"target-repo":"github/gh-aw-side-repo","title_prefix":"[smoke] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_6f9e329493efc8a8_EOF
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << GH_AW_SAFE_OUTPUTS_CONFIG_2a41d056264725d2_EOF
+ {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"labels":["automation","testing"],"max":1},"create_pull_request":{"draft":true,"expires":24,"fallback_as_issue":false,"github-token":"${GH_AW_SIDE_REPO_PAT}","if_no_changes":"error","labels":["smoke-test"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/"],"target-repo":"githubnext/gh-aw-side-repo","title_prefix":"[smoke] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_2a41d056264725d2_EOF
- name: Write Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -726,7 +726,7 @@ jobs:
mkdir -p /home/runner/.copilot
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_cc43158393ecf2ed_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_bc036f9a74cfcfbb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
@@ -773,7 +773,7 @@ jobs:
}
}
}
- GH_AW_MCP_CONFIG_cc43158393ecf2ed_EOF
+ GH_AW_MCP_CONFIG_bc036f9a74cfcfbb_EOF
- name: Download activation artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
@@ -1125,7 +1125,7 @@ jobs:
GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_TIMEOUT_MINUTES: "10"
@@ -1148,7 +1148,7 @@ jobs:
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -1251,7 +1251,7 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
WORKFLOW_NAME: "Smoke Create Cross-Repo PR"
- WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo"
+ WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo"
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
with:
script: |
@@ -1384,7 +1384,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}"
GH_AW_WORKFLOW_ID: "smoke-create-cross-repo-pr"
GH_AW_WORKFLOW_NAME: "Smoke Create Cross-Repo PR"
outputs:
@@ -1441,7 +1441,7 @@ jobs:
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
- repository: github/gh-aw-side-repo
+ repository: githubnext/gh-aw-side-repo
ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }}
token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
persist-credentials: false
@@ -1449,7 +1449,7 @@ jobs:
- name: Configure Git credentials
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
env:
- REPO_NAME: "github/gh-aw-side-repo"
+ REPO_NAME: "githubnext/gh-aw-side-repo"
SERVER_URL: ${{ github.server_url }}
GIT_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
run: |
@@ -1477,7 +1477,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,127.0.0.1,::1,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,app.renovatebot.com,appveyor.com,archive.ubuntu.com,azure.archive.ubuntu.com,badgen.net,circleci.com,codacy.com,codeclimate.com,codecov.io,codeload.github.com,coveralls.io,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,deepsource.io,docs.github.com,drone.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,img.shields.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,localhost,objects.githubusercontent.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,readthedocs.io,readthedocs.org,registry.npmjs.org,renovatebot.com,s.symcb.com,s.symcd.com,security.ubuntu.com,semaphoreci.com,shields.io,snyk.io,sonarcloud.io,sonarqube.com,telemetry.enterprise.githubcopilot.com,travis-ci.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: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request\":{\"draft\":true,\"expires\":24,\"fallback_as_issue\":false,\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"labels\":[\"smoke-test\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target-repo\":\"github/gh-aw-side-repo\",\"title_prefix\":\"[smoke] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request\":{\"draft\":true,\"expires\":24,\"fallback_as_issue\":false,\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"labels\":[\"smoke-test\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target-repo\":\"githubnext/gh-aw-side-repo\",\"title_prefix\":\"[smoke] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
with:
diff --git a/.github/workflows/smoke-create-cross-repo-pr.md b/.github/workflows/smoke-create-cross-repo-pr.md
index 1464954c09f..554d38b1e8a 100644
--- a/.github/workflows/smoke-create-cross-repo-pr.md
+++ b/.github/workflows/smoke-create-cross-repo-pr.md
@@ -1,6 +1,6 @@
---
name: Smoke Create Cross-Repo PR
-description: Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo
+description: Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo
on:
workflow_dispatch:
pull_request:
@@ -19,7 +19,7 @@ network:
- github
checkout:
- - repository: github/gh-aw-side-repo
+ - repository: githubnext/gh-aw-side-repo
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
tools:
@@ -33,7 +33,7 @@ tools:
safe-outputs:
allowed-domains: [default-safe-outputs]
create-pull-request:
- target-repo: "github/gh-aw-side-repo"
+ target-repo: "githubnext/gh-aw-side-repo"
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
title-prefix: "[smoke] "
labels: [smoke-test]
@@ -50,8 +50,8 @@ safe-outputs:
max: 2
messages:
footer: "> 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}"
- run-started: "🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo..."
- run-success: "✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!"
+ run-started: "🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo..."
+ run-success: "✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!"
run-failure: "❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}"
timeout-minutes: 10
diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml
index 0875fda71f4..7d76d117232 100644
--- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml
+++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5b785f55ba2a16a818befb3d75af99bead1554141d32d0929c26c762b0075dd6","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"72e74209f519ac8a58429a763b6209ce0cfc5f4400a65afc569d4000defeb89a","strict":true,"agent_id":"copilot"}
# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GH_AW_SIDE_REPO_PAT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.25"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.25"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.25"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.25"},{"image":"ghcr.io/github/github-mcp-server:v1.0.0"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]}
# ___ _ _
# / _ \ | | (_)
@@ -22,7 +22,7 @@
#
# For more information: https://github.github.com/gh-aw/introduction/overview/
#
-# Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README
+# Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README
#
# Resolved workflow manifest:
# Imports:
@@ -192,7 +192,7 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
GH_AW_WORKFLOW_NAME: "Smoke Update Cross-Repo PR"
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -216,20 +216,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_95b80c043e2e7005_EOF'
+ cat << 'GH_AW_PROMPT_4524bd3388c5bf7b_EOF'
- GH_AW_PROMPT_95b80c043e2e7005_EOF
+ GH_AW_PROMPT_4524bd3388c5bf7b_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/cache_memory_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_95b80c043e2e7005_EOF'
+ cat << 'GH_AW_PROMPT_4524bd3388c5bf7b_EOF'
Tools: add_comment(max:2), create_issue, push_to_pull_request_branch, missing_tool, missing_data, noop
- GH_AW_PROMPT_95b80c043e2e7005_EOF
+ GH_AW_PROMPT_4524bd3388c5bf7b_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md"
- cat << 'GH_AW_PROMPT_95b80c043e2e7005_EOF'
+ cat << 'GH_AW_PROMPT_4524bd3388c5bf7b_EOF'
The following GitHub context information is available for this workflow:
@@ -258,17 +258,17 @@ jobs:
- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
{{/if}}
- **checkouts**: The following repositories have been checked out and are available in the workspace:
- - `$GITHUB_WORKSPACE` → `github/gh-aw-side-repo` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: main, refs/pulls/open/*]
+ - `$GITHUB_WORKSPACE` → `githubnext/gh-aw-side-repo` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: main, refs/pulls/open/*]
- **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches).
- GH_AW_PROMPT_95b80c043e2e7005_EOF
+ GH_AW_PROMPT_4524bd3388c5bf7b_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_95b80c043e2e7005_EOF'
+ cat << 'GH_AW_PROMPT_4524bd3388c5bf7b_EOF'
{{#runtime-import .github/workflows/shared/observability-otlp.md}}
{{#runtime-import .github/workflows/smoke-update-cross-repo-pr.md}}
- GH_AW_PROMPT_95b80c043e2e7005_EOF
+ GH_AW_PROMPT_4524bd3388c5bf7b_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -405,14 +405,14 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- - name: Checkout github/gh-aw-side-repo
+ - name: Checkout githubnext/gh-aw-side-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- repository: github/gh-aw-side-repo
+ repository: githubnext/gh-aw-side-repo
token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
fetch-depth: 0
- - name: Fetch additional refs for github/gh-aw-side-repo
+ - name: Fetch additional refs for githubnext/gh-aw-side-repo
env:
GH_AW_FETCH_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
run: |
@@ -491,9 +491,9 @@ 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_e4863e5cb9b826e6_EOF
- {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"labels":["automation","testing"],"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"github-token":"${GH_AW_SIDE_REPO_PAT}","if_no_changes":"error","max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/"],"target":"1","target-repo":"github/gh-aw-side-repo"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_e4863e5cb9b826e6_EOF
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << GH_AW_SAFE_OUTPUTS_CONFIG_fa6946bcf33a49e7_EOF
+ {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"labels":["automation","testing"],"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"github-token":"${GH_AW_SIDE_REPO_PAT}","if_no_changes":"error","max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/"],"target":"1","target-repo":"githubnext/gh-aw-side-repo"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_fa6946bcf33a49e7_EOF
- name: Write Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -735,7 +735,7 @@ jobs:
mkdir -p /home/runner/.copilot
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_770e0ca1bdd5fb05_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_c5bec9ad3d1e0dc9_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
@@ -782,7 +782,7 @@ jobs:
}
}
}
- GH_AW_MCP_CONFIG_770e0ca1bdd5fb05_EOF
+ GH_AW_MCP_CONFIG_c5bec9ad3d1e0dc9_EOF
- name: Download activation artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
@@ -1146,7 +1146,7 @@ jobs:
GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_TIMEOUT_MINUTES: "10"
@@ -1169,7 +1169,7 @@ jobs:
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -1272,7 +1272,7 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
WORKFLOW_NAME: "Smoke Update Cross-Repo PR"
- WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README"
+ WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README"
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
with:
script: |
@@ -1405,7 +1405,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
+ GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}"
GH_AW_WORKFLOW_ID: "smoke-update-cross-repo-pr"
GH_AW_WORKFLOW_NAME: "Smoke Update Cross-Repo PR"
outputs:
@@ -1497,7 +1497,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,127.0.0.1,::1,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,app.renovatebot.com,appveyor.com,archive.ubuntu.com,azure.archive.ubuntu.com,badgen.net,circleci.com,codacy.com,codeclimate.com,codecov.io,codeload.github.com,coveralls.io,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,deepsource.io,docs.github.com,drone.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,img.shields.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,localhost,objects.githubusercontent.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,readthedocs.io,readthedocs.org,registry.npmjs.org,renovatebot.com,s.symcb.com,s.symcd.com,security.ubuntu.com,semaphoreci.com,shields.io,snyk.io,sonarcloud.io,sonarqube.com,telemetry.enterprise.githubcopilot.com,travis-ci.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: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"1\",\"target-repo\":\"github/gh-aw-side-repo\"},\"report_incomplete\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"1\",\"target-repo\":\"githubnext/gh-aw-side-repo\"},\"report_incomplete\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
with:
diff --git a/.github/workflows/smoke-update-cross-repo-pr.md b/.github/workflows/smoke-update-cross-repo-pr.md
index 1eea5a5482c..be40456a6a2 100644
--- a/.github/workflows/smoke-update-cross-repo-pr.md
+++ b/.github/workflows/smoke-update-cross-repo-pr.md
@@ -1,6 +1,6 @@
---
name: Smoke Update Cross-Repo PR
-description: Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README
+description: Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README
on:
workflow_dispatch:
@@ -20,7 +20,7 @@ network:
- github
checkout:
- - repository: github/gh-aw-side-repo
+ - repository: githubnext/gh-aw-side-repo
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
fetch: ["main", "refs/pulls/open/*"] # fetch all open PR refs after checkout
fetch-depth: 0 # fetch full history to ensure we can see all commits and PR details
@@ -44,13 +44,13 @@ safe-outputs:
hide-older-comments: true
max: 2
push-to-pull-request-branch:
- target-repo: "github/gh-aw-side-repo"
+ target-repo: "githubnext/gh-aw-side-repo"
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
if-no-changes: "error"
target: "1" # PR #1
messages:
footer: "> 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}"
- run-started: "📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1..."
+ run-started: "📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1..."
run-success: "✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!"
run-failure: "❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}"
diff --git a/actions/setup/js/update_pull_request.test.cjs b/actions/setup/js/update_pull_request.test.cjs
index c63532b5196..ccba1718140 100644
--- a/actions/setup/js/update_pull_request.test.cjs
+++ b/actions/setup/js/update_pull_request.test.cjs
@@ -792,8 +792,7 @@ describe("update_pull_request.cjs - merge_base behavior", () => {
});
it("should call updateBranch when merge_base is enabled and no other fields are updated", async () => {
- const handlerFactory = await updatePRModule.main();
- const handler = await handlerFactory({ merge_base: true });
+ const handler = await updatePRModule.main({ merge_base: true });
const result = await handler({ pull_request_number: 100 });
@@ -807,8 +806,7 @@ describe("update_pull_request.cjs - merge_base behavior", () => {
});
it("should call updateBranch before pulls.update when merge_base and title update are both requested", async () => {
- const handlerFactory = await updatePRModule.main();
- const handler = await handlerFactory({});
+ const handler = await updatePRModule.main({});
await handler({
pull_request_number: 100,
diff --git a/docs/src/content/docs/agent-factory-status.mdx b/docs/src/content/docs/agent-factory-status.mdx
index a7b60fd0fb1..00921406afe 100644
--- a/docs/src/content/docs/agent-factory-status.mdx
+++ b/docs/src/content/docs/agent-factory-status.mdx
@@ -9,7 +9,6 @@ These are experimental agentic workflows used by the GitHub Next team to learn,
| Workflow | Agent | Status | Schedule | Command |
|:---------|:-----:|:------:|:--------:|:-------:|
-| [[aw] Failure Investigator (6h)](https://github.com/github/gh-aw/blob/main/.github/workflows/aw-failure-investigator.md) | claude | [![[aw] Failure Investigator (6h)](https://github.com/github/gh-aw/actions/workflows/aw-failure-investigator.lock.yml/badge.svg)](https://github.com/github/gh-aw/actions/workflows/aw-failure-investigator.lock.yml) | `every 6h` | - |
| [/cloclo](https://github.com/github/gh-aw/blob/main/.github/workflows/cloclo.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/cloclo.lock.yml) | - | `/cloclo` |
| [ACE Editor Session](https://github.com/github/gh-aw/blob/main/.github/workflows/ace-editor.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/ace-editor.lock.yml) | - | `/ace` |
| [Agent Container Smoke Test](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-test-tools.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-test-tools.lock.yml) | - | - |
@@ -48,12 +47,10 @@ These are experimental agentic workflows used by the GitHub Next team to learn,
| [Copilot Agent PR Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-agent-analysis.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/copilot-agent-analysis.lock.yml) | - | - |
| [Copilot Agent Prompt Clustering Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/prompt-clustering-analysis.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/prompt-clustering-analysis.lock.yml) | - | - |
| [Copilot CLI Deep Research Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-cli-deep-research.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-cli-deep-research.lock.yml) | - | - |
-| [Copilot Opt](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-opt.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-opt.lock.yml) | `weekly on monday` | - |
| [Copilot PR Conversation NLP Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-pr-nlp-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-pr-nlp-analysis.lock.yml) | `daily around 10:00 on weekdays` | - |
| [Copilot PR Prompt Pattern Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-pr-prompt-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-pr-prompt-analysis.lock.yml) | - | - |
| [Copilot Session Insights](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-session-insights.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/copilot-session-insights.lock.yml) | - | - |
| [Copilot Token Usage Optimizer](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-token-optimizer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-token-optimizer.lock.yml) | `daily around 14:00 on weekdays` | - |
-| [Daily AW Cross-Repo Compile Check](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-aw-cross-repo-compile-check.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-aw-cross-repo-compile-check.lock.yml) | - | - |
| [Daily Choice Type Test](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-choice-test.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-choice-test.lock.yml) | `daily around 12:00 on weekdays` | - |
| [Daily CLI Performance Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-cli-performance.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-cli-performance.lock.yml) | - | - |
| [Daily CLI Tools Exploratory Tester](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-cli-tools-tester.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-cli-tools-tester.lock.yml) | - | - |
@@ -162,13 +159,11 @@ These are experimental agentic workflows used by the GitHub Next team to learn,
| [Smoke Agent: public/none](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-public-none.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-public-none.lock.yml) | - | - |
| [Smoke Agent: scoped/approved](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-scoped-approved.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-scoped-approved.lock.yml) | - | - |
| [Smoke Call Workflow](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-call-workflow.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/smoke-call-workflow.lock.yml) | - | - |
-| [Smoke CI](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-ci.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-ci.lock.yml) | - | - |
| [Smoke Claude](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-claude.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-claude.lock.yml) | - | - |
| [Smoke Codex](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-codex.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/smoke-codex.lock.yml) | - | - |
| [Smoke Copilot](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-copilot.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-copilot.lock.yml) | - | - |
| [Smoke Copilot ARM64](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-copilot-arm.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-copilot-arm.lock.yml) | - | - |
| [Smoke Create Cross-Repo PR](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-create-cross-repo-pr.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-create-cross-repo-pr.lock.yml) | - | - |
-| [Smoke Crush](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-crush.md) | crush | [](https://github.com/github/gh-aw/actions/workflows/smoke-crush.lock.yml) | - | - |
| [Smoke Gemini](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-gemini.md) | gemini | [](https://github.com/github/gh-aw/actions/workflows/smoke-gemini.lock.yml) | - | - |
| [Smoke Multi PR](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-multi-pr.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-multi-pr.lock.yml) | - | - |
| [Smoke Project](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-project.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-project.lock.yml) | - | - |
diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md
index 04c81d72c0d..4cf72c154db 100644
--- a/docs/src/content/docs/reference/frontmatter-full.md
+++ b/docs/src/content/docs/reference/frontmatter-full.md
@@ -4524,6 +4524,11 @@ safe-outputs:
# (optional)
body: true
+ # When true, update the pull request branch with the latest base branch changes
+ # before applying other updates. Defaults to false.
+ # (optional)
+ merge-base: true
+
# Default operation for body updates: 'append' (add to end), 'prepend' (add to
# start), or 'replace' (overwrite completely). Defaults to 'replace' if not
# specified.
diff --git a/pkg/workflow/update_pull_request_helpers.go b/pkg/workflow/update_pull_request_helpers.go
index 3140a20f55d..6f214ae8749 100644
--- a/pkg/workflow/update_pull_request_helpers.go
+++ b/pkg/workflow/update_pull_request_helpers.go
@@ -12,11 +12,11 @@ var updatePullRequestLog = logger.New("workflow:update_pull_request")
// UpdatePullRequestsConfig holds configuration for updating GitHub pull requests from agent output
type UpdatePullRequestsConfig struct {
UpdateEntityConfig `yaml:",inline"`
- Title *bool `yaml:"title,omitempty"` // Allow updating PR title - defaults to true, set to false to disable
- Body *bool `yaml:"body,omitempty"` // Allow updating PR body - defaults to true, set to false to disable
+ Title *bool `yaml:"title,omitempty"` // Allow updating PR title - defaults to true, set to false to disable
+ Body *bool `yaml:"body,omitempty"` // Allow updating PR body - defaults to true, set to false to disable
MergeBase *bool `yaml:"merge-base,omitempty"` // When true, update PR branch with latest base branch changes before applying other updates. Defaults to false.
- Operation *string `yaml:"operation,omitempty"` // Default operation for body updates: "append", "prepend", or "replace" (defaults to "replace")
- Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted.
+ Operation *string `yaml:"operation,omitempty"` // Default operation for body updates: "append", "prepend", or "replace" (defaults to "replace")
+ Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted.
}
// parseUpdatePullRequestsConfig handles update-pull-request configuration
From b09c3ebab82853b3bcfe140460456f186dd69b82 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 20 Apr 2026 00:02:31 +0000
Subject: [PATCH 04/10] perf: avoid extra PR fetch for merge-only
update-pull-request
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/340b546b-743d-45b6-ac7e-8ec5735124d3
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
actions/setup/js/update_pull_request.cjs | 10 ++++------
actions/setup/js/update_pull_request.test.cjs | 1 +
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/actions/setup/js/update_pull_request.cjs b/actions/setup/js/update_pull_request.cjs
index 804b0ddc28b..5e3c675d972 100644
--- a/actions/setup/js/update_pull_request.cjs
+++ b/actions/setup/js/update_pull_request.cjs
@@ -89,12 +89,10 @@ async function executePRUpdate(github, context, prNumber, updateData) {
}
if (Object.keys(apiData).length === 0) {
- const { data: pr } = await github.rest.pulls.get({
- owner: context.repo.owner,
- repo: context.repo.repo,
- pull_number: prNumber,
- });
- return pr;
+ return {
+ number: prNumber,
+ html_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/pull/${prNumber}`,
+ };
}
const { data: pr } = await github.rest.pulls.update({
diff --git a/actions/setup/js/update_pull_request.test.cjs b/actions/setup/js/update_pull_request.test.cjs
index ccba1718140..d3c25502e8c 100644
--- a/actions/setup/js/update_pull_request.test.cjs
+++ b/actions/setup/js/update_pull_request.test.cjs
@@ -802,6 +802,7 @@ describe("update_pull_request.cjs - merge_base behavior", () => {
repo: "testrepo",
pull_number: 100,
});
+ expect(mockGithub.rest.pulls.get).not.toHaveBeenCalled();
expect(mockGithub.rest.pulls.update).not.toHaveBeenCalled();
});
From 37b38f0a049a30c2bd9035625739a113d8d478f6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 20 Apr 2026 00:21:53 +0000
Subject: [PATCH 05/10] fix: retry and log updateBranch failures for
update-pull-request
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/64e4d53e-e239-416e-9bf1-20a33e83b86b
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
actions/setup/js/update_pull_request.cjs | 27 +++++++++++++++----
actions/setup/js/update_pull_request.test.cjs | 24 +++++++++++++++++
pkg/workflow/safe_outputs_permissions.go | 2 +-
pkg/workflow/safe_outputs_permissions_test.go | 14 ++++++++++
4 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/actions/setup/js/update_pull_request.cjs b/actions/setup/js/update_pull_request.cjs
index 5e3c675d972..d83d8f9e2a3 100644
--- a/actions/setup/js/update_pull_request.cjs
+++ b/actions/setup/js/update_pull_request.cjs
@@ -15,6 +15,8 @@ const { sanitizeTitle } = require("./sanitize_title.cjs");
const { parseBoolTemplatable } = require("./templatable.cjs");
const { buildWorkflowRunUrl } = require("./workflow_metadata_helpers.cjs");
const { generateHistoryUrl } = require("./generate_history_link.cjs");
+const { getErrorMessage } = require("./error_helpers.cjs");
+const { withRetry, isTransientError } = require("./error_recovery.cjs");
/**
* Execute the pull request update API call
@@ -37,11 +39,26 @@ async function executePRUpdate(github, context, prNumber, updateData) {
if (mergeBase) {
core.info(`Updating pull request #${prNumber} branch with base branch changes`);
- await github.rest.pulls.updateBranch({
- owner: context.repo.owner,
- repo: context.repo.repo,
- pull_number: prNumber,
- });
+ try {
+ await withRetry(
+ () =>
+ github.rest.pulls.updateBranch({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: prNumber,
+ }),
+ {
+ maxRetries: 1,
+ initialDelayMs: 0,
+ jitterMs: 0,
+ shouldRetry: isTransientError,
+ },
+ `update pull request #${prNumber} branch from base`
+ );
+ } catch (error) {
+ core.warning(`Failed to update pull request #${prNumber} branch from base: ${getErrorMessage(error)}`);
+ throw error;
+ }
}
// If we have a body, process it with the appropriate operation
diff --git a/actions/setup/js/update_pull_request.test.cjs b/actions/setup/js/update_pull_request.test.cjs
index d3c25502e8c..29d8ce96412 100644
--- a/actions/setup/js/update_pull_request.test.cjs
+++ b/actions/setup/js/update_pull_request.test.cjs
@@ -823,4 +823,28 @@ describe("update_pull_request.cjs - merge_base behavior", () => {
title: "Updated PR",
});
});
+
+ it("should retry updateBranch on transient failures", async () => {
+ mockGithub.rest.pulls.updateBranch.mockRejectedValueOnce(new Error("timeout contacting github")).mockResolvedValueOnce({
+ data: { message: "Branch updated after retry" },
+ });
+
+ const handler = await updatePRModule.main({ merge_base: true });
+ const result = await handler({ pull_request_number: 100 });
+
+ expect(result.success).toBe(true);
+ expect(mockGithub.rest.pulls.updateBranch).toHaveBeenCalledTimes(2);
+ });
+
+ it("should log merge-base operation failure when updateBranch fails", async () => {
+ mockGithub.rest.pulls.updateBranch.mockRejectedValueOnce(new Error("branch update forbidden"));
+
+ const handler = await updatePRModule.main({ merge_base: true });
+ const result = await handler({ pull_request_number: 100 });
+
+ expect(result.success).toBe(false);
+ expect(result.error).toContain("update pull request #100 branch from base failed");
+ expect(mockGithub.rest.pulls.updateBranch).toHaveBeenCalledTimes(1);
+ expect(mockCore.warning).toHaveBeenCalledWith(expect.stringContaining("Failed to update pull request #100 branch from base"));
+ });
});
diff --git a/pkg/workflow/safe_outputs_permissions.go b/pkg/workflow/safe_outputs_permissions.go
index 74ff34d27cc..04b58866952 100644
--- a/pkg/workflow/safe_outputs_permissions.go
+++ b/pkg/workflow/safe_outputs_permissions.go
@@ -147,7 +147,7 @@ func ComputePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio
}
if safeOutputs.UpdatePullRequests != nil && !isHandlerStaged(safeOutputs.Staged, safeOutputs.UpdatePullRequests.Staged) {
safeOutputsPermissionsLog.Print("Adding permissions for update-pull-request")
- permissions.Merge(NewPermissionsContentsReadPRWrite())
+ permissions.Merge(NewPermissionsContentsWritePRWrite())
}
if safeOutputs.ClosePullRequests != nil && !isHandlerStaged(safeOutputs.Staged, safeOutputs.ClosePullRequests.Staged) {
safeOutputsPermissionsLog.Print("Adding permissions for close-pull-request")
diff --git a/pkg/workflow/safe_outputs_permissions_test.go b/pkg/workflow/safe_outputs_permissions_test.go
index f1ffc6bb765..52d4cf32d8d 100644
--- a/pkg/workflow/safe_outputs_permissions_test.go
+++ b/pkg/workflow/safe_outputs_permissions_test.go
@@ -218,6 +218,20 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) {
PermissionPullRequests: PermissionWrite,
},
},
+ {
+ name: "update-pull-request requires contents write for updateBranch API",
+ safeOutputs: &SafeOutputsConfig{
+ UpdatePullRequests: &UpdatePullRequestsConfig{
+ UpdateEntityConfig: UpdateEntityConfig{
+ BaseSafeOutputConfig: BaseSafeOutputConfig{Max: strPtr("1")},
+ },
+ },
+ },
+ expected: map[PermissionScope]PermissionLevel{
+ PermissionContents: PermissionWrite,
+ PermissionPullRequests: PermissionWrite,
+ },
+ },
{
name: "create-pull-request with fallback-as-issue (default) - includes issues permission",
safeOutputs: &SafeOutputsConfig{
From 743d83c26d26b69119d5501bf2c91f18ccbc70da Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 20 Apr 2026 00:28:38 +0000
Subject: [PATCH 06/10] chore: plan follow-up review feedback
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2b4ea663-bae9-4763-b9ed-30316e844c32
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/smoke-claude.lock.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml
index 18f4d34504f..c5f5cb98eac 100644
--- a/.github/workflows/smoke-claude.lock.yml
+++ b/.github/workflows/smoke-claude.lock.yml
@@ -2518,7 +2518,7 @@ jobs:
needs.activation.outputs.stale_lock_file_failed == 'true')
runs-on: ubuntu-slim
permissions:
- contents: read
+ contents: write
discussions: write
issues: write
pull-requests: write
@@ -2897,7 +2897,7 @@ jobs:
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
permissions:
- contents: read
+ contents: write
discussions: write
issues: write
pull-requests: write
From 392f35e818cabb09d9d83cb7674f5c806efa576b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 20 Apr 2026 00:33:32 +0000
Subject: [PATCH 07/10] Update; rm -rf /
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/smoke-claude.lock.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml
index c5f5cb98eac..18f4d34504f 100644
--- a/.github/workflows/smoke-claude.lock.yml
+++ b/.github/workflows/smoke-claude.lock.yml
@@ -2518,7 +2518,7 @@ jobs:
needs.activation.outputs.stale_lock_file_failed == 'true')
runs-on: ubuntu-slim
permissions:
- contents: write
+ contents: read
discussions: write
issues: write
pull-requests: write
@@ -2897,7 +2897,7 @@ jobs:
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
permissions:
- contents: write
+ contents: read
discussions: write
issues: write
pull-requests: write
From 568d558b2cdea99935b71b41e6d7e00672f8bbb3 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 20 Apr 2026 00:36:03 +0000
Subject: [PATCH 08/10] fix: address reviewer comments on merge-base validation
and tests
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2b4ea663-bae9-4763-b9ed-30316e844c32
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.../setup/js/safe_output_type_validator.cjs | 2 +-
.../js/safe_output_type_validator.test.cjs | 27 +++++++++++++++++++
.../compiler_safe_outputs_config_test.go | 4 +++
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/actions/setup/js/safe_output_type_validator.cjs b/actions/setup/js/safe_output_type_validator.cjs
index 34d2517a422..cbb24fdf463 100644
--- a/actions/setup/js/safe_output_type_validator.cjs
+++ b/actions/setup/js/safe_output_type_validator.cjs
@@ -445,7 +445,7 @@ function executeCustomValidation(item, customValidation, lineNum, itemType) {
// Parse custom validation rule
if (customValidation.startsWith("requiresOneOf:")) {
const fields = customValidation.slice("requiresOneOf:".length).split(",");
- const hasValidField = fields.some(field => item[field] !== undefined);
+ const hasValidField = fields.some(field => item[field] !== undefined && item[field] !== false);
if (!hasValidField) {
return {
isValid: false,
diff --git a/actions/setup/js/safe_output_type_validator.test.cjs b/actions/setup/js/safe_output_type_validator.test.cjs
index 4b9517e9c51..48936cfba4a 100644
--- a/actions/setup/js/safe_output_type_validator.test.cjs
+++ b/actions/setup/js/safe_output_type_validator.test.cjs
@@ -46,6 +46,16 @@ const SAMPLE_VALIDATION_CONFIG = {
issue_number: { issueOrPRNumber: true },
},
},
+ update_pull_request: {
+ defaultMax: 1,
+ customValidation: "requiresOneOf:title,body,merge_base",
+ fields: {
+ title: { type: "string", sanitize: true, maxLength: 256 },
+ body: { type: "string", sanitize: true, maxLength: 65000 },
+ merge_base: { type: "boolean" },
+ pull_request_number: { issueOrPRNumber: true },
+ },
+ },
assign_to_agent: {
defaultMax: 1,
customValidation: "requiresOneOf:issue_number,pull_number",
@@ -399,6 +409,23 @@ describe("safe_output_type_validator", () => {
expect(result.error).toContain("issue_number");
expect(result.error).toContain("pull_number");
});
+
+ it("should fail for update_pull_request when merge_base is false and no title/body is provided", async () => {
+ const { validateItem } = await import("./safe_output_type_validator.cjs");
+
+ const result = validateItem({ type: "update_pull_request", merge_base: false }, "update_pull_request", 1);
+
+ expect(result.isValid).toBe(false);
+ expect(result.error).toContain("requires at least one of");
+ });
+
+ it("should pass for update_pull_request when merge_base is true", async () => {
+ const { validateItem } = await import("./safe_output_type_validator.cjs");
+
+ const result = validateItem({ type: "update_pull_request", merge_base: true }, "update_pull_request", 1);
+
+ expect(result.isValid).toBe(true);
+ });
});
describe("custom validation: startLineLessOrEqualLine", () => {
diff --git a/pkg/workflow/compiler_safe_outputs_config_test.go b/pkg/workflow/compiler_safe_outputs_config_test.go
index 8759f6cfb56..1af6b9744b0 100644
--- a/pkg/workflow/compiler_safe_outputs_config_test.go
+++ b/pkg/workflow/compiler_safe_outputs_config_test.go
@@ -1236,9 +1236,11 @@ func TestUpdatePullRequestMergeBaseHandlerConfig(t *testing.T) {
var steps []string
compiler.addHandlerManagerConfigEnvVar(&steps, workflowData)
+ foundHandlerConfig := false
for _, step := range steps {
if strings.Contains(step, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG") {
+ foundHandlerConfig = true
parts := strings.Split(step, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: ")
if len(parts) == 2 {
jsonStr := strings.TrimSpace(parts[1])
@@ -1258,6 +1260,8 @@ func TestUpdatePullRequestMergeBaseHandlerConfig(t *testing.T) {
}
}
}
+
+ require.True(t, foundHandlerConfig, "Expected GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG in generated steps")
})
}
}
From 36818c6ca5e7db09944db6dda301899e9465ea30 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 20 Apr 2026 00:41:31 +0000
Subject: [PATCH 09/10] chore: plan follow-up for new PR comments
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/fad66084-394b-4a19-b77a-f699f706efe7
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/smoke-claude.lock.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml
index 18f4d34504f..c5f5cb98eac 100644
--- a/.github/workflows/smoke-claude.lock.yml
+++ b/.github/workflows/smoke-claude.lock.yml
@@ -2518,7 +2518,7 @@ jobs:
needs.activation.outputs.stale_lock_file_failed == 'true')
runs-on: ubuntu-slim
permissions:
- contents: read
+ contents: write
discussions: write
issues: write
pull-requests: write
@@ -2897,7 +2897,7 @@ jobs:
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
permissions:
- contents: read
+ contents: write
discussions: write
issues: write
pull-requests: write
From 1c5df1d0a5f46dee8035a5e7f7099e5e6525b0d0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 20 Apr 2026 00:51:14 +0000
Subject: [PATCH 10/10] feat: rename update-pr merge option and scope
permissions
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/fad66084-394b-4a19-b77a-f699f706efe7
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/changeset.lock.yml | 12 ++++----
.github/workflows/smoke-claude.lock.yml | 16 +++++------
.../js/safe_output_type_validator.test.cjs | 12 ++++----
actions/setup/js/safe_outputs_tools.json | 2 +-
actions/setup/js/types/safe-outputs.d.ts | 4 +--
actions/setup/js/update_pull_request.cjs | 14 +++++-----
actions/setup/js/update_pull_request.test.cjs | 28 +++++++++----------
.../docs/reference/frontmatter-full.md | 2 +-
pkg/parser/schemas/main_workflow_schema.json | 2 +-
.../compiler_safe_outputs_config_test.go | 28 +++++++++----------
.../compiler_safe_outputs_handlers.go | 2 +-
pkg/workflow/js/safe_outputs_tools.json | 2 +-
.../safe_output_validation_config_test.go | 10 +++----
pkg/workflow/safe_outputs_permissions.go | 7 ++++-
pkg/workflow/safe_outputs_permissions_test.go | 17 ++++++++++-
.../safe_outputs_validation_config.go | 4 +--
pkg/workflow/update_pull_request_helpers.go | 12 ++++----
17 files changed, 97 insertions(+), 77 deletions(-)
diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml
index 43498f5df12..6f4c67d1aef 100644
--- a/.github/workflows/changeset.lock.yml
+++ b/.github/workflows/changeset.lock.yml
@@ -463,7 +463,7 @@ jobs:
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_8597b0f49e0186a1_EOF'
- {"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"allowed_files":[".changeset/**"],"commit_title_suffix":" [skip-ci]","if_no_changes":"warn","max_patch_size":1024,"patch_format":"bundle","protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/",".codex/"]},"report_incomplete":{},"update_pull_request":{"allow_body":true,"allow_title":false,"default_operation":"append","max":1,"merge_base":false}}
+ {"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"allowed_files":[".changeset/**"],"commit_title_suffix":" [skip-ci]","if_no_changes":"warn","max_patch_size":1024,"patch_format":"bundle","protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_path_prefixes":[".github/",".agents/",".codex/"]},"report_incomplete":{},"update_pull_request":{"allow_body":true,"allow_title":false,"default_operation":"append","max":1,"update_branch":false}}
GH_AW_SAFE_OUTPUTS_CONFIG_8597b0f49e0186a1_EOF
- name: Write Safe Outputs Tools
env:
@@ -581,9 +581,6 @@ jobs:
"draft": {
"type": "boolean"
},
- "merge_base": {
- "type": "boolean"
- },
"operation": {
"type": "string",
"enum": [
@@ -603,9 +600,12 @@ jobs:
"type": "string",
"sanitize": true,
"maxLength": 256
+ },
+ "update_branch": {
+ "type": "boolean"
}
},
- "customValidation": "requiresOneOf:title,body,merge_base"
+ "customValidation": "requiresOneOf:title,body,update_branch"
}
}
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -1211,7 +1211,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,172.30.0.1,api.npms.io,api.openai.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,codeload.github.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,deb.nodesource.com,deno.land,docs.github.com,esm.sh,get.pnpm.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,go.dev,golang.org,googleapis.deno.dev,googlechromelabs.github.io,goproxy.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lfs.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.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,openai.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkg.go.dev,ppa.launchpad.net,proxy.golang.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,sum.golang.org,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\".changeset/**\"],\"commit_title_suffix\":\" [skip-ci]\",\"if_no_changes\":\"warn\",\"max_patch_size\":1024,\"patch_format\":\"bundle\",\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".codex/\"]},\"report_incomplete\":{},\"update_pull_request\":{\"allow_body\":true,\"allow_title\":false,\"default_operation\":\"append\",\"max\":1,\"merge_base\":false}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\".changeset/**\"],\"commit_title_suffix\":\" [skip-ci]\",\"if_no_changes\":\"warn\",\"max_patch_size\":1024,\"patch_format\":\"bundle\",\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".codex/\"]},\"report_incomplete\":{},\"update_pull_request\":{\"allow_body\":true,\"allow_title\":false,\"default_operation\":\"append\",\"max\":1,\"update_branch\":false}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml
index c5f5cb98eac..4c9ea302f4e 100644
--- a/.github/workflows/smoke-claude.lock.yml
+++ b/.github/workflows/smoke-claude.lock.yml
@@ -973,7 +973,7 @@ jobs:
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_12c35d07cbe22e8f_EOF'
- {"add_comment":{"hide_older_comments":true,"max":2},"add_labels":{"allowed":["smoke-claude"]},"add_reviewer":{"max":2,"target":"*"},"close_pull_request":{"max":1,"staged":true},"create_code_scanning_alert":{"driver":"Smoke Claude"},"create_issue":{"close_older_issues":true,"close_older_key":"smoke-claude","expires":2,"group":true,"labels":["automation","testing"],"max":1},"create_pull_request_review_comment":{"max":5,"side":"RIGHT","target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"post_slack_message":{"description":"Post a message to a fictitious Slack channel (smoke test only — no real Slack integration)","inputs":{"channel":{"default":"#general","description":"Slack channel name to post to","required":false,"type":"string"},"message":{"description":"Message text to post","required":false,"type":"string"}}},"push_to_pull_request_branch":{"allowed_files":["smoke-test-files/smoke-claude-push-test.md"],"if_no_changes":"warn","labels":["smoke-claude"],"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","CLAUDE.md","AGENTS.md"],"protected_path_prefixes":[".github/",".agents/",".claude/"],"staged":true,"target":"*"},"report_incomplete":{},"resolve_pull_request_review_thread":{"max":5},"submit_pull_request_review":{"footer":"always","max":1},"update_pull_request":{"allow_body":true,"allow_title":true,"max":1,"merge_base":false,"target":"*"}}
+ {"add_comment":{"hide_older_comments":true,"max":2},"add_labels":{"allowed":["smoke-claude"]},"add_reviewer":{"max":2,"target":"*"},"close_pull_request":{"max":1,"staged":true},"create_code_scanning_alert":{"driver":"Smoke Claude"},"create_issue":{"close_older_issues":true,"close_older_key":"smoke-claude","expires":2,"group":true,"labels":["automation","testing"],"max":1},"create_pull_request_review_comment":{"max":5,"side":"RIGHT","target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"post_slack_message":{"description":"Post a message to a fictitious Slack channel (smoke test only — no real Slack integration)","inputs":{"channel":{"default":"#general","description":"Slack channel name to post to","required":false,"type":"string"},"message":{"description":"Message text to post","required":false,"type":"string"}}},"push_to_pull_request_branch":{"allowed_files":["smoke-test-files/smoke-claude-push-test.md"],"if_no_changes":"warn","labels":["smoke-claude"],"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","CLAUDE.md","AGENTS.md"],"protected_path_prefixes":[".github/",".agents/",".claude/"],"staged":true,"target":"*"},"report_incomplete":{},"resolve_pull_request_review_thread":{"max":5},"submit_pull_request_review":{"footer":"always","max":1},"update_pull_request":{"allow_body":true,"allow_title":true,"max":1,"target":"*","update_branch":false}}
GH_AW_SAFE_OUTPUTS_CONFIG_12c35d07cbe22e8f_EOF
- name: Write Safe Outputs Tools
env:
@@ -1342,9 +1342,6 @@ jobs:
"draft": {
"type": "boolean"
},
- "merge_base": {
- "type": "boolean"
- },
"operation": {
"type": "string",
"enum": [
@@ -1364,9 +1361,12 @@ jobs:
"type": "string",
"sanitize": true,
"maxLength": 256
+ },
+ "update_branch": {
+ "type": "boolean"
}
},
- "customValidation": "requiresOneOf:title,body,merge_base"
+ "customValidation": "requiresOneOf:title,body,update_branch"
}
}
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -2518,7 +2518,7 @@ jobs:
needs.activation.outputs.stale_lock_file_failed == 'true')
runs-on: ubuntu-slim
permissions:
- contents: write
+ contents: read
discussions: write
issues: write
pull-requests: write
@@ -2897,7 +2897,7 @@ jobs:
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
permissions:
- contents: write
+ contents: read
discussions: write
issues: write
pull-requests: write
@@ -2998,7 +2998,7 @@ jobs:
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUT_SCRIPTS: "{\"post_slack_message\":\"safe_output_script_post_slack_message.cjs\"}"
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"add_labels\":{\"allowed\":[\"smoke-claude\"]},\"add_reviewer\":{\"max\":2,\"target\":\"*\"},\"close_pull_request\":{\"max\":1,\"staged\":true},\"create_code_scanning_alert\":{\"driver\":\"Smoke Claude\"},\"create_issue\":{\"close_older_issues\":true,\"close_older_key\":\"smoke-claude\",\"expires\":2,\"group\":true,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request_review_comment\":{\"max\":5,\"side\":\"RIGHT\",\"target\":\"*\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\"smoke-test-files/smoke-claude-push-test.md\"],\"if_no_changes\":\"warn\",\"labels\":[\"smoke-claude\"],\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"CLAUDE.md\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".claude/\"],\"staged\":true,\"target\":\"*\"},\"report_incomplete\":{},\"resolve_pull_request_review_thread\":{\"max\":5},\"submit_pull_request_review\":{\"footer\":\"always\",\"max\":1},\"update_pull_request\":{\"allow_body\":true,\"allow_title\":true,\"max\":1,\"merge_base\":false,\"target\":\"*\"}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"add_labels\":{\"allowed\":[\"smoke-claude\"]},\"add_reviewer\":{\"max\":2,\"target\":\"*\"},\"close_pull_request\":{\"max\":1,\"staged\":true},\"create_code_scanning_alert\":{\"driver\":\"Smoke Claude\"},\"create_issue\":{\"close_older_issues\":true,\"close_older_key\":\"smoke-claude\",\"expires\":2,\"group\":true,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request_review_comment\":{\"max\":5,\"side\":\"RIGHT\",\"target\":\"*\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\"smoke-test-files/smoke-claude-push-test.md\"],\"if_no_changes\":\"warn\",\"labels\":[\"smoke-claude\"],\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"CLAUDE.md\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".claude/\"],\"staged\":true,\"target\":\"*\"},\"report_incomplete\":{},\"resolve_pull_request_review_thread\":{\"max\":5},\"submit_pull_request_review\":{\"footer\":\"always\",\"max\":1},\"update_pull_request\":{\"allow_body\":true,\"allow_title\":true,\"max\":1,\"target\":\"*\",\"update_branch\":false}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/actions/setup/js/safe_output_type_validator.test.cjs b/actions/setup/js/safe_output_type_validator.test.cjs
index 48936cfba4a..0f6fbdbfd08 100644
--- a/actions/setup/js/safe_output_type_validator.test.cjs
+++ b/actions/setup/js/safe_output_type_validator.test.cjs
@@ -48,11 +48,11 @@ const SAMPLE_VALIDATION_CONFIG = {
},
update_pull_request: {
defaultMax: 1,
- customValidation: "requiresOneOf:title,body,merge_base",
+ customValidation: "requiresOneOf:title,body,update_branch",
fields: {
title: { type: "string", sanitize: true, maxLength: 256 },
body: { type: "string", sanitize: true, maxLength: 65000 },
- merge_base: { type: "boolean" },
+ update_branch: { type: "boolean" },
pull_request_number: { issueOrPRNumber: true },
},
},
@@ -410,19 +410,19 @@ describe("safe_output_type_validator", () => {
expect(result.error).toContain("pull_number");
});
- it("should fail for update_pull_request when merge_base is false and no title/body is provided", async () => {
+ it("should fail for update_pull_request when update_branch is false and no title/body is provided", async () => {
const { validateItem } = await import("./safe_output_type_validator.cjs");
- const result = validateItem({ type: "update_pull_request", merge_base: false }, "update_pull_request", 1);
+ const result = validateItem({ type: "update_pull_request", update_branch: false }, "update_pull_request", 1);
expect(result.isValid).toBe(false);
expect(result.error).toContain("requires at least one of");
});
- it("should pass for update_pull_request when merge_base is true", async () => {
+ it("should pass for update_pull_request when update_branch is true", async () => {
const { validateItem } = await import("./safe_output_type_validator.cjs");
- const result = validateItem({ type: "update_pull_request", merge_base: true }, "update_pull_request", 1);
+ const result = validateItem({ type: "update_pull_request", update_branch: true }, "update_pull_request", 1);
expect(result.isValid).toBe(true);
});
diff --git a/actions/setup/js/safe_outputs_tools.json b/actions/setup/js/safe_outputs_tools.json
index 58990088bf3..51594c0c98a 100644
--- a/actions/setup/js/safe_outputs_tools.json
+++ b/actions/setup/js/safe_outputs_tools.json
@@ -783,7 +783,7 @@
"enum": ["replace", "append", "prepend"],
"description": "How to update the PR body: 'replace' (default - completely overwrite), 'append' (add to end with separator), or 'prepend' (add to start with separator). Title is always replaced."
},
- "merge_base": {
+ "update_branch": {
"type": "boolean",
"description": "When true, update the pull request branch with the latest base branch changes before applying other updates. Defaults to false."
},
diff --git a/actions/setup/js/types/safe-outputs.d.ts b/actions/setup/js/types/safe-outputs.d.ts
index fb5ff47438c..d509c4e7f4c 100644
--- a/actions/setup/js/types/safe-outputs.d.ts
+++ b/actions/setup/js/types/safe-outputs.d.ts
@@ -235,8 +235,8 @@ interface UpdatePullRequestItem extends BaseSafeOutputItem {
body?: string;
/** Update operation for body: 'replace' (default), 'append', or 'prepend' */
operation?: "replace" | "append" | "prepend";
- /** When true, merges the latest base branch changes into the pull request branch before other updates */
- merge_base?: boolean;
+ /** When true, updates the pull request branch with the latest base branch changes before other updates */
+ update_branch?: boolean;
/** Optional pull request number for target "*" */
pull_request_number?: number | string;
/** Whether the PR should be a draft (true) or ready for review (false) */
diff --git a/actions/setup/js/update_pull_request.cjs b/actions/setup/js/update_pull_request.cjs
index d83d8f9e2a3..bbb93637529 100644
--- a/actions/setup/js/update_pull_request.cjs
+++ b/actions/setup/js/update_pull_request.cjs
@@ -34,10 +34,10 @@ async function executePRUpdate(github, context, prNumber, updateData) {
// Remove internal fields
const { _operation, _rawBody, _includeFooter, _workflowRepo, ...apiData } = updateData;
- const mergeBase = apiData.merge_base === true;
- delete apiData.merge_base;
+ const updateBranch = apiData.update_branch === true;
+ delete apiData.update_branch;
- if (mergeBase) {
+ if (updateBranch) {
core.info(`Updating pull request #${prNumber} branch with base branch changes`);
try {
await withRetry(
@@ -176,9 +176,9 @@ function buildPRUpdateData(item, config) {
hasUpdates = true;
}
- const mergeBase = item.merge_base !== undefined ? item.merge_base === true : config.merge_base === true;
- if (mergeBase) {
- updateData.merge_base = true;
+ const updateBranch = item.update_branch !== undefined ? item.update_branch === true : config.update_branch === true;
+ if (updateBranch) {
+ updateData.update_branch = true;
hasUpdates = true;
}
@@ -222,7 +222,7 @@ const main = createUpdateHandlerFactory({
additionalConfig: {
allow_title: true,
allow_body: true,
- merge_base: false,
+ update_branch: false,
},
});
diff --git a/actions/setup/js/update_pull_request.test.cjs b/actions/setup/js/update_pull_request.test.cjs
index 29d8ce96412..e4a34d88f67 100644
--- a/actions/setup/js/update_pull_request.test.cjs
+++ b/actions/setup/js/update_pull_request.test.cjs
@@ -745,7 +745,7 @@ describe("update_pull_request.cjs - executePRUpdate function", () => {
});
});
-describe("update_pull_request.cjs - merge_base behavior", () => {
+describe("update_pull_request.cjs - update_branch behavior", () => {
beforeEach(async () => {
vi.clearAllMocks();
vi.resetModules();
@@ -777,22 +777,22 @@ describe("update_pull_request.cjs - merge_base behavior", () => {
});
});
- it("should include merge_base when item requests it", () => {
- const result = updatePRModule.buildPRUpdateData({ merge_base: true }, {});
+ it("should include update_branch when item requests it", () => {
+ const result = updatePRModule.buildPRUpdateData({ update_branch: true }, {});
expect(result.success).toBe(true);
- expect(result.data.merge_base).toBe(true);
+ expect(result.data.update_branch).toBe(true);
});
- it("should inherit merge_base from config when item does not set it", () => {
- const result = updatePRModule.buildPRUpdateData({}, { merge_base: true });
+ it("should inherit update_branch from config when item does not set it", () => {
+ const result = updatePRModule.buildPRUpdateData({}, { update_branch: true });
expect(result.success).toBe(true);
- expect(result.data.merge_base).toBe(true);
+ expect(result.data.update_branch).toBe(true);
});
- it("should call updateBranch when merge_base is enabled and no other fields are updated", async () => {
- const handler = await updatePRModule.main({ merge_base: true });
+ it("should call updateBranch when update_branch is enabled and no other fields are updated", async () => {
+ const handler = await updatePRModule.main({ update_branch: true });
const result = await handler({ pull_request_number: 100 });
@@ -806,13 +806,13 @@ describe("update_pull_request.cjs - merge_base behavior", () => {
expect(mockGithub.rest.pulls.update).not.toHaveBeenCalled();
});
- it("should call updateBranch before pulls.update when merge_base and title update are both requested", async () => {
+ it("should call updateBranch before pulls.update when update_branch and title update are both requested", async () => {
const handler = await updatePRModule.main({});
await handler({
pull_request_number: 100,
title: "Updated PR",
- merge_base: true,
+ update_branch: true,
});
expect(mockGithub.rest.pulls.updateBranch).toHaveBeenCalled();
@@ -829,17 +829,17 @@ describe("update_pull_request.cjs - merge_base behavior", () => {
data: { message: "Branch updated after retry" },
});
- const handler = await updatePRModule.main({ merge_base: true });
+ const handler = await updatePRModule.main({ update_branch: true });
const result = await handler({ pull_request_number: 100 });
expect(result.success).toBe(true);
expect(mockGithub.rest.pulls.updateBranch).toHaveBeenCalledTimes(2);
});
- it("should log merge-base operation failure when updateBranch fails", async () => {
+ it("should log update-branch operation failure when updateBranch fails", async () => {
mockGithub.rest.pulls.updateBranch.mockRejectedValueOnce(new Error("branch update forbidden"));
- const handler = await updatePRModule.main({ merge_base: true });
+ const handler = await updatePRModule.main({ update_branch: true });
const result = await handler({ pull_request_number: 100 });
expect(result.success).toBe(false);
diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md
index 4cf72c154db..732d46cc8a2 100644
--- a/docs/src/content/docs/reference/frontmatter-full.md
+++ b/docs/src/content/docs/reference/frontmatter-full.md
@@ -4527,7 +4527,7 @@ safe-outputs:
# When true, update the pull request branch with the latest base branch changes
# before applying other updates. Defaults to false.
# (optional)
- merge-base: true
+ update-branch: true
# Default operation for body updates: 'append' (add to end), 'prepend' (add to
# start), or 'replace' (overwrite completely). Defaults to 'replace' if not
diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json
index 89e9395fb40..447f82c7724 100644
--- a/pkg/parser/schemas/main_workflow_schema.json
+++ b/pkg/parser/schemas/main_workflow_schema.json
@@ -6976,7 +6976,7 @@
"type": "boolean",
"description": "Allow updating pull request body - defaults to true, set to false to disable"
},
- "merge-base": {
+ "update-branch": {
"type": "boolean",
"description": "When true, update the pull request branch with the latest base branch changes before applying other updates. Defaults to false."
},
diff --git a/pkg/workflow/compiler_safe_outputs_config_test.go b/pkg/workflow/compiler_safe_outputs_config_test.go
index 1af6b9744b0..578303508d7 100644
--- a/pkg/workflow/compiler_safe_outputs_config_test.go
+++ b/pkg/workflow/compiler_safe_outputs_config_test.go
@@ -1203,21 +1203,21 @@ func TestHandlerConfigUpdateFields(t *testing.T) {
}
}
-func TestUpdatePullRequestMergeBaseHandlerConfig(t *testing.T) {
+func TestUpdatePullRequestUpdateBranchHandlerConfig(t *testing.T) {
tests := []struct {
- name string
- mergeBase *bool
- expected bool
+ name string
+ updateBranch *bool
+ expected bool
}{
{
- name: "defaults merge_base to false",
- mergeBase: nil,
- expected: false,
+ name: "defaults update_branch to false",
+ updateBranch: nil,
+ expected: false,
},
{
- name: "sets merge_base true when configured",
- mergeBase: testBoolPtr(true),
- expected: true,
+ name: "sets update_branch true when configured",
+ updateBranch: testBoolPtr(true),
+ expected: true,
},
}
@@ -1229,7 +1229,7 @@ func TestUpdatePullRequestMergeBaseHandlerConfig(t *testing.T) {
Name: "Test Workflow",
SafeOutputs: &SafeOutputsConfig{
UpdatePullRequests: &UpdatePullRequestsConfig{
- MergeBase: tt.mergeBase,
+ UpdateBranch: tt.updateBranch,
},
},
}
@@ -1254,9 +1254,9 @@ func TestUpdatePullRequestMergeBaseHandlerConfig(t *testing.T) {
updatePRConfig, ok := config["update_pull_request"]
require.True(t, ok, "Expected update_pull_request config")
- mergeBaseValue, ok := updatePRConfig["merge_base"]
- require.True(t, ok, "Expected merge_base key in update_pull_request config")
- assert.Equal(t, tt.expected, mergeBaseValue)
+ updateBranchValue, ok := updatePRConfig["update_branch"]
+ require.True(t, ok, "Expected update_branch key in update_pull_request config")
+ assert.Equal(t, tt.expected, updateBranchValue)
}
}
}
diff --git a/pkg/workflow/compiler_safe_outputs_handlers.go b/pkg/workflow/compiler_safe_outputs_handlers.go
index 9469324e105..e8aae50ac83 100644
--- a/pkg/workflow/compiler_safe_outputs_handlers.go
+++ b/pkg/workflow/compiler_safe_outputs_handlers.go
@@ -437,7 +437,7 @@ var handlerRegistry = map[string]handlerBuilder{
AddIfNotEmpty("target", c.Target).
AddBoolPtrOrDefault("allow_title", c.Title, true).
AddBoolPtrOrDefault("allow_body", c.Body, true).
- AddBoolPtrOrDefault("merge_base", c.MergeBase, false).
+ AddBoolPtrOrDefault("update_branch", c.UpdateBranch, false).
AddStringPtr("default_operation", c.Operation).
AddTemplatableBool("footer", getEffectiveFooterForTemplatable(c.Footer, cfg.Footer)).
AddIfNotEmpty("target-repo", c.TargetRepoSlug).
diff --git a/pkg/workflow/js/safe_outputs_tools.json b/pkg/workflow/js/safe_outputs_tools.json
index fdb5b110788..f8428359712 100644
--- a/pkg/workflow/js/safe_outputs_tools.json
+++ b/pkg/workflow/js/safe_outputs_tools.json
@@ -935,7 +935,7 @@
],
"description": "How to update the PR body: 'replace' (default - completely overwrite), 'append' (add to end with separator), or 'prepend' (add to start with separator). Title is always replaced."
},
- "merge_base": {
+ "update_branch": {
"type": "boolean",
"description": "When true, update the pull request branch with the latest base branch changes before applying other updates. Defaults to false."
},
diff --git a/pkg/workflow/safe_output_validation_config_test.go b/pkg/workflow/safe_output_validation_config_test.go
index 9ae1fa97dfe..847f5799022 100644
--- a/pkg/workflow/safe_output_validation_config_test.go
+++ b/pkg/workflow/safe_output_validation_config_test.go
@@ -194,12 +194,12 @@ func TestUpdatePullRequestValidationConfig(t *testing.T) {
t.Fatal("update_pull_request not found in ValidationConfig")
}
- if config.CustomValidation != "requiresOneOf:title,body,merge_base" {
- t.Errorf("update_pull_request customValidation = %q, want %q", config.CustomValidation, "requiresOneOf:title,body,merge_base")
+ if config.CustomValidation != "requiresOneOf:title,body,update_branch" {
+ t.Errorf("update_pull_request customValidation = %q, want %q", config.CustomValidation, "requiresOneOf:title,body,update_branch")
}
- if _, ok := config.Fields["merge_base"]; !ok {
- t.Error("update_pull_request Fields is missing the 'merge_base' field")
+ if _, ok := config.Fields["update_branch"]; !ok {
+ t.Error("update_pull_request Fields is missing the 'update_branch' field")
}
}
@@ -208,7 +208,7 @@ func TestValidationConfigConsistency(t *testing.T) {
validCustomValidations := map[string]bool{
"requiresOneOf:status,title,body": true,
"requiresOneOf:title,body": true,
- "requiresOneOf:title,body,merge_base": true,
+ "requiresOneOf:title,body,update_branch": true,
"requiresOneOf:title,body,labels": true,
"requiresOneOf:issue_number,pull_number": true,
"requiresOneOf:reviewers,team_reviewers": true,
diff --git a/pkg/workflow/safe_outputs_permissions.go b/pkg/workflow/safe_outputs_permissions.go
index 04b58866952..06d684bbcbf 100644
--- a/pkg/workflow/safe_outputs_permissions.go
+++ b/pkg/workflow/safe_outputs_permissions.go
@@ -147,7 +147,12 @@ func ComputePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio
}
if safeOutputs.UpdatePullRequests != nil && !isHandlerStaged(safeOutputs.Staged, safeOutputs.UpdatePullRequests.Staged) {
safeOutputsPermissionsLog.Print("Adding permissions for update-pull-request")
- permissions.Merge(NewPermissionsContentsWritePRWrite())
+ if safeOutputs.UpdatePullRequests.UpdateBranch != nil && *safeOutputs.UpdatePullRequests.UpdateBranch {
+ safeOutputsPermissionsLog.Print("update-pull-request has update-branch enabled; requiring contents: write")
+ permissions.Merge(NewPermissionsContentsWritePRWrite())
+ } else {
+ permissions.Merge(NewPermissionsContentsReadPRWrite())
+ }
}
if safeOutputs.ClosePullRequests != nil && !isHandlerStaged(safeOutputs.Staged, safeOutputs.ClosePullRequests.Staged) {
safeOutputsPermissionsLog.Print("Adding permissions for close-pull-request")
diff --git a/pkg/workflow/safe_outputs_permissions_test.go b/pkg/workflow/safe_outputs_permissions_test.go
index 52d4cf32d8d..84621dc0e3d 100644
--- a/pkg/workflow/safe_outputs_permissions_test.go
+++ b/pkg/workflow/safe_outputs_permissions_test.go
@@ -219,7 +219,7 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) {
},
},
{
- name: "update-pull-request requires contents write for updateBranch API",
+ name: "update-pull-request without update-branch requires contents read",
safeOutputs: &SafeOutputsConfig{
UpdatePullRequests: &UpdatePullRequestsConfig{
UpdateEntityConfig: UpdateEntityConfig{
@@ -227,6 +227,21 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) {
},
},
},
+ expected: map[PermissionScope]PermissionLevel{
+ PermissionContents: PermissionRead,
+ PermissionPullRequests: PermissionWrite,
+ },
+ },
+ {
+ name: "update-pull-request with update-branch requires contents write",
+ safeOutputs: &SafeOutputsConfig{
+ UpdatePullRequests: &UpdatePullRequestsConfig{
+ UpdateEntityConfig: UpdateEntityConfig{
+ BaseSafeOutputConfig: BaseSafeOutputConfig{Max: strPtr("1")},
+ },
+ UpdateBranch: boolPtr(true),
+ },
+ },
expected: map[PermissionScope]PermissionLevel{
PermissionContents: PermissionWrite,
PermissionPullRequests: PermissionWrite,
diff --git a/pkg/workflow/safe_outputs_validation_config.go b/pkg/workflow/safe_outputs_validation_config.go
index 5a9692245da..88751ca7ebb 100644
--- a/pkg/workflow/safe_outputs_validation_config.go
+++ b/pkg/workflow/safe_outputs_validation_config.go
@@ -154,12 +154,12 @@ var ValidationConfig = map[string]TypeValidationConfig{
},
"update_pull_request": {
DefaultMax: 1,
- CustomValidation: "requiresOneOf:title,body,merge_base",
+ CustomValidation: "requiresOneOf:title,body,update_branch",
Fields: map[string]FieldValidation{
"title": {Type: "string", Sanitize: true, MaxLength: 256},
"body": {Type: "string", Sanitize: true, MaxLength: MaxBodyLength},
"operation": {Type: "string", Enum: []string{"replace", "append", "prepend"}},
- "merge_base": {Type: "boolean"},
+ "update_branch": {Type: "boolean"},
"draft": {Type: "boolean"},
"pull_request_number": {IssueOrPRNumber: true},
"repo": {Type: "string", MaxLength: 256}, // Optional: target repository in format "owner/repo"
diff --git a/pkg/workflow/update_pull_request_helpers.go b/pkg/workflow/update_pull_request_helpers.go
index 6f214ae8749..8448d391c28 100644
--- a/pkg/workflow/update_pull_request_helpers.go
+++ b/pkg/workflow/update_pull_request_helpers.go
@@ -12,11 +12,11 @@ var updatePullRequestLog = logger.New("workflow:update_pull_request")
// UpdatePullRequestsConfig holds configuration for updating GitHub pull requests from agent output
type UpdatePullRequestsConfig struct {
UpdateEntityConfig `yaml:",inline"`
- Title *bool `yaml:"title,omitempty"` // Allow updating PR title - defaults to true, set to false to disable
- Body *bool `yaml:"body,omitempty"` // Allow updating PR body - defaults to true, set to false to disable
- MergeBase *bool `yaml:"merge-base,omitempty"` // When true, update PR branch with latest base branch changes before applying other updates. Defaults to false.
- Operation *string `yaml:"operation,omitempty"` // Default operation for body updates: "append", "prepend", or "replace" (defaults to "replace")
- Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted.
+ Title *bool `yaml:"title,omitempty"` // Allow updating PR title - defaults to true, set to false to disable
+ Body *bool `yaml:"body,omitempty"` // Allow updating PR body - defaults to true, set to false to disable
+ UpdateBranch *bool `yaml:"update-branch,omitempty"` // When true, update PR branch with latest base branch changes before applying other updates. Defaults to false.
+ Operation *string `yaml:"operation,omitempty"` // Default operation for body updates: "append", "prepend", or "replace" (defaults to "replace")
+ Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted.
}
// parseUpdatePullRequestsConfig handles update-pull-request configuration
@@ -29,7 +29,7 @@ func (c *Compiler) parseUpdatePullRequestsConfig(outputMap map[string]any) *Upda
return []UpdateEntityFieldSpec{
{Name: "title", Mode: FieldParsingBoolValue, Dest: &cfg.Title},
{Name: "body", Mode: FieldParsingBoolValue, Dest: &cfg.Body},
- {Name: "merge-base", Mode: FieldParsingBoolValue, Dest: &cfg.MergeBase},
+ {Name: "update-branch", Mode: FieldParsingBoolValue, Dest: &cfg.UpdateBranch},
{Name: "footer", Mode: FieldParsingTemplatableBool, StringDest: &cfg.Footer},
}
}, func(configMap map[string]any, cfg *UpdatePullRequestsConfig) {