@@ -83,22 +83,27 @@ jobs:
8383 permissions :
8484 contents : read
8585 packages : read
86+ copilot-requests : write
87+ env :
88+ GH_AW_RUNTIME_FEATURES : ${{ vars.GH_AW_RUNTIME_FEATURES }}
8689 outputs :
8790 detection_conclusion : ${{ steps.detection_conclusion.outputs.conclusion }}
8891 detection_reason : ${{ steps.detection_conclusion.outputs.reason }}
8992 detection_success : ${{ steps.detection_conclusion.outputs.success }}
9093 steps :
9194 - name : Setup Scripts
9295 id : setup
93- uses : github/gh-aw-actions/setup@v0.79.6
96+ uses : github/gh-aw-actions/setup@v0.82.14
9497 with :
9598 destination : ${{ runner.temp }}/gh-aw/actions
9699 job-name : ${{ github.job }}
97100 trace-id : ${{ needs.activation.outputs.setup-trace-id }}
98101 env :
99- GH_AW_SETUP_WORKFLOW_NAME : " Smoke Copilot"
102+ GH_AW_SETUP_WORKFLOW_NAME : " Smoke Copilot Standalone "
100103 GH_AW_CURRENT_WORKFLOW_REF : ${{ github.repository }}/.github/workflows/smoke-copilot-standalone.lock.yml@${{ github.ref }}
101- GH_AW_INFO_VERSION : " 1.0.40"
104+ GH_AW_INFO_VERSION : " 1.0.71"
105+ GH_AW_INFO_AWF_VERSION : " v0.27.37"
106+ GH_AW_INFO_ENGINE_ID : " copilot"
102107 - name : Download agent output artifact
103108 id : download-agent-output
104109 continue-on-error : true
@@ -124,7 +129,7 @@ jobs:
124129 rm -rf /tmp/gh-aw/sandbox/firewall/logs
125130 rm -rf /tmp/gh-aw/sandbox/firewall/audit
126131 - name : Download container images
127- run : bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.2 @sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2 @sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2 @sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
132+ run : bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.37 @sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37 @sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317 ghcr.io/github/gh-aw-firewall/squid:0.27.37 @sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b
128133 - name : Check if detection needed
129134 id : detection_guard
130135 if : always()
@@ -143,13 +148,17 @@ jobs:
143148 if : always() && steps.detection_guard.outputs.run_detection == 'true'
144149 run : |
145150 rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
146- rm -f /home/runner/ .copilot/mcp-config.json
151+ rm -f "$HOME/ .copilot/mcp-config.json"
147152 rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
148153 - name : Prepare threat detection files
149154 if : always() && steps.detection_guard.outputs.run_detection == 'true'
150155 run : |
151156 mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
157+ rm -f /tmp/gh-aw/agent_usage.json
152158 cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
159+ if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then
160+ echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context."
161+ fi
153162 cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
154163 for f in /tmp/gh-aw/aw-*.patch; do
155164 [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
@@ -163,8 +172,8 @@ jobs:
163172 if : always() && steps.detection_guard.outputs.run_detection == 'true'
164173 uses : actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
165174 env :
166- WORKFLOW_NAME : " Smoke Copilot"
167- WORKFLOW_DESCRIPTION : " Smoke test workflow that validates Copilot engine execution in this repository "
175+ WORKFLOW_NAME : " Smoke Copilot Standalone "
176+ WORKFLOW_DESCRIPTION : " Smoke test workflow that validates Copilot engine execution with the released threat-detect binary "
168177 HAS_PATCH : ${{ needs.agent.outputs.has_patch }}
169178 with :
170179 script : |
@@ -177,64 +186,79 @@ jobs:
177186 run : |
178187 mkdir -p /tmp/gh-aw/threat-detection
179188 touch /tmp/gh-aw/threat-detection/detection.log
180- - name : Setup Node.js
181- uses : actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
182- with :
183- node-version : ' 24'
184- package-manager-cache : false
189+ - name : Install AWF binary
190+ run : bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.37
185191 - name : Install GitHub Copilot CLI
186- run : bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40
192+ run : bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.71
187193 env :
188194 GH_HOST : github.com
189- - name : Install AWF binary
190- run : bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
191- - name : Download threat detection binary
195+ - name : Install threat-detect binary
192196 if : always() && steps.detection_guard.outputs.run_detection == 'true'
193197 env :
194- GH_TOKEN : ${{ secrets.GH_AW_GITHUB_TOKEN || github.token }}
195198 THREAT_DETECTION_VERSION : ${{ vars.GH_AW_THREAT_DETECTION_VERSION || '' }}
196- DETECTOR_REPO : github/gh-aw-threat-detection
197199 run : |
198- set -euo pipefail
199- dest_dir="${RUNNER_TEMP}/gh-aw/threat-detect-bin"
200- mkdir -p "$dest_dir"
201- download_dir="$(mktemp -d)"
202- trap 'rm -rf "$download_dir"' EXIT
203- case "$(uname -m)" in
204- x86_64|amd64) asset="threat-detect-linux-amd64" ;;
205- aarch64|arm64) asset="threat-detect-linux-arm64" ;;
206- *) echo "::error::Unsupported architecture: $(uname -m)"; exit 1 ;;
207- esac
208- args=(--repo "$DETECTOR_REPO" --pattern "$asset" --pattern checksums.txt --dir "$download_dir")
209- if [ -n "${THREAT_DETECTION_VERSION:-}" ]; then
210- gh release download "$THREAT_DETECTION_VERSION" "${args[@]}"
211- else
212- gh release download "${args[@]}"
213- fi
214- ( cd "$download_dir" && sha256sum --check --ignore-missing checksums.txt )
215- install -m 0755 "$download_dir/$asset" "$dest_dir/threat-detect"
200+ bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" "${THREAT_DETECTION_VERSION:-v0.2.2}"
216201 - name : Execute threat detection with AWF
202+ id : detection_agentic_execution
217203 if : always() && steps.detection_guard.outputs.run_detection == 'true'
218204 continue-on-error : true
219- id : detection_agentic_execution
220- timeout-minutes : 20
221- env :
222- COPILOT_GITHUB_TOKEN : ${{ secrets.COPILOT_GITHUB_TOKEN }}
223- THREAT_DETECTION_MODEL : ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
224- WORKFLOW_DESCRIPTION : " Smoke test workflow that validates Copilot engine execution in this repository"
225- WORKFLOW_NAME : ${{ github.workflow }}
226205 run : |
227206 set -o pipefail
228- touch /tmp/gh-aw/agent-step-summary.md
207+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
229208 (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
230209 GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
231210 # Validate that the credit limit is a numeric JSON literal to prevent malformed JSON
232211 [[ "${GH_AW_MAX_AI_CREDITS}" =~ ^(0|[1-9][0-9]*)(\.[0-9]+)?$ ]] || GH_AW_MAX_AI_CREDITS="400"
233- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
234- # shellcheck disable=SC1003
235- sudo -E 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" --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull --mount "/tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw" \
236- -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | paste -sd: -):$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; result_path="/tmp/gh-aw/threat-detection/detection_result.json"; status_path="/tmp/gh-aw/threat-detection/detection-status.txt"; args=(--engine copilot); if [ -n "${THREAT_DETECTION_MODEL:-}" ]; then args+=(--model "$THREAT_DETECTION_MODEL"); fi; run_status=0; "${RUNNER_TEMP}/gh-aw/threat-detect-bin/threat-detect" "${args[@]}" --output "$result_path" /tmp/gh-aw/threat-detection 2>"$status_path" || run_status=$?; cat "$status_path" >&2 || true; if [ -f "$result_path" ]; then exit 0; fi; if grep -q "reason=invalid_report_exhausted" "$status_path" 2>/dev/null; then exit 0; fi; exit "$run_status"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
237- - name : Upload threat detection artifacts
212+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.37/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"go.dev\",\"golang.org\",\"goproxy.io\",\"host.docker.internal\",\"pkg.go.dev\",\"proxy.golang.org\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"storage.googleapis.com\",\"sum.golang.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.37,squid=sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b,agent=sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67,api-proxy=sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317,cli-proxy=sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
213+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
214+ export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
215+ GH_AW_DOCKER_HOST=""
216+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
217+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
218+ fi
219+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
220+ _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
221+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
222+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
223+ fi
224+ GH_AW_TOOL_CACHE_MOUNT=""
225+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
226+ if [ -d "$GH_AW_TOOL_CACHE" ]; then
227+ if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
228+ GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
229+ fi
230+ fi
231+ # shellcheck disable=SC1003,SC2016,SC2086
232+ 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 COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \
233+ -- /bin/bash -c 'set +o histexpand; : "${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 && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
234+ env :
235+ AWF_REFLECT_ENABLED : 1
236+ COPILOT_AGENT_RUNNER_TYPE : STANDALONE
237+ COPILOT_DUMMY_BYOK : dummy-byok-key-for-offline-mode
238+ COPILOT_GITHUB_TOKEN : ${{ github.token }}
239+ COPILOT_MODEL : ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
240+ GH_AW_LLM_PROVIDER : github
241+ GH_AW_MAX_AI_CREDITS : ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
242+ GH_AW_MAX_TURNS : ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
243+ GH_AW_PHASE : detection
244+ GH_AW_PROMPT : /tmp/gh-aw/aw-prompts/prompt.txt
245+ GH_AW_TIMEOUT_MINUTES : 20
246+ GH_AW_VERSION : v0.82.14
247+ GITHUB_API_URL : ${{ github.api_url }}
248+ GITHUB_AW : true
249+ GITHUB_COPILOT_INTEGRATION_ID : agentic-workflows
250+ GITHUB_HEAD_REF : ${{ github.head_ref }}
251+ GITHUB_REF_NAME : ${{ github.ref_name }}
252+ GITHUB_SERVER_URL : ${{ github.server_url }}
253+ GITHUB_STEP_SUMMARY : /tmp/gh-aw/agent-step-summary.md
254+ GITHUB_WORKSPACE : ${{ github.workspace }}
255+ GIT_AUTHOR_EMAIL : github-actions[bot]@users.noreply.github.com
256+ GIT_AUTHOR_NAME : github-actions[bot]
257+ GIT_COMMITTER_EMAIL : github-actions[bot]@users.noreply.github.com
258+ GIT_COMMITTER_NAME : github-actions[bot]
259+ RUNNER_TEMP : ${{ runner.temp }}
260+ S2STOKENS : true
261+ - name : Upload threat detection artifact
238262 if : always() && steps.detection_guard.outputs.run_detection == 'true'
239263 uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
240264 with :
@@ -243,7 +267,7 @@ jobs:
243267 /tmp/gh-aw/threat-detection/detection_result.json
244268 /tmp/gh-aw/threat-detection/detection.log
245269 if-no-files-found : ignore
246- - name : Parse and conclude threat detection
270+ - name : Conclude threat detection
247271 id : detection_conclusion
248272 if : always()
249273 continue-on-error : true
@@ -252,17 +276,4 @@ jobs:
252276 DETECTION_AGENTIC_EXECUTION_OUTCOME : ${{ steps.detection_agentic_execution.outcome }}
253277 GH_AW_DETECTION_CONTINUE_ON_ERROR : " true"
254278 run : |
255- bin="${RUNNER_TEMP}/gh-aw/threat-detect-bin/threat-detect"
256- if [ ! -x "$bin" ]; then
257- {
258- echo "conclusion=skipped"
259- echo "success=true"
260- echo "reason="
261- } >> "$GITHUB_OUTPUT"
262- {
263- echo "GH_AW_DETECTION_CONCLUSION=skipped"
264- echo "GH_AW_DETECTION_REASON="
265- } >> "$GITHUB_ENV"
266- exit 0
267- fi
268- "$bin" conclude --result-file /tmp/gh-aw/threat-detection/detection_result.json
279+ bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json
0 commit comments