Promotion Pipeline Template
| Field | Value |
|---|---|
| Repository URL | https://github.com/konstructio/konstruct-templates |
| Path | pipeline-templates/promotion |
| Branch | main |
The promotion pipeline template implements a 4-environment progressive deployment model with full artifact traceability. The same container image and Helm chart validated in dev flows through test and stage before being released to production.
Overview
push to main
│
▼
┌────────────┐ ┌──────────────┐ ┌────────────────┐ ┌──────────────┐
│ publish-dev│──▶│ promote-test │──▶│ promote-staging│──▶│ release-prod │
│ (auto) │ │ (manual) │ │ (manual) │ │ (manual) │
│ │ │ │ │ │ │ │
│ build+push │ │ reads dev │ │ reads test │ │ reads stage │
│ deploy dev │ │ deploys test │ │ deploys stage │ │ re-tags chart│
└────────────┘ └──────────────┘ └────────────────┘ │ releases │
│ deploys prod │
│ bumps main │
└──────────────┘
Environments and Clusters
The template assumes a 2-cluster topology:
| Cluster | Environments |
|---|---|
| Pre-production cluster | dev, test, stage |
| Production cluster | prod |
Workflows
1. publish-dev.yaml — Build and Deploy to Dev
Triggers: Push to main or hotfix-* branches, or manual dispatch.
| Step | Description |
|---|---|
| Create build commit | On dispatch only — creates an empty commit for a unique SHA |
| Build container | Tags with short SHA, pushes to ECR |
| Package chart | Versions as {base}-rc.{sha}, pushes to ECR OCI registry |
| Deploy to dev | Dispatches GitOps update-environment.yaml for the dev environment |
Versioning: Charts use release candidate notation — 0.2.0-rc.abc1234. The base version comes from Chart.yaml in the repository. The SHA suffix ensures every build is uniquely identifiable.
2. promote-test.yaml — Promote from Dev to Test
Trigger: Manual dispatch (zero inputs — just click "Run workflow").
- Checks out the GitOps repository
- Finds the Argo CD Application manifest at
registry/environments/dev/{cluster}/{app}.yaml - Reads the
targetRevisionfield (the chart version currently deployed in dev) - Dispatches GitOps update to deploy that exact version to the
testenvironment
3. promote-staging.yaml — Promote from Test to Stage
Trigger: Manual dispatch (zero inputs).
Same pattern as promote-test: reads targetRevision from the test environment and deploys it to stage.
4. release-prod.yaml — Release to Production
Trigger: Manual dispatch (zero inputs).
This is the most involved workflow:
| Step | Description |
|---|---|
| Read version from stage | Gets the RC version (0.2.0-rc.abc1234) from the stage environment's GitOps manifest |
| Pull RC chart from ECR | Downloads the exact Helm chart artifact that was validated through dev, test, and stage |
| Re-tag as release | Repackages the chart with clean semver (0.2.0) — same content, different version label |
| Publish release chart | Pushes the clean semver chart to ECR |
| Create GitHub release | Tags the repository with v0.2.0 and generates release notes |
| Deploy to prod | Dispatches GitOps update for the prod environment |
| Bump chart version on main | Increments patch version in Chart.yaml (e.g., 0.2.0 → 0.2.1) |
| Trigger next dev build | Dispatches publish-dev.yaml so the bumped version immediately publishes |
Artifact traceability: The release chart is the exact same artifact that passed through all pre-production environments. Re-tagging changes only the version label, not the content or the container image reference inside.
5. hotfix.yaml — Create Hotfix Branch
Trigger: Manual dispatch with one input — a release tag (e.g., v4.3.3).
- Validates the tag exists and matches
vX.Y.Zformat - Computes the hotfix version by bumping patch (
4.3.3→4.3.4) - Creates a branch named
hotfix-4-3-4from the tag - Updates
Chart.yamlwith the hotfix version - Pushes the branch and creates a draft PR to
main
Pushing to a hotfix-* branch triggers publish-dev.yaml, so the hotfix is immediately built and deployed to dev for testing.
6. bump-version.yaml — Manual Version Bump
Trigger: Manual dispatch with a dropdown: patch, minor, or major.
Bumps the chart version in Chart.yaml and pushes to main. Rarely needed since release-prod.yaml auto-bumps patch after every release. Use this for minor or major version increments.
How Promotion Works
Promotion is GitOps-native. Each environment has Argo CD Application manifests in the GitOps repository:
{org}-gitops/
└── registry/
└── environments/
├── dev/
│ └── {cluster}/
│ └── {app}.yaml ← targetRevision: 0.2.0-rc.abc1234
├── test/
│ └── {cluster}/
│ └── {app}.yaml ← targetRevision: 0.2.0-rc.abc1234
├── stage/
│ └── {cluster}/
│ └── {app}.yaml ← targetRevision: 0.2.0-rc.abc1234
└── prod/
└── {cluster}/
└── {app}.yaml ← targetRevision: 0.2.0
Promote workflows read the targetRevision from the source environment and write it to the destination. Argo CD detects the change and syncs.
Prerequisites
AWS
- IAM OIDC trust policy must include both
mainandhotfix-*branches (see example below) - ECR repositories for container images and Helm charts
OIDC trust policy example:
"StringLike": {
"token.actions.githubusercontent.com:sub": [
"repo:{org}/{repo}:ref:refs/heads/main",
"repo:{org}/{repo}:ref:refs/heads/hotfix-*"
]
}
GitHub
- GitHub App with repository access to both the app repository and GitOps repository
- Store
APP_IDandAPP_PRIVATE_KEYas repository secrets
- Store
- Workflow permissions: Organization settings must allow "Read and write permissions" and "Allow GitHub Actions to create and approve pull requests" (required for the hotfix workflow)
GitOps Repository
update-environment.yamlworkflow that acceptsenvironment,app_version, andapp_nameinputs- Argo CD Application manifests at
registry/environments/{env}/{cluster}/{app}.yamlwith atargetRevisionfield
Helm Chart
The promotion template uses the same chart structure as the default template, with CHART_VERSION and IMAGE environment variables injected into the deployment:
env:
- name: CHART_VERSION
value: {{ .Chart.Version | quote }}
- name: IMAGE
value: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
This lets you verify which version is running by hitting the application endpoint or checking pod environment variables.
When to Use This Template
The promotion template is designed for teams that need:
- Artifact traceability — proof that what's in prod was tested in lower environments
- Progressive confidence — manual gates between environments
- Release management — clean semver releases with GitHub release notes
- Hotfix capability — branch from any release tag and deploy through the same pipeline
- Automated version lifecycle — patch bumps and next-version builds happen automatically after release