This document describes the reusable GitHub Actions scaffolding generated by cpflow generate-github-actions.
The goal is to bring the Heroku Flow model into any cpflow project:
- Comment
/deploy-review-appon a pull request to create or update a review app. - Push more commits to the PR to auto-redeploy that review app.
- Push to the staging branch to auto-deploy staging.
- Promote the already-built staging artifact to production from the Actions tab.
- Let a nightly workflow clean up stale review apps.
Run these commands from the project root:
# Create .controlplane/ if it does not exist yet
cpflow generate
# Add reusable GitHub Actions for the Control Plane flow
cpflow generate-github-actionsThe second command writes namespaced files so they can coexist with an app's existing CI:
.github/actions/cpflow-build-docker-image/action.yml.github/actions/cpflow-delete-control-plane-app/action.yml.github/actions/cpflow-delete-control-plane-app/delete-app.sh.github/actions/cpflow-setup-environment/action.yml.github/workflows/cpflow-review-app-help.yml.github/workflows/cpflow-help-command.yml.github/workflows/cpflow-deploy-review-app.yml.github/workflows/cpflow-delete-review-app.yml.github/workflows/cpflow-deploy-staging.yml.github/workflows/cpflow-promote-staging-to-production.yml.github/workflows/cpflow-cleanup-stale-review-apps.yml
The generated workflows assume that .controlplane/controlplane.yml defines:
- one staging app
- one review-app prefix with
match_if_app_name_starts_with: true - one production app with
upstreampointing to staging
Typical shape:
aliases:
common: &common
cpln_org: my-org-staging
default_location: aws-us-east-2
setup_app_templates:
- app
- postgres
- redis
- rails
app_workloads:
- rails
additional_workloads:
- postgres
- redis
apps:
my-app-staging:
<<: *common
my-app-review:
<<: *common
match_if_app_name_starts_with: true
hooks:
post_creation: bundle exec rails db:prepare
pre_deletion: bundle exec rails db:drop
my-app-production:
<<: *common
allow_org_override_by_env: false
allow_app_override_by_env: false
cpln_org: my-org-production
upstream: my-app-staging
release_script: release_script.shImportant points:
REVIEW_APP_PREFIXin GitHub Actions must match the review config key prefix, for examplemy-app-review.match_if_app_name_starts_with: trueis what allows a single config entry to backmy-app-review-123,my-app-review-456, and cleanup commands likecpflow cleanup-stale-apps -a my-app-review.upstream: my-app-stagingis what lets the production promotion workflow copy the exact staging artifact.- If your main web workload is not named
rails, set the optionalPRIMARY_WORKLOADrepository variable described below.
Configure these repository secrets:
CPLN_TOKEN_STAGING: token for the staging Control Plane orgCPLN_TOKEN_PRODUCTION: token for the production Control Plane org
Configure these repository variables:
CPLN_ORG_STAGING: staging org name, for examplecompany-stagingCPLN_ORG_PRODUCTION: production org name, for examplecompany-productionSTAGING_APP_NAME: staging GVC name, for examplemy-app-stagingPRODUCTION_APP_NAME: production GVC name, for examplemy-app-productionREVIEW_APP_PREFIX: review-app prefix, for examplemy-app-reviewSTAGING_APP_BRANCH: optional branch that auto-deploys staging; defaults tomainormasterif unsetPRIMARY_WORKLOAD: optional workload name used to discover the public endpoint and do production health checks; defaults torails
Recommended org layout:
- keep review apps and staging in a staging org that developers can access
- keep production in a separate org with tighter access controls
cpflow-review-app-help.yml
- Posts a quick reference when a pull request opens.
cpflow-help-command.yml
- Replies to
/helpon a pull request with the commands and required repo settings.
cpflow-deploy-review-app.yml
- Creates a review app when someone comments
/deploy-review-app. - Redeploys an existing review app automatically on later PR pushes.
- Creates a GitHub deployment and comments with the review URL and logs.
- Leaves PR pushes alone until the first review app is explicitly requested, which keeps demo-app costs down.
cpflow-delete-review-app.yml
- Deletes the review app on
/delete-review-app. - Also deletes it automatically when the pull request closes.
cpflow-deploy-staging.yml
- Builds and deploys the staging app on pushes to
STAGING_APP_BRANCH. - Falls back to
mainormasterwhenSTAGING_APP_BRANCHis unset.
cpflow-promote-staging-to-production.yml
- Manually promotes the staging artifact to production with a confirmation input.
- Verifies that production has the env var names staging expects.
- Runs a health check and attempts a rollback of every container image in
PRIMARY_WORKLOADif the new production image does not come up healthy. - Creates a GitHub release after a successful promotion.
cpflow-cleanup-stale-review-apps.yml
- Runs nightly and on demand.
- Deletes stale review apps using
cpflow cleanup-stale-apps.
The generated workflows share these local composite actions:
cpflow-setup-environment: installs Ruby, the Control Plane CLI, and thecpflowgem, then logs into the target orgcpflow-build-docker-image: builds and pushes the app image with the desired commit SHAcpflow-delete-control-plane-app: safely deletes temporary apps and refuses to touch names outside the configured review-app prefix
This flow is a good fit for the React on Rails demo apps because they already follow the same basic assumptions:
- the deployable app is a Rails project
- the primary web workload is usually
rails - review environments should be temporary and opt-in
- staging should auto-follow a single branch
- production should promote the already-tested staging image
In practice, porting the flow into a demo app usually means:
- Generate
.controlplane/if the app does not have it yet. - Generate the
cpflow-*GitHub Actions files. - Update
.controlplane/controlplane.ymlwith staging, review, and production entries. - Add any additional app workloads the app needs at runtime, for example
sidekiq, a Node renderer, or any other process type that should deploy the same application image. - Make sure the repo variables and secrets line up with those app names.
- Adjust
PRIMARY_WORKLOADonly if the public workload is not namedrails. - Validate the real production Docker build before relying on the workflows, especially if asset compilation or SSR requires Node, extra system packages, or multiple processes.
If you want an AI agent to apply this flow to another project, this prompt is the intended starting point:
Set up Control Plane GitHub Flow for this repo. If `.controlplane/` is missing, run `cpflow generate`. Then run `cpflow generate-github-actions`, update `.controlplane/controlplane.yml` so it defines `<app>-staging`, `<app>-review`, and `<app>-production`, keep review apps opt-in via `/deploy-review-app`, use `STAGING_APP_BRANCH` or the default branch for staging deploys, and list the GitHub secrets/variables that must be configured. If the public workload is not named `rails`, set `PRIMARY_WORKLOAD` or adjust the generated workflows.
Expand that prompt with app-specific requirements before editing files:
- inspect the production Dockerfile and make sure it can build the app's assets in CI
- add extra
app_workloadsand template files for any runtime sidecars, workers, or renderer processes - make sure any sidecar process exposed to sibling workloads binds to
0.0.0.0instead of container-locallocalhost - make sure sidecar caches or bundle directories live in writable paths for the runtime user, such as
tmp/, instead of root-owned image paths - keep workflow files generic and put app names, org names, and branch names in repository
varsandsecrets
When the agent applies this to a project, it should avoid hardcoding app names or org names into the workflow files. Those belong in repository vars and secrets.