Cookbook: Release Flow
This recipe models a safe, profile-aware release with retries and explicit unsafe controls.
Scenario
You want one release command that is strict in production but still testable locally.
qp.yaml Recipe
profiles:
_default: "{{env.QP_PROFILE}}"
staging:
vars:
deploy_env: staging
prod:
vars:
deploy_env: prod
tasks:
deploy:
when: branch() == "main"
timeout: 30m
vars:
deploy_env: local
tasks:
build:
desc: Build release artifacts
cmd: make dist
safety: idempotent
publish:
desc: Publish artifacts
cmd: ./scripts/publish.sh --env {{vars.deploy_env}}
safety: external
retry: 3
retry_delay: 5s
retry_backoff: exponential
deploy:
desc: Deploy release
cmd: ./scripts/deploy.sh --env {{vars.deploy_env}}
safety: external
retry: 2
retry_delay: 10s
release:
desc: Release pipeline
run: build -> publish -> deployRun It
Staging rehearsal:
QP_PROFILE=staging qp release --allow-unsafe --eventsProduction:
QP_PROFILE=prod qp release --allow-unsafe --events --jsondeploy only runs on main in prod profile due to task-level profile override.
Guarding Releases
Add a pre-release validation guard:
guards:
release-ready:
steps: [check, build]Then run:
qp guard release-ready --json && QP_PROFILE=prod qp release --allow-unsafeWhy This Works Well
- Local/staging/prod share one graph with profile overlays.
- Publish/deploy retries absorb transient failures.
- Unsafe side effects require explicit opt-in.
- Event stream gives auditable release timeline.