From 001a08dccb5b6bfd5d232bab5cba19ec34b31d56 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 19:26:09 +0000 Subject: [PATCH 1/6] Initial plan From 42387c7b393e43ff5fbf7035009a5b213fddd8ee Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 19:32:30 +0000 Subject: [PATCH 2/6] docs: remove Custom AWF Configuration and Custom MCP Gateway Configuration sections These are now implementation/debugging details and should not be publicly documented. Removes: - Custom AWF Configuration section (command, args, env overrides) - Custom Mounts subsection (sandbox.agent.mounts) - MCP Gateway Configuration Options table (command, container, etc.) - Dangling reference to sandbox.agent.mounts in Filesystem Access Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/gh-aw/sessions/4b4f1db3-8b63-420c-b13a-644990344883 --- docs/src/content/docs/reference/sandbox.md | 115 --------------------- 1 file changed, 115 deletions(-) diff --git a/docs/src/content/docs/reference/sandbox.md b/docs/src/content/docs/reference/sandbox.md index 703b9177266..c23d2ee6069 100644 --- a/docs/src/content/docs/reference/sandbox.md +++ b/docs/src/content/docs/reference/sandbox.md @@ -93,8 +93,6 @@ AWF makes the host filesystem visible inside the container with appropriate perm | System paths | Read-only | `/usr`, `/opt`, `/bin`, `/lib` | | Docker socket | Hidden | `/var/run/docker.sock` (security) | -Custom mounts can still be added via `sandbox.agent.mounts` for paths that need different permissions. - #### Host Binaries All host binaries are available without explicit mounts: system utilities, `gh`, language runtimes, build tools, and anything installed via `apt-get` or setup actions. Verify with `which `. @@ -129,123 +127,10 @@ jobs: Use `go build` or `python3` - both are available. ``` -#### Custom AWF Configuration - -Use custom commands, arguments, and environment variables to replace the standard AWF installation with a custom setup: - -```yaml wrap -sandbox: - agent: - id: awf - command: "/usr/local/bin/custom-awf-wrapper" - args: - - "--custom-logging" - - "--debug-mode" - env: - AWF_CUSTOM_VAR: "custom_value" - DEBUG_LEVEL: "verbose" -``` - -##### Custom Mounts - -Add custom container mounts to make host paths available inside the AWF container: - -```yaml wrap -sandbox: - agent: - id: awf - mounts: - - "/host/data:/data:ro" - - "/usr/local/bin/custom-tool:/usr/local/bin/custom-tool:ro" - - "/tmp/cache:/cache:rw" -``` - -Mount syntax follows Docker's format: `source:destination:mode` - -- `source`: Path on the host system -- `destination`: Path inside the container -- `mode`: Either `ro` (read-only) or `rw` (read-write) - -Custom mounts are useful for: - -- Providing access to datasets or configuration files -- Making custom tools available in the container -- Sharing cache directories between host and container - -| Field | Type | Description | -|-------|------|-------------| -| `id` | `string` | Agent identifier: `awf` | -| `command` | `string` | Custom command to replace AWF binary installation | -| `args` | `string[]` | Additional arguments appended to the command | -| `env` | `object` | Environment variables set on the execution step | -| `mounts` | `string[]` | Container mounts using syntax `source:destination:mode` | - -When `command` is specified, the standard AWF installation is skipped and your custom command is used instead. - ## MCP Gateway The MCP Gateway routes all MCP server calls through a unified HTTP gateway, enabling centralized management, logging, and authentication for MCP tools. -### Configuration Options - -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `command` | `string` | No | Custom command to execute (mutually exclusive with `container`) | -| `container` | `string` | No | Container image for the MCP gateway (mutually exclusive with `command`) | -| `version` | `string` | No | Version tag for the container image | -| `port` | `integer` | No | HTTP server port (default: 8080) | -| `api-key` | `string` | No | API key for gateway authentication | -| `args` | `string[]` | No | Command/container execution arguments | -| `entrypointArgs` | `string[]` | No | Container entrypoint arguments (only valid with `container`) | -| `env` | `object` | No | Environment variables for the gateway | - -**Execution Modes** - -The MCP gateway supports two execution modes: - -1. **Custom command** - Use `command` field to specify a custom binary or script -2. **Container** - Use `container` field for Docker-based execution - -The `command` and `container` fields are mutually exclusive - only one can be specified. -You must specify either `command` or `container` to use the MCP gateway feature. - -When MCP gateway is configured: - -1. The gateway starts using the specified execution mode (command or container) -2. A health check verifies the gateway is ready -3. All MCP server configurations are transformed to route through the gateway -4. The gateway receives server configs via a configuration file - -### Example: Custom Command Mode - -```yaml wrap -features: - mcp-gateway: true - -sandbox: - mcp: - command: "/usr/local/bin/mcp-gateway" - args: ["--port", "9000", "--verbose"] - env: - LOG_LEVEL: "debug" -``` - -### Example: Container Mode - -```yaml wrap -features: - mcp-gateway: true - -sandbox: - mcp: - container: "ghcr.io/github/gh-aw-mcpg:latest" - args: ["--rm", "-i"] - entrypointArgs: ["--routed", "--listen", "0.0.0.0:8000", "--config-stdin"] - port: 8000 - env: - LOG_LEVEL: "info" -``` - ## Feature Flags Some sandbox features require feature flags: From d18ef23b8bafe6b2fb34221424b9d1435469fd52 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:05:34 +0000 Subject: [PATCH 3/6] feat: mark internal sandbox fields with x-internal, skip in docs, validate in strict mode - Add "x-internal": true to agent sandbox (command, args, env) and MCP gateway (container, version, entrypoint, args, entrypointArgs) fields in the JSON schema - Update generate-schema-docs.js to skip x-internal fields (analogous to deprecated field handling) - Add validateStrictSandboxCustomization() that errors when internal sandbox fields are used in strict mode - Call the new validation from the compiler orchestrator - Set strict: false on smoke test workflows that legitimately use internal sandbox fields - Add strict: false to existing test fixtures that use internal fields - Add tests for the new strict mode sandbox validation Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/gh-aw/sessions/693539a7-68f3-40fe-a2fa-df98eb6d9e13 --- .github/workflows/smoke-claude.lock.yml | 4 +- .github/workflows/smoke-claude.md | 2 +- .github/workflows/smoke-codex.lock.yml | 4 +- .github/workflows/smoke-codex.md | 2 +- .github/workflows/smoke-copilot-arm.lock.yml | 4 +- .github/workflows/smoke-copilot-arm.md | 2 +- .github/workflows/smoke-copilot.lock.yml | 4 +- .github/workflows/smoke-copilot.md | 2 +- .../docs/reference/frontmatter-full.md | 619 ++++++++++++++++-- pkg/parser/schemas/main_workflow_schema.json | 8 + pkg/workflow/compiler_orchestrator_engine.go | 8 + .../mcp_gateway_entrypoint_mounts_e2e_test.go | 5 + pkg/workflow/sandbox_custom_agent_test.go | 1 + .../strict_mode_sandbox_validation.go | 72 ++ .../strict_mode_sandbox_validation_test.go | 184 ++++++ scripts/generate-schema-docs.js | 5 + 16 files changed, 847 insertions(+), 79 deletions(-) create mode 100644 pkg/workflow/strict_mode_sandbox_validation.go create mode 100644 pkg/workflow/strict_mode_sandbox_validation_test.go diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index db5b1b36686..5211e110542 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -34,7 +34,7 @@ # # inlined-imports: true # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"9a4d79294c209d0051ffe00014b288b54a2be522a7908fd96f44fab6aa5c9e60","strict":true,"agent_id":"claude"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"fe699b7701341977425ab709b5fa92bd1ca9d99e83fc3f6472e7749dbfe01e02","agent_id":"claude"} name: "Smoke Claude" "on": @@ -109,7 +109,7 @@ jobs: GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_APM_VERSION: "v0.8.3" GH_AW_INFO_FIREWALL_TYPE: "squid" - GH_AW_COMPILED_STRICT: "true" + GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 with: script: | diff --git a/.github/workflows/smoke-claude.md b/.github/workflows/smoke-claude.md index 20c974ecf24..39a42041613 100644 --- a/.github/workflows/smoke-claude.md +++ b/.github/workflows/smoke-claude.md @@ -19,7 +19,7 @@ name: Smoke Claude engine: id: claude max-turns: 100 -strict: true +strict: false inlined-imports: true imports: - shared/mcp-pagination.md diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index f99faf2084a..4480cc7bcdf 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -27,7 +27,7 @@ # - shared/gh.md # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"0f4668b9ab1badf192f489c4a66a16cdaa218a0f31d7ad325ec26159e0d7e4d8","strict":true,"agent_id":"codex"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"8ccab7e12d1831d3a6e67bf289dbda8640b9254de4657fc2b2d8cfc3f33fcfb9","agent_id":"codex"} name: "Smoke Codex" "on": @@ -99,7 +99,7 @@ jobs: GH_AW_INFO_AWF_VERSION: "v0.24.5" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" - GH_AW_COMPILED_STRICT: "true" + GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 with: script: | diff --git a/.github/workflows/smoke-codex.md b/.github/workflows/smoke-codex.md index 87b345ae83e..49ce9c71e9a 100644 --- a/.github/workflows/smoke-codex.md +++ b/.github/workflows/smoke-codex.md @@ -14,7 +14,7 @@ permissions: pull-requests: read name: Smoke Codex engine: codex -strict: true +strict: false imports: - shared/gh.md - shared/reporting.md diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index 5612a90b980..067c7b3b4c2 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -28,7 +28,7 @@ # - shared/github-queries-mcp-script.md # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"7d98a942c43c77f4d9757066e1492cdd3c197fb6272337d072c67412dfa07e95","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b8c52bb25dd5e53dd4cd9c19582e7759a58d025d7218306c34c3789d82c383e9","agent_id":"copilot"} name: "Smoke Copilot ARM64" "on": @@ -98,7 +98,7 @@ jobs: GH_AW_INFO_AWF_VERSION: "v0.24.5" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" - GH_AW_COMPILED_STRICT: "true" + GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 with: script: | diff --git a/.github/workflows/smoke-copilot-arm.md b/.github/workflows/smoke-copilot-arm.md index f54a95bd6a1..39abe9bbd6a 100644 --- a/.github/workflows/smoke-copilot-arm.md +++ b/.github/workflows/smoke-copilot-arm.md @@ -108,7 +108,7 @@ safe-outputs: run-success: "📰 VERDICT: [{workflow_name}]({run_url}) has concluded. All systems operational. This is a developing story. 🎤" run-failure: "📰 DEVELOPING STORY: [{workflow_name}]({run_url}) reports {status}. Our correspondents are investigating the incident..." timeout-minutes: 15 -strict: true +strict: false --- # Smoke Test: Copilot Engine Validation (ARM64) diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 2ca4c376296..581454899f1 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -28,7 +28,7 @@ # - shared/github-queries-mcp-script.md # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c69fb0db5e338569de880edcb18e606cf17efe9016ab532a0c4f17c1ba71729c","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"9a25686dcb16bf3ce0e37b5b72799686f0fc1d8cd14a06249604373fb9d0a59c","agent_id":"copilot"} name: "Smoke Copilot" "on": @@ -100,7 +100,7 @@ jobs: GH_AW_INFO_AWF_VERSION: "v0.24.5" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" - GH_AW_COMPILED_STRICT: "true" + GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 with: script: | diff --git a/.github/workflows/smoke-copilot.md b/.github/workflows/smoke-copilot.md index afe8607e57a..cdf79211f9f 100644 --- a/.github/workflows/smoke-copilot.md +++ b/.github/workflows/smoke-copilot.md @@ -116,7 +116,7 @@ safe-outputs: run-success: "📰 VERDICT: [{workflow_name}]({run_url}) has concluded. All systems operational. This is a developing story. 🎤" run-failure: "📰 DEVELOPING STORY: [{workflow_name}]({run_url}) reports {status}. Our correspondents are investigating the incident..." timeout-minutes: 15 -strict: true +strict: false --- # Smoke Test: Copilot Engine Validation diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index b9e514f0d41..966b5be8446 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -193,6 +193,65 @@ on: events: [] # Array items: GitHub Actions event name. + # On Label Command trigger: fires when a specific label is added to an issue, pull + # request, or discussion. The triggering label is automatically removed at + # workflow start so it can be applied again to re-trigger. Use the 'events' field + # to restrict which item types (issues, pull_request, discussion) activate the + # trigger. + # (optional) + # This field supports multiple formats (oneOf): + + # Option 1: Label name as a string (shorthand format). The workflow fires when + # this label is added to any supported item type (issue, pull request, or + # discussion). + label_command: "example-value" + + # Option 2: Label command configuration object with label name(s) and optional + # event filtering. + label_command: + # Label name(s) that trigger the workflow when added to an issue, pull request, or + # discussion. + # (optional) + # This field supports multiple formats (oneOf): + + # Option 1: Single label name that acts as a command (e.g., 'deploy' triggers the + # workflow when the 'deploy' label is added). + name: "My Workflow" + + # Option 2: Array of label names — any of these labels will trigger the workflow. + name: [] + # Array items: A label name + + # Alternative to 'name': label name(s) that trigger the workflow. + # (optional) + # This field supports multiple formats (oneOf): + + # Option 1: Single label name. + names: "example-value" + + # Option 2: Array of label names — any of these labels will trigger the workflow. + names: [] + # Array items: A label name + + # Item types where the label-command trigger should be active. Default is all + # supported types: issues, pull_request, discussion. + # (optional) + # This field supports multiple formats (oneOf): + + # Option 1: Single item type or '*' for all types. + events: "*" + + # Option 2: Array of item types where the trigger is active. + events: [] + # Array items: Item type. + + # Whether to automatically remove the triggering label after the workflow starts. + # Defaults to true. Set to false to keep the label on the item and skip the + # label-removal step. When false, the issues:write and discussions:write + # permissions required for label removal are also omitted. + # (optional) + remove_label: true + # Push event trigger that runs the workflow when code is pushed to the repository # (optional) # This field supports multiple formats (oneOf): @@ -738,6 +797,90 @@ on: repositories: [] # Array of strings + # Steps to inject into the pre-activation job. These steps run after all built-in + # checks (membership, stop-time, skip-if, etc.) and their results are exposed as + # pre-activation outputs. Use 'id' on steps to reference their results via + # needs.pre_activation.outputs._result. + # (optional) + steps: [] + # Array items: + # Optional name for the step + # (optional) + name: "My Workflow" + + # Optional step ID. When set, the step result is exposed as + # needs.pre_activation.outputs._result + # (optional) + id: "example-value" + + # Shell command to run + # (optional) + run: "example-value" + + # Action to use (e.g., 'actions/checkout@v4') + # (optional) + uses: "example-value" + + # Input parameters for the action + # (optional) + with: + {} + + # Environment variables for the step + # (optional) + env: + {} + + # Conditional expression for the step + # (optional) + if: "example-value" + + # Whether to continue if the step fails + # (optional) + continue-on-error: true + + # Additional permissions for the pre-activation job. Use to declare extra scopes + # required by on.steps (e.g., issues: read for GitHub API calls in steps). + # (optional) + # Map of permission scope to level + # (optional) + permissions: + # (optional) + actions: "read" + + # (optional) + checks: "read" + + # (optional) + contents: "read" + + # (optional) + deployments: "read" + + # (optional) + discussions: "read" + + # (optional) + issues: "read" + + # (optional) + packages: "read" + + # (optional) + pages: "read" + + # (optional) + pull-requests: "read" + + # (optional) + repository-projects: "read" + + # (optional) + security-events: "read" + + # (optional) + statuses: "read" + # GitHub token permissions for the workflow. Controls what the GITHUB_TOKEN can # access during execution. Use the principle of least privilege - only grant the # minimum permissions needed. @@ -837,6 +980,13 @@ permissions: # (optional) statuses: "read" + # Permission level for Dependabot vulnerability alerts (read/write/none). GitHub + # App-only permission: required to access Dependabot alerts via the GitHub MCP + # server. The GITHUB_TOKEN does not have this permission — a GitHub App must be + # configured. + # (optional) + vulnerability-alerts: "read" + # Permission shorthand that applies read access to all permission scopes. Can be # combined with specific write permissions to override individual scopes. 'write' # is not allowed for all. @@ -1132,22 +1282,6 @@ sandbox: # (optional) type: "awf" - # Custom command to replace the default AWF installation. For AWF: 'docker run - # my-custom-awf-image' - # (optional) - command: "example-value" - - # Additional arguments to append to the command (applies to AWF, for standard and - # custom commands) - # (optional) - args: [] - # Array of strings - - # Environment variables to set on the execution step (applies to AWF) - # (optional) - env: - {} - # Container mounts to add when using AWF. Each mount is specified using Docker # mount syntax: 'source:destination:mode' where mode can be 'ro' (read-only) or # 'rw' (read-write). Example: '/host/path:/container/path:ro' @@ -1155,6 +1289,11 @@ sandbox: mounts: [] # Array of Mount specification in format 'source:destination:mode' + # Memory limit for the AWF container (e.g., '4g', '8g'). Passed as --memory-limit + # to AWF. If not specified, AWF's default memory limit is used. + # (optional) + memory: "example-value" + # Custom sandbox runtime configuration. Note: Network configuration is controlled # by the top-level 'network' field, not here. # (optional) @@ -1229,28 +1368,6 @@ sandbox: # Specification v1.0.0: Only container-based execution is supported. # (optional) mcp: - # Container image for the MCP gateway executable (required) - container: "example-value" - - # Optional version/tag for the container image (e.g., 'latest', 'v1.0.0') - # (optional) - version: null - - # Optional custom entrypoint for the MCP gateway container. Overrides the - # container's default entrypoint. - # (optional) - entrypoint: "example-value" - - # Arguments for docker run - # (optional) - args: [] - # Array of strings - - # Arguments to add after the container image (container entrypoint arguments) - # (optional) - entrypointArgs: [] - # Array of strings - # Volume mounts for the MCP gateway container. Each mount is specified using # Docker mount syntax: 'source:destination:mode' where mode can be 'ro' # (read-only) or 'rw' (read-write). Example: '/host/data:/container/data:ro' @@ -1672,9 +1789,8 @@ tools: # (optional) read-only: true - # DEPRECATED: Use 'min-integrity: approved' instead. Enable lockdown mode to limit - # content surfaced from public repositories (only items authored by users with push - # access). Default: false + # Enable lockdown mode to limit content surfaced from public repositories (only + # items authored by users with push access). Default: false # (optional) lockdown: true @@ -1696,7 +1812,7 @@ tools: mounts: [] # Array of Mount specification in format 'host:container:mode' - # GitHub Tools repository access configuration. Restricts which repositories the + # Guard policy: repository access configuration. Restricts which repositories the # agent can access. Use 'all' to allow all repos, 'public' for public repositories # only, or an array of repository patterns (e.g., 'owner/repo', 'owner/*', # 'owner/prefix*'). @@ -1713,7 +1829,7 @@ tools: # Array items: Repository pattern in the format 'owner/repo', 'owner/*' (all repos # under owner), or 'owner/prefix*' (repos with name prefix) - # GitHub Tools minimum required integrity level for repository access. Restricts + # Guard policy: minimum required integrity level for repository access. Restricts # the agent to users with at least the specified permission level. # (optional) min-integrity: "none" @@ -2152,8 +2268,11 @@ cache: [] # permissions in the main job # (optional) safe-outputs: - # List of allowed domains for URI filtering in AI workflow output. URLs from other - # domains will be replaced with '(redacted)' for security. + # List of allowed domains for URL redaction in safe output handlers. Supports + # ecosystem identifiers (e.g., "python", "node", "default-safe-outputs") like + # network.allowed. These domains are unioned with the engine defaults and + # network.allowed when computing the final allowed domain set. localhost and + # github.com are always included. # (optional) allowed-domains: [] # Array of strings @@ -2167,12 +2286,13 @@ safe-outputs: # Array of strings # Enable AI agents to create GitHub issues from workflow output. Supports title - # prefixes, automatic labeling, assignees, and cross-repository creation. + # prefixes, automatic labeling, assignees, and cross-repository creation. Does not + # require 'issues: write' permission. # (optional) # This field supports multiple formats (oneOf): # Option 1: Configuration for automatically creating GitHub issues from AI - # workflow output. + # workflow output. The main job does not need 'issues: write' permission. create-issue: # Optional prefix to add to the beginning of the issue title (e.g., '[ai] ' or # '[analysis] ') @@ -2261,6 +2381,15 @@ safe-outputs: # (optional) close-older-issues: true + # Optional explicit deduplication key for close-older matching. When set, a `` marker is embedded in the issue body and used as + # the primary key for searching and filtering older issues instead of the + # workflow-id markers. This gives deterministic isolation across caller workflows + # and is stable across workflow renames. The value is normalized to identifier + # style (lowercase alphanumeric, dashes, underscores). + # (optional) + close-older-key: "example-value" + # Controls whether AI-generated footer is added to the issue. When false, the # visible footer content is omitted but XML markers (workflow-id, tracker-id, # metadata) are still included for searchability. Defaults to true. @@ -2272,6 +2401,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable issue creation with default configuration create-issue: null @@ -2318,6 +2452,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable agent session creation with default configuration create-agent-task: null @@ -2364,6 +2503,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable agent session creation with default configuration create-agent-session: null @@ -2410,6 +2554,27 @@ safe-outputs: # fallback. Must be a valid GitHub Projects v2 URL. project: "example-value" + # Default repository in format 'owner/repo' for cross-repository content + # resolution. When specified, the agent can use 'target_repo' in agent output to + # resolve issues or PRs from this repository. Wildcards ('*') are not allowed. + # Supports GitHub Actions expression syntax (e.g., '${{ vars.TARGET_REPO }}'). + # (optional) + # This field supports multiple formats (oneOf): + + # Option 1: string + target-repo: "example-value" + + # Option 2: GitHub Actions expression that resolves to owner/repo at runtime + target-repo: "example-value" + + # List of additional repositories in format 'owner/repo' allowed for + # cross-repository content resolution via 'target_repo'. The target-repo (or + # current repo) is always implicitly allowed. Supports wildcard patterns (e.g., + # 'org/*', '*/repo', '*') and GitHub Actions expression syntax for individual + # entries. + # (optional) + allowed-repos: [] + # Optional array of project views to create. Each view must have a name and # layout. Views are created during project setup. # (optional) @@ -2450,6 +2615,11 @@ safe-outputs: options: [] # Array of strings + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable project management with default configuration (max=10) update-project: null @@ -2539,11 +2709,14 @@ safe-outputs: options: [] # Array of strings + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable project creation with default configuration (max=1) create-project: null - # Option 3: Alternative null value syntax - # Enable AI agents to post status updates to GitHub Projects for progress tracking # and stakeholder communication. # (optional) @@ -2581,6 +2754,11 @@ safe-outputs: # fallback. Must be a valid GitHub Projects v2 URL. project: "example-value" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable project status updates with default configuration (max=1) create-project-status-update: null @@ -2651,6 +2829,15 @@ safe-outputs: # (optional) close-older-discussions: true + # Optional explicit deduplication key for close-older matching. When set, a `` marker is embedded in the discussion body and used + # as the primary key for searching and filtering older discussions instead of the + # workflow-id markers. This gives deterministic isolation across caller workflows + # and is stable across workflow renames. The value is normalized to identifier + # style (lowercase alphanumeric, dashes, underscores). + # (optional) + close-older-key: "example-value" + # When true (default), fallback to creating an issue if discussion creation fails # due to permissions. The fallback issue will include a note indicating it was # intended to be a discussion. If close-older-discussions is enabled, the @@ -2687,6 +2874,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable discussion creation with default configuration create-discussion: null @@ -2732,6 +2924,11 @@ safe-outputs: # (optional) target-repo: "example-value" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable discussion closing with default configuration close-discussion: null @@ -2789,6 +2986,16 @@ safe-outputs: # (optional) footer: true + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + + # GitHub token to use for this specific output type. Overrides global github-token + # if specified. + # (optional) + github-token: "${{ secrets.GITHUB_TOKEN }}" + # Option 2: Enable discussion updating with default configuration update-discussion: null @@ -2838,6 +3045,11 @@ safe-outputs: allowed-repos: [] # Array of strings + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable issue closing with default configuration close-issue: null @@ -2935,6 +3147,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable marking pull requests as ready for review with default # configuration mark-pull-request-as-ready-for-review: null @@ -3020,6 +3237,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable issue comment creation with default configuration add-comment: null @@ -3186,6 +3408,21 @@ safe-outputs: # (optional) preserve-branch-name: true + # List of glob patterns for files to exclude from the patch. Each pattern is + # passed to `git format-patch` as a `:(exclude)` magic pathspec, so + # matching files are stripped by git at generation time and will not appear in the + # commit. Excluded files are also not subject to `allowed-files` or + # `protected-files` checks. Supports * (any characters except /) and ** (any + # characters including /). + # (optional) + excluded-files: [] + # Array of strings + + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable pull request creation with default configuration create-pull-request: null @@ -3235,6 +3472,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable PR review comment creation with default configuration create-pull-request-review-comment: null @@ -3300,6 +3542,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable PR review submission with default configuration submit-pull-request-review: null @@ -3343,6 +3590,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable with default configuration reply-to-pull-request-review-comment: null @@ -3371,6 +3623,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable review thread resolution with default configuration resolve-pull-request-review-thread: null @@ -3416,6 +3673,11 @@ safe-outputs: allowed-repos: [] # Array of strings + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable code scanning alert creation with default configuration # (unlimited findings) create-code-scanning-alert: null @@ -3443,6 +3705,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable code scanning autofix creation with default configuration (max: # 10) autofix-code-scanning-alert: null @@ -3507,6 +3774,11 @@ safe-outputs: allowed-repos: [] # Array of strings + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to remove labels from GitHub issues or pull requests. # (optional) # This field supports multiple formats (oneOf): @@ -3564,6 +3836,11 @@ safe-outputs: allowed-repos: [] # Array of strings + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to request reviews from users or teams on pull requests based # on code changes or expertise matching. # (optional) @@ -3606,6 +3883,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to assign GitHub milestones to issues or pull requests based on # workflow analysis or project planning. # (optional) @@ -3644,6 +3926,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to assign issues or pull requests to GitHub Copilot (@copilot) # for automated handling. # (optional) @@ -3738,6 +4025,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to assign issues or pull requests to specific GitHub users # based on workflow logic or expertise matching. # (optional) @@ -3799,6 +4091,11 @@ safe-outputs: allowed-repos: [] # Array of strings + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to unassign users from issues or pull requests. Useful for # reassigning work or removing users from issues. # (optional) @@ -3855,6 +4152,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to create hierarchical relationships between issues using # GitHub's sub-issue (tasklist) feature. # (optional) @@ -3905,6 +4207,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to edit and update existing GitHub issue content, titles, # labels, assignees, and metadata. # (optional) @@ -3971,6 +4278,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable issue updating with default configuration update-issue: null @@ -4027,6 +4339,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable pull request updating with default configuration (title and # body updates enabled) update-pull-request: null @@ -4137,6 +4454,16 @@ safe-outputs: allowed-files: [] # Array of strings + # List of glob patterns for files to exclude from the patch. Each pattern is + # passed to `git format-patch` as a `:(exclude)` magic pathspec, so + # matching files are stripped by git at generation time and will not appear in the + # commit. Excluded files are also not subject to `allowed-files` or + # `protected-files` checks. Supports * (any characters except /) and ** (any + # characters including /). + # (optional) + excluded-files: [] + # Array of strings + # Enable AI agents to minimize (hide) comments on issues or pull requests based on # relevance, spam detection, or moderation rules. # (optional) @@ -4177,6 +4504,11 @@ safe-outputs: # (optional) discussions: true + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Enable AI agents to set or clear the type of GitHub issues. Use an empty string # to clear the current type. # (optional) @@ -4228,6 +4560,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Dispatch workflow_dispatch events to other workflows. Used by orchestrators to # delegate work to worker workflows with controlled maximum dispatch count. # (optional) @@ -4269,11 +4606,57 @@ safe-outputs: # (optional) target-ref: "example-value" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Shorthand array format: list of workflow names (without .md extension) # to allow dispatching dispatch-workflow: [] # Array items: string + # Call reusable workflows via workflow_call fan-out. The compiler generates static + # conditional jobs; the agent selects which worker to activate. Use this for + # orchestrator/dispatcher patterns within the same repository. + # (optional) + # This field supports multiple formats (oneOf): + + # Option 1: Configuration for calling reusable workflows via workflow_call + # fan-out. The compiler generates conditional `uses:` jobs at compile time; the + # agent selects which worker to activate at runtime. + call-workflow: + # List of workflow names (without .md extension) to allow calling. Each workflow + # must exist in .github/workflows/ and declare a workflow_call trigger. + workflows: [] + # Array of strings + + # Maximum number of workflow_call fan-out operations per run (default: 1, max: + # 50). Supports integer or GitHub Actions expression (e.g. '${{ inputs.max }}'). + # (optional) + # This field supports multiple formats (oneOf): + + # Option 1: integer + max: 1 + + # Option 2: GitHub Actions expression that resolves to an integer at runtime + max: "example-value" + + # GitHub token passed to called workflows. Overrides global github-token if + # specified. + # (optional) + github-token: "${{ secrets.GITHUB_TOKEN }}" + + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + + # Option 2: Shorthand array format: list of workflow names (without .md extension) + # to allow calling + call-workflow: [] + # Array items: string + # Enable AI agents to report when required MCP tools are unavailable. Used for # workflow diagnostics and tool discovery. # (optional) @@ -4311,6 +4694,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable missing tool reporting with default configuration missing-tool: null @@ -4357,6 +4745,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable missing data reporting with default configuration missing-data: null @@ -4393,6 +4786,11 @@ safe-outputs: # (optional) report-as-issue: true + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable noop output with default configuration (max: 1) noop: null @@ -4436,6 +4834,11 @@ safe-outputs: # (optional) github-token: "${{ secrets.GITHUB_TOKEN }}" + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable asset publishing with default configuration upload-asset: null @@ -4467,6 +4870,11 @@ safe-outputs: # (optional) footer: true + # If true, emit step summary messages instead of making GitHub API calls for this + # specific output type (preview mode) + # (optional) + staged: true + # Option 2: Enable release updates with default configuration update-release: null @@ -4490,22 +4898,20 @@ safe-outputs: # operations. # (optional) github-app: - # GitHub App ID. Should reference a variable (e.g., ${{ vars.APP_ID }}). + # GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token. app-id: "example-value" - # GitHub App private key. Should reference a secret (e.g., ${{ - # secrets.APP_PRIVATE_KEY }}). + # GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to + # mint a GitHub App token. private-key: "example-value" - # Optional: The owner of the GitHub App installation. If empty, defaults to the - # current repository owner. + # Optional owner of the GitHub App installation (defaults to current repository + # owner if not specified) # (optional) owner: "example-value" - # Optional: Comma or newline-separated list of repositories to grant access to. If - # owner is set and repositories is empty, access will be scoped to all - # repositories in the provided repository owner's installation. If owner and - # repositories are empty, access will be scoped to only the current repository. + # Optional list of repositories to grant access to (defaults to current repository + # if not specified) # (optional) repositories: [] # Array of strings @@ -4561,6 +4967,17 @@ safe-outputs: jobs: {} + # Inline JavaScript script handlers that run inside the consolidated safe-outputs + # job handler loop. Unlike 'jobs' (which create separate GitHub Actions jobs), + # scripts execute in-process alongside the built-in handlers. Users write only the + # body of the main function — the compiler wraps it with 'async function + # main(config = {}) { ... }' and 'module.exports = { main };' automatically. + # Script names containing dashes will be automatically normalized to underscores + # (e.g., 'post-slack-message' becomes 'post_slack_message'). + # (optional) + scripts: + {} + # Custom message templates for safe-output footer and notification messages. # Available placeholders: {workflow_name} (workflow name), {run_url} (GitHub # Actions run URL), {triggering_number} (issue/PR/discussion number), @@ -4796,6 +5213,15 @@ safe-outputs: # (optional) steps: [] + # Custom GitHub Actions to mount as once-callable MCP tools. Each action is + # resolved at compile time to derive its input schema from action.yml, and a + # guarded `uses:` step is injected in the safe_outputs job. Action names + # containing dashes will be automatically normalized to underscores (e.g., + # 'add-smoked-label' becomes 'add_smoked_label'). + # (optional) + actions: + {} + # Configuration for secret redaction behavior in workflow outputs and artifacts # (optional) secret-masking: @@ -4885,22 +5311,22 @@ runtimes: {} # Checkout configuration for the agent job. Controls how actions/checkout is -# invoked. Can be a single checkout configuration or an array for multiple -# checkouts. +# invoked. Can be a single checkout configuration, an array for multiple +# checkouts, or false to disable the default checkout step entirely (dev-mode +# checkouts are unaffected). # (optional) # This field supports multiple formats (oneOf): -# Option 1: Disable checkout entirely (no actions/checkout step is injected). -# Useful for workflows that access repositories via MCP servers or other -# mechanisms that do not require a local clone. -# checkout: false - -# Option 2: Single checkout configuration for the default workspace +# Option 1: Single checkout configuration for the default workspace -# Option 3: Multiple checkout configurations +# Option 2: Multiple checkout configurations checkout: [] # Array items: undefined +# Option 3: Set to false to disable the default checkout step. The agent job will +# not check out any repository (dev-mode checkouts are unaffected). +checkout: true + # APM package references to install. Supports array format (list of package slugs) # or object format with packages and isolated fields. # (optional) @@ -4921,6 +5347,65 @@ dependencies: # If true, agent restore step clears primitive dirs before unpacking. # (optional) isolated: true + + # GitHub App credentials for minting installation access tokens used by APM to + # access cross-org private repositories. + # (optional) + github-app: + # GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token. + app-id: "example-value" + + # GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to + # mint a GitHub App token. + private-key: "example-value" + + # Optional owner of the GitHub App installation (defaults to current repository + # owner if not specified) + # (optional) + owner: "example-value" + + # Optional list of repositories to grant access to (defaults to current repository + # if not specified) + # (optional) + repositories: [] + # Array of strings + + # Environment variables to set on the APM pack step (e.g., tokens or registry + # URLs). + # (optional) + env: + {} + + # GitHub token expression to authenticate APM with private package repositories. + # Uses cascading fallback (GH_AW_PLUGINS_TOKEN → GH_AW_GITHUB_TOKEN → + # GITHUB_TOKEN) when not specified. Takes effect unless github-app is also + # configured (which takes precedence). + # (optional) + github-token: "${{ secrets.GITHUB_TOKEN }}" + +# Top-level GitHub App configuration used as a fallback for all nested github-app +# token minting operations (on, safe-outputs, checkout, tools.github, +# dependencies). When a nested section does not define its own github-app, this +# top-level configuration is used automatically. +# (optional) +github-app: + # GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token. + app-id: "example-value" + + # GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to + # mint a GitHub App token. + private-key: "example-value" + + # Optional owner of the GitHub App installation (defaults to current repository + # owner if not specified) + # (optional) + owner: "example-value" + + # Optional list of repositories to grant access to (defaults to current repository + # if not specified) + # (optional) + repositories: [] + # Array of strings --- ``` diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index 7c5f5cf5acd..94eaf8de259 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -2651,10 +2651,12 @@ }, "command": { "type": "string", + "x-internal": true, "description": "Custom command to replace the default AWF installation. For AWF: 'docker run my-custom-awf-image'" }, "args": { "type": "array", + "x-internal": true, "description": "Additional arguments to append to the command (applies to AWF, for standard and custom commands)", "items": { "type": "string" @@ -2662,6 +2664,7 @@ }, "env": { "type": "object", + "x-internal": true, "description": "Environment variables to set on the execution step (applies to AWF)", "additionalProperties": { "type": "string" @@ -2792,21 +2795,25 @@ "properties": { "container": { "type": "string", + "x-internal": true, "pattern": "^[a-zA-Z0-9][a-zA-Z0-9/:_.-]*$", "description": "Container image for the MCP gateway executable (required)" }, "version": { "type": ["string", "number"], + "x-internal": true, "description": "Optional version/tag for the container image (e.g., 'latest', 'v1.0.0')", "examples": ["latest", "v1.0.0"] }, "entrypoint": { "type": "string", + "x-internal": true, "description": "Optional custom entrypoint for the MCP gateway container. Overrides the container's default entrypoint.", "examples": ["/bin/bash", "/custom/start.sh", "/usr/bin/env"] }, "args": { "type": "array", + "x-internal": true, "items": { "type": "string" }, @@ -2814,6 +2821,7 @@ }, "entrypointArgs": { "type": "array", + "x-internal": true, "items": { "type": "string" }, diff --git a/pkg/workflow/compiler_orchestrator_engine.go b/pkg/workflow/compiler_orchestrator_engine.go index f1624176af5..8f2c4073578 100644 --- a/pkg/workflow/compiler_orchestrator_engine.go +++ b/pkg/workflow/compiler_orchestrator_engine.go @@ -294,6 +294,14 @@ func (c *Compiler) setupEngineAndImports(result *parser.FrontmatterResult, clean return nil, err } + // Validate that internal sandbox customization fields are not used in strict mode + orchestratorEngineLog.Printf("Validating strict sandbox customization (strict=%v)", c.strictMode) + if err := c.validateStrictSandboxCustomization(sandboxConfig); err != nil { + orchestratorEngineLog.Printf("Strict sandbox customization validation failed: %v", err) + c.strictMode = initialStrictModeForFirewall + return nil, err + } + // Check if the engine supports network restrictions when they are defined if err := c.checkNetworkSupport(agenticEngine, networkPermissions); err != nil { orchestratorEngineLog.Printf("Network support check failed: %v", err) diff --git a/pkg/workflow/mcp_gateway_entrypoint_mounts_e2e_test.go b/pkg/workflow/mcp_gateway_entrypoint_mounts_e2e_test.go index 44827c430c4..6212ca6beca 100644 --- a/pkg/workflow/mcp_gateway_entrypoint_mounts_e2e_test.go +++ b/pkg/workflow/mcp_gateway_entrypoint_mounts_e2e_test.go @@ -19,6 +19,7 @@ func TestMCPGatewayEntrypointE2E(t *testing.T) { markdown := `--- on: workflow_dispatch engine: copilot +strict: false sandbox: mcp: container: ghcr.io/github/gh-aw-mcpg @@ -74,6 +75,7 @@ func TestMCPGatewayMountsE2E(t *testing.T) { markdown := `--- on: workflow_dispatch engine: copilot +strict: false sandbox: mcp: container: ghcr.io/github/gh-aw-mcpg @@ -121,6 +123,7 @@ func TestMCPGatewayEntrypointAndMountsE2E(t *testing.T) { markdown := `--- on: workflow_dispatch engine: copilot +strict: false sandbox: mcp: container: ghcr.io/github/gh-aw-mcpg @@ -223,6 +226,7 @@ func TestMCPGatewayEntrypointWithSpecialCharacters(t *testing.T) { markdown := `--- on: workflow_dispatch engine: copilot +strict: false sandbox: mcp: container: ghcr.io/github/gh-aw-mcpg @@ -274,6 +278,7 @@ func TestMCPGatewayMountsWithVariables(t *testing.T) { markdown := `--- on: workflow_dispatch engine: copilot +strict: false sandbox: mcp: container: ghcr.io/github/gh-aw-mcpg diff --git a/pkg/workflow/sandbox_custom_agent_test.go b/pkg/workflow/sandbox_custom_agent_test.go index f108b24ca5f..1a00ef9830b 100644 --- a/pkg/workflow/sandbox_custom_agent_test.go +++ b/pkg/workflow/sandbox_custom_agent_test.go @@ -254,6 +254,7 @@ sandbox: on: workflow_dispatch: engine: copilot +strict: false sandbox: agent: id: awf diff --git a/pkg/workflow/strict_mode_sandbox_validation.go b/pkg/workflow/strict_mode_sandbox_validation.go new file mode 100644 index 00000000000..46881adb6b0 --- /dev/null +++ b/pkg/workflow/strict_mode_sandbox_validation.go @@ -0,0 +1,72 @@ +// This file contains strict mode sandbox customization validation. +// +// It enforces that internal-only sandbox fields (AWF agent customization and +// MCP gateway customization) cannot be configured when strict mode is enabled. + +package workflow + +import "fmt" + +// internalSandboxFieldError returns a standardised strict-mode error for an +// internal sandbox field that must not be configured by end users. +func internalSandboxFieldError(fieldPath string) error { + return fmt.Errorf( + "strict mode: '%s' is not allowed because it is an internal implementation detail. "+ + "Remove '%s' or set 'strict: false' to disable strict mode. "+ + "See: https://github.github.com/gh-aw/reference/sandbox/", + fieldPath, fieldPath, + ) +} + +// validateStrictSandboxCustomization refuses internal sandbox customization fields in strict mode. +// +// The following fields are considered internal implementation/debugging details and +// are not allowed in strict mode: +// - sandbox.agent.command, sandbox.agent.args, sandbox.agent.env (AWF customization) +// - sandbox.mcp.container, sandbox.mcp.version, sandbox.mcp.entrypoint, +// sandbox.mcp.args, sandbox.mcp.entrypointArgs (MCP gateway customization) +func (c *Compiler) validateStrictSandboxCustomization(sandboxConfig *SandboxConfig) error { + if !c.strictMode { + strictModeValidationLog.Printf("Strict mode disabled, skipping sandbox customization validation") + return nil + } + + if sandboxConfig == nil { + return nil + } + + // Check agent sandbox internal fields + if agent := sandboxConfig.Agent; agent != nil { + if agent.Command != "" { + return internalSandboxFieldError("sandbox.agent.command") + } + if len(agent.Args) > 0 { + return internalSandboxFieldError("sandbox.agent.args") + } + if len(agent.Env) > 0 { + return internalSandboxFieldError("sandbox.agent.env") + } + } + + // Check MCP gateway internal fields + if mcp := sandboxConfig.MCP; mcp != nil { + if mcp.Container != "" { + return internalSandboxFieldError("sandbox.mcp.container") + } + if mcp.Version != "" { + return internalSandboxFieldError("sandbox.mcp.version") + } + if mcp.Entrypoint != "" { + return internalSandboxFieldError("sandbox.mcp.entrypoint") + } + if len(mcp.Args) > 0 { + return internalSandboxFieldError("sandbox.mcp.args") + } + if len(mcp.EntrypointArgs) > 0 { + return internalSandboxFieldError("sandbox.mcp.entrypointArgs") + } + } + + strictModeValidationLog.Printf("Sandbox customization validation passed") + return nil +} diff --git a/pkg/workflow/strict_mode_sandbox_validation_test.go b/pkg/workflow/strict_mode_sandbox_validation_test.go new file mode 100644 index 00000000000..73c07916593 --- /dev/null +++ b/pkg/workflow/strict_mode_sandbox_validation_test.go @@ -0,0 +1,184 @@ +//go:build !integration + +package workflow + +import ( + "strings" + "testing" +) + +// TestValidateStrictSandboxCustomization tests that internal sandbox fields are +// rejected in strict mode. +func TestValidateStrictSandboxCustomization(t *testing.T) { + tests := []struct { + name string + sandbox *SandboxConfig + expectError bool + errorMsg string + }{ + { + name: "nil sandbox config is allowed", + sandbox: nil, + expectError: false, + }, + { + name: "basic awf sandbox without customization is allowed", + sandbox: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + ID: "awf", + }, + }, + expectError: false, + }, + { + name: "sandbox.agent.command is rejected", + sandbox: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + ID: "awf", + Command: "/usr/local/bin/custom-awf", + }, + }, + expectError: true, + errorMsg: "strict mode: 'sandbox.agent.command' is not allowed because it is an internal implementation detail", + }, + { + name: "sandbox.agent.args is rejected", + sandbox: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + ID: "awf", + Args: []string{"--debug"}, + }, + }, + expectError: true, + errorMsg: "strict mode: 'sandbox.agent.args' is not allowed because it is an internal implementation detail", + }, + { + name: "sandbox.agent.env is rejected", + sandbox: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + ID: "awf", + Env: map[string]string{"DEBUG": "true"}, + }, + }, + expectError: true, + errorMsg: "strict mode: 'sandbox.agent.env' is not allowed because it is an internal implementation detail", + }, + { + name: "sandbox.mcp.container is rejected", + sandbox: &SandboxConfig{ + MCP: &MCPGatewayRuntimeConfig{ + Container: "ghcr.io/example/gateway", + }, + }, + expectError: true, + errorMsg: "strict mode: 'sandbox.mcp.container' is not allowed because it is an internal implementation detail", + }, + { + name: "sandbox.mcp.version is rejected", + sandbox: &SandboxConfig{ + MCP: &MCPGatewayRuntimeConfig{ + Version: "v1.0.0", + }, + }, + expectError: true, + errorMsg: "strict mode: 'sandbox.mcp.version' is not allowed because it is an internal implementation detail", + }, + { + name: "sandbox.mcp.entrypoint is rejected", + sandbox: &SandboxConfig{ + MCP: &MCPGatewayRuntimeConfig{ + Entrypoint: "/custom/start.sh", + }, + }, + expectError: true, + errorMsg: "strict mode: 'sandbox.mcp.entrypoint' is not allowed because it is an internal implementation detail", + }, + { + name: "sandbox.mcp.args is rejected", + sandbox: &SandboxConfig{ + MCP: &MCPGatewayRuntimeConfig{ + Args: []string{"--verbose"}, + }, + }, + expectError: true, + errorMsg: "strict mode: 'sandbox.mcp.args' is not allowed because it is an internal implementation detail", + }, + { + name: "sandbox.mcp.entrypointArgs is rejected", + sandbox: &SandboxConfig{ + MCP: &MCPGatewayRuntimeConfig{ + EntrypointArgs: []string{"--listen", "0.0.0.0:8000"}, + }, + }, + expectError: true, + errorMsg: "strict mode: 'sandbox.mcp.entrypointArgs' is not allowed because it is an internal implementation detail", + }, + { + name: "sandbox.mcp with only allowed fields is permitted", + sandbox: &SandboxConfig{ + MCP: &MCPGatewayRuntimeConfig{ + Port: 8080, + APIKey: "${{ secrets.MCP_KEY }}", + }, + }, + expectError: false, + }, + { + name: "sandbox.agent.mounts is allowed (not an internal field)", + sandbox: &SandboxConfig{ + Agent: &AgentSandboxConfig{ + ID: "awf", + Mounts: []string{"/host/data:/data:ro"}, + }, + }, + expectError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + compiler := NewCompiler() + compiler.strictMode = true + + err := compiler.validateStrictSandboxCustomization(tt.sandbox) + + if tt.expectError && err == nil { + t.Error("Expected validation to fail but it succeeded") + } else if !tt.expectError && err != nil { + t.Errorf("Expected validation to succeed but it failed: %v", err) + } else if tt.expectError && err != nil && tt.errorMsg != "" { + if !strings.Contains(err.Error(), tt.errorMsg) { + t.Errorf("Expected error containing %q, got %q", tt.errorMsg, err.Error()) + } + } + }) + } +} + +// TestValidateStrictSandboxCustomizationNonStrictMode verifies that internal fields +// are not rejected when strict mode is disabled. +func TestValidateStrictSandboxCustomizationNonStrictMode(t *testing.T) { + compiler := NewCompiler() + compiler.strictMode = false + + sandbox := &SandboxConfig{ + Agent: &AgentSandboxConfig{ + ID: "awf", + Command: "/custom/awf", + Args: []string{"--debug"}, + Env: map[string]string{"LOG": "verbose"}, + }, + MCP: &MCPGatewayRuntimeConfig{ + Container: "ghcr.io/example/gateway", + Version: "latest", + Entrypoint: "/bin/sh", + Args: []string{"--rm"}, + EntrypointArgs: []string{"--listen", "0.0.0.0"}, + }, + } + + err := compiler.validateStrictSandboxCustomization(sandbox) + if err != nil { + t.Errorf("Expected non-strict mode to allow all sandbox fields, got error: %v", err) + } +} diff --git a/scripts/generate-schema-docs.js b/scripts/generate-schema-docs.js index 6c113c44d44..3e8d7e98bb4 100755 --- a/scripts/generate-schema-docs.js +++ b/scripts/generate-schema-docs.js @@ -274,6 +274,11 @@ function generateProperties(properties, required = [], indent = 0) { return; } + // Skip internal-only properties (marked with "x-internal": true in the schema). + // These are implementation/debugging details not intended for end users. + if (resolvedProp["x-internal"] === true) { + return; + } if (addedCount > 0) { lines.push(""); } From 75ff6996a567766b6795e8f5760778ba0aeb6594 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:29:24 +0000 Subject: [PATCH 4/6] fix: address review comments - schema required/x-internal conflict, boolean variant docs Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/gh-aw/sessions/e4724ceb-85c4-4356-a097-03d500ec8c60 --- docs/src/content/docs/reference/frontmatter-full.md | 6 +++--- pkg/parser/schemas/main_workflow_schema.json | 1 - scripts/generate-schema-docs.js | 9 +++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index 6eae8f2e1e0..af654b0673b 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -2359,7 +2359,7 @@ safe-outputs: expires: "example-value" # Option 3: Set to false to explicitly disable expiration - expires: true + expires: false # If true, group issues as sub-issues under a parent issue. The workflow ID is # used as the group identifier. Parent issues are automatically created and @@ -2860,7 +2860,7 @@ safe-outputs: expires: "example-value" # Option 3: Set to false to explicitly disable expiration - expires: true + expires: false # GitHub token to use for this specific output type. Overrides global github-token # if specified. @@ -5318,7 +5318,7 @@ checkout: [] # Option 3: Set to false to disable the default checkout step. The agent job will # not check out any repository (dev-mode checkouts are unaffected). -checkout: true +checkout: false # APM package references to install. Supports array format (list of package slugs) # or object format with packages and isolated fields. diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index ac41948ecee..80bb42405b1 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -2864,7 +2864,6 @@ "description": "Gateway domain for URL generation (default: 'host.docker.internal' when agent is enabled, 'localhost' when disabled)" } }, - "required": ["container"], "additionalProperties": false } }, diff --git a/scripts/generate-schema-docs.js b/scripts/generate-schema-docs.js index 3e8d7e98bb4..18f3dd86087 100755 --- a/scripts/generate-schema-docs.js +++ b/scripts/generate-schema-docs.js @@ -188,7 +188,8 @@ function generateVariants(prop, propName, indent = 0, required = []) { lines.push(formatComment(`Array items: ${variant.items.description || variant.items.type}`, indent + 2)); } } else if (variant.type === "boolean") { - lines.push(`${indentStr}${propName}: true`); + const boolExample = getExampleValue(variant, propName); + lines.push(`${indentStr}${propName}: ${boolExample}`); } else if (variant.type === "null") { lines.push(`${indentStr}${propName}: null`); } else if (variant.type === "number" || variant.type === "integer") { @@ -276,15 +277,15 @@ function generateProperties(properties, required = [], indent = 0) { // Skip internal-only properties (marked with "x-internal": true in the schema). // These are implementation/debugging details not intended for end users. - if (resolvedProp["x-internal"] === true) { + // Required fields are still rendered so that generated YAML examples remain schema-valid. + const isRequired = required.includes(propName); + if (resolvedProp["x-internal"] === true && !isRequired) { return; } if (addedCount > 0) { lines.push(""); } - const isRequired = required.includes(propName); - // Check if property has variants if (resolvedProp.oneOf || resolvedProp.anyOf) { lines.push(generateVariants(resolvedProp, propName, indent, required)); From c40d97c5d9a02a1fc22b4db199946ece14a9bd62 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Sun, 22 Mar 2026 20:59:39 +0000 Subject: [PATCH 5/6] fix: update repository references from githubnext to github in workflow files --- .../constraint-solving-potd.lock.yml | 2 +- .github/workflows/constraint-solving-potd.md | 4 +-- .github/workflows/contribution-check.lock.yml | 2 +- .github/workflows/contribution-check.md | 4 +-- .../daily-architecture-diagram.lock.yml | 2 +- .../workflows/daily-architecture-diagram.md | 6 ++-- .../smoke-create-cross-repo-pr.lock.yml | 28 +++++++++---------- .../workflows/smoke-create-cross-repo-pr.md | 12 ++++---- .../smoke-update-cross-repo-pr.lock.yml | 24 ++++++++-------- .../workflows/smoke-update-cross-repo-pr.md | 10 +++---- 10 files changed, 47 insertions(+), 47 deletions(-) diff --git a/.github/workflows/constraint-solving-potd.lock.yml b/.github/workflows/constraint-solving-potd.lock.yml index 6f4a8809212..534e69e24fb 100644 --- a/.github/workflows/constraint-solving-potd.lock.yml +++ b/.github/workflows/constraint-solving-potd.lock.yml @@ -21,7 +21,7 @@ # For more information: https://github.github.com/gh-aw/introduction/overview/ # # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"8b8e7739047a7e1a0c6540f7574b93437f0a2b7607c424e28a72fd5745c56be5","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b614d2b177f891f2474ec04ef2dadf47a16142bc2933d8a36a8e165870fae677","strict":true,"agent_id":"copilot"} name: "Constraint Solving — Problem of the Day" "on": diff --git a/.github/workflows/constraint-solving-potd.md b/.github/workflows/constraint-solving-potd.md index 87b79c4a1b8..41af9d795b5 100644 --- a/.github/workflows/constraint-solving-potd.md +++ b/.github/workflows/constraint-solving-potd.md @@ -18,7 +18,7 @@ safe-outputs: title-prefix: "🧩 Constraint Solving POTD:" labels: [constraint-solving, problem-of-the-day] close-older-discussions: true - expires: 7 + expires: 7d --- # Constraint Solving — Problem of the Day @@ -116,4 +116,4 @@ List 2–4 seminal or accessible references: When you have written the problem discussion, post it using `create-discussion`. -If today's category was recently covered and you cannot find a sufficiently different problem, call `noop` with an explanation of why you skipped. +If today's category was recently covered and you cannot find a sufficiently different problem, call `noop` with an explanation of why you skipped. \ No newline at end of file diff --git a/.github/workflows/contribution-check.lock.yml b/.github/workflows/contribution-check.lock.yml index 2d9d2508248..5a0e0096737 100644 --- a/.github/workflows/contribution-check.lock.yml +++ b/.github/workflows/contribution-check.lock.yml @@ -21,7 +21,7 @@ # For more information: https://github.github.com/gh-aw/introduction/overview/ # # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"23a89d50ad95694dbbfba8c7872a41f03697c87526de949a7725c12497d05d1c","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"a483a637eae7d8a0f5a045245c6f5d72ec408dd470865a2cd889122b1ac18680","strict":true,"agent_id":"copilot"} name: "Contribution Check" "on": diff --git a/.github/workflows/contribution-check.md b/.github/workflows/contribution-check.md index c26f2c6b529..09da9119f85 100644 --- a/.github/workflows/contribution-check.md +++ b/.github/workflows/contribution-check.md @@ -23,7 +23,7 @@ safe-outputs: labels: - contribution-report close-older-issues: true - expires: 1 + expires: 1d add-labels: allowed: [spam, needs-work, outdated, lgtm] max: 4 @@ -185,4 +185,4 @@ If any subagent call failed (❓), also apply `outdated`. ```json {"noop": {"message": "No action needed: [brief explanation of what was analyzed and why]"}} -``` +``` \ No newline at end of file diff --git a/.github/workflows/daily-architecture-diagram.lock.yml b/.github/workflows/daily-architecture-diagram.lock.yml index 6e3454f07f3..c161c1e09c1 100644 --- a/.github/workflows/daily-architecture-diagram.lock.yml +++ b/.github/workflows/daily-architecture-diagram.lock.yml @@ -26,7 +26,7 @@ # Imports: # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"15c319e318a6b9de87fc6b5acd2a3c80463bb2ac5970875c00ce5325d428a71d","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"219c5898fd299f2ed4fb902a027b8acdc19ea0405f85f6af82d20abc1a27a076","strict":true,"agent_id":"copilot"} name: "Architecture Diagram Generator" "on": diff --git a/.github/workflows/daily-architecture-diagram.md b/.github/workflows/daily-architecture-diagram.md index 3f8364e5aec..e48def3bb9c 100644 --- a/.github/workflows/daily-architecture-diagram.md +++ b/.github/workflows/daily-architecture-diagram.md @@ -22,10 +22,10 @@ safe-outputs: title-prefix: "🏗️ Architecture Diagram:" labels: [architecture, diagram] close-older-issues: true - expires: 7 + expires: 7d max: 1 create-pull-request: - expires: 7 + expires: 7d title-prefix: "[architecture] " labels: [architecture, diagram, documentation] noop: @@ -207,4 +207,4 @@ This diagram shows the package structure and dependencies of the `gh-aw` codebas ```` - When the diagram **changes**: update `scratchpad/architecture.md` via `create_pull_request` with a PR titled `[architecture] Update architecture diagram - `. -- When the diagram is **unchanged** (noop path): skip the scratchpad update entirely. +- When the diagram is **unchanged** (noop path): skip the scratchpad update entirely. \ No newline at end of file diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index 9d2f748e442..b819502f416 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -20,9 +20,9 @@ # # For more information: https://github.github.com/gh-aw/introduction/overview/ # -# Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo +# Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"23144cc5cfaff8c43f78aeac9193fc954d2391a4d6fc0207772ebb4127c0ad56","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"65c1c88218bd8753bc2cf126b203276b895f77cab886d5e031b4f7a9fae628aa","strict":true,"agent_id":"copilot"} name: "Smoke Create Cross-Repo PR" "on": @@ -135,7 +135,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_WORKFLOW_NAME: "Smoke Create Cross-Repo PR" - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" + GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -199,7 +199,7 @@ jobs: - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ {{/if}} - **checkouts**: The following repositories have been checked out and are available in the workspace: - - `$GITHUB_WORKSPACE` → `githubnext/gh-aw-side-repo` (cwd) [shallow clone, fetch-depth=1 (default)] + - `$GITHUB_WORKSPACE` → `github/gh-aw-side-repo` (cwd) [shallow clone, fetch-depth=1 (default)] - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). @@ -325,11 +325,11 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Checkout githubnext/gh-aw-side-repo + - name: Checkout github/gh-aw-side-repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - repository: githubnext/gh-aw-side-repo + repository: github/gh-aw-side-repo token: ${{ secrets.GH_AW_SIDE_REPO_PAT }} - name: Create gh-aw temp directory run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh @@ -387,7 +387,7 @@ jobs: mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF' - {"add_comment":{"max":2},"create_issue":{"expires":2,"max":1},"create_pull_request":{"draft":true,"expires":24,"fallback_as_issue":false,"max":1,"target-repo":"githubnext/gh-aw-side-repo","title_prefix":"[smoke] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}} + {"add_comment":{"max":2},"create_issue":{"expires":2,"max":1},"create_pull_request":{"draft":true,"expires":24,"fallback_as_issue":false,"max":1,"target-repo":"github/gh-aw-side-repo","title_prefix":"[smoke] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}} GH_AW_SAFE_OUTPUTS_CONFIG_EOF - name: Write Safe Outputs Tools run: | @@ -871,7 +871,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: WORKFLOW_NAME: "Smoke Create Cross-Repo PR" - WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo" + WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo" HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }} with: script: | @@ -1046,7 +1046,7 @@ jobs: GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }} - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" + GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" GH_AW_GROUP_REPORTS: "false" GH_AW_FAILURE_REPORT_AS_ISSUE: "true" GH_AW_TIMEOUT_MINUTES: "10" @@ -1099,7 +1099,7 @@ jobs: GH_AW_WORKFLOW_NAME: "Smoke Create Cross-Repo PR" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.agent.outputs.detection_conclusion }} - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" + GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1158,7 +1158,7 @@ jobs: env: GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/smoke-create-cross-repo-pr" GH_AW_ENGINE_ID: "copilot" - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" + GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" GH_AW_WORKFLOW_ID: "smoke-create-cross-repo-pr" GH_AW_WORKFLOW_NAME: "Smoke Create Cross-Repo PR" outputs: @@ -1210,7 +1210,7 @@ jobs: if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - repository: githubnext/gh-aw-side-repo + repository: github/gh-aw-side-repo ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }} token: ${{ secrets.GH_AW_SIDE_REPO_PAT }} persist-credentials: false @@ -1218,7 +1218,7 @@ jobs: - name: Configure Git credentials if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') env: - REPO_NAME: "githubnext/gh-aw-side-repo" + REPO_NAME: "github/gh-aw-side-repo" SERVER_URL: ${{ github.server_url }} GIT_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }} run: | @@ -1245,7 +1245,7 @@ jobs: GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,127.0.0.1,::1,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,app.renovatebot.com,appveyor.com,archive.ubuntu.com,azure.archive.ubuntu.com,badgen.net,circleci.com,codacy.com,codeclimate.com,codecov.io,codeload.github.com,coveralls.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deepsource.io,docs.github.com,drone.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,img.shields.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,localhost,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,readthedocs.io,readthedocs.org,registry.npmjs.org,renovatebot.com,s.symcb.com,s.symcd.com,security.ubuntu.com,semaphoreci.com,shields.io,snyk.io,sonarcloud.io,sonarqube.com,telemetry.enterprise.githubcopilot.com,travis-ci.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request\":{\"draft\":true,\"expires\":24,\"fallback_as_issue\":false,\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"labels\":[\"smoke-test\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target-repo\":\"githubnext/gh-aw-side-repo\",\"title_prefix\":\"[smoke] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"create_pull_request\":{\"draft\":true,\"expires\":24,\"fallback_as_issue\":false,\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"labels\":[\"smoke-test\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target-repo\":\"github/gh-aw-side-repo\",\"title_prefix\":\"[smoke] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} GITHUB_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }} with: diff --git a/.github/workflows/smoke-create-cross-repo-pr.md b/.github/workflows/smoke-create-cross-repo-pr.md index b5df9fba6a2..dbc0c647816 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.md +++ b/.github/workflows/smoke-create-cross-repo-pr.md @@ -1,6 +1,6 @@ --- name: Smoke Create Cross-Repo PR -description: Smoke test validating cross-repo pull request creation in githubnext/gh-aw-side-repo +description: Smoke test validating cross-repo pull request creation in github/gh-aw-side-repo on: schedule: every 12h workflow_dispatch: @@ -20,7 +20,7 @@ network: - github checkout: - - repository: githubnext/gh-aw-side-repo + - repository: github/gh-aw-side-repo github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }} tools: @@ -34,7 +34,7 @@ tools: safe-outputs: allowed-domains: [default-safe-outputs] create-pull-request: - target-repo: "githubnext/gh-aw-side-repo" + target-repo: "github/gh-aw-side-repo" github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }} title-prefix: "[smoke] " labels: [smoke-test] @@ -51,8 +51,8 @@ safe-outputs: max: 2 messages: footer: "> 🔬 *Cross-repo smoke test by [{workflow_name}]({run_url})*{history_link}" - run-started: "🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in githubnext/gh-aw-side-repo..." - run-success: "✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in githubnext/gh-aw-side-repo!" + run-started: "🔬 [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo..." + run-success: "✅ [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!" run-failure: "❌ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}" timeout-minutes: 10 @@ -107,4 +107,4 @@ Status: cross-repo PR creation smoke test - "Smoke Test: Copilot - Cross-repo create PR ${{ github.run_id }}" - The line that was added to the cross-repo PR - Overall status: SUCCESS - - Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + - Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \ No newline at end of file diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index f34a3c71c2d..15ece41a700 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -20,9 +20,9 @@ # # For more information: https://github.github.com/gh-aw/introduction/overview/ # -# Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README +# Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"1b83093f25431da3943130e4dc7707a88b79a2f8454e38a5773f5f5031b6b1d2","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b2779782e046af3e7d6bf341c0986e2981403799645d57898bd72ae136f133df","strict":true,"agent_id":"copilot"} name: "Smoke Update Cross-Repo PR" "on": @@ -135,7 +135,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_WORKFLOW_NAME: "Smoke Update Cross-Repo PR" - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" + GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -200,7 +200,7 @@ jobs: - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ {{/if}} - **checkouts**: The following repositories have been checked out and are available in the workspace: - - `$GITHUB_WORKSPACE` → `githubnext/gh-aw-side-repo` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: main, refs/pulls/open/*] + - `$GITHUB_WORKSPACE` → `github/gh-aw-side-repo` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: main, refs/pulls/open/*] - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). @@ -332,14 +332,14 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Checkout githubnext/gh-aw-side-repo + - name: Checkout github/gh-aw-side-repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - repository: githubnext/gh-aw-side-repo + repository: github/gh-aw-side-repo token: ${{ secrets.GH_AW_SIDE_REPO_PAT }} fetch-depth: 0 - - name: Fetch additional refs for githubnext/gh-aw-side-repo + - name: Fetch additional refs for github/gh-aw-side-repo env: GH_AW_FETCH_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }} run: | @@ -884,7 +884,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: WORKFLOW_NAME: "Smoke Update Cross-Repo PR" - WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README" + WORKFLOW_DESCRIPTION: "Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README" HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }} with: script: | @@ -1060,7 +1060,7 @@ jobs: GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }} - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" + GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" GH_AW_GROUP_REPORTS: "false" GH_AW_FAILURE_REPORT_AS_ISSUE: "true" GH_AW_TIMEOUT_MINUTES: "10" @@ -1099,7 +1099,7 @@ jobs: GH_AW_WORKFLOW_NAME: "Smoke Update Cross-Repo PR" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.agent.outputs.detection_conclusion }} - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" + GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | @@ -1158,7 +1158,7 @@ jobs: env: GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/smoke-update-cross-repo-pr" GH_AW_ENGINE_ID: "copilot" - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" + GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}\",\"runStarted\":\"📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" GH_AW_WORKFLOW_ID: "smoke-update-cross-repo-pr" GH_AW_WORKFLOW_NAME: "Smoke Update Cross-Repo PR" outputs: @@ -1244,7 +1244,7 @@ jobs: GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,127.0.0.1,::1,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,app.renovatebot.com,appveyor.com,archive.ubuntu.com,azure.archive.ubuntu.com,badgen.net,circleci.com,codacy.com,codeclimate.com,codecov.io,codeload.github.com,coveralls.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deepsource.io,docs.github.com,drone.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,img.shields.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,localhost,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,readthedocs.io,readthedocs.org,registry.npmjs.org,renovatebot.com,s.symcb.com,s.symcd.com,security.ubuntu.com,semaphoreci.com,shields.io,snyk.io,sonarcloud.io,sonarqube.com,telemetry.enterprise.githubcopilot.com,travis-ci.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"1\",\"target-repo\":\"githubnext/gh-aw-side-repo\"}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"labels\":[\"automation\",\"testing\"],\"max\":1},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"github-token\":\"${{ secrets.GH_AW_SIDE_REPO_PAT }}\",\"if_no_changes\":\"error\",\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"1\",\"target-repo\":\"github/gh-aw-side-repo\"}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} GITHUB_TOKEN: ${{ secrets.GH_AW_SIDE_REPO_PAT }} with: diff --git a/.github/workflows/smoke-update-cross-repo-pr.md b/.github/workflows/smoke-update-cross-repo-pr.md index 4da7a8103d1..91cd3d2486e 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.md +++ b/.github/workflows/smoke-update-cross-repo-pr.md @@ -1,6 +1,6 @@ --- name: Smoke Update Cross-Repo PR -description: Smoke test validating cross-repo pull request updates in githubnext/gh-aw-side-repo by adding lines from Homer's Odyssey to the README +description: Smoke test validating cross-repo pull request updates in github/gh-aw-side-repo by adding lines from Homer's Odyssey to the README on: schedule: every 12h @@ -21,7 +21,7 @@ network: - github checkout: - - repository: githubnext/gh-aw-side-repo + - repository: github/gh-aw-side-repo github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }} fetch: ["main", "refs/pulls/open/*"] # fetch all open PR refs after checkout fetch-depth: 0 # fetch full history to ensure we can see all commits and PR details @@ -45,13 +45,13 @@ safe-outputs: hide-older-comments: true max: 2 push-to-pull-request-branch: - target-repo: "githubnext/gh-aw-side-repo" + target-repo: "github/gh-aw-side-repo" github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }} if-no-changes: "error" target: "1" # PR #1 messages: footer: "> 📜 *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{history_link}" - run-started: "📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to githubnext/gh-aw-side-repo PR #1..." + run-started: "📜 [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1..." run-success: "✅ [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!" run-failure: "❌ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}" @@ -94,4 +94,4 @@ Mark this step ✅ if the checkout succeeds, ❌ otherwise. - "Smoke Test: Copilot - Cross-repo update PR ${{ github.run_id }}" - The line that was added to the cross-repo PR - Overall status: SUCCESS - - Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + - Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \ No newline at end of file From b7eff910ea6177b4de50d7981e91578bf859f452 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 21:08:20 +0000 Subject: [PATCH 6/6] fix: add strict: false to integration tests using sandbox.mcp.container; update pinned commit Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/gh-aw/sessions/a3dc739a-cc65-422c-bfa3-73b3eeca1a83 --- pkg/cli/add_integration_test.go | 7 +++---- pkg/workflow/mcp_setup_generator_test.go | 4 ++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/cli/add_integration_test.go b/pkg/cli/add_integration_test.go index 915e433b38e..d517cfc21af 100644 --- a/pkg/cli/add_integration_test.go +++ b/pkg/cli/add_integration_test.go @@ -979,10 +979,9 @@ func TestAddWorkflowWithDispatchWorkflowFromSharedImport(t *testing.T) { // workflow). The fetcher falls back to .yml when .md is 404, so both the main // workflow and the dispatch-workflow dependency are written to disk. // - // Note: pinned to a specific commit SHA from the branch that renamed - // allowed-url-domains → allowed-domains (schema change). Update to @main once - // that change has been merged. - workflowSpec := "github/gh-aw/.github/workflows/smoke-copilot.md@c93eec8" + // Note: pinned to a specific commit SHA that includes strict: false in smoke-copilot.md + // (required since sandbox.mcp.container is now blocked in strict mode). + workflowSpec := "github/gh-aw/.github/workflows/smoke-copilot.md@c40d97c" cmd := exec.Command(setup.binaryPath, "add", workflowSpec, "--verbose") cmd.Dir = setup.tempDir diff --git a/pkg/workflow/mcp_setup_generator_test.go b/pkg/workflow/mcp_setup_generator_test.go index df3904f01f5..0680d32ae0e 100644 --- a/pkg/workflow/mcp_setup_generator_test.go +++ b/pkg/workflow/mcp_setup_generator_test.go @@ -245,6 +245,7 @@ func TestMCPGatewayVersionParsedFromSource(t *testing.T) { frontmatter: `--- on: issues engine: claude +strict: false sandbox: mcp: container: ghcr.io/github/gh-aw-mcpg @@ -281,6 +282,7 @@ Test workflow without sandbox.mcp.version specified.`, frontmatter: `--- on: issues engine: claude +strict: false sandbox: mcp: container: ghcr.io/github/gh-aw-mcpg @@ -301,6 +303,7 @@ Test workflow with version: latest.`, frontmatter: `--- on: issues engine: claude +strict: false sandbox: mcp: container: ghcr.io/github/gh-aw-mcpg @@ -321,6 +324,7 @@ Test workflow with version 1.2.3.`, frontmatter: `--- on: issues engine: claude +strict: false sandbox: mcp: container: ghcr.io/custom/gateway