Skip to content

Support deployment: false on environment (top-level and safe-outputs.environment) #73200

Closed

Description

@ekbritecore

Analysis

GitHub Actions can now reference an environment without creating a deployment: environment: { name: <env>, deployment: false } (changelog, March 2026; docs: "Using environments without deployments"). The job keeps the environment's secrets and protection rules (branch policy, required reviewers, wait timers), but no deployment object is created. deployment also accepts an expression, e.g. deployment: ${{ github.ref_name == 'main' }}.

gh-aw can't express it. In v0.93.5 and v1.0.1, pkg/parser/schemas/main_workflow_schema.json allows environment (top-level), safe-outputs.environment and jobs.<id>.environment to be either a string or an object with only name and url. Adding deployment: false is rejected and compilation fails:

safe-outputs:
  environment:
    name: my-protected-env
    deployment: false
✗ compilation failed

The compiler itself already passes the object through as raw YAML:

  • safe_outputs_config_global.go (around line 290): config.Environment = c.extractTopLevelYAMLSection(outputMap, "environment");
  • workflow_builder_frontmatter_extract.go (around line 181): workflowData.Environment = c.extractTopLevelYAMLSection(frontmatter, "environment").

The only blocker therefore appears to be the schema.

Use case. A common pattern uses an environment only to gate a write credential, not to deploy. For example, an agentic workflow keeps a token for an external write API as environment secrets, on an environment whose branch policy allows only the default branch. The safe-output job that performs the write declares safe-outputs.environment, so a run started from an unreviewed branch can't reach the credential. Today every run creates a GitHub deployment:

  • a scheduled agentic workflow produces a steady stream of deployment records in the repository's Deployments list;
  • pull requests show "failed (outdated) deployment" whenever the workflow is started from a branch and the branch policy correctly refuses it.

Nothing is being deployed, so this is pure noise.

Implementation Plan

Please implement the following changes:

  1. Update the schema (pkg/parser/schemas/main_workflow_schema.json): in the object form of environment (top-level), safe-outputs.environment and jobs.<id>.environment, add
    • deployment: oneOf boolean, or a string matching a GitHub Actions expression (^\$\{\{.*\}\}$);
    • a description: "Set to false to use the environment's secrets and protection rules without creating a GitHub deployment."
  2. Verify the compiler pass-through (extractTopLevelYAMLSection for both call sites above). The emitted job keeps deployment exactly as written, on every job that receives the environment: the safe-output jobs, and any other job gh-aw applies safe-outputs.environment or the top-level environment to. If any code path rebuilds the environment from name only, carry deployment through as well.
  3. Leave the CLI --environment override (compiler_environment_override.go) unchanged: it sets a literal name. Optionally document that it replaces the whole environment block, including deployment.
  4. Add tests:
    • Schema validation: object with deployment: false, deployment: true, and deployment: ${{ github.ref_name == 'main' }} accepted; deployment: "no" (non-expression string) rejected.
    • Compiler: a workflow with safe-outputs.environment: { name: x, deployment: false } compiles, and every job that carries the environment has environment.deployment: false in the lock file. The same for top-level environment.
  5. Update the docs (frontmatter reference for environment and safe-outputs.environment) with an example and a note on when to use it: environments that only gate secrets.
  6. Follow guidelines: run make agent-finish.

Acceptance Criteria

  • safe-outputs.environment and top-level environment accept deployment: false (and true or an expression) in the object form, and the compiled jobs carry it unchanged.
  • A workflow using deployment: false keeps the environment's secrets and branch policy, and its runs create no GitHub deployment.
  • Workflows without deployment compile exactly as before.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions