Skip to content

fix: omit job-level environment on reusable-workflow deploy jobs#138

Merged
joshua-temple merged 1 commit into
mainfrom
fix/env-gate-reusable-workflow
Jun 13, 2026
Merged

fix: omit job-level environment on reusable-workflow deploy jobs#138
joshua-temple merged 1 commit into
mainfrom
fix/env-gate-reusable-workflow

Conversation

@joshua-temple

Copy link
Copy Markdown
Collaborator

Problem

When a manifest sets gha_environment and a deploy uses an external reusable workflow:, the generator emitted a job-level environment: key on the same caller job as uses:. GitHub Actions forbids environment: on a reusable-workflow caller job. actionlint confirms:

when a reusable workflow is called with "uses", "environment" is not available.
only following keys are allowed: name, uses, with, secrets, needs, if, permissions

The generated orchestrate/promote workflows were invalid and GitHub refused to run them. The env-gate path for external deploys was effectively broken.

Fix

A job-level environment: key is valid on a steps job (inline run: deploy) but invalid on a uses: job. The fix gates the job-level environment: emission on the deploy being inline-run: at all three sites:

  • internal/generate/generator.go orchestrate deploy job (now requires info.Run != "").
  • internal/generate/promote.go single-deploy job (the else external branch no longer emits it).
  • internal/generate/promote.go prod-deploy job (gated under d.Run != "").

External (uses:) deploys keep passing the environment name via the existing with: environment: input. GitHub Environment protection must be declared on the job inside the reusable workflow; cascade cannot set it on the caller.

A generate-time note now fires when gha_environment is configured for an environment whose deploys are external reusable workflows, explaining where to declare protection.

Docs

docs/src/content/docs/callback-contract.md and docs/src/content/docs/workflows.md now document the contract: job-level environment gating applies to inline-run deploys; for external reusable-workflow deploys, declare environment: inside the reusable workflow (cascade passes the env name as the environment input).

Verification

  • New tests assert external+gha_environment deploy jobs carry uses: and with: environment: but no job-level environment:, while inline-run deploys keep it; a warning test; and an actionlint check that the generated orchestrate and promote workflows no longer trigger the "environment is not available" error.
  • go build ./..., go test ./... (1186 passed), golangci-lint run ./internal/generate/..., and actionlint over generated samples all green.
  • Existing env-gate tests that asserted the buggy environment: on external deploys were switched to inline-run deploys (the only case where the job-level key is valid); the external case is covered by the new tests.

Closes #137

GitHub Actions forbids a job-level environment: key on a job that calls a
reusable workflow with uses:; actionlint rejects it with "environment is
not available". When gha_environment was configured and a deploy used an
external workflow:, the orchestrate and promote generators emitted both
environment: and uses: on the same caller job, producing an invalid
workflow GitHub refuses to run.

Gate the job-level environment: key on the deploy being an inline run:
(steps) job in all three emission sites: the orchestrate deploy job and
the promote single-deploy and prod-deploy jobs. External deploys keep
passing the environment name via the with: environment input; protection
must be declared inside the reusable workflow. Warn at generate time when
gha_environment is set for an environment whose deploys are external, and
document the contract.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
@joshua-temple joshua-temple merged commit 63fc140 into main Jun 13, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generator emits 'environment:' on reusable-workflow (uses:) deploy jobs, which GitHub rejects

1 participant