Context
BMW staging exposed a product gap in wfctl: wfctl infra plan --env staging can preview resolved infrastructure resources, but the operational commands we actually use in CI do not have equivalent dry-run coverage:
wfctl infra apply --env staging --config infra.yaml has no --dry-run flag.
wfctl ci run --phase deploy --env staging --config infra.yaml has no --dry-run flag.
This makes it harder to dogfood wfctl safely, because we cannot locally validate the exact staging apply/deploy path without risking real provider mutations.
Desired outcome
Add dry-run support that validates the same config resolution, environment overrides, provider selection, secret wiring shape, pre-deploy sequencing, and deployment target naming that the real apply/deploy paths use, while guaranteeing no provider mutation calls are made.
Design constraints
- Keep wfctl holistic and provider-agnostic; do not hard-code DigitalOcean-only behavior in core.
- Prefer plugin/provider interfaces for planned API calls where provider specifics matter.
- Support non-Go projects and CI portability; dry-run output should be useful in GitHub Actions, GitLab, Jenkins, and local shells.
- Make dry-runs security-aware: never print secret values by default, but show which secret keys would be required/resolved.
- Ensure plan output matches deploy/apply behavior, including env-resolved names like BMW staging
bmw-staging.
Initial acceptance criteria
wfctl infra apply --dry-run --env staging -c infra.yaml prints the apply operations it would execute and exits without provider mutations.
wfctl ci run --phase deploy --dry-run --env staging --config infra.yaml prints pre-deploy, deploy provider, target resource, image ref/tag source, health-check plan, and required secrets without executing provider mutations or health polling.
- Dry-run output has a structured format option suitable for automation.
- Tests prove dry-run and real deploy paths share the same planning logic for resource names and image resolution.
- BMW staging can use this locally to confirm
bmw-staging before running a real deploy.
Context
BMW staging exposed a product gap in wfctl:
wfctl infra plan --env stagingcan preview resolved infrastructure resources, but the operational commands we actually use in CI do not have equivalent dry-run coverage:wfctl infra apply --env staging --config infra.yamlhas no--dry-runflag.wfctl ci run --phase deploy --env staging --config infra.yamlhas no--dry-runflag.This makes it harder to dogfood wfctl safely, because we cannot locally validate the exact staging apply/deploy path without risking real provider mutations.
Desired outcome
Add dry-run support that validates the same config resolution, environment overrides, provider selection, secret wiring shape, pre-deploy sequencing, and deployment target naming that the real apply/deploy paths use, while guaranteeing no provider mutation calls are made.
Design constraints
bmw-staging.Initial acceptance criteria
wfctl infra apply --dry-run --env staging -c infra.yamlprints the apply operations it would execute and exits without provider mutations.wfctl ci run --phase deploy --dry-run --env staging --config infra.yamlprints pre-deploy, deploy provider, target resource, image ref/tag source, health-check plan, and required secrets without executing provider mutations or health polling.bmw-stagingbefore running a real deploy.