diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 7208dfaf885..cc61844d93b 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -971,29 +971,7 @@ jobs: - name: Execute Claude Code CLI id: agentic_execution # Allowed tools (sorted): - # - Bash(/tmp/gh-aw/jqschema.sh) - # - Bash(cat) - # - Bash(date) - # - Bash(echo) - # - Bash(git add:*) - # - Bash(git branch:*) - # - Bash(git checkout:*) - # - Bash(git commit:*) - # - Bash(git merge:*) - # - Bash(git rm:*) - # - Bash(git status) - # - Bash(git switch:*) - # - Bash(git) - # - Bash(grep) - # - Bash(head) - # - Bash(jq *) - # - Bash(ls) - # - Bash(pwd) - # - Bash(sort) - # - Bash(tail) - # - Bash(uniq) - # - Bash(wc) - # - Bash(yq) + # - Bash # - BashOutput # - Edit # - Edit(/tmp/gh-aw/cache-memory/*) @@ -1092,7 +1070,7 @@ jobs: (umask 177 && touch /tmp/gh-aw/agent-stdio.log) # shellcheck disable=SC1003 sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --tty --env-all --exclude-env ANTHROPIC_API_KEY --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,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,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,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,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \ - -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && claude --print --no-chrome --max-turns 100 --mcp-config /tmp/gh-aw/mcp-config/mcp-servers.json --allowed-tools '\''Bash(/tmp/gh-aw/jqschema.sh),Bash(cat),Bash(date),Bash(echo),Bash(git add:*),Bash(git branch:*),Bash(git checkout:*),Bash(git commit:*),Bash(git merge:*),Bash(git rm:*),Bash(git status),Bash(git switch:*),Bash(git),Bash(grep),Bash(head),Bash(jq *),Bash(ls),Bash(pwd),Bash(sort),Bash(tail),Bash(uniq),Bash(wc),Bash(yq),BashOutput,Edit,Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__playwright__browser_click,mcp__playwright__browser_close,mcp__playwright__browser_console_messages,mcp__playwright__browser_drag,mcp__playwright__browser_evaluate,mcp__playwright__browser_file_upload,mcp__playwright__browser_fill_form,mcp__playwright__browser_handle_dialog,mcp__playwright__browser_hover,mcp__playwright__browser_install,mcp__playwright__browser_navigate,mcp__playwright__browser_navigate_back,mcp__playwright__browser_network_requests,mcp__playwright__browser_press_key,mcp__playwright__browser_resize,mcp__playwright__browser_select_option,mcp__playwright__browser_snapshot,mcp__playwright__browser_tabs,mcp__playwright__browser_take_screenshot,mcp__playwright__browser_type,mcp__playwright__browser_wait_for'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode bypassPermissions --output-format stream-json "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && claude --print --no-chrome --max-turns 100 --mcp-config /tmp/gh-aw/mcp-config/mcp-servers.json --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__playwright__browser_click,mcp__playwright__browser_close,mcp__playwright__browser_console_messages,mcp__playwright__browser_drag,mcp__playwright__browser_evaluate,mcp__playwright__browser_file_upload,mcp__playwright__browser_fill_form,mcp__playwright__browser_handle_dialog,mcp__playwright__browser_hover,mcp__playwright__browser_install,mcp__playwright__browser_navigate,mcp__playwright__browser_navigate_back,mcp__playwright__browser_network_requests,mcp__playwright__browser_press_key,mcp__playwright__browser_resize,mcp__playwright__browser_select_option,mcp__playwright__browser_snapshot,mcp__playwright__browser_tabs,mcp__playwright__browser_take_screenshot,mcp__playwright__browser_type,mcp__playwright__browser_wait_for'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode bypassPermissions --output-format stream-json "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} BASH_DEFAULT_TIMEOUT_MS: 60000 diff --git a/.github/workflows/copilot-pr-merged-report.lock.yml b/.github/workflows/copilot-pr-merged-report.lock.yml index 37767d7ffab..06b1ef1236d 100644 --- a/.github/workflows/copilot-pr-merged-report.lock.yml +++ b/.github/workflows/copilot-pr-merged-report.lock.yml @@ -1,5 +1,5 @@ # gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"75f825fd2068d558449e2b05450d7a6410d7f0d74817065330e715e36e0fcbbc","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","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.20","digest":"sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20@sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20","digest":"sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20@sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20","digest":"sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20@sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19","digest":"sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.2.19@sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd"},{"image":"ghcr.io/github/github-mcp-server:v0.32.0","digest":"sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28","pinned_image":"ghcr.io/github/github-mcp-server:v0.32.0@sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","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.20","digest":"sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20@sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20","digest":"sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20@sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20","digest":"sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20@sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19","digest":"sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.2.19@sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -51,7 +51,6 @@ # - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20@sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519 # - ghcr.io/github/gh-aw-firewall/squid:0.25.20@sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236 # - ghcr.io/github/gh-aw-mcpg:v0.2.19@sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd -# - ghcr.io/github/github-mcp-server:v0.32.0@sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b name: "Daily Copilot PR Merged Report" @@ -152,14 +151,8 @@ jobs: env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} # poutine:ignore untrusted_checkout_exec run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" @@ -176,37 +169,6 @@ jobs: Tools: create_discussion, missing_tool, missing_data, noop - - The following GitHub context information is available for this workflow: - {{#if __GH_AW_GITHUB_ACTOR__ }} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if __GH_AW_GITHUB_REPOSITORY__ }} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if __GH_AW_GITHUB_WORKSPACE__ }} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }} - - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }} - - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }} - - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }} - - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__ - {{/if}} - {{#if __GH_AW_GITHUB_RUN_ID__ }} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - - GH_AW_PROMPT_131c8ab1c72011df_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_131c8ab1c72011df_EOF' {{#runtime-import .github/workflows/shared/gh.md}} {{#runtime-import .github/workflows/shared/copilot-pr-analysis-base.md}} @@ -235,14 +197,8 @@ jobs: GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -257,14 +213,8 @@ jobs: GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, - GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, - GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER, - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, - GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE + GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID } }); - name: Validate prompt placeholders @@ -411,18 +361,8 @@ jobs: GH_HOST: github.com - name: Install AWF binary run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.20 - - name: Determine automatic lockdown mode for GitHub MCP Server - id: determine-automatic-lockdown - uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 - env: - GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} - GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - with: - script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); - await determineAutomaticLockdown(github, context, core); - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.20@sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20@sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519 ghcr.io/github/gh-aw-firewall/squid:0.25.20@sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236 ghcr.io/github/gh-aw-mcpg:v0.2.19@sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd ghcr.io/github/github-mcp-server:v0.32.0@sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.20@sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20@sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519 ghcr.io/github/gh-aw-firewall/squid:0.25.20@sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236 ghcr.io/github/gh-aw-mcpg:v0.2.19@sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b - name: Write Safe Outputs Config run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" @@ -701,9 +641,6 @@ jobs: GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} GH_DEBUG: 1 - GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} - GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} - GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} run: | set -eo pipefail mkdir -p /tmp/gh-aw/mcp-config @@ -726,34 +663,11 @@ jobs: cat << GH_AW_MCP_CONFIG_214c4b63db1c096a_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh" { "mcpServers": { - "github": { - "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v0.32.0", - "env": { - "GITHUB_HOST": "\${GITHUB_SERVER_URL}", - "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", - "GITHUB_READ_ONLY": "1", - "GITHUB_TOOLSETS": "context,repos,issues,pull_requests" - }, - "guard-policies": { - "allow-only": { - "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY", - "repos": "$GITHUB_MCP_GUARD_REPOS" - } - } - }, "mcpscripts": { "type": "http", "url": "http://host.docker.internal:$GH_AW_MCP_SCRIPTS_PORT", "headers": { "Authorization": "\${GH_AW_MCP_SCRIPTS_API_KEY}" - }, - "guard-policies": { - "write-sink": { - "accept": [ - "*" - ] - } } }, "safeoutputs": { @@ -761,13 +675,6 @@ jobs: "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", "headers": { "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}" - }, - "guard-policies": { - "write-sink": { - "accept": [ - "*" - ] - } } } }, @@ -796,7 +703,7 @@ jobs: touch /tmp/gh-aw/agent-step-summary.md (umask 177 && touch /tmp/gh-aw/agent-stdio.log) # shellcheck disable=SC1003 - sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_AW_GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,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,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,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,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \ + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_AW_GH_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,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,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,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,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \ -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE @@ -812,7 +719,6 @@ jobs: GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITHUB_REF_NAME: ${{ github.ref_name }} GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml index 12fd0cd4275..bde55ba3c9e 100644 --- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml +++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml @@ -413,10 +413,10 @@ jobs: - name: Restore cache-memory file share data uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-copilot-pr-data-${{ github.run_id }} + key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory restore-keys: | - memory-none-nopolicy-copilot-pr-data- + memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- - name: Setup cache-memory git repository env: GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory @@ -1489,6 +1489,6 @@ jobs: if: steps.check_cache_default.outputs.has_content == 'true' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-copilot-pr-data-${{ github.run_id }} + key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml index 89d6a780df3..e72f25bf548 100644 --- a/.github/workflows/copilot-session-insights.lock.yml +++ b/.github/workflows/copilot-session-insights.lock.yml @@ -413,10 +413,10 @@ jobs: - name: Restore cache-memory file share data uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} + key: memory-none-nopolicy-copilot-session-data-${{ github.run_id }} path: /tmp/gh-aw/cache-memory restore-keys: | - memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- + memory-none-nopolicy-copilot-session-data- - name: Setup cache-memory git repository env: GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory @@ -1560,6 +1560,6 @@ jobs: if: steps.check_cache_default.outputs.has_content == 'true' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} + key: memory-none-nopolicy-copilot-session-data-${{ github.run_id }} path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml index c2eff670c52..e54f99410de 100644 --- a/.github/workflows/daily-issues-report.lock.yml +++ b/.github/workflows/daily-issues-report.lock.yml @@ -437,10 +437,10 @@ jobs: - name: Restore cache-memory file share data uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-approved-6f25a3c0-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} + key: memory-approved-6f25a3c0-issues-data-${{ github.run_id }} path: /tmp/gh-aw/cache-memory restore-keys: | - memory-approved-6f25a3c0-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- + memory-approved-6f25a3c0-issues-data- - name: Setup cache-memory git repository env: GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory @@ -1463,6 +1463,6 @@ jobs: if: steps.check_cache_default.outputs.has_content == 'true' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-approved-6f25a3c0-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} + key: memory-approved-6f25a3c0-issues-data-${{ github.run_id }} path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index 32c8b22cbdf..aab0b570904 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -427,10 +427,10 @@ jobs: - name: Restore cache-memory file share data uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-weekly-issues-data-${{ github.run_id }} + key: memory-none-nopolicy-discussions-data-${{ github.run_id }} path: /tmp/gh-aw/cache-memory restore-keys: | - memory-none-nopolicy-weekly-issues-data- + memory-none-nopolicy-discussions-data- - name: Setup cache-memory git repository env: GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory @@ -1655,6 +1655,6 @@ jobs: if: steps.check_cache_default.outputs.has_content == 'true' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-weekly-issues-data-${{ github.run_id }} + key: memory-none-nopolicy-discussions-data-${{ github.run_id }} path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/github-mcp-structural-analysis.lock.yml b/.github/workflows/github-mcp-structural-analysis.lock.yml index c7eaa8a4f49..3d9ff8bb4c0 100644 --- a/.github/workflows/github-mcp-structural-analysis.lock.yml +++ b/.github/workflows/github-mcp-structural-analysis.lock.yml @@ -378,10 +378,10 @@ jobs: - name: Restore cache-memory file share data uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} + key: memory-none-nopolicy-mcp-response-analysis-${{ github.workflow }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory restore-keys: | - memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- + memory-none-nopolicy-mcp-response-analysis-${{ github.workflow }}- - name: Setup cache-memory git repository env: GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory @@ -1411,6 +1411,6 @@ jobs: if: steps.check_cache_default.outputs.has_content == 'true' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} + key: memory-none-nopolicy-mcp-response-analysis-${{ github.workflow }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml index ae40ee11cba..f2373e85363 100644 --- a/.github/workflows/prompt-clustering-analysis.lock.yml +++ b/.github/workflows/prompt-clustering-analysis.lock.yml @@ -444,10 +444,10 @@ jobs: - name: Restore cache-memory file share data uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-trending-data-${{ github.workflow }}-${{ github.run_id }} + key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory restore-keys: | - memory-none-nopolicy-trending-data-${{ github.workflow }}- + memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- - name: Setup cache-memory git repository env: GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory @@ -1520,6 +1520,6 @@ jobs: if: steps.check_cache_default.outputs.has_content == 'true' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-trending-data-${{ github.workflow }}-${{ github.run_id }} + key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/python-data-charts.lock.yml b/.github/workflows/python-data-charts.lock.yml index dd839de58b1..557eb1d5374 100644 --- a/.github/workflows/python-data-charts.lock.yml +++ b/.github/workflows/python-data-charts.lock.yml @@ -409,10 +409,10 @@ jobs: - name: Restore cache-memory file share data uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} + key: memory-none-nopolicy-charts-trending-${{ github.workflow }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory restore-keys: | - memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- + memory-none-nopolicy-charts-trending-${{ github.workflow }}- - name: Setup cache-memory git repository env: GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory @@ -1412,6 +1412,6 @@ jobs: if: steps.check_cache_default.outputs.has_content == 'true' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} + key: memory-none-nopolicy-charts-trending-${{ github.workflow }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index b4ab57899df..7c7170795af 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -437,10 +437,10 @@ jobs: - name: Restore cache-memory file share data uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-approved-6f25a3c0-trending-data-${{ github.workflow }}-${{ github.run_id }} + key: memory-approved-6f25a3c0-stale-repos-analysis-${{ github.workflow }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory restore-keys: | - memory-approved-6f25a3c0-trending-data-${{ github.workflow }}- + memory-approved-6f25a3c0-stale-repos-analysis-${{ github.workflow }}- - name: Setup cache-memory git repository env: GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory @@ -1410,6 +1410,6 @@ jobs: if: steps.check_cache_default.outputs.has_content == 'true' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - key: memory-approved-6f25a3c0-trending-data-${{ github.workflow }}-${{ github.run_id }} + key: memory-approved-6f25a3c0-stale-repos-analysis-${{ github.workflow }}-${{ github.run_id }} path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/video-analyzer.lock.yml b/.github/workflows/video-analyzer.lock.yml index cd84ec0e02d..77c9414b7a3 100644 --- a/.github/workflows/video-analyzer.lock.yml +++ b/.github/workflows/video-analyzer.lock.yml @@ -650,23 +650,6 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): - # --allow-tool github - # --allow-tool safeoutputs - # --allow-tool shell(cat) - # --allow-tool shell(date) - # --allow-tool shell(echo) - # --allow-tool shell(ffmpeg *) - # --allow-tool shell(ffprobe *) - # --allow-tool shell(grep) - # --allow-tool shell(head) - # --allow-tool shell(ls) - # --allow-tool shell(pwd) - # --allow-tool shell(sort) - # --allow-tool shell(tail) - # --allow-tool shell(uniq) - # --allow-tool shell(wc) - # --allow-tool shell(yq) - # --allow-tool write timeout-minutes: 15 run: | set -o pipefail @@ -674,7 +657,7 @@ jobs: (umask 177 && touch /tmp/gh-aw/agent-stdio.log) # shellcheck disable=SC1003 sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \ - -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(ffmpeg *)'\'' --allow-tool '\''shell(ffprobe *)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} diff --git a/docs/adr/26323-tools-config-base-wins-on-type-conflict.md b/docs/adr/26323-tools-config-base-wins-on-type-conflict.md new file mode 100644 index 00000000000..1366f01d5d6 --- /dev/null +++ b/docs/adr/26323-tools-config-base-wins-on-type-conflict.md @@ -0,0 +1,81 @@ +# ADR-26323: Tools Configuration Merge — Base Workflow Wins on Type Conflict + +**Date**: 2026-04-14 +**Status**: Draft +**Deciders**: pelikhan, Copilot + +--- + +## Part 1 — Narrative (Human-Friendly) + +### Context + +The gh-aw workflow compiler supports importing shared workflows. Both the main (base) workflow and imported shared workflows can declare `tools` configuration. When the compiler merges these configurations, it must decide which value takes precedence when the same key appears in both. The documented principle is "the main workflow overrides imports." Before this fix, `MergeTools` in `pkg/parser/tools_merger.go` had a type-mismatch fallback that overwrote the base value with the additional (import) value, silently violating that principle. A concrete symptom: setting `tools.github: false` in a main workflow had no effect if any imported shared workflow declared `tools.github` as a map (e.g., `tools.github: mode: remote`), leaving the GitHub MCP server enabled against the user's explicit intent. + +### Decision + +We will make the base (main workflow) value win unconditionally for all non-array, non-map conflicts in `MergeTools`, including type mismatches. When both values are scalars of different types — such as `bool` vs. `map` — the base value is kept and the import value is discarded. Arrays are always union-merged (deduplicated). Maps are recursively merged. This extends and makes uniform the existing "workflow overrides imports" principle for every scalar conflict, not just same-type conflicts. + +### Alternatives Considered + +#### Alternative 1: Return an error on type mismatch + +Treat a type mismatch between base and additional as a configuration conflict and fail compilation with a descriptive error, requiring the author to resolve the inconsistency explicitly. + +This was considered because it makes conflicts visible rather than silently ignoring one side. It was rejected because it would be a breaking change — existing workflows that import shared configs with overlapping keys of different types would start failing — and because the correct resolution is already well-defined by the documented "base wins" principle. + +#### Alternative 2: Log a warning and keep the existing (pre-fix) behaviour + +Emit a warning when a type mismatch is encountered but continue to let the import value override the base, matching the old behaviour. + +This was rejected because it preserves the incorrect behaviour: an explicit `tools.github: false` in the main workflow would still be silently overridden by an import. The documented contract — that main workflows override imports — would remain broken. + +#### Alternative 3: Require explicit `override:` syntax for scalar conflicts + +Introduce a dedicated `override:` field or a special sentinel value in frontmatter so that the author must consciously express "this value should win even if the type differs." + +This was considered as a more principled long-term design but rejected for this fix because it requires schema changes, parser updates, and documentation work that are disproportionate to the scope of the bug. The "base always wins" rule is already documented and consistent with all other merge behaviour. + +### Consequences + +#### Positive +- `tools.github: false` (and equivalent scalar disable values) in a main workflow now reliably prevents imported configurations from re-enabling that tool. +- The `MergeTools` function behaves consistently: base wins for all scalar conflicts, regardless of type, matching the documented contract. +- No behaviour change for same-type scalar overrides (those were already base-wins in practice, since `result[key]` was set from base before the loop) — only the type-mismatch branch changes. + +#### Negative +- Any workflow that previously relied on an import overriding a scalar value in the base via a type mismatch will now silently behave differently. This was always the intended behaviour, but any workflow depending on the bug would now change. +- The fix is a silent behaviour change with no migration path; authors won't receive an error or warning if their import's value is now discarded. + +#### Neutral +- The fix is a single-line removal in `tools_merger.go` (`result[key] = newValue` is removed from the type-mismatch branch). +- Two new test files (`frontmatter_merge_test.go`, `importable_tools_test.go`) document the expected merge semantics and serve as regression guards. +- Recursive map merging and array union-merge behaviour are unchanged. + +--- + +## Part 2 — Normative Specification (RFC 2119) + +> The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **MAY**, and **OPTIONAL** in this section are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119). + +### Tools Configuration Merge Semantics + +1. Implementations **MUST** give the base (main workflow) value precedence over the additional (imported workflow) value when merging `tools` configuration and a conflict exists for the same key. +2. Implementations **MUST NOT** overwrite a base scalar value with an additional value when the two values are of different types (e.g., `bool` vs. `map`). +3. Implementations **MUST** union-merge array values (with deduplication) when both the base and additional values for a key are arrays. +4. Implementations **MUST** recursively merge map values when both the base and additional values for a key are maps, applying the same base-wins precedence rule at every level of nesting. +5. Implementations **MUST** add keys that are present in the additional configuration but absent from the base configuration without modification. + +### Conflict Resolution + +1. Implementations **MUST** treat a type mismatch between a base value and an additional value for the same key as a base-wins conflict, retaining the base value and discarding the additional value. +2. Implementations **SHOULD NOT** emit an error or warning for type-mismatch conflicts; silent base-wins resolution is the intended behaviour. +3. Implementations **MAY** log a debug-level message when a type-mismatch conflict is silently resolved, to aid diagnostics. + +### Conformance + +An implementation is considered conformant with this ADR if it satisfies all **MUST** and **MUST NOT** requirements above. Failure to meet any **MUST** or **MUST NOT** requirement — in particular allowing an import to override a base scalar value through a type mismatch — constitutes non-conformance. + +--- + +*This is a DRAFT ADR generated by the [Design Decision Gate](https://github.com/github/gh-aw/actions/runs/24428894483) workflow. The PR author must review, complete, and finalize this document before the PR can merge.* diff --git a/pkg/parser/frontmatter_merge_test.go b/pkg/parser/frontmatter_merge_test.go index 7af88499027..304c1e36d46 100644 --- a/pkg/parser/frontmatter_merge_test.go +++ b/pkg/parser/frontmatter_merge_test.go @@ -130,6 +130,122 @@ func TestMergeTools(t *testing.T) { }, }, }, + { + name: "base false overrides additional map (tools.github: false)", + base: map[string]any{ + "github": false, + }, + additional: map[string]any{ + "github": map[string]any{ + "mode": "remote", + }, + }, + expected: map[string]any{ + "github": false, + }, + }, + { + name: "base map not overridden by additional false", + base: map[string]any{ + "github": map[string]any{ + "mode": "remote", + }, + }, + additional: map[string]any{ + "github": false, + }, + expected: map[string]any{ + "github": map[string]any{ + "mode": "remote", + }, + }, + }, + { + name: "base scalar values override additional scalars in nested maps", + base: map[string]any{ + "tool1": map[string]any{ + "config": "base-value", + "other": "kept", + }, + }, + additional: map[string]any{ + "tool1": map[string]any{ + "config": "additional-value", + "new-key": "added", + }, + }, + expected: map[string]any{ + "tool1": map[string]any{ + "config": "base-value", + "other": "kept", + "new-key": "added", + }, + }, + }, + { + // bash: true in main workflow (or parent import) must win over an import's + // specific bash command list, e.g. ["ls", "cat"]. Both are valid bash tool + // configurations, but they are different types (bool vs array). + name: "base bash true overrides additional bash array", + base: map[string]any{ + "bash": true, + }, + additional: map[string]any{ + "bash": []any{"ls", "cat"}, + }, + expected: map[string]any{ + "bash": true, + }, + }, + { + // A parent import's specific bash command list must not be overridden by a + // child import's unrestricted bash: true. + name: "base bash array not overridden by additional bash true", + base: map[string]any{ + "bash": []any{"ls", "cat"}, + }, + additional: map[string]any{ + "bash": true, + }, + expected: map[string]any{ + "bash": []any{"ls", "cat"}, + }, + }, + { + // cache-memory: {key: "specific-name"} in a parent import must win over a + // child import's generic cache-memory: true. The specific key provides + // more information and should not be overwritten by a generic boolean. + name: "base cache-memory map with key overrides additional cache-memory true", + base: map[string]any{ + "cache-memory": map[string]any{ + "key": "my-specific-cache-key-${{ github.run_id }}", + }, + }, + additional: map[string]any{ + "cache-memory": true, + }, + expected: map[string]any{ + "cache-memory": map[string]any{ + "key": "my-specific-cache-key-${{ github.run_id }}", + }, + }, + }, + { + // cache-memory: true in main workflow must not be overridden by an import's + // specific cache-memory map configuration. + name: "base cache-memory true not overridden by additional cache-memory map", + base: map[string]any{ + "cache-memory": true, + }, + additional: map[string]any{ + "cache-memory": map[string]any{ + "key": "import-specific-key-${{ github.run_id }}", + }, + }, + expected: map[string]any{ + "cache-memory": true, + }, + }, } for _, tt := range tests { @@ -211,7 +327,7 @@ func TestMergeToolsFromJSON(t *testing.T) { name: "objects with overlapping keys", content: `{"tool1": {"enabled": true, "config": "old"}} {"tool1": {"config": "new", "version": 2}}`, - expected: `{"tool1":{"config":"new","enabled":true,"version":2}}`, + expected: `{"tool1":{"config":"old","enabled":true,"version":2}}`, wantErr: false, }, { diff --git a/pkg/parser/tools_merger.go b/pkg/parser/tools_merger.go index b6c0a307c5e..4f191ed3ad3 100644 --- a/pkg/parser/tools_merger.go +++ b/pkg/parser/tools_merger.go @@ -132,9 +132,10 @@ func MergeTools(base, additional map[string]any) (map[string]any, error) { if newAllowed, hasNewAllowed := newMap["allowed"]; hasNewAllowed { // Merge allowed arrays merged := mergeAllowedArrays(existingAllowed, newAllowed) + // Base map wins for all scalar fields; add new keys from the import only. mergedMap := make(map[string]any) - maps.Copy(mergedMap, existingMap) - maps.Copy(mergedMap, newMap) + maps.Copy(mergedMap, newMap) // import values first (lower precedence) + maps.Copy(mergedMap, existingMap) // base values overwrite (higher precedence) mergedMap["allowed"] = merged result[key] = mergedMap continue @@ -147,10 +148,9 @@ func MergeTools(base, additional map[string]any) (map[string]any, error) { return nil, err } result[key] = recursiveMerged - } else { - // Not both same type, overwrite with new value - result[key] = newValue } + // Type mismatch (or same non-array, non-map type): base value takes precedence. + // result[key] already contains existingValue from maps.Copy above — no action needed. } else { // New key, just add it result[key] = newValue diff --git a/pkg/workflow/importable_tools_test.go b/pkg/workflow/importable_tools_test.go index e072f61f6a9..1b2d4880e55 100644 --- a/pkg/workflow/importable_tools_test.go +++ b/pkg/workflow/importable_tools_test.go @@ -767,3 +767,238 @@ Uses all imported neutral tools. t.Error("Expected compiled workflow to contain startup-timeout configuration (90 seconds)") } } + +// TestBashMainWorkflowOverridesImportBashList verifies that bash: true in the main workflow +// (unrestricted bash) takes precedence over a specific bash command list defined in an import. +// This prevents imports from accidentally restricting the main workflow's bash permissions. +func TestBashMainWorkflowOverridesImportBashList(t *testing.T) { + tempDir := testutil.TempDir(t, "test-*") + + // Create a shared workflow with a restricted bash tool list + sharedPath := filepath.Join(tempDir, "bash-restricted.md") + sharedContent := `--- +description: "Shared workflow that restricts bash to specific commands" +tools: + bash: + - "ls" + - "cat" +--- + +# Restricted Bash Import +` + if err := os.WriteFile(sharedPath, []byte(sharedContent), 0644); err != nil { + t.Fatalf("Failed to write shared file: %v", err) + } + + // Main workflow with bash: true (unrestricted), importing the restricted shared file + workflowPath := filepath.Join(tempDir, "my-workflow.md") + workflowContent := `--- +on: issues +engine: copilot +strict: false +permissions: + contents: read + issues: read +tools: + bash: true +sandbox: + agent: false +imports: + - bash-restricted.md +--- + +# My Workflow + +This workflow needs unrestricted bash. +` + if err := os.WriteFile(workflowPath, []byte(workflowContent), 0644); err != nil { + t.Fatalf("Failed to write workflow file: %v", err) + } + + compiler := workflow.NewCompiler() + if err := compiler.CompileWorkflow(workflowPath); err != nil { + t.Fatalf("CompileWorkflow failed: %v", err) + } + + lockFilePath := stringutil.MarkdownToLockFile(workflowPath) + lockFileContent, err := os.ReadFile(lockFilePath) + if err != nil { + t.Fatalf("Failed to read lock file: %v", err) + } + + workflowData := string(lockFileContent) + + // The compiled output must NOT contain shell(ls) or shell(cat) — those would indicate + // the import's restricted list won over the main workflow's bash: true. + restrictedCmds := []string{"shell(ls)", "shell(cat)"} + for _, cmd := range restrictedCmds { + if strings.Contains(workflowData, cmd) { + t.Errorf("Expected compiled workflow to NOT contain %q (bash: true in main workflow should override import's restricted bash list)", cmd) + } + } + + // bash: true gets converted to unrestricted bash (["*"]), which produces --allow-all-tools. + if !strings.Contains(workflowData, "--allow-all-tools") { + t.Error("Expected compiled workflow to contain '--allow-all-tools' (unrestricted bash from bash: true in main workflow)") + } +} + +// TestCacheMemoryMapOverridesBoolInImportChain verifies that when a parent import sets +// tools.cache-memory: {key: "specific-key"}, and a further-nested (child) import sets +// tools.cache-memory: true, the parent import's specific key wins. +// This preserves custom cache isolation across workflow runs. +func TestCacheMemoryMapOverridesBoolInImportChain(t *testing.T) { + tempDir := testutil.TempDir(t, "test-*") + + // Create a deeply nested import that sets cache-memory: true (generic) + childPath := filepath.Join(tempDir, "generic-cache.md") + childContent := `--- +description: "A utility import that enables cache-memory generically" +tools: + cache-memory: true +--- + +# Generic Cache Utility +` + if err := os.WriteFile(childPath, []byte(childContent), 0644); err != nil { + t.Fatalf("Failed to write child shared file: %v", err) + } + + // Create a parent import that sets a specific cache-memory key and imports the child + parentPath := filepath.Join(tempDir, "specific-cache.md") + parentContent := `--- +description: "Parent import with a specific cache-memory key" +tools: + cache-memory: + key: my-specific-cache-key +imports: + - generic-cache.md +--- + +# Specific Cache Parent +` + if err := os.WriteFile(parentPath, []byte(parentContent), 0644); err != nil { + t.Fatalf("Failed to write parent shared file: %v", err) + } + + // Main workflow with no cache-memory of its own, importing the parent + workflowPath := filepath.Join(tempDir, "my-workflow.md") + workflowContent := `--- +on: issues +engine: copilot +strict: false +permissions: + contents: read + issues: read +sandbox: + agent: false +imports: + - specific-cache.md +--- + +# My Workflow + +This workflow relies on the parent import's cache-memory key. +` + if err := os.WriteFile(workflowPath, []byte(workflowContent), 0644); err != nil { + t.Fatalf("Failed to write workflow file: %v", err) + } + + compiler := workflow.NewCompiler() + if err := compiler.CompileWorkflow(workflowPath); err != nil { + t.Fatalf("CompileWorkflow failed: %v", err) + } + + lockFilePath := stringutil.MarkdownToLockFile(workflowPath) + lockFileContent, err := os.ReadFile(lockFilePath) + if err != nil { + t.Fatalf("Failed to read lock file: %v", err) + } + + workflowData := string(lockFileContent) + + // The specific key from the parent import must appear in the compiled cache key. + if !strings.Contains(workflowData, "my-specific-cache-key") { + t.Error("Expected compiled workflow to contain 'my-specific-cache-key' in the cache key (parent import's specific key should win over child's generic cache-memory: true)") + } + + // The generic default key pattern (using GH_AW_WORKFLOW_ID_SANITIZED) must NOT be + // used as the cache key suffix, which would indicate cache-memory: true won. + // Note: GH_AW_WORKFLOW_ID_SANITIZED is also set as an env var; we look for it in the + // context of a "key:" line to distinguish the two. + if strings.Contains(workflowData, "key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}") { + t.Error("Expected compiled workflow cache key to NOT use the default GH_AW_WORKFLOW_ID_SANITIZED pattern (parent import's specific key should win)") + } +} + +// TestGitHubToolFalseOverridesImport verifies that tools.github: false in the main workflow +// takes precedence over tools.github.mode: remote (or any github tool config) from an import. +func TestGitHubToolFalseOverridesImport(t *testing.T) { + tempDir := testutil.TempDir(t, "test-*") + + // Create a shared workflow that enables the GitHub MCP server + sharedPath := filepath.Join(tempDir, "side-repository.md") + sharedContent := `--- +description: "Shared side-repo configuration with GitHub MCP" +tools: + github: + mode: remote +--- + +# Shared Side Repository Configuration +` + if err := os.WriteFile(sharedPath, []byte(sharedContent), 0644); err != nil { + t.Fatalf("Failed to write shared file: %v", err) + } + + // Create main workflow that explicitly disables github tools, but imports the shared file + workflowPath := filepath.Join(tempDir, "my-workflow.md") + workflowContent := `--- +on: issues +engine: copilot +strict: false +permissions: + contents: read + issues: read +tools: + github: false +sandbox: + agent: false +imports: + - side-repository.md +--- + +# My Workflow + +This workflow explicitly opts out of GitHub MCP tools. +` + if err := os.WriteFile(workflowPath, []byte(workflowContent), 0644); err != nil { + t.Fatalf("Failed to write workflow file: %v", err) + } + + compiler := workflow.NewCompiler() + if err := compiler.CompileWorkflow(workflowPath); err != nil { + t.Fatalf("CompileWorkflow failed: %v", err) + } + + lockFilePath := stringutil.MarkdownToLockFile(workflowPath) + lockFileContent, err := os.ReadFile(lockFilePath) + if err != nil { + t.Fatalf("Failed to read lock file: %v", err) + } + + workflowData := string(lockFileContent) + + // The GitHub MCP server should NOT appear in the compiled output because + // tools.github: false in the main workflow must override the import. + githubMCPIndicators := []string{ + "X-MCP-Toolsets", + "api.githubcopilot.com/mcp/", + "ghcr.io/github/github-mcp-server", + } + for _, indicator := range githubMCPIndicators { + if strings.Contains(workflowData, indicator) { + t.Errorf("Expected compiled workflow to NOT contain GitHub MCP server indicator %q (github MCP server should be disabled by tools.github: false)", indicator) + } + } +}