Skip to main content

AI Rollout Prompt for Control Plane GitHub Flow

Copy the recommended prompt below when you want an AI agent to add the reusable cpflow review-app, staging, and production-promotion flow to a repository. It works whether cpflow is already installed or the agent needs to install it first.

Set up Control Plane GitHub Flow for this repo.

Before generating anything:
- First make sure the `cpflow` CLI is available: use the repo's existing `bundle exec cpflow` if
present, otherwise install the published `cpflow` Ruby gem with `gem install cpflow`; if neither
is possible, stop and report that blocker.
- Use the same `cpflow` invocation for the rest of the rollout.
- Start with `cpflow github-flow-readiness` and stop on any reported blockers.
- The repo must be deployable from a clean clone: published package versions, complete runtime
scaffold, and a production Dockerfile that can build the app.
- If any package version is unpublished, inaccessible from CI, or requires credentials that are not
already modeled in the repo or GitHub settings, stop and report the blocker instead of generating
workflow files.
- If the repo is a legacy sample pinned to an obsolete Ruby or Bundler toolchain, if it does not
even have a production Dockerfile yet, or if it is a monorepo without an already-decided single
app boundary for this flow, stop and report that as a prerequisite instead of forcing the rollout.

Generate the flow:
- If `.controlplane/` is missing, run `cpflow generate`.
- Treat the generated app names as the repo-name default and rename them only if the
project needs a different prefix.
- Then run `cpflow generate-github-actions` (or `cpflow generate-github-actions --staging-branch
BRANCH` when staging should deploy from a branch other than `main`/`master`).
- Keep review apps opt-in via `+review-app-deploy`.
- Make sure any `STAGING_APP_BRANCH` repository variable is also present in the generated staging
workflow's `on.push.branches` filter.
- List the GitHub secrets and variables that must be configured.

Keep the Control Plane Flow source pins together:
- Do not hand-edit duplicated upstream refs into the generated wrappers.
- Keep every generated Control Plane Flow source pin synchronized at the same `vX.Y.Z`: each
reusable-workflow `uses: ...@vX.Y.Z` ref, the production promotion `.cpflow` checkout ref, and its
`control_plane_flow_ref` setup input.
- By default, `cpflow generate-github-actions` derives these values from the installed `cpflow` gem
version; temporary explicit ref overrides are for unreleased testing and must keep all three
values synchronized.
- Do not add `.github/actions/cpflow-*` copies; the workflows load cpflow's composite actions and
runtime source from the pinned `.cpflow` checkout.

When bumping the `cpflow` gem in a downstream repo:
- `cpflow update-github-actions` refreshes helpers while preserving all top-level workflows,
including their refs and triggers.
- It reports `.github/actions/cpflow-*` copies left by cpflow 6.0.0; delete them once no workflow is
pinned to 6.0.0 or names one.
- Use `cpflow update-github-actions --workflows FILE...` to explicitly select wrappers for
replacement, then review the diff and reapply downstream customizations.
- A differing existing validator blocks all writes: preserve its downstream checks in executable
`bin/test-cpflow-github-flow-custom`, then remove or rename the old generated validator before
retrying.
- The generated validator invokes that preserved extension and propagates its failures.
- Follow `docs/ci-automation.md` for the migration procedure, keep source pins compatible with the
updated actions, and run `bin/test-cpflow-github-flow` in the same PR (or
`bin/test-cpflow-github-flow bundle exec cpflow` when using Bundler).

Review apps and workload sizing:
- Keep the normal generated review-app setup simple: review apps require only `CPLN_TOKEN_STAGING`
when the generated review app config can be inferred.
- For public demos, starter staging apps, and long-lived review apps, keep the app workload `type:
standard` with one warm replica, set its autoscaling metric to `disabled`, and enable `capacityAI:
true` so Control Plane can right-size CPU and memory allocation at that fixed replica count.
- Shared Postgres and other stateful workloads are the usual exceptions and should stay manually
sized; Capacity AI is for supported stateless app/service workloads.
- If true idle scale-to-zero is explicitly required, create a separate `serverless` workload before
first deploy or plan a delete/recreate migration because Control Plane will not change an existing
`standard` workload to `serverless` in place.
- For shared review-app resources such as one staging database, use `shared_secret_grants` and
`{{SHARED_SECRET_DATABASE}}` placeholders instead of hardcoding the base app secret name; this
keeps review-app policy binding and cleanup automatic while avoiding per-PR database cost.

Staging and production:
- Document the one-time Control Plane bootstrap command for persistent staging and production apps
with `cpflow setup-app --skip-post-creation-hook`; for existing apps or later template updates,
document `cpflow apply-template` and the need for the app identity to have `reveal` on the app
secret policy.
- Do not imply the staging deploy or promotion workflows create those persistent GVCs.
- For production promotion, document a protected `production` GitHub Environment with required
reviewers, prevent self-review, and `CPLN_TOKEN_PRODUCTION` stored as an environment secret, not
as a repository or organization secret.

Docker image and runtime:
- Keep Node available in the final image if asset compilation or SSR depends on ExecJS, Yarn,
`pnpm`, or npm after the main install layer.
- Make sure the generated Dockerfile uses a Ruby base image compatible with the app's declared Ruby
requirement.
- Preserve repo-defined frontend build hooks: if `config/shakapacker.yml` defines a
`precompile_hook`, or React on Rails enables `config.auto_load_bundle = true`, confirm the
generated Dockerfile runs that codegen step before `rails assets:precompile`.
- If `config/database.yml` shows SQLite in production, confirm that the generated scaffold redirects
every production database file into persistent `/app/data` (or keeps it under persistent
`/app/storage`) without mounting over the image's `/app/db` migrations, stores Active Storage
under `/app/storage`, and runs `rails db:prepare`; otherwise keep the default Postgres workload.
- If the public workload is not named `rails`, set `PRIMARY_WORKLOAD` or adjust the generated
workflows.
- Inspect the Dockerfile and package sources for private GitHub dependencies or `RUN
--mount=type=ssh`; if present, wire `DOCKER_BUILD_SSH_KEY`, optionally set
`DOCKER_BUILD_SSH_KNOWN_HOSTS` for non-GitHub SSH hosts, and keep `DOCKER_BUILD_EXTRA_ARGS` to
newline-delimited single tokens such as `--build-arg=FOO=bar`.

Validate and finish:
- Run the real local validations you can: Docker build if feasible, repo tests or smoke checks, YAML
validation, and any CI-equivalent build steps.
- Push the branch and check the GitHub Actions results.
- Only stop early for a real external blocker or a product decision that changes scope.

Local Shortcut​

If cpflow is already available in the target repo, this local-only command prints the same recommended prompt with the repo-name default app prefix filled in:

cpflow ai-github-flow-prompt

That command works even before cpln is installed.

Hard Stop Conditions​

Stop and report the blocker instead of generating cpflow-* workflow files when:

  • the repo is a partial sample or generator snapshot rather than a deployable app
  • the app depends on unpublished or inaccessible gem or npm package versions
  • the repo is pinned to a legacy Ruby or Bundler toolchain that you cannot validate in the current environment
  • there is no production Dockerfile and the app's production build path is still undefined
  • the repo is a monorepo or contains multiple deployable apps and the flow target is not already decided
  • the local checkout does not match the intended remote repository
  • the app needs product decisions about workload shape, secrets, or promotion behavior that are not already implied by the repo

Definition of Done​

The rollout is done when all of the following are true:

  • .controlplane/ exists and matches the actual app shape
  • .github/cpflow-help.md and .github/workflows/cpflow-* are in place, with no .github/actions/cpflow-* copies
  • review apps are opt-in, staging auto-deploys from one branch, and production promotion is manual
  • required GitHub secrets and variables are documented for the repo
  • the production image build path is validated for the real app
  • repo-specific runtime concerns are handled, such as SQLite volumes, sidekiq workloads, SSR runtime Node access, React on Rails pack generation hooks, or private dependency fetches
  • the branch is pushed and the relevant GitHub checks are either green or blocked only by an external system failure

React on Rails Notes​

For React on Rails and React on Rails Pro apps, explicitly verify:

  • SSR or renderer workloads do not lose Node or package-manager access in the final image
  • sidecar renderers or worker processes bind to 0.0.0.0, not container-local localhost
  • writable caches, bundle outputs, or SQLite files live in runtime-writable paths
  • old demo repos are treated as legacy exceptions unless they can still build from a clean clone