Skip to main content

Promotion

Promotion workflows deploy releases to staging and production environments. This guide covers the promotion model, the manifest dispatch mechanism, and setting up promotion workflows.

Prerequisites

Before using promotion workflows, ensure you have:

  • A GitHub release with a digest.txt artifact from your build workflow
  • GitHub tag for the version you want to promote (required for staging and production)
  • Repository secrets configured: UPDATE_MANIFEST_TOKEN
  • Repository variables configured: PLATFORM_DISPATCH_URL
Managed by Ybor

The UPDATE_MANIFEST_TOKEN and PLATFORM_DISPATCH_URL are provisioned by the Ybor platform. If promotions are failing, contact your Admin or DevOps team to verify the configuration.

What You'll Learn

  • The environment promotion model (dev → stg → prd)
  • How manifest dispatch triggers deployments
  • Setting up promotion workflows
  • Tracking promotions in GitHub releases

Promotion Model

The platform uses a staged promotion model:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Dev │ ──► │ Staging │ ──► │ Production │
│ │ │ │ │ │
│ Automatic │ │ Manual │ │ Manual │
│ on merge │ │ promotion │ │ promotion │
└─────────────┘ └─────────────┘ └─────────────┘
EnvironmentTriggerPurpose
DevAutomatic on merge to mainContinuous integration testing
StagingManual workflow dispatchPre-production validation
ProductionManual workflow dispatchLive traffic

How Promotion Works

  1. Build creates a container image and records its digest in a GitHub release
  2. Promote downloads the digest and dispatches an update to the platform repository
  3. Platform updates Kubernetes manifests with the new image digest
  4. ArgoCD detects the manifest change and deploys the new version
┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│ Release │ │ Promote │ │ Platform │ │ ArgoCD │
│ │ │ Workflow │ │ Repo │ │ │
│ digest.txt │───►│ dispatch │───►│ manifests │───►│ deploy │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘

The Manifest Dispatch Action

The platform-application-manifest-dispatch action is the key integration point. It sends a repository dispatch event to the platform repository, which updates the Kubernetes manifests.

- uses: p6m-actions/platform-application-manifest-dispatch@v1
with:
repository: ${{ github.repository }}
image-name: my-service
directory-name: my-service
environment: stg
digest: ${{ steps.get-digest.outputs.digest }}
update-manifest-token: ${{ secrets.UPDATE_MANIFEST_TOKEN }}
platform-dispatch-url: ${{ vars.PLATFORM_DISPATCH_URL }}

Inputs

InputDescriptionRequired
repositorySource repository (owner/repo format)Yes
image-nameName of the Docker imageYes
directory-nameDirectory in platform repo (.platform/kubernetes/<directory-name>)Yes
environmentTarget environment: dev, stg, or prdYes
digestDocker image digest (sha256:...)Yes
update-manifest-tokenToken for platform dispatch APIYes
platform-dispatch-urlURL of platform dispatch endpointYes

What Gets Updated

The dispatch updates the application's Kustomize overlay for the target environment:

.platform/kubernetes/my-service/
├── base/
│ └── kustomization.yaml
└── overlays/
├── dev/
│ └── kustomization.yaml ← digest updated here
├── stg/
│ └── kustomization.yaml ← or here
└── prd/
└── kustomization.yaml ← or here
note

These Kubernetes manifests typically live in your application repository under .platform/kubernetes/, but may also be in a dedicated platform repository depending on your organization's setup.

Promotion Workflow

name: Promote

on:
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
type: choice
options:
- stg
- prd
tag:
description: 'Release tag to promote (e.g., v1.2.3)'
required: true
type: string

jobs:
promote:
runs-on: ubuntu-latest
steps:
# Download digest from release
- name: Download digest
uses: actions/download-artifact@v4
with:
name: digest
github-token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
run-id: # from release

# Dispatch to platform
- name: Update manifest
uses: p6m-actions/platform-application-manifest-dispatch@v1
with:
environment: ${{ inputs.environment }}
digest: ${{ steps.digest.outputs.value }}
# ... other inputs

Environment Protection

Use GitHub environments to add approval requirements for production:

  1. Go to repository Settings → Environments
  2. Create environments: stg, prd
  3. For prd, add required reviewers
jobs:
promote:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }} # Triggers approval for prd

When promoting to prd, designated reviewers must approve before the workflow runs.

Automatic Dev Deployment

Dev deployments happen automatically after successful builds on main:

# In build.yml
deploy-dev:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: p6m-actions/platform-application-manifest-dispatch@v1
with:
environment: dev
digest: ${{ needs.build.outputs.digest }}
# ... other inputs

This ensures every merge to main is immediately deployed to dev for testing.

Tracking Promotions

Update GitHub releases to record promotion history:

- name: Update release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api repos/${{ github.repository }}/releases/tags/${{ inputs.tag }} \
-X PATCH \
-f body="$(cat <<EOF
... existing body ...

## Promotions
- **${{ inputs.environment }}**: Promoted by @${{ github.actor }} at $(date -u)
EOF
)"

This creates an audit trail of when and by whom each version was promoted.

Rollback

To rollback, promote a previous version:

  1. Find the previous working release tag (e.g., v1.2.2)
  2. Run the promote workflow with that tag
  3. The previous image digest will be deployed

Since digests are immutable, you're guaranteed to deploy the exact same image.

Connection to Deployments

After promotion:

  1. Platform repo manifests are updated with the new digest
  2. ArgoCD detects the change
  3. ArgoCD syncs the new version to the cluster

See Deployments for details on:

  • How ArgoCD manages deployments
  • Verifying deployment status
  • Troubleshooting deployment issues

Best Practices

Test in Staging First

Always promote to staging before production. Staging should mirror production as closely as possible.

Document Promotion Decisions

Use the release notes to document why a version was promoted:

- name: Record promotion reason
run: |
echo "Promoted to ${{ inputs.environment }}: ${{ inputs.reason }}"

Monitor After Promotion

After promoting to production:

  1. Watch application metrics
  2. Check error rates
  3. Be ready to rollback if issues arise

Required Secrets and Variables

NameTypeDescription
UPDATE_MANIFEST_TOKENSecretToken for platform dispatch API
PLATFORM_DISPATCH_URLVariableURL of platform dispatch endpoint
GITHUB_TOKENSecretAutomatic; used for release access