9201ef759e
CI / lint (push) Waiting to run
CI / mypy (push) Waiting to run
CI / docs (push) Waiting to run
CI / test on 3.10 (standard) (push) Waiting to run
CI / test on 3.11 (standard) (push) Waiting to run
CI / test on 3.12 (standard) (push) Waiting to run
CI / test on 3.10 (all-extras) (push) Waiting to run
CI / test on 3.11 (all-extras) (push) Waiting to run
CI / test on 3.12 (all-extras) (push) Waiting to run
CI / test on 3.13 (all-extras) (push) Waiting to run
CI / test on 3.14 (pydantic-evals) (push) Waiting to run
CI / test on 3.13 (standard) (push) Waiting to run
CI / test on 3.14 (standard) (push) Waiting to run
CI / test on 3.14 (all-extras) (push) Waiting to run
CI / test on 3.10 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.11 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.12 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.13 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.14 (pydantic-ai-slim) (push) Waiting to run
CI / test on 3.10 (pydantic-evals) (push) Waiting to run
CI / test on 3.11 (pydantic-evals) (push) Waiting to run
CI / test on 3.12 (pydantic-evals) (push) Waiting to run
CI / test on 3.13 (pydantic-evals) (push) Waiting to run
CI / test on 3.10 (lowest-versions) (push) Waiting to run
CI / test on 3.11 (lowest-versions) (push) Waiting to run
CI / test on 3.12 (lowest-versions) (push) Waiting to run
CI / test on 3.13 (lowest-versions) (push) Waiting to run
CI / test on 3.14 (lowest-versions) (push) Waiting to run
CI / test examples on 3.11 (push) Waiting to run
CI / test examples on 3.12 (push) Waiting to run
CI / test examples on 3.13 (push) Waiting to run
CI / test examples on 3.14 (push) Waiting to run
CI / coverage (push) Blocked by required conditions
CI / check (push) Blocked by required conditions
CI / deploy-docs (push) Blocked by required conditions
CI / deploy-docs-preview (push) Blocked by required conditions
CI / build release artifacts (push) Blocked by required conditions
CI / publish to PyPI (push) Blocked by required conditions
CI / Send tweet (push) Blocked by required conditions
Harness Compat / harness compat (push) Failing after 0s
1622 lines
101 KiB
YAML
Generated
1622 lines
101 KiB
YAML
Generated
# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"18d18811c742c3bc1c672f4b8929061a0ec4ee670c1889f253c9152beb53208f","compiler_version":"v0.74.8","strict":true,"agent_id":"claude","agent_model":"${{ vars.GH_AW_MODEL }}"}
|
|
# gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","LOGFIRE_READ_EXTERNAL_VARIABLES","LOGFIRE_TOKEN","LOGFIRE_URL","MINIMAX_API_KEY"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/setup-python","sha":"a309ff8b426b58ec0e2a45f0f869d46889d02405","version":"v6.2.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"astral-sh/setup-uv","sha":"08807647e7069bb48b6ef5acd8ec9567f424441b","version":"v8.1.0"},{"repo":"github/gh-aw-actions/setup","sha":"efa55847f72aadb03490d955263ff911bf758700","version":"v0.74.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.49"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.49"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.49"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.49"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.9","digest":"sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
|
|
# ___ _ _
|
|
# / _ \ | | (_)
|
|
# | |_| | __ _ ___ _ __ | |_ _ ___
|
|
# | _ |/ _` |/ _ \ '_ \| __| |/ __|
|
|
# | | | | (_| | __/ | | | |_| | (__
|
|
# \_| |_/\__, |\___|_| |_|\__|_|\___|
|
|
# __/ |
|
|
# _ _ |___/
|
|
# | | | | / _| |
|
|
# | | | | ___ _ __ _ __| |_| | _____ ____
|
|
# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
|
|
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
|
|
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
|
|
#
|
|
# This file was automatically generated by gh-aw (v0.74.8). DO NOT EDIT.
|
|
#
|
|
# To update this file, edit the corresponding .md file and run:
|
|
# gh aw compile
|
|
# Not all edits will cause changes to this file.
|
|
#
|
|
# For more information: https://github.github.com/gh-aw/introduction/overview/
|
|
#
|
|
# AI-driven PR review on the Pydantic AI gh-aw shim: inline comments + a single review verdict. Prompt iterable from a Logfire managed variable; read-only via gh-aw safe-outputs.
|
|
#
|
|
# Resolved workflow manifest:
|
|
# Imports:
|
|
# - shared/checkout.md
|
|
# - shared/engine-minimax.md
|
|
# - shared/network-vendor-domains.md
|
|
# - shared/otel-logfire.md
|
|
# - shared/pre-agent-steps.md
|
|
# - shared/pre-steps.md
|
|
# - shared/repo-context.md
|
|
# - shared/review-context.md
|
|
# - shared/rigor.md
|
|
# - shared/tool-hints.md
|
|
#
|
|
# Secrets used:
|
|
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
|
|
# - GH_AW_GITHUB_TOKEN
|
|
# - GITHUB_TOKEN
|
|
# - LOGFIRE_READ_EXTERNAL_VARIABLES
|
|
# - LOGFIRE_TOKEN
|
|
# - LOGFIRE_URL
|
|
# - MINIMAX_API_KEY
|
|
#
|
|
# Custom actions used:
|
|
# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
|
|
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
# - actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
# - astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
# - github/gh-aw-actions/setup@efa55847f72aadb03490d955263ff911bf758700 # v0.74.8
|
|
#
|
|
# Container images used:
|
|
# - ghcr.io/github/gh-aw-firewall/agent:0.25.49
|
|
# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.49
|
|
# - ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.49
|
|
# - ghcr.io/github/gh-aw-firewall/squid:0.25.49
|
|
# - ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388
|
|
# - ghcr.io/github/github-mcp-server:v1.0.4
|
|
# - node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
|
|
|
|
name: "Pydantic AI PR Review"
|
|
on:
|
|
pull_request:
|
|
types:
|
|
- opened
|
|
- synchronize
|
|
- ready_for_review
|
|
# roles: # Roles processed as role check in pre-activation job
|
|
# - admin # Roles processed as role check in pre-activation job
|
|
# - maintainer # Roles processed as role check in pre-activation job
|
|
# - write # Roles processed as role check in pre-activation job
|
|
workflow_dispatch:
|
|
inputs:
|
|
aw_context:
|
|
default: ""
|
|
description: "Agent caller context (used internally by Agentic Workflows)."
|
|
required: false
|
|
type: string
|
|
|
|
permissions: {}
|
|
|
|
concurrency:
|
|
cancel-in-progress: true
|
|
group: ${{ github.workflow }}-pr-review-${{ github.event.pull_request.number || github.ref }}
|
|
|
|
run-name: "Pydantic AI PR Review"
|
|
|
|
env:
|
|
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.LOGFIRE_URL || 'https://logfire-api.pydantic.dev' }}
|
|
OTEL_SERVICE_NAME: gh-aw.pydantic-ai-pr-review
|
|
OTEL_EXPORTER_OTLP_HEADERS: Authorization=${{ secrets.LOGFIRE_TOKEN }}
|
|
GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.LOGFIRE_URL || ''https://logfire-api.pydantic.dev'' }}","headers":"Authorization=${{ secrets.LOGFIRE_TOKEN }}"}]'
|
|
|
|
jobs:
|
|
activation:
|
|
needs:
|
|
- fetch_dynamic_prompt
|
|
- pre_activation
|
|
if: >
|
|
needs.pre_activation.outputs.activated == 'true' && ((!contains(github.event.pull_request.labels.*.name, 'auto-review')) &&
|
|
(github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id))
|
|
runs-on: ubuntu-slim
|
|
permissions:
|
|
actions: read
|
|
contents: read
|
|
outputs:
|
|
body: ${{ steps.sanitized.outputs.body }}
|
|
comment_id: ""
|
|
comment_repo: ""
|
|
engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
|
|
lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
|
|
model: ${{ steps.generate_aw_info.outputs.model }}
|
|
setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
|
|
setup-span-id: ${{ steps.setup.outputs.span-id }}
|
|
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
|
|
stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
|
|
text: ${{ steps.sanitized.outputs.text }}
|
|
title: ${{ steps.sanitized.outputs.title }}
|
|
steps:
|
|
- name: Setup Scripts
|
|
id: setup
|
|
uses: github/gh-aw-actions/setup@efa55847f72aadb03490d955263ff911bf758700 # v0.74.8
|
|
with:
|
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
job-name: ${{ github.job }}
|
|
trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
|
|
parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
|
|
env:
|
|
GH_AW_SETUP_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pydantic-ai-pr-review.lock.yml@${{ github.ref }}
|
|
GH_AW_INFO_VERSION: "2.1.142"
|
|
GH_AW_INFO_ENGINE_ID: "claude"
|
|
- name: Mask OTLP telemetry headers
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
|
|
- name: Generate agentic run info
|
|
id: generate_aw_info
|
|
env:
|
|
GH_AW_INFO_ENGINE_ID: "claude"
|
|
GH_AW_INFO_ENGINE_NAME: "Claude Code"
|
|
GH_AW_INFO_MODEL: "${{ vars.GH_AW_MODEL }}"
|
|
GH_AW_INFO_VERSION: "2.1.142"
|
|
GH_AW_INFO_AGENT_VERSION: "2.1.142"
|
|
GH_AW_INFO_CLI_VERSION: "v0.74.8"
|
|
GH_AW_INFO_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_INFO_EXPERIMENTAL: "false"
|
|
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
|
|
GH_AW_INFO_STAGED: "false"
|
|
GH_AW_INFO_ALLOWED_DOMAINS: '["ai-sdk.dev","ai.azure.com","ai.google.dev","ai.pydantic.dev","amazonaws.com","anthropic.com","api-docs.deepseek.com","api.cerebras.ai","api.cohere.com","api.deepseek.com","api.fireworks.ai","api.groq.com","api.minimax.io","api.mistral.ai","api.openai.com","api.perplexity.ai","api.sambanova.ai","api.studio.nebius.com","api.together.xyz","api.x.ai","aws.amazon.com","boto3.amazonaws.com","cerebras.ai","chrome","cloud.cerebras.ai","cloud.sambanova.ai","cohere.com","console.anthropic.com","console.groq.com","console.mistral.ai","console.x.ai","dashboard.cohere.com","dashscope-intl.aliyuncs.com","dashscope.aliyuncs.com","deepseek.com","defaults","developers.openai.com","docs.ag-ui.com","docs.anthropic.com","docs.aws.amazon.com","docs.perplexity.ai","docs.sambanova.ai","docs.x.ai","endpoints.ai.cloud.ovh.net","fireworks.ai","github","groq.com","hf.co","huggingface.co","inference-docs.cerebras.ai","learn.microsoft.com","logfire-api.pydantic.dev","logfire-api.pydantic.info","logfire-eu.pydantic.dev","logfire-eu.pydantic.info","logfire-us.pydantic.dev","logfire-us.pydantic.info","mistral.ai","models.github.ai","ollama.com","openrouter.ai","ovh.com","platform.claude.com","platform.moonshot.ai","platform.openai.com","pydantic.dev","python","studio.nebius.com","vercel.com","www.alibabacloud.com","www.together.ai","x.ai"]'
|
|
GH_AW_INFO_FIREWALL_ENABLED: "true"
|
|
GH_AW_INFO_AWF_VERSION: "v0.25.49"
|
|
GH_AW_INFO_AWMG_VERSION: ""
|
|
GH_AW_INFO_FIREWALL_TYPE: "squid"
|
|
GH_AW_INFO_FRONTMATTER_EMOJI: "🔎"
|
|
GH_AW_COMPILED_STRICT: "true"
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
|
|
await main(core, context);
|
|
- name: Checkout .github and .agents folders
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
sparse-checkout: |
|
|
.github
|
|
.agents
|
|
.claude
|
|
.codex
|
|
.crush
|
|
.gemini
|
|
.opencode
|
|
.pi
|
|
sparse-checkout-cone-mode: true
|
|
fetch-depth: 1
|
|
- name: Save agent config folders for base branch restoration
|
|
env:
|
|
GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi"
|
|
GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
|
|
# poutine:ignore untrusted_checkout_exec
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
|
|
- name: Check workflow lock file
|
|
id: check-lock-file
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_WORKFLOW_FILE: "pydantic-ai-pr-review.lock.yml"
|
|
GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
|
|
await main();
|
|
- name: Check compile-agentic version
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_COMPILED_VERSION: "v0.74.8"
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs');
|
|
await main();
|
|
- name: Compute current body text
|
|
id: sanitized
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.google.com,*.googleapis.com,*.gvt1.com,*.pythonhosted.org,ai-sdk.dev,ai.azure.com,ai.google.dev,ai.pydantic.dev,amazonaws.com,anaconda.org,anthropic.com,api-docs.deepseek.com,api.anthropic.com,api.cerebras.ai,api.cohere.com,api.deepseek.com,api.fireworks.ai,api.github.com,api.groq.com,api.minimax.io,api.mistral.ai,api.openai.com,api.perplexity.ai,api.sambanova.ai,api.snapcraft.io,api.studio.nebius.com,api.together.xyz,api.x.ai,archive.ubuntu.com,aws.amazon.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,boto3.amazonaws.com,cdn.playwright.dev,cerebras.ai,cloud.cerebras.ai,cloud.sambanova.ai,codeload.github.com,cohere.com,conda.anaconda.org,conda.binstar.org,console.anthropic.com,console.groq.com,console.mistral.ai,console.x.ai,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,dashboard.cohere.com,dashscope-intl.aliyuncs.com,dashscope.aliyuncs.com,deepseek.com,developers.openai.com,docs.ag-ui.com,docs.anthropic.com,docs.aws.amazon.com,docs.github.com,docs.perplexity.ai,docs.sambanova.ai,docs.x.ai,endpoints.ai.cloud.ovh.net,files.pythonhosted.org,fireworks.ai,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,groq.com,hf.co,host.docker.internal,huggingface.co,inference-docs.cerebras.ai,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,learn.microsoft.com,lfs.github.com,logfire-api.pydantic.dev,logfire-api.pydantic.info,logfire-eu.pydantic.dev,logfire-eu.pydantic.info,logfire-us.pydantic.dev,logfire-us.pydantic.info,mistral.ai,models.github.ai,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,ollama.com,openrouter.ai,ovh.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,pip.pypa.io,platform.claude.com,platform.moonshot.ai,platform.openai.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pydantic.dev,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,studio.nebius.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,vercel.com,www.alibabacloud.com,www.googleapis.com,www.together.ai,x.ai"
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/compute_text.cjs');
|
|
await main();
|
|
- name: Create prompt with built-in context
|
|
env:
|
|
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
|
GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
|
|
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_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 }}
|
|
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
|
|
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
|
|
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
|
|
GH_AW_NEEDS_FETCH_DYNAMIC_PROMPT_OUTPUTS_DYNAMIC_PROMPT: ${{ needs.fetch_dynamic_prompt.outputs.dynamic_prompt }}
|
|
# poutine:ignore untrusted_checkout_exec
|
|
run: |
|
|
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
|
|
{
|
|
cat << 'GH_AW_PROMPT_9488585ea95de506_EOF'
|
|
<system>
|
|
GH_AW_PROMPT_9488585ea95de506_EOF
|
|
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
|
|
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
|
|
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
|
|
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
|
|
cat << 'GH_AW_PROMPT_9488585ea95de506_EOF'
|
|
<safe-output-tools>
|
|
Tools: create_pull_request_review_comment(max:30), submit_pull_request_review, missing_tool, missing_data, noop
|
|
</safe-output-tools>
|
|
GH_AW_PROMPT_9488585ea95de506_EOF
|
|
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
|
|
cat << 'GH_AW_PROMPT_9488585ea95de506_EOF'
|
|
<github-context>
|
|
The following GitHub context information is available for this workflow:
|
|
{{#if github.actor}}
|
|
- **actor**: __GH_AW_GITHUB_ACTOR__
|
|
{{/if}}
|
|
{{#if github.repository}}
|
|
- **repository**: __GH_AW_GITHUB_REPOSITORY__
|
|
{{/if}}
|
|
{{#if github.workspace}}
|
|
- **workspace**: __GH_AW_GITHUB_WORKSPACE__
|
|
{{/if}}
|
|
{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}
|
|
- **issue-number**: #__GH_AW_EXPR_802A9F6A__
|
|
{{/if}}
|
|
{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}
|
|
- **discussion-number**: #__GH_AW_EXPR_1A3A194A__
|
|
{{/if}}
|
|
{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}
|
|
- **pull-request-number**: #__GH_AW_EXPR_463A214A__
|
|
{{/if}}
|
|
{{#if github.event.comment.id || github.aw.context.comment_id}}
|
|
- **comment-id**: __GH_AW_EXPR_FF1D34CE__
|
|
{{/if}}
|
|
{{#if github.run_id}}
|
|
- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
|
|
{{/if}}
|
|
- **checkouts**: The following repositories have been checked out and are available in the workspace:
|
|
- `$GITHUB_WORKSPACE` → `__GH_AW_GITHUB_REPOSITORY__` (cwd) [full history, all branches available as remote-tracking refs]
|
|
- **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches).
|
|
</github-context>
|
|
|
|
GH_AW_PROMPT_9488585ea95de506_EOF
|
|
cat "${RUNNER_TEMP}/gh-aw/prompts/cli_proxy_with_safeoutputs_prompt.md"
|
|
cat << 'GH_AW_PROMPT_9488585ea95de506_EOF'
|
|
</system>
|
|
{{#runtime-import .github/workflows/shared/network-vendor-domains.md}}
|
|
{{#runtime-import .github/workflows/shared/otel-logfire.md}}
|
|
{{#runtime-import .github/workflows/shared/tool-hints.md}}
|
|
{{#runtime-import .github/workflows/shared/repo-context.md}}
|
|
{{#runtime-import .github/workflows/shared/rigor.md}}
|
|
{{#runtime-import .github/workflows/shared/review-context.md}}
|
|
{{#runtime-import .github/workflows/shared/checkout.md}}
|
|
{{#runtime-import .github/workflows/shared/engine-minimax.md}}
|
|
{{#runtime-import .github/workflows/shared/pre-steps.md}}
|
|
{{#runtime-import .github/workflows/shared/pre-agent-steps.md}}
|
|
{{#runtime-import .github/workflows/pydantic-ai-pr-review.md}}
|
|
GH_AW_PROMPT_9488585ea95de506_EOF
|
|
} > "$GH_AW_PROMPT"
|
|
- name: Interpolate variables and render templates
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
|
GH_AW_ENGINE_ID: "claude"
|
|
GH_AW_NEEDS_FETCH_DYNAMIC_PROMPT_OUTPUTS_DYNAMIC_PROMPT: ${{ needs.fetch_dynamic_prompt.outputs.dynamic_prompt }}
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
|
|
await main();
|
|
- name: Substitute placeholders
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_PROMPT: /tmp/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_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 }}
|
|
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
|
|
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
|
|
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
|
|
GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
|
|
GH_AW_NEEDS_FETCH_DYNAMIC_PROMPT_OUTPUTS_DYNAMIC_PROMPT: ${{ needs.fetch_dynamic_prompt.outputs.dynamic_prompt }}
|
|
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
|
|
const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
|
|
|
|
// Call the substitution function
|
|
return await substitutePlaceholders({
|
|
file: process.env.GH_AW_PROMPT,
|
|
substitutions: {
|
|
GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
|
|
GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
|
|
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,
|
|
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_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
|
|
GH_AW_NEEDS_FETCH_DYNAMIC_PROMPT_OUTPUTS_DYNAMIC_PROMPT: process.env.GH_AW_NEEDS_FETCH_DYNAMIC_PROMPT_OUTPUTS_DYNAMIC_PROMPT,
|
|
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
|
|
}
|
|
});
|
|
- name: Validate prompt placeholders
|
|
env:
|
|
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
|
# poutine:ignore untrusted_checkout_exec
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh"
|
|
- name: Print prompt
|
|
env:
|
|
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
|
# poutine:ignore untrusted_checkout_exec
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh"
|
|
- name: Upload activation artifact
|
|
if: success()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: activation
|
|
include-hidden-files: true
|
|
path: |
|
|
/tmp/gh-aw/aw_info.json
|
|
/tmp/gh-aw/aw-prompts/prompt.txt
|
|
/tmp/gh-aw/aw-prompts/prompt-template.txt
|
|
/tmp/gh-aw/aw-prompts/prompt-import-tree.json
|
|
/tmp/gh-aw/github_rate_limits.jsonl
|
|
/tmp/gh-aw/base
|
|
/tmp/gh-aw/.claude/agents
|
|
if-no-files-found: ignore
|
|
retention-days: 1
|
|
|
|
agent:
|
|
needs:
|
|
- activation
|
|
- fetch_dynamic_prompt
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
issues: read
|
|
pull-requests: read
|
|
env:
|
|
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
|
|
GH_AW_ASSETS_ALLOWED_EXTS: ""
|
|
GH_AW_ASSETS_BRANCH: ""
|
|
GH_AW_ASSETS_MAX_SIZE_KB: 0
|
|
GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
|
|
GH_AW_WORKFLOW_ID_SANITIZED: pydanticaiprreview
|
|
outputs:
|
|
checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
|
|
effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
|
|
effective_tokens_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.effective_tokens_rate_limit_error || 'false' }}
|
|
has_patch: ${{ steps.collect_output.outputs.has_patch }}
|
|
model: ${{ needs.activation.outputs.model }}
|
|
output: ${{ steps.collect_output.outputs.output }}
|
|
output_types: ${{ steps.collect_output.outputs.output_types }}
|
|
setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
|
|
setup-span-id: ${{ steps.setup.outputs.span-id }}
|
|
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
|
|
steps:
|
|
- name: Setup Scripts
|
|
id: setup
|
|
uses: github/gh-aw-actions/setup@efa55847f72aadb03490d955263ff911bf758700 # v0.74.8
|
|
with:
|
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
job-name: ${{ github.job }}
|
|
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
|
|
parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
|
|
env:
|
|
GH_AW_SETUP_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pydantic-ai-pr-review.lock.yml@${{ github.ref }}
|
|
GH_AW_INFO_VERSION: "2.1.142"
|
|
GH_AW_INFO_ENGINE_ID: "claude"
|
|
- name: Set runtime paths
|
|
id: set-runtime-paths
|
|
run: |
|
|
{
|
|
echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl"
|
|
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: Mask OTLP telemetry headers
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
|
|
- name: Install AWF firewall binary (skipped by custom engine.command)
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.46
|
|
- name: Install AWF firewall binary (skipped by custom engine.command)
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.46
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
- name: Setup Python
|
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
with:
|
|
python-version: '3.12'
|
|
- name: Setup uv
|
|
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
- 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
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh"
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
- name: Configure Git credentials
|
|
env:
|
|
REPO_NAME: ${{ github.repository }}
|
|
SERVER_URL: ${{ github.server_url }}
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
run: |
|
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
git config --global user.name "github-actions[bot]"
|
|
git config --global am.keepcr true
|
|
# Re-authenticate git with GitHub token
|
|
SERVER_URL_STRIPPED="${SERVER_URL#https://}"
|
|
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
|
|
echo "Git configured with standard GitHub Actions identity"
|
|
- name: Checkout PR branch
|
|
id: checkout-pr
|
|
if: |
|
|
github.event.pull_request || github.event.issue.pull_request
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
with:
|
|
github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
|
|
await main();
|
|
- name: Determine automatic lockdown mode for GitHub MCP Server
|
|
id: determine-automatic-lockdown
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source 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 activation artifact
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: activation
|
|
path: /tmp/gh-aw
|
|
- name: Restore agent config folders from base branch
|
|
if: steps.checkout-pr.outcome == 'success'
|
|
env:
|
|
GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi"
|
|
GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
|
|
- name: Restore inline sub-agents from activation artifact
|
|
env:
|
|
GH_AW_SUB_AGENT_DIR: ".claude/agents"
|
|
GH_AW_SUB_AGENT_EXT: ".md"
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
|
|
- name: Stage Pydantic AI gh-aw shim launcher
|
|
run: |
|
|
mkdir -p /tmp/gh-aw/bin
|
|
install -m 755 .github/scripts/pydantic-ai-runner-launch.sh /tmp/gh-aw/bin/pydantic-ai-runner-launch
|
|
- name: Install tools for AWF sandbox (ripgrep)
|
|
run: bash .github/scripts/install-sandbox-tools.sh
|
|
- name: Pre-warm Pydantic AI gh-aw shim uv environment
|
|
run: bash .github/scripts/prewarm-pydantic-ai-runner.sh
|
|
- name: Stage Pydantic AI gh-aw shim launcher
|
|
run: |
|
|
mkdir -p /tmp/gh-aw/bin
|
|
install -m 755 .github/scripts/pydantic-ai-runner-launch.sh /tmp/gh-aw/bin/pydantic-ai-runner-launch
|
|
- name: Pre-warm Pydantic AI gh-aw shim uv environment
|
|
run: bash .github/scripts/prewarm-pydantic-ai-runner.sh
|
|
- env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
REPO: ${{ github.repository }}
|
|
if: ${{ github.event.pull_request.number }}
|
|
name: Gather PR review context
|
|
run: "set -uo pipefail\n# Diagnostic: log the workspace state of both scripts/ and .github/scripts/\n# so we can verify the gh-aw restore-from-base step left them untouched.\necho \"::group::workspace inventory at gather time\"\nls -la scripts/ 2>&1 | head -50 || true\necho \"---\"\nls -la .github/scripts/ 2>&1 | head -50 || true\necho \"::endgroup::\"\nscript=scripts/gather-pydantic-ai-review-context.sh\nif [ -x \"$script\" ]; then\n \"$script\" \"$PR_NUMBER\" \"$REPO\" \\\n || echo \"::warning::${script} failed; reviewer will run with less context\"\nelse\n echo \"::warning::${script} not present; reviewer will run with less context\"\nfi\n"
|
|
|
|
- name: Download container images
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.49 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.49 ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.49 ghcr.io/github/gh-aw-firewall/squid:0.25.49 ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388 ghcr.io/github/github-mcp-server:v1.0.4 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
|
|
- name: Generate Safe Outputs Config
|
|
run: |
|
|
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
|
|
mkdir -p /tmp/gh-aw/safeoutputs
|
|
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
|
|
cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_fdbb34ffd77958c2_EOF'
|
|
{"create_pull_request_review_comment":{"max":30,"side":"RIGHT"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{},"submit_pull_request_review":{"footer":"none","max":1,"supersede_older_reviews":true}}
|
|
GH_AW_SAFE_OUTPUTS_CONFIG_fdbb34ffd77958c2_EOF
|
|
- name: Generate Safe Outputs Tools
|
|
env:
|
|
GH_AW_TOOLS_META_JSON: |
|
|
{
|
|
"description_suffixes": {
|
|
"create_pull_request_review_comment": " CONSTRAINTS: Maximum 30 review comment(s) can be created. Comments will be on the RIGHT side of the diff.",
|
|
"submit_pull_request_review": " CONSTRAINTS: Maximum 1 review(s) can be submitted."
|
|
},
|
|
"repo_params": {},
|
|
"dynamic_tools": []
|
|
}
|
|
GH_AW_VALIDATION_JSON: |
|
|
{
|
|
"create_pull_request_review_comment": {
|
|
"defaultMax": 1,
|
|
"fields": {
|
|
"body": {
|
|
"required": true,
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 65000
|
|
},
|
|
"line": {
|
|
"required": true,
|
|
"positiveInteger": true
|
|
},
|
|
"path": {
|
|
"required": true,
|
|
"type": "string"
|
|
},
|
|
"pull_request_number": {
|
|
"optionalPositiveInteger": true
|
|
},
|
|
"repo": {
|
|
"type": "string",
|
|
"maxLength": 256
|
|
},
|
|
"side": {
|
|
"type": "string",
|
|
"enum": [
|
|
"LEFT",
|
|
"RIGHT"
|
|
]
|
|
},
|
|
"start_line": {
|
|
"optionalPositiveInteger": true
|
|
}
|
|
},
|
|
"customValidation": "startLineLessOrEqualLine"
|
|
},
|
|
"missing_data": {
|
|
"defaultMax": 20,
|
|
"fields": {
|
|
"alternatives": {
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 256
|
|
},
|
|
"context": {
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 256
|
|
},
|
|
"data_type": {
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 128
|
|
},
|
|
"reason": {
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 256
|
|
}
|
|
}
|
|
},
|
|
"missing_tool": {
|
|
"defaultMax": 20,
|
|
"fields": {
|
|
"alternatives": {
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 512
|
|
},
|
|
"reason": {
|
|
"required": true,
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 256
|
|
},
|
|
"tool": {
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 128
|
|
}
|
|
}
|
|
},
|
|
"noop": {
|
|
"defaultMax": 1,
|
|
"fields": {
|
|
"message": {
|
|
"required": true,
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 65000
|
|
}
|
|
}
|
|
},
|
|
"report_incomplete": {
|
|
"defaultMax": 5,
|
|
"fields": {
|
|
"details": {
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 65000
|
|
},
|
|
"reason": {
|
|
"required": true,
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 1024
|
|
}
|
|
}
|
|
},
|
|
"submit_pull_request_review": {
|
|
"defaultMax": 1,
|
|
"fields": {
|
|
"body": {
|
|
"type": "string",
|
|
"sanitize": true,
|
|
"maxLength": 65000
|
|
},
|
|
"event": {
|
|
"type": "string",
|
|
"enum": [
|
|
"APPROVE",
|
|
"REQUEST_CHANGES",
|
|
"COMMENT"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
|
|
await main();
|
|
- name: Generate Safe Outputs MCP Server Config
|
|
id: safe-outputs-config
|
|
run: |
|
|
# Generate a secure random API key (360 bits of entropy, 40+ chars)
|
|
# Mask immediately to prevent timing vulnerabilities
|
|
API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
|
|
echo "::add-mask::${API_KEY}"
|
|
|
|
PORT=3001
|
|
|
|
# Set outputs for next steps
|
|
{
|
|
echo "safe_outputs_api_key=${API_KEY}"
|
|
echo "safe_outputs_port=${PORT}"
|
|
} >> "$GITHUB_OUTPUT"
|
|
|
|
echo "Safe Outputs MCP server will run on port ${PORT}"
|
|
|
|
- name: Start Safe Outputs MCP HTTP Server
|
|
id: safe-outputs-start
|
|
env:
|
|
DEBUG: '*'
|
|
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
|
GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
|
|
GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
|
|
GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
|
|
GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
|
|
GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
|
|
run: |
|
|
# Environment variables are set above to prevent template injection
|
|
export DEBUG
|
|
export GH_AW_SAFE_OUTPUTS
|
|
export GH_AW_SAFE_OUTPUTS_PORT
|
|
export GH_AW_SAFE_OUTPUTS_API_KEY
|
|
export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
|
|
export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
|
|
export GH_AW_MCP_LOG_DIR
|
|
|
|
bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
|
|
|
|
- name: Start MCP Gateway
|
|
id: start-mcp-gateway
|
|
env:
|
|
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
|
GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
|
|
GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
|
|
run: |
|
|
set -eo pipefail
|
|
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
|
|
|
|
# Export gateway environment variables for MCP config and gateway script
|
|
export MCP_GATEWAY_PORT="8080"
|
|
export MCP_GATEWAY_DOMAIN="host.docker.internal"
|
|
export MCP_GATEWAY_HOST_DOMAIN="localhost"
|
|
MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
|
|
echo "::add-mask::${MCP_GATEWAY_API_KEY}"
|
|
export MCP_GATEWAY_API_KEY
|
|
export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
|
|
mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
|
|
export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
|
|
export DEBUG="*"
|
|
|
|
export GH_AW_ENGINE="claude"
|
|
MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
|
|
MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
|
|
case "${DOCKER_HOST:-}" in
|
|
unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;;
|
|
/* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;;
|
|
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
|
|
esac
|
|
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
|
|
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.9'
|
|
|
|
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
|
|
cat << GH_AW_MCP_CONFIG_33548bcef9569f7f_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
|
|
{
|
|
"mcpServers": {
|
|
"safeoutputs": {
|
|
"type": "http",
|
|
"url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
|
|
"headers": {
|
|
"Authorization": "$GH_AW_SAFE_OUTPUTS_API_KEY"
|
|
},
|
|
"guard-policies": {
|
|
"write-sink": {
|
|
"accept": [
|
|
"*"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"gateway": {
|
|
"port": $MCP_GATEWAY_PORT,
|
|
"domain": "${MCP_GATEWAY_DOMAIN}",
|
|
"apiKey": "${MCP_GATEWAY_API_KEY}",
|
|
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}",
|
|
"opentelemetry": {
|
|
"endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}",
|
|
"traceId": "${GITHUB_AW_OTEL_TRACE_ID}",
|
|
"spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}"
|
|
}
|
|
}
|
|
}
|
|
GH_AW_MCP_CONFIG_33548bcef9569f7f_EOF
|
|
- name: Mount MCP servers as CLIs
|
|
id: mount-mcp-clis
|
|
continue-on-error: true
|
|
env:
|
|
MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
|
|
MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
|
|
MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
|
|
await main();
|
|
- name: Clean credentials
|
|
continue-on-error: true
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
|
|
- name: Audit pre-agent workspace
|
|
id: pre_agent_audit
|
|
continue-on-error: true
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
|
|
- name: Start CLI Proxy
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
CLI_PROXY_POLICY: '{"allow-only":{"repos":"all","min-integrity":"none"}}'
|
|
CLI_PROXY_IMAGE: 'ghcr.io/github/gh-aw-mcpg:v0.3.9'
|
|
run: |
|
|
bash "${RUNNER_TEMP}/gh-aw/actions/start_cli_proxy.sh"
|
|
- name: Execute Claude Code CLI
|
|
id: agentic_execution
|
|
# Allowed tools (sorted):
|
|
# - Bash
|
|
# - BashOutput
|
|
# - Edit
|
|
# - Edit(/tmp/*)
|
|
# - ExitPlanMode
|
|
# - Glob
|
|
# - Grep
|
|
# - KillBash
|
|
# - LS
|
|
# - MultiEdit
|
|
# - MultiEdit(/tmp/*)
|
|
# - NotebookEdit
|
|
# - NotebookRead
|
|
# - Read
|
|
# - Read(/tmp/*)
|
|
# - Task
|
|
# - TodoWrite
|
|
# - Write
|
|
# - Write(/tmp/*)
|
|
# - 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__safeoutputs
|
|
timeout-minutes: 30
|
|
run: |
|
|
set -o pipefail
|
|
printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
|
|
touch /tmp/gh-aw/agent-step-summary.md
|
|
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
|
|
printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.49/awf-config.schema.json","network":{"allowDomains":["*.githubusercontent.com","*.google.com","*.googleapis.com","*.gvt1.com","*.pythonhosted.org","ai-sdk.dev","ai.azure.com","ai.google.dev","ai.pydantic.dev","amazonaws.com","anaconda.org","anthropic.com","api-docs.deepseek.com","api.anthropic.com","api.cerebras.ai","api.cohere.com","api.deepseek.com","api.fireworks.ai","api.github.com","api.groq.com","api.minimax.io","api.mistral.ai","api.openai.com","api.perplexity.ai","api.sambanova.ai","api.snapcraft.io","api.studio.nebius.com","api.together.xyz","api.x.ai","archive.ubuntu.com","aws.amazon.com","azure.archive.ubuntu.com","binstar.org","bootstrap.pypa.io","boto3.amazonaws.com","cdn.playwright.dev","cerebras.ai","cloud.cerebras.ai","cloud.sambanova.ai","codeload.github.com","cohere.com","conda.anaconda.org","conda.binstar.org","console.anthropic.com","console.groq.com","console.mistral.ai","console.x.ai","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","dashboard.cohere.com","dashscope-intl.aliyuncs.com","dashscope.aliyuncs.com","deepseek.com","developers.openai.com","docs.ag-ui.com","docs.anthropic.com","docs.aws.amazon.com","docs.github.com","docs.perplexity.ai","docs.sambanova.ai","docs.x.ai","endpoints.ai.cloud.ovh.net","files.pythonhosted.org","fireworks.ai","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","groq.com","hf.co","host.docker.internal","huggingface.co","inference-docs.cerebras.ai","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","learn.microsoft.com","lfs.github.com","logfire-api.pydantic.dev","logfire-api.pydantic.info","logfire-eu.pydantic.dev","logfire-eu.pydantic.info","logfire-us.pydantic.dev","logfire-us.pydantic.info","mistral.ai","models.github.ai","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","ollama.com","openrouter.ai","ovh.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","pip.pypa.io","platform.claude.com","platform.moonshot.ai","platform.openai.com","playwright.download.prss.microsoft.com","ppa.launchpad.net","pydantic.dev","pypi.org","pypi.python.org","raw.githubusercontent.com","registry.npmjs.org","repo.anaconda.com","repo.continuum.io","s.symcb.com","s.symcd.com","security.ubuntu.com","sentry.io","statsig.anthropic.com","studio.nebius.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","vercel.com","www.alibabacloud.com","www.googleapis.com","www.together.ai","x.ai"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"targets":{"anthropic":{"host":"api.minimax.io"}},"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5","gemini-pro","haiku","any"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["large"],"claude":["agent","sonnet-6x","haiku","any"],"codex":["agent","gpt-5-codex","gpt-5","any"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"copilot":["agent","gpt-5.4","sonnet","gpt-5","any"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini":["agent","gemini-pro","gemini-flash","any"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite","copilot/raptor*mini*"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4-5*","anthropic/*sonnet-4.5*","anthropic/*sonnet-4-5*","copilot/*sonnet-3.7*","copilot/*sonnet-3-7*","anthropic/*sonnet-3.7*","anthropic/*sonnet-3-7*","copilot/*sonnet-3.5*","copilot/*sonnet-3-5*","anthropic/*sonnet-3.5*","anthropic/*sonnet-3-5*"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.25.49"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
|
|
cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
|
|
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
|
|
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
|
|
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
|
|
fi
|
|
# shellcheck disable=SC1003
|
|
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" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --tty --env-all --exclude-env ANTHROPIC_API_KEY --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --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 --difc-proxy-host host.docker.internal:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt --anthropic-api-base-path /anthropic \
|
|
-- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/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_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs /tmp/gh-aw/bin/pydantic-ai-runner-launch --print --no-chrome --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/*),NotebookEdit,NotebookRead,Read,Read(/tmp/*),Task,TodoWrite,Write,Write(/tmp/*),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__safeoutputs'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode bypassPermissions --output-format stream-json --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
|
|
env:
|
|
ANTHROPIC_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
|
|
ANTHROPIC_BASE_URL: https://api.minimax.io/anthropic
|
|
ANTHROPIC_MODEL: ${{ vars.GH_AW_MODEL }}
|
|
BASH_DEFAULT_TIMEOUT_MS: 60000
|
|
BASH_MAX_TIMEOUT_MS: 60000
|
|
CLAUDE_CODE_DISABLE_FAST_MODE: 1
|
|
DISABLE_BUG_COMMAND: 1
|
|
DISABLE_ERROR_REPORTING: 1
|
|
DISABLE_TELEMETRY: 1
|
|
GH_AW_MCP_CONFIG: ${{ runner.temp }}/gh-aw/mcp-config/mcp-servers.json
|
|
GH_AW_PHASE: agent
|
|
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
|
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
|
GH_AW_VERSION: v0.74.8
|
|
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || github.token }}
|
|
GITHUB_AW: true
|
|
GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
|
|
GITHUB_WORKSPACE: ${{ github.workspace }}
|
|
GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
|
|
GIT_AUTHOR_NAME: github-actions[bot]
|
|
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
|
|
GIT_COMMITTER_NAME: github-actions[bot]
|
|
MCP_TIMEOUT: 120000
|
|
MCP_TOOL_TIMEOUT: 60000
|
|
- name: Stop CLI Proxy
|
|
if: always()
|
|
continue-on-error: true
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/stop_cli_proxy.sh"
|
|
- name: Configure Git credentials
|
|
env:
|
|
REPO_NAME: ${{ github.repository }}
|
|
SERVER_URL: ${{ github.server_url }}
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
run: |
|
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
git config --global user.name "github-actions[bot]"
|
|
git config --global am.keepcr true
|
|
# Re-authenticate git with GitHub token
|
|
SERVER_URL_STRIPPED="${SERVER_URL#https://}"
|
|
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
|
|
echo "Git configured with standard GitHub Actions identity"
|
|
- name: Stop MCP Gateway
|
|
if: always()
|
|
continue-on-error: true
|
|
env:
|
|
MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
|
|
MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
|
|
GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
|
|
run: |
|
|
bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID"
|
|
- name: Redact secrets in logs
|
|
if: always()
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
|
|
await main();
|
|
env:
|
|
GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,MINIMAX_API_KEY'
|
|
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
|
|
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
|
|
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
SECRET_MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
|
|
- name: Append agent step summary
|
|
if: always()
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh"
|
|
- name: Copy Safe Outputs
|
|
if: always()
|
|
env:
|
|
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
|
run: |
|
|
mkdir -p /tmp/gh-aw
|
|
cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
|
|
- name: Ingest agent output
|
|
id: collect_output
|
|
if: always()
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
|
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.google.com,*.googleapis.com,*.gvt1.com,*.pythonhosted.org,ai-sdk.dev,ai.azure.com,ai.google.dev,ai.pydantic.dev,amazonaws.com,anaconda.org,anthropic.com,api-docs.deepseek.com,api.anthropic.com,api.cerebras.ai,api.cohere.com,api.deepseek.com,api.fireworks.ai,api.github.com,api.groq.com,api.minimax.io,api.mistral.ai,api.openai.com,api.perplexity.ai,api.sambanova.ai,api.snapcraft.io,api.studio.nebius.com,api.together.xyz,api.x.ai,archive.ubuntu.com,aws.amazon.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,boto3.amazonaws.com,cdn.playwright.dev,cerebras.ai,cloud.cerebras.ai,cloud.sambanova.ai,codeload.github.com,cohere.com,conda.anaconda.org,conda.binstar.org,console.anthropic.com,console.groq.com,console.mistral.ai,console.x.ai,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,dashboard.cohere.com,dashscope-intl.aliyuncs.com,dashscope.aliyuncs.com,deepseek.com,developers.openai.com,docs.ag-ui.com,docs.anthropic.com,docs.aws.amazon.com,docs.github.com,docs.perplexity.ai,docs.sambanova.ai,docs.x.ai,endpoints.ai.cloud.ovh.net,files.pythonhosted.org,fireworks.ai,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,groq.com,hf.co,host.docker.internal,huggingface.co,inference-docs.cerebras.ai,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,learn.microsoft.com,lfs.github.com,logfire-api.pydantic.dev,logfire-api.pydantic.info,logfire-eu.pydantic.dev,logfire-eu.pydantic.info,logfire-us.pydantic.dev,logfire-us.pydantic.info,mistral.ai,models.github.ai,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,ollama.com,openrouter.ai,ovh.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,pip.pypa.io,platform.claude.com,platform.moonshot.ai,platform.openai.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pydantic.dev,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,studio.nebius.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,vercel.com,www.alibabacloud.com,www.googleapis.com,www.together.ai,x.ai"
|
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
GITHUB_API_URL: ${{ github.api_url }}
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
|
|
await main();
|
|
- name: Parse agent logs for step summary
|
|
if: always()
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_AGENT_OUTPUT: /tmp/gh-aw/agent-stdio.log
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_claude_log.cjs');
|
|
await main();
|
|
- name: Parse MCP Gateway logs for step summary
|
|
if: always()
|
|
id: parse-mcp-gateway
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
|
|
await main();
|
|
- name: Print firewall logs
|
|
if: always()
|
|
continue-on-error: true
|
|
env:
|
|
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
|
|
run: |
|
|
# Fix permissions on firewall logs/audit dirs so they can be uploaded as artifacts
|
|
# AWF runs with sudo, creating files owned by root
|
|
sudo chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
|
|
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
|
|
if command -v awf &> /dev/null; then
|
|
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
|
|
else
|
|
echo 'AWF binary not installed, skipping firewall log summary'
|
|
fi
|
|
- name: Parse token usage for step summary
|
|
if: always()
|
|
continue-on-error: true
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
|
|
await main();
|
|
- name: Print AWF reflect summary
|
|
if: always()
|
|
continue-on-error: true
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs');
|
|
await main();
|
|
- name: Generate observability summary
|
|
if: always()
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_observability_summary.cjs');
|
|
await main(core);
|
|
- name: Write agent output placeholder if missing
|
|
if: always()
|
|
run: |
|
|
if [ ! -f /tmp/gh-aw/agent_output.json ]; then
|
|
echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
|
|
fi
|
|
- name: Upload agent artifacts
|
|
if: always()
|
|
continue-on-error: true
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: agent
|
|
path: |
|
|
/tmp/gh-aw/aw-prompts/prompt.txt
|
|
/tmp/gh-aw/mcp-logs/
|
|
/tmp/gh-aw/agent_usage.json
|
|
/tmp/gh-aw/agent-stdio.log
|
|
/tmp/gh-aw/pre-agent-audit.txt
|
|
/tmp/gh-aw/agent/
|
|
/tmp/gh-aw/github_rate_limits.jsonl
|
|
/tmp/gh-aw/otel.jsonl
|
|
/tmp/gh-aw/otlp-export-errors.jsonl
|
|
/tmp/gh-aw/safeoutputs.jsonl
|
|
/tmp/gh-aw/agent_output.json
|
|
/tmp/gh-aw/aw-*.patch
|
|
/tmp/gh-aw/aw-*.bundle
|
|
/tmp/gh-aw/awf-config.json
|
|
/tmp/gh-aw/sandbox/firewall/logs/
|
|
/tmp/gh-aw/sandbox/firewall/audit/
|
|
/tmp/gh-aw/sandbox/firewall/awf-reflect.json
|
|
if-no-files-found: ignore
|
|
|
|
conclusion:
|
|
needs:
|
|
- activation
|
|
- agent
|
|
- detection
|
|
- fetch_dynamic_prompt
|
|
- safe_outputs
|
|
if: >
|
|
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
|
|
needs.activation.outputs.stale_lock_file_failed == 'true')
|
|
runs-on: ubuntu-slim
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
concurrency:
|
|
group: "gh-aw-conclusion-pydantic-ai-pr-review"
|
|
cancel-in-progress: false
|
|
queue: max
|
|
outputs:
|
|
incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
|
|
noop_message: ${{ steps.noop.outputs.noop_message }}
|
|
tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
|
|
total_count: ${{ steps.missing_tool.outputs.total_count }}
|
|
steps:
|
|
- name: Setup Scripts
|
|
id: setup
|
|
uses: github/gh-aw-actions/setup@efa55847f72aadb03490d955263ff911bf758700 # v0.74.8
|
|
with:
|
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
job-name: ${{ github.job }}
|
|
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
|
|
parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
|
|
env:
|
|
GH_AW_SETUP_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pydantic-ai-pr-review.lock.yml@${{ github.ref }}
|
|
GH_AW_INFO_VERSION: "2.1.142"
|
|
GH_AW_INFO_ENGINE_ID: "claude"
|
|
- name: Download agent output artifact
|
|
id: download-agent-output
|
|
continue-on-error: true
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: agent
|
|
path: /tmp/gh-aw/
|
|
- name: Setup agent output environment variable
|
|
id: setup-agent-output-env
|
|
if: steps.download-agent-output.outcome == 'success'
|
|
run: |
|
|
mkdir -p /tmp/gh-aw/
|
|
find "/tmp/gh-aw/" -type f -print
|
|
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
|
|
- name: Process no-op messages
|
|
id: noop
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
|
GH_AW_NOOP_MAX: "1"
|
|
GH_AW_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
|
|
GH_AW_NOOP_REPORT_AS_ISSUE: "true"
|
|
with:
|
|
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
|
|
await main();
|
|
- name: Log detection run
|
|
id: detection_runs
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
|
GH_AW_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
|
|
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
|
|
with:
|
|
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs');
|
|
await main();
|
|
- name: Record missing tool
|
|
id: missing_tool
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
|
GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
|
|
GH_AW_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
with:
|
|
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
|
|
await main();
|
|
- name: Record incomplete
|
|
id: report_incomplete
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
|
GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
|
|
GH_AW_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
with:
|
|
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs');
|
|
await main();
|
|
- name: Handle agent failure
|
|
id: handle_agent_failure
|
|
if: always()
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
|
GH_AW_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
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: "pydantic-ai-pr-review"
|
|
GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
|
|
GH_AW_ENGINE_ID: "claude"
|
|
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
|
|
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
|
|
GH_AW_EFFECTIVE_TOKENS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.effective_tokens_rate_limit_error || 'false' }}
|
|
GH_AW_ENGINE_API_HOSTS: "api.anthropic.com"
|
|
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
|
|
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
|
|
GH_AW_SAFE_OUTPUT_MESSAGES: "{\"activationComments\":\"false\"}"
|
|
GH_AW_GROUP_REPORTS: "false"
|
|
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
|
|
GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
|
|
GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
|
|
GH_AW_TIMEOUT_MINUTES: "30"
|
|
GH_AW_MAX_EFFECTIVE_TOKENS: "25000000"
|
|
with:
|
|
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
|
|
await main();
|
|
|
|
detection:
|
|
needs:
|
|
- activation
|
|
- agent
|
|
if: >
|
|
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
outputs:
|
|
detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
|
|
detection_reason: ${{ steps.detection_conclusion.outputs.reason }}
|
|
detection_success: ${{ steps.detection_conclusion.outputs.success }}
|
|
steps:
|
|
- name: Setup Scripts
|
|
id: setup
|
|
uses: github/gh-aw-actions/setup@efa55847f72aadb03490d955263ff911bf758700 # v0.74.8
|
|
with:
|
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
job-name: ${{ github.job }}
|
|
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
|
|
parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
|
|
env:
|
|
GH_AW_SETUP_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pydantic-ai-pr-review.lock.yml@${{ github.ref }}
|
|
GH_AW_INFO_VERSION: "2.1.142"
|
|
GH_AW_INFO_ENGINE_ID: "claude"
|
|
- name: Download agent output artifact
|
|
id: download-agent-output
|
|
continue-on-error: true
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: agent
|
|
path: /tmp/gh-aw/
|
|
- name: Setup agent output environment variable
|
|
id: setup-agent-output-env
|
|
if: steps.download-agent-output.outcome == 'success'
|
|
run: |
|
|
mkdir -p /tmp/gh-aw/
|
|
find "/tmp/gh-aw/" -type f -print
|
|
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
|
|
- name: Checkout repository for patch context
|
|
if: needs.agent.outputs.has_patch == 'true'
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
# --- Threat Detection ---
|
|
- name: Clean stale firewall files from agent artifact
|
|
run: |
|
|
rm -rf /tmp/gh-aw/sandbox/firewall/logs
|
|
rm -rf /tmp/gh-aw/sandbox/firewall/audit
|
|
- name: Download container images
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.49 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.49 ghcr.io/github/gh-aw-firewall/squid:0.25.49
|
|
- name: Check if detection needed
|
|
id: detection_guard
|
|
if: always()
|
|
env:
|
|
OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
|
|
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
|
|
run: |
|
|
if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
|
|
echo "run_detection=true" >> "$GITHUB_OUTPUT"
|
|
echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
|
|
else
|
|
echo "run_detection=false" >> "$GITHUB_OUTPUT"
|
|
echo "Detection skipped: no agent outputs or patches to analyze"
|
|
fi
|
|
- name: Clear MCP Config for detection
|
|
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
|
run: |
|
|
rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
|
|
rm -f /home/runner/.copilot/mcp-config.json
|
|
rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
|
|
- name: Prepare threat detection files
|
|
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
|
run: |
|
|
mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
|
|
cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
|
|
cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
|
|
for f in /tmp/gh-aw/aw-*.patch; do
|
|
[ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
|
|
done
|
|
for f in /tmp/gh-aw/aw-*.bundle; do
|
|
[ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
|
|
done
|
|
echo "Prepared threat detection files:"
|
|
ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
|
|
- name: Setup threat detection
|
|
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
WORKFLOW_DESCRIPTION: "AI-driven PR review on the Pydantic AI gh-aw shim: inline comments + a single review verdict. Prompt iterable from a Logfire managed variable; read-only via gh-aw safe-outputs."
|
|
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
|
|
with:
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
|
|
await main();
|
|
- name: Ensure threat-detection directory and log
|
|
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
|
run: |
|
|
mkdir -p /tmp/gh-aw/threat-detection
|
|
touch /tmp/gh-aw/threat-detection/detection.log
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
with:
|
|
node-version: '24'
|
|
package-manager-cache: false
|
|
- name: Install AWF binary
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.49
|
|
- name: Install Claude Code CLI
|
|
run: npm install -g @anthropic-ai/claude-code@2.1.142
|
|
- name: Execute Claude Code CLI
|
|
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
|
continue-on-error: true
|
|
id: detection_agentic_execution
|
|
# Allowed tools (sorted):
|
|
# - Bash
|
|
# - BashOutput
|
|
# - Edit(/tmp/*)
|
|
# - ExitPlanMode
|
|
# - Glob
|
|
# - Grep
|
|
# - KillBash
|
|
# - LS
|
|
# - MultiEdit(/tmp/*)
|
|
# - NotebookRead
|
|
# - Read
|
|
# - Read(/tmp/*)
|
|
# - Task
|
|
# - TodoWrite
|
|
# - Write(/tmp/*)
|
|
timeout-minutes: 20
|
|
run: |
|
|
set -o pipefail
|
|
printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
|
|
touch /tmp/gh-aw/agent-step-summary.md
|
|
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
|
|
printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.49/awf-config.schema.json","network":{"allowDomains":["*.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"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"targets":{"anthropic":{"host":"api.minimax.io"}}},"container":{"imageTag":"0.25.49"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
|
|
cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
|
|
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
|
|
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
|
|
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
|
|
fi
|
|
# shellcheck disable=SC1003
|
|
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" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --tty --env-all --exclude-env ANTHROPIC_API_KEY --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 --anthropic-api-base-path /anthropic \
|
|
-- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/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_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --allowed-tools '\''Bash,BashOutput,Edit(/tmp/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit(/tmp/*),NotebookRead,Read,Read(/tmp/*),Task,TodoWrite,Write(/tmp/*)'\'' --debug-file /tmp/gh-aw/threat-detection/detection.log --verbose --permission-mode bypassPermissions --output-format stream-json --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
|
|
env:
|
|
ANTHROPIC_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
|
|
ANTHROPIC_BASE_URL: https://api.minimax.io/anthropic
|
|
ANTHROPIC_MODEL: ${{ vars.GH_AW_MODEL }}
|
|
BASH_DEFAULT_TIMEOUT_MS: 60000
|
|
BASH_MAX_TIMEOUT_MS: 60000
|
|
CLAUDE_CODE_DISABLE_FAST_MODE: 1
|
|
DISABLE_BUG_COMMAND: 1
|
|
DISABLE_ERROR_REPORTING: 1
|
|
DISABLE_TELEMETRY: 1
|
|
GH_AW_PHASE: detection
|
|
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
|
GH_AW_VERSION: v0.74.8
|
|
GITHUB_AW: true
|
|
GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
|
|
GITHUB_WORKSPACE: ${{ github.workspace }}
|
|
GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
|
|
GIT_AUTHOR_NAME: github-actions[bot]
|
|
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
|
|
GIT_COMMITTER_NAME: github-actions[bot]
|
|
MCP_TIMEOUT: 120000
|
|
MCP_TOOL_TIMEOUT: 60000
|
|
- name: Upload threat detection log
|
|
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: detection
|
|
path: /tmp/gh-aw/threat-detection/detection.log
|
|
if-no-files-found: ignore
|
|
- name: Parse and conclude threat detection
|
|
id: detection_conclusion
|
|
if: always()
|
|
continue-on-error: true
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
|
|
DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }}
|
|
GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
|
|
with:
|
|
script: |
|
|
try {
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
|
|
await main();
|
|
} catch (loadErr) {
|
|
const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false';
|
|
const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure';
|
|
const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr));
|
|
core.error(msg);
|
|
core.setOutput('reason', 'parse_error');
|
|
if (continueOnError && !detectionExecutionFailed) {
|
|
core.warning('\u26A0\uFE0F ' + msg);
|
|
core.setOutput('conclusion', 'warning');
|
|
core.setOutput('success', 'false');
|
|
} else {
|
|
core.setOutput('conclusion', 'failure');
|
|
core.setOutput('success', 'false');
|
|
core.setFailed(msg);
|
|
}
|
|
}
|
|
|
|
fetch_dynamic_prompt:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
|
|
timeout-minutes: 5
|
|
outputs:
|
|
dynamic_prompt: ${{ steps.resolve.outputs.dynamic_prompt }}
|
|
steps:
|
|
- name: Configure GH_HOST for enterprise compatibility
|
|
id: ghes-host-config
|
|
shell: bash
|
|
run: |
|
|
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
|
|
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
|
|
GH_HOST="${GITHUB_SERVER_URL#https://}"
|
|
GH_HOST="${GH_HOST#http://}"
|
|
echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
|
|
- name: Check out the prompt resolver action and default prompt
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
sparse-checkout: |
|
|
.github/actions/fetch-dynamic-prompt
|
|
.github/workflows/shared/prompts/pydantic-ai-pr-review.md
|
|
sparse-checkout-cone-mode: false
|
|
- name: Resolve agent prompt (Logfire managed variable, else committed default)
|
|
id: resolve
|
|
uses: ./.github/actions/fetch-dynamic-prompt
|
|
with:
|
|
default-prompt-file: .github/workflows/shared/prompts/pydantic-ai-pr-review.md
|
|
logfire-base-url: ${{ secrets.LOGFIRE_URL || vars.LOGFIRE_URL || 'https://logfire-api.pydantic.dev' }}
|
|
logfire-read-key: ${{ secrets.LOGFIRE_READ_EXTERNAL_VARIABLES }}
|
|
logfire-variable-key: gh_aw_pydantic_ai_pr_review_prompt
|
|
|
|
pre_activation:
|
|
if: >
|
|
(!contains(github.event.pull_request.labels.*.name, 'auto-review')) && (github.event_name != 'pull_request' ||
|
|
github.event.pull_request.head.repo.id == github.repository_id)
|
|
runs-on: ubuntu-slim
|
|
outputs:
|
|
activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
|
|
matched_command: ''
|
|
setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
|
|
setup-span-id: ${{ steps.setup.outputs.span-id }}
|
|
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
|
|
steps:
|
|
- name: Setup Scripts
|
|
id: setup
|
|
uses: github/gh-aw-actions/setup@efa55847f72aadb03490d955263ff911bf758700 # v0.74.8
|
|
with:
|
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
job-name: ${{ github.job }}
|
|
env:
|
|
GH_AW_SETUP_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pydantic-ai-pr-review.lock.yml@${{ github.ref }}
|
|
GH_AW_INFO_VERSION: "2.1.142"
|
|
GH_AW_INFO_ENGINE_ID: "claude"
|
|
- name: Check team membership for workflow
|
|
id: check_membership
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
|
|
with:
|
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
|
|
await main();
|
|
|
|
safe_outputs:
|
|
needs:
|
|
- activation
|
|
- agent
|
|
- detection
|
|
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
|
|
runs-on: ubuntu-slim
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
timeout-minutes: 15
|
|
env:
|
|
GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/pydantic-ai-pr-review"
|
|
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
|
|
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
|
|
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
|
|
GH_AW_ENGINE_ID: "claude"
|
|
GH_AW_ENGINE_MODEL: "${{ vars.GH_AW_MODEL }}"
|
|
GH_AW_SAFE_OUTPUT_MESSAGES: "{\"activationComments\":\"false\"}"
|
|
GH_AW_WORKFLOW_EMOJI: "🔎"
|
|
GH_AW_WORKFLOW_ID: "pydantic-ai-pr-review"
|
|
GH_AW_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
outputs:
|
|
code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
|
|
code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
|
|
create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
|
|
create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
|
|
process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
|
|
process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
|
|
steps:
|
|
- name: Setup Scripts
|
|
id: setup
|
|
uses: github/gh-aw-actions/setup@efa55847f72aadb03490d955263ff911bf758700 # v0.74.8
|
|
with:
|
|
destination: ${{ runner.temp }}/gh-aw/actions
|
|
job-name: ${{ github.job }}
|
|
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
|
|
parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
|
|
env:
|
|
GH_AW_SETUP_WORKFLOW_NAME: "Pydantic AI PR Review"
|
|
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/pydantic-ai-pr-review.lock.yml@${{ github.ref }}
|
|
GH_AW_INFO_VERSION: "2.1.142"
|
|
GH_AW_INFO_ENGINE_ID: "claude"
|
|
- name: Mask OTLP telemetry headers
|
|
run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
|
|
- name: Download agent output artifact
|
|
id: download-agent-output
|
|
continue-on-error: true
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: agent
|
|
path: /tmp/gh-aw/
|
|
- name: Setup agent output environment variable
|
|
id: setup-agent-output-env
|
|
if: steps.download-agent-output.outcome == 'success'
|
|
run: |
|
|
mkdir -p /tmp/gh-aw/
|
|
find "/tmp/gh-aw/" -type f -print
|
|
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
|
|
- name: Configure GH_HOST for enterprise compatibility
|
|
id: ghes-host-config
|
|
shell: bash
|
|
run: |
|
|
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
|
|
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
|
|
GH_HOST="${GITHUB_SERVER_URL#https://}"
|
|
GH_HOST="${GH_HOST#http://}"
|
|
echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
|
|
- name: Process Safe Outputs
|
|
id: process_safe_outputs
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
|
GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
|
|
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.google.com,*.googleapis.com,*.gvt1.com,*.pythonhosted.org,ai-sdk.dev,ai.azure.com,ai.google.dev,ai.pydantic.dev,amazonaws.com,anaconda.org,anthropic.com,api-docs.deepseek.com,api.anthropic.com,api.cerebras.ai,api.cohere.com,api.deepseek.com,api.fireworks.ai,api.github.com,api.groq.com,api.minimax.io,api.mistral.ai,api.openai.com,api.perplexity.ai,api.sambanova.ai,api.snapcraft.io,api.studio.nebius.com,api.together.xyz,api.x.ai,archive.ubuntu.com,aws.amazon.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,boto3.amazonaws.com,cdn.playwright.dev,cerebras.ai,cloud.cerebras.ai,cloud.sambanova.ai,codeload.github.com,cohere.com,conda.anaconda.org,conda.binstar.org,console.anthropic.com,console.groq.com,console.mistral.ai,console.x.ai,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,dashboard.cohere.com,dashscope-intl.aliyuncs.com,dashscope.aliyuncs.com,deepseek.com,developers.openai.com,docs.ag-ui.com,docs.anthropic.com,docs.aws.amazon.com,docs.github.com,docs.perplexity.ai,docs.sambanova.ai,docs.x.ai,endpoints.ai.cloud.ovh.net,files.pythonhosted.org,fireworks.ai,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,groq.com,hf.co,host.docker.internal,huggingface.co,inference-docs.cerebras.ai,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,learn.microsoft.com,lfs.github.com,logfire-api.pydantic.dev,logfire-api.pydantic.info,logfire-eu.pydantic.dev,logfire-eu.pydantic.info,logfire-us.pydantic.dev,logfire-us.pydantic.info,mistral.ai,models.github.ai,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,ollama.com,openrouter.ai,ovh.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,pip.pypa.io,platform.claude.com,platform.moonshot.ai,platform.openai.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pydantic.dev,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,studio.nebius.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,vercel.com,www.alibabacloud.com,www.googleapis.com,www.together.ai,x.ai"
|
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
GITHUB_API_URL: ${{ github.api_url }}
|
|
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request_review_comment\":{\"max\":30,\"side\":\"RIGHT\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{},\"submit_pull_request_review\":{\"footer\":\"none\",\"max\":1,\"supersede_older_reviews\":true}}"
|
|
with:
|
|
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
|
setupGlobals(core, github, context, exec, io, getOctokit);
|
|
const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
|
|
await main();
|
|
- name: Upload Safe Outputs Items
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: safe-outputs-items
|
|
path: |
|
|
/tmp/gh-aw/safe-output-items.jsonl
|
|
/tmp/gh-aw/temporary-id-map.json
|
|
if-no-files-found: ignore
|
|
|