From cdb99289cbe99b650157df7109e524af2273aa5b Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Wed, 7 Oct 2026 14:05:11 -0700 Subject: [PATCH 1/3] Fix silent breaking-change documentation publication failures --- .../workflows/breaking-change-doc.lock.yml | 59 ++++++++- .github/workflows/breaking-change-doc.md | 124 +++++++++++++++++- 2 files changed, 175 insertions(+), 8 deletions(-) diff --git a/.github/workflows/breaking-change-doc.lock.yml b/.github/workflows/breaking-change-doc.lock.yml index c85068c49544e2..80e4f3f836b5c7 100644 --- a/.github/workflows/breaking-change-doc.lock.yml +++ b/.github/workflows/breaking-change-doc.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"2234c316156ae1f98fd3c9498183000da2c1c08663eeee56afdc0df1fca45089","body_hash":"1b90f04424f84fa58da33de70b0b4c28dd219c86438b63b6795ff532aeb73a9e","compiler_version":"v0.86.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.79"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"aa95c7abef66b49dc701e549d25539c65b939252334c2672a4892e7d48b28750","body_hash":"b0305bd9dc7f6fabeb436b3da6f744383c80993ef81e01be50b5f064a706681e","compiler_version":"v0.86.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.79"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"actions/upload-artifact","sha":"ea165f8d65b6e75b540449e92b4886f43607fa02","version":"v4"},{"repo":"github/gh-aw-actions/setup","sha":"6aab9e5b5c91c615506061f09bedd81a23babe3c","version":"v0.86.2"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44","digest":"sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44@sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44","digest":"sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44@sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44","digest":"sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44@sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.9","digest":"sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.9@sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.9.0","digest":"sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e","pinned_image":"ghcr.io/github/github-mcp-server:v1.9.0@sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e"}],"has_pull_request_target":true} # This file was automatically generated by gh-aw (v0.86.2). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -301,7 +301,7 @@ jobs: GH_AW_PROMPT_CONTENT_0000: "\n" GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, missing_tool, missing_data, noop\n" GH_AW_PROMPT_CONTENT_0002: "\n" - GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n\n\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1 (default)]\n - **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. 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).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" GH_AW_PROMPT_CONTENT_0004: "\n" GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/workflows/breaking-change-doc.md}}\n" with: @@ -461,6 +461,26 @@ jobs: echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Checkout ${{ github.repository }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + repository: ${{ github.repository }} + - name: Build checkout manifest for safe-outputs handlers + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + GH_AW_CHECKOUT_MANIFEST_COUNT: "1" + GH_AW_CHECKOUT_REPO_0: ${{ github.repository }} + GH_AW_CHECKOUT_PATH_0: "" + with: + script: | + const { main } = require('${{ runner.temp }}/gh-aw/actions/build_checkout_manifest.cjs'); + await main(); - name: Create gh-aw temp directory run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh" - name: Configure gh CLI for GitHub Enterprise @@ -472,6 +492,12 @@ jobs: with: name: activation path: /tmp/gh-aw + - name: Configure Git credentials + env: + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_TOKEN: ${{ github.token }} + run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh" - name: Install ripgrep run: bash "${RUNNER_TEMP}/gh-aw/actions/install_ripgrep.sh" - name: Install GitHub Copilot CLI @@ -777,7 +803,9 @@ jobs: # --allow-tool shell(github:*) # --allow-tool shell(grep) # --allow-tool shell(head) + # --allow-tool shell(jq) # --allow-tool shell(ls) + # --allow-tool shell(mkdir) # --allow-tool shell(printf) # --allow-tool shell(pwd) # --allow-tool shell(pwsh) @@ -834,7 +862,7 @@ jobs: fi # shellcheck disable=SC1003,SC2016,SC2086 awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --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" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/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(gh:*)'\'' --allow-tool '\''shell(github:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(pwsh)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --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-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/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(gh:*)'\'' --allow-tool '\''shell(github:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(pwsh)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --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-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE @@ -869,6 +897,12 @@ jobs: id: detect-agent-errors continue-on-error: true run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + - name: Configure Git credentials + env: + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_TOKEN: ${{ github.token }} + run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh" - name: Copy Copilot session state files to logs if: always() continue-on-error: true @@ -993,6 +1027,14 @@ jobs: name: breaking-change-docs path: artifacts/docs/breakingChanges/ retention-days: 30 + - env: + PR_NUMBER: ${{ github.event.pull_request.number || inputs.pr_number }} + SAFE_OUTPUTS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} + SUPPRESS_OUTPUT: ${{ github.event_name == 'workflow_dispatch' && inputs.suppress_output }} + name: Validate documentation outcome + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + with: + script: "const fs = require('node:fs');\nfunction parsePrNumber(value) {\n const text = String(value);\n const number = Number(text);\n if ((typeof value !== 'number' && typeof value !== 'string') ||\n !/^\\d+$/.test(text) || !Number.isSafeInteger(number) || number <= 0) {\n throw new Error('Invalid PR number: ' + text);\n }\n return number;\n}\nconst output = JSON.parse(fs.readFileSync('/tmp/gh-aw/agent_output.json', 'utf8'));\nif (!Array.isArray(output.items) || output.errors?.length) {\n throw new Error('Documentation output is invalid: ' + JSON.stringify(output.errors));\n}\nconst failures = output.items.filter(item =>\n ['missing_tool', 'missing_data', 'report_incomplete'].includes(item.type));\nif (failures.length) {\n throw new Error('Documentation could not be completed: ' + JSON.stringify(failures));\n}\nconst comments = output.items.filter(item => item.type === 'add_comment');\nconst noops = output.items.filter(item => item.type === 'noop');\nconst dryRun = process.env.SUPPRESS_OUTPUT === 'true';\nif (dryRun && comments.length) {\n throw new Error('Dry-run documentation must not request publication.');\n}\nif (comments.length === 1 && noops.length === 0) {\n const comment = comments[0];\n const prNumber = parsePrNumber(process.env.PR_NUMBER);\n if (parsePrNumber(comment.item_number) !== prNumber) {\n throw new Error('Documentation comment targets the wrong PR.');\n }\n if (!comment.body?.trim()) {\n throw new Error('Documentation comment is empty.');\n }\n const rawComments = fs.readFileSync(process.env.SAFE_OUTPUTS_PATH, 'utf8')\n .split('\\n')\n .filter(line => line.trim())\n .map(line => JSON.parse(line))\n .filter(item => item.type === 'add_comment');\n if (rawComments.length !== 1 || parsePrNumber(rawComments[0].item_number) !== prNumber) {\n throw new Error('Documentation requires exactly one raw comment intent for the source PR.');\n }\n const expectedBody = fs.readFileSync('artifacts/docs/breakingChanges/pr-comment.md', 'utf8');\n if (rawComments[0].body !== expectedBody) {\n throw new Error('Documentation comment does not match pr-comment.md before sanitization.');\n }\n} else if (comments.length !== 0 || noops.length !== 1 || !noops[0].message?.trim()) {\n throw new Error('Documentation must emit a comment or an explicit noop; drafts alone are not completion.');\n} else if (!dryRun && fs.existsSync('artifacts/docs/breakingChanges/pr-comment.md')) {\n throw new Error('Generated documentation drafts require publication or report_incomplete, not a noop.');\n}\nif (comments.length ||\n fs.existsSync('artifacts/docs/breakingChanges/issue-draft.md') ||\n fs.existsSync('artifacts/docs/breakingChanges/pr-comment.md')) {\n for (const name of ['issue-draft.md', 'pr-comment.md']) {\n if (!fs.readFileSync('artifacts/docs/breakingChanges/' + name, 'utf8').trim()) {\n throw new Error('Documentation draft is empty: ' + name);\n }\n }\n}" - name: Upload agent artifacts if: always() @@ -1225,7 +1267,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} GH_AW_WORKFLOW_ID: "breaking-change-doc" - GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "0" + GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168" GH_AW_ENGINE_ID: "copilot" GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }} GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }} @@ -1730,6 +1772,15 @@ jobs: GH_HOST="${GITHUB_SERVER_URL#https://}" GH_HOST="${GH_HOST#http://}" echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" + - name: Require successful documentation generation + run: | + if [ "$AGENT_RESULT" != "success" ]; then + echo "::error::Documentation generation or outcome validation failed; refusing to publish." + exit 1 + fi + env: + AGENT_RESULT: ${{ needs.agent.result }} + shell: bash - name: Process Safe Outputs id: process_safe_outputs uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 diff --git a/.github/workflows/breaking-change-doc.md b/.github/workflows/breaking-change-doc.md index cbb1ee5eba8056..a9e54b598057d2 100644 --- a/.github/workflows/breaking-change-doc.md +++ b/.github/workflows/breaking-change-doc.md @@ -13,8 +13,11 @@ permissions: pull-requests: read issues: read +checkout: + repository: ${{ github.repository }} + tools: - bash: ["pwsh", "gh"] + bash: ["pwsh", "gh", "jq", "mkdir"] safe-outputs: report-failure-as-issue: false @@ -23,6 +26,16 @@ safe-outputs: target: "*" noop: report-as-issue: false # Disable posting noop messages as issue comments + steps: + - name: Require successful documentation generation + shell: bash + env: + AGENT_RESULT: ${{ needs.agent.result }} + run: | + if [ "$AGENT_RESULT" != "success" ]; then + echo "::error::Documentation generation or outcome validation failed; refusing to publish." + exit 1 + fi if: | github.event_name == 'workflow_dispatch' || @@ -41,6 +54,74 @@ post-steps: path: artifacts/docs/breakingChanges/ retention-days: 30 if-no-files-found: ignore + - name: Validate documentation outcome + uses: actions/github-script@v9 + env: + PR_NUMBER: ${{ github.event.pull_request.number || inputs.pr_number }} + SUPPRESS_OUTPUT: ${{ github.event_name == 'workflow_dispatch' && inputs.suppress_output }} + SAFE_OUTPUTS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} + with: + script: | + const fs = require('node:fs'); + function parsePrNumber(value) { + const text = String(value); + const number = Number(text); + if ((typeof value !== 'number' && typeof value !== 'string') || + !/^\d+$/.test(text) || !Number.isSafeInteger(number) || number <= 0) { + throw new Error('Invalid PR number: ' + text); + } + return number; + } + const output = JSON.parse(fs.readFileSync('/tmp/gh-aw/agent_output.json', 'utf8')); + if (!Array.isArray(output.items) || output.errors?.length) { + throw new Error('Documentation output is invalid: ' + JSON.stringify(output.errors)); + } + const failures = output.items.filter(item => + ['missing_tool', 'missing_data', 'report_incomplete'].includes(item.type)); + if (failures.length) { + throw new Error('Documentation could not be completed: ' + JSON.stringify(failures)); + } + const comments = output.items.filter(item => item.type === 'add_comment'); + const noops = output.items.filter(item => item.type === 'noop'); + const dryRun = process.env.SUPPRESS_OUTPUT === 'true'; + if (dryRun && comments.length) { + throw new Error('Dry-run documentation must not request publication.'); + } + if (comments.length === 1 && noops.length === 0) { + const comment = comments[0]; + const prNumber = parsePrNumber(process.env.PR_NUMBER); + if (parsePrNumber(comment.item_number) !== prNumber) { + throw new Error('Documentation comment targets the wrong PR.'); + } + if (!comment.body?.trim()) { + throw new Error('Documentation comment is empty.'); + } + const rawComments = fs.readFileSync(process.env.SAFE_OUTPUTS_PATH, 'utf8') + .split('\n') + .filter(line => line.trim()) + .map(line => JSON.parse(line)) + .filter(item => item.type === 'add_comment'); + if (rawComments.length !== 1 || parsePrNumber(rawComments[0].item_number) !== prNumber) { + throw new Error('Documentation requires exactly one raw comment intent for the source PR.'); + } + const expectedBody = fs.readFileSync('artifacts/docs/breakingChanges/pr-comment.md', 'utf8'); + if (rawComments[0].body !== expectedBody) { + throw new Error('Documentation comment does not match pr-comment.md before sanitization.'); + } + } else if (comments.length !== 0 || noops.length !== 1 || !noops[0].message?.trim()) { + throw new Error('Documentation must emit a comment or an explicit noop; drafts alone are not completion.'); + } else if (!dryRun && fs.existsSync('artifacts/docs/breakingChanges/pr-comment.md')) { + throw new Error('Generated documentation drafts require publication or report_incomplete, not a noop.'); + } + if (comments.length || + fs.existsSync('artifacts/docs/breakingChanges/issue-draft.md') || + fs.existsSync('artifacts/docs/breakingChanges/pr-comment.md')) { + for (const name of ['issue-draft.md', 'pr-comment.md']) { + if (!fs.readFileSync('artifacts/docs/breakingChanges/' + name, 'utf8').trim()) { + throw new Error('Documentation draft is empty: ' + name); + } + } + } on: pull_request_target: @@ -89,8 +170,9 @@ Create breaking change documentation for the pull request identified below. ## Dry-run mode - If triggered by `workflow_dispatch` with `suppress_output` = `true`, - **do not** post a comment on the PR after producing the files. Just - write the markdown files and stop. + **do not** post a comment on the PR after producing the files. Write + the markdown files and emit a `noop` explaining that dry-run drafts + were generated without publication. - For pull_request triggers, post the comment only when permitted by the skill's "Post the comment" rules, including its uncertainty gate. @@ -100,15 +182,49 @@ Using the breaking-change-doc skill from `.github/skills/breaking-change-doc/SKILL.md`, execute **all steps (0 through 6)** for the PR above. +Run `Get-VersionInfo.ps1` and `Build-IssueComment.ps1` as required by the +skill; do not infer the release version or recreate the comment by hand +instead of running the helpers. Use `pwsh --version` to check PowerShell, +not a compound shell command beginning with `command -v`. + In Step 6, if dry-run mode is active, skip publishing any output to the pull request. The generated files in `artifacts/docs/breakingChanges/` are automatically uploaded as a workflow artifact named **breaking-change-docs** and can be downloaded from the workflow run summary page. +## Publication + +For an authorized, non-dry-run outcome, read the complete +`artifacts/docs/breakingChanges/pr-comment.md` and submit it through the +`add_comment` safe output. This records the comment intent; the separate +safe-output job performs the GitHub write. Do not post with `gh pr comment`. + +Use one shell command whose executable is `safeoutputs`, passing exactly +one JSON object through a single-quoted here-document: + +```bash +safeoutputs add_comment . <<'EOF' +{"item_number": 123, "body": "Complete contents of pr-comment.md"} +EOF +``` + +Replace `123` with the source PR number and encode the complete file as a +valid JSON string, preserving its contents exactly. Do not chain commands +or pipe JSON from another command into `safeoutputs`. If the invocation +fails, correct it and retry this single-command form once. If publication +still fails, emit `report_incomplete` with the actual error; do not report +only `missing_tool`, silently finish with drafts, or substitute a `noop` +for a failed publication. + +If the skill's uncertainty gate prevents publication, retain the drafts +and emit `report_incomplete` explaining what requires human review. + ## When no action is needed If no action is needed (PR has no area label, documentation already exists, -etc.), you MUST call the `noop` tool with a message explaining why: +etc.), you MUST call the `noop` tool with a message explaining why. In a +non-dry-run, determine this before creating `pr-comment.md`; once the +comment is generated, submit it or report why publication is incomplete. ```json {"noop": {"message": "No action needed: [brief explanation]"}} From 73ea0d33b026547b5527c3538c9b11f801d6682c Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Wed, 7 Oct 2026 14:38:45 -0700 Subject: [PATCH 2/3] Pass resolved dry-run mode to documentation workflow --- .github/workflows/breaking-change-doc.lock.yml | 6 +++++- .github/workflows/breaking-change-doc.md | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/breaking-change-doc.lock.yml b/.github/workflows/breaking-change-doc.lock.yml index 80e4f3f836b5c7..0aacdac0f1bccb 100644 --- a/.github/workflows/breaking-change-doc.lock.yml +++ b/.github/workflows/breaking-change-doc.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"aa95c7abef66b49dc701e549d25539c65b939252334c2672a4892e7d48b28750","body_hash":"b0305bd9dc7f6fabeb436b3da6f744383c80993ef81e01be50b5f064a706681e","compiler_version":"v0.86.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.79"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"aa95c7abef66b49dc701e549d25539c65b939252334c2672a4892e7d48b28750","body_hash":"799c2a1de3cc9bfbb6a2926da41756d4f8ba89d422ca2d7c1af360632caa7c6c","compiler_version":"v0.86.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.79"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"actions/upload-artifact","sha":"ea165f8d65b6e75b540449e92b4886f43607fa02","version":"v4"},{"repo":"github/gh-aw-actions/setup","sha":"6aab9e5b5c91c615506061f09bedd81a23babe3c","version":"v0.86.2"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44","digest":"sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44@sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44","digest":"sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44@sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44","digest":"sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44@sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.9","digest":"sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.9@sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.9.0","digest":"sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e","pinned_image":"ghcr.io/github/github-mcp-server:v1.9.0@sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e"}],"has_pull_request_target":true} # This file was automatically generated by gh-aw (v0.86.2). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -290,6 +290,7 @@ jobs: GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_493D3F5F: ${{ github.event.inputs.suppress_output || false }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -316,6 +317,7 @@ jobs: GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" GH_AW_GITHUB_EVENT_INPUTS_PR_NUMBER: ${{ github.event.inputs.pr_number }} + GH_AW_EXPR_493D3F5F: ${{ github.event.inputs.suppress_output || false }} GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} with: script: | @@ -329,6 +331,7 @@ jobs: GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_493D3F5F: ${{ github.event.inputs.suppress_output || false }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} @@ -352,6 +355,7 @@ jobs: substitutions: { GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_493D3F5F: process.env.GH_AW_EXPR_493D3F5F, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, diff --git a/.github/workflows/breaking-change-doc.md b/.github/workflows/breaking-change-doc.md index a9e54b598057d2..65bddbcdce2572 100644 --- a/.github/workflows/breaking-change-doc.md +++ b/.github/workflows/breaking-change-doc.md @@ -169,11 +169,13 @@ Create breaking change documentation for the pull request identified below. ## Dry-run mode -- If triggered by `workflow_dispatch` with `suppress_output` = `true`, +Dry-run mode for this run: `${{ github.event.inputs.suppress_output || false }}`. + +- If the value above is `true`, **do not** post a comment on the PR after producing the files. Write the markdown files and emit a `noop` explaining that dry-run drafts were generated without publication. -- For pull_request triggers, post the comment only when permitted by the +- If the value above is `false`, post the comment only when permitted by the skill's "Post the comment" rules, including its uncertainty gate. ## Instructions From 4db4d8311d98f140bb96254e0ee68a24a9bab329 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Wed, 7 Oct 2026 15:05:59 -0700 Subject: [PATCH 3/3] Use a single default checkout for breaking-change documentation --- .../workflows/breaking-change-doc.lock.yml | 21 +++---------------- .github/workflows/breaking-change-doc.md | 2 +- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/.github/workflows/breaking-change-doc.lock.yml b/.github/workflows/breaking-change-doc.lock.yml index 0aacdac0f1bccb..b4d94d5d35f332 100644 --- a/.github/workflows/breaking-change-doc.lock.yml +++ b/.github/workflows/breaking-change-doc.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"aa95c7abef66b49dc701e549d25539c65b939252334c2672a4892e7d48b28750","body_hash":"799c2a1de3cc9bfbb6a2926da41756d4f8ba89d422ca2d7c1af360632caa7c6c","compiler_version":"v0.86.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.79"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9551ace5f185b3ca3c461f640ca0a6e040233c443cadeafb294b30aaf0f596a3","body_hash":"799c2a1de3cc9bfbb6a2926da41756d4f8ba89d422ca2d7c1af360632caa7c6c","compiler_version":"v0.86.2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.79"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"actions/upload-artifact","sha":"ea165f8d65b6e75b540449e92b4886f43607fa02","version":"v4"},{"repo":"github/gh-aw-actions/setup","sha":"6aab9e5b5c91c615506061f09bedd81a23babe3c","version":"v0.86.2"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44","digest":"sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.44@sha256:0d727725c737b58c7bdf51f640cffb928385ec46517e0917c7f1a02f1bada8b4"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44","digest":"sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.44@sha256:b50fbadba138f6e9aba94aca09711335c489bb3b15861220cb66f6092e042dc7"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44","digest":"sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.44@sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.9","digest":"sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.9@sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.9.0","digest":"sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e","pinned_image":"ghcr.io/github/github-mcp-server:v1.9.0@sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e"}],"has_pull_request_target":true} # This file was automatically generated by gh-aw (v0.86.2). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -302,7 +302,7 @@ jobs: GH_AW_PROMPT_CONTENT_0000: "\n" GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, missing_tool, missing_data, noop\n" GH_AW_PROMPT_CONTENT_0002: "\n" - GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1 (default)]\n - **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. 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).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **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. 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).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" GH_AW_PROMPT_CONTENT_0004: "\n" GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/workflows/breaking-change-doc.md}}\n" with: @@ -469,22 +469,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - name: Checkout ${{ github.repository }} - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - repository: ${{ github.repository }} - - name: Build checkout manifest for safe-outputs handlers - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - GH_AW_CHECKOUT_MANIFEST_COUNT: "1" - GH_AW_CHECKOUT_REPO_0: ${{ github.repository }} - GH_AW_CHECKOUT_PATH_0: "" - with: - script: | - const { main } = require('${{ runner.temp }}/gh-aw/actions/build_checkout_manifest.cjs'); - await main(); + fetch-depth: 1 - name: Create gh-aw temp directory run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh" - name: Configure gh CLI for GitHub Enterprise diff --git a/.github/workflows/breaking-change-doc.md b/.github/workflows/breaking-change-doc.md index 65bddbcdce2572..016d02d2536f79 100644 --- a/.github/workflows/breaking-change-doc.md +++ b/.github/workflows/breaking-change-doc.md @@ -14,7 +14,7 @@ permissions: issues: read checkout: - repository: ${{ github.repository }} + fetch-depth: 1 tools: bash: ["pwsh", "gh", "jq", "mkdir"]