-
Notifications
You must be signed in to change notification settings - Fork 373
Document cpflow downstream setup #747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
d5e1fd6
e3f03a0
c78d0f1
8e2722f
31a8103
e230f63
5bc5ef8
9be9140
f443270
8bec185
11033a9
84ea6b3
2a62d01
eb25cc6
4eea355
9e5a0dd
c659043
3319280
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,104 @@ In a real app, you would likely use persistent, external resources, such as AWS | |
|
|
||
| You can see the definition of Postgres and Redis in the `.controlplane/templates` directory. | ||
|
|
||
| ## GitHub Review App Setup | ||
|
|
||
| For normal generated review apps in this repo, GitHub needs only one repository | ||
| secret: | ||
|
|
||
| | Secret | Notes | | ||
| | --- | --- | | ||
| | `CPLN_TOKEN_STAGING` | Control Plane service-account token for `shakacode-open-source-examples-staging`. | | ||
|
|
||
| No GitHub repository variables are required for the standard review-app path. | ||
| The generated workflow infers the review app prefix | ||
| `qa-react-webpack-rails-tutorial` and staging org | ||
| `shakacode-open-source-examples-staging` from `.controlplane/controlplane.yml` | ||
| because that file defines exactly one app with | ||
| `match_if_app_name_starts_with: true`. | ||
|
|
||
| Optional review-app variables: | ||
|
|
||
| | Variable | Notes | | ||
| | --- | --- | | ||
| | `CPLN_ORG_STAGING` | Override the inferred staging org. | | ||
| | `REVIEW_APP_PREFIX` | Override or disambiguate the inferred review app prefix. | | ||
| | `PRIMARY_WORKLOAD` | Public workload name used to discover the review URL; defaults to `rails`. | | ||
|
|
||
| For staging auto-deploys, also configure: | ||
|
|
||
| | Secret or variable | Value | | ||
| | --- | --- | | ||
| | `CPLN_TOKEN_STAGING` | Same staging Control Plane token used by review apps. | | ||
| | `CPLN_ORG_STAGING` | `shakacode-open-source-examples-staging` | | ||
| | `STAGING_APP_NAME` | `react-webpack-rails-tutorial-staging` | | ||
|
|
||
| For production promotion, configure a protected GitHub Environment named | ||
| `production`: | ||
|
|
||
| | Secret or variable | Value | | ||
| | --- | --- | | ||
| | `CPLN_TOKEN_PRODUCTION` | Environment secret on `production`, not a repository or organization secret. | | ||
| | `CPLN_ORG_PRODUCTION` | Environment variable on `production`: `shakacode-open-source-examples-production` | | ||
| | `PRODUCTION_APP_NAME` | Environment variable on `production`: `react-webpack-rails-tutorial-production` | | ||
|
|
||
| Protect the `production` environment with required reviewers, enable prevent | ||
| self-review, and consider disabling administrator bypass. Only release managers | ||
| or similarly trusted maintainers should be able to approve the promotion job. | ||
| The promotion workflow uses that environment before it can access | ||
| `CPLN_TOKEN_PRODUCTION`, so the production token is not exposed to ordinary | ||
| review-app or staging runs. | ||
|
|
||
| Advanced optional variables: | ||
|
|
||
| | Name | Notes | | ||
| | --- | --- | | ||
| | `REVIEW_APP_DEPLOYING_ICON_URL` | Cosmetic custom animated icon for review-app comments. Ignore this for the standard setup. | | ||
| | `CPLN_CLI_VERSION` | Pin only when Control Plane CLI compatibility requires it. | | ||
| | `CPFLOW_VERSION` | Runtime gem override. Leave unset when workflow wrappers are pinned to a GitHub commit SHA for upstream PR testing. | | ||
|
|
||
| ## Control Plane Setup | ||
|
|
||
| The GitHub secret is only the automation credential. The Control Plane org also | ||
| needs the app resources and runtime secrets that the workloads read at boot. | ||
|
|
||
| For review-app testing, the standard setup is: | ||
|
|
||
| | Control Plane item | Where | Notes | | ||
| | --- | --- | --- | | ||
| | Staging/review org | `shakacode-open-source-examples-staging` | The `CPLN_TOKEN_STAGING` service account must be able to create and update GVCs, workloads, images, identities, policies, and secrets in this org. | | ||
| | Review app prefix | `qa-react-webpack-rails-tutorial` | Review apps are named `qa-react-webpack-rails-tutorial-<PR number>`. This is inferred from `.controlplane/controlplane.yml`. | | ||
| | Review app secret dictionary | `qa-react-webpack-rails-tutorial-secrets` | Shared by generated review apps because the QA app entry uses `match_if_app_name_starts_with: true`. | | ||
|
|
||
| For staging deploys later, also use: | ||
|
|
||
| | Control Plane item | Where | Notes | | ||
| | --- | --- | --- | | ||
| | Staging app | `react-webpack-rails-tutorial-staging` | The `CPLN_TOKEN_STAGING` token deploys this app from `master`. | | ||
| | Staging app secret dictionary | `react-webpack-rails-tutorial-staging-secrets` | Same required keys as the review app secret dictionary. | | ||
|
|
||
| For production promotion later, use a separate production org and token: | ||
|
|
||
| | Control Plane item | Where | Notes | | ||
| | --- | --- | --- | | ||
| | Production org | `shakacode-open-source-examples-production` | Do not give the staging token access to this org. | | ||
| | Production app | `react-webpack-rails-tutorial-production` | Promotion copies the staging image into this app. | | ||
| | Production app secret dictionary | `react-webpack-rails-tutorial-production-secrets` | Create before the first promotion. Use production-only values. | | ||
| | Production service-account token | GitHub Environment secret `CPLN_TOKEN_PRODUCTION` | Keep this token in the protected `production` GitHub Environment only. | | ||
|
|
||
| The app secret dictionaries must include: | ||
|
|
||
| - `SECRET_KEY_BASE` | ||
| - `RENDERER_PASSWORD` | ||
| - `REACT_ON_RAILS_PRO_LICENSE` | ||
|
|
||
| Generate `SECRET_KEY_BASE` with `openssl rand -hex 64` and | ||
| `RENDERER_PASSWORD` with `openssl rand -hex 32`. The review/staging template | ||
| currently contains a test placeholder for `SECRET_KEY_BASE`; replace it with a | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documenting the placeholder is good, but this phrasing ("replace it with a secret-backed value before promoting production") leaves staging running with a known, weak |
||
| secret-backed value before promoting production. The demo Postgres and Redis | ||
| workloads are useful for review apps and staging demos. For real production, | ||
| prefer managed services and update `DATABASE_URL` and `REDIS_URL` accordingly. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| 1. Ensure your [Control Plane](https://shakacode.controlplane.com) account is set up. | ||
|
|
@@ -388,11 +486,11 @@ The production promotion workflow checks that production has all environment | |
| variable names present in staging; it does not compare secret values, workload | ||
| environment variables, or Control Plane secret references. | ||
|
|
||
| The repository variables and secrets must match the app names in | ||
| `.controlplane/controlplane.yml`. In particular, `REVIEW_APP_PREFIX` should | ||
| include the `-pr` suffix for this app, such as | ||
| `qa-react-webpack-rails-tutorial-pr`, so generated review apps are named | ||
| `qa-react-webpack-rails-tutorial-pr-1234`. | ||
| The GitHub settings and Control Plane resources must match the app names in | ||
| `.controlplane/controlplane.yml`. For the standard review-app path, leave | ||
| `REVIEW_APP_PREFIX` unset and let the workflow infer | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This silently changes the naming convention from the previously documented Consider adding a migration note here, even one sentence: "If you previously had |
||
| `qa-react-webpack-rails-tutorial`; generated review apps are named | ||
| `qa-react-webpack-rails-tutorial-<PR number>`. | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| This allows teams to: | ||
| - Preview changes in a production-like environment | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,26 +35,77 @@ You asked for review app help. These commands are generated by [cpflow](https:// | |
| | Name | Required | Notes | | ||
| | --- | --- | --- | | ||
| | `CPLN_TOKEN_STAGING` | yes | Service-account token scoped to the staging Control Plane org on controlplane.com. | | ||
| | `CPLN_TOKEN_PRODUCTION` | yes (for promote) | Service-account token scoped to the production Control Plane org on controlplane.com. | | ||
| | `CPLN_TOKEN_PRODUCTION` | yes (for promote) | Store this as a secret on the protected `production` GitHub Environment, not as a repository or organization secret. | | ||
| | `DOCKER_BUILD_SSH_KEY` | optional | Private SSH key used when Docker builds fetch private deps via `RUN --mount=type=ssh`. | | ||
|
|
||
| For normal generated review apps, `CPLN_TOKEN_STAGING` is the only required | ||
| GitHub setting. The review app prefix and staging org are inferred from | ||
| `.controlplane/controlplane.yml` when it defines exactly one app with | ||
| `match_if_app_name_starts_with: true`. | ||
|
|
||
| For production promotion, create a GitHub Environment named `production`, add | ||
| required reviewers, enable prevent self-review, and store | ||
| `CPLN_TOKEN_PRODUCTION` as an environment secret there. The generated promotion | ||
| workflow uses that environment before it can access production secrets. | ||
|
|
||
| ### GitHub Actions variables | ||
|
|
||
| | Name | Required | Notes | | ||
| | --- | --- | --- | | ||
| | `CPLN_ORG_STAGING` | yes | Control Plane org on controlplane.com for staging and review apps. | | ||
| | `CPLN_ORG_PRODUCTION` | yes (for promote) | Control Plane org on controlplane.com for production. | | ||
| | `CPLN_ORG_STAGING` | optional for review apps; yes for staging | Override the staging/review Control Plane org inferred from `controlplane.yml`. | | ||
| | `CPLN_ORG_PRODUCTION` | yes (for promote) | Control Plane org on controlplane.com for production. Prefer a `production` environment variable. | | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| | `STAGING_APP_NAME` | yes | App name in `controlplane.yml` used as the staging deploy target. | | ||
| | `PRODUCTION_APP_NAME` | yes (for promote) | App name in `controlplane.yml` used as the production deploy target. | | ||
| | `REVIEW_APP_PREFIX` | yes | Prefix for per-PR review app names (e.g. `review-app`). | | ||
| | `REVIEW_APP_DEPLOYING_ICON_URL` | optional | Custom image URL for the animated deploying icon in review-app PR comments. Set to `none` to use the text fallback icon. | | ||
| | `PRODUCTION_APP_NAME` | yes (for promote) | App name in `controlplane.yml` used as the production deploy target. Prefer a `production` environment variable. | | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same issue as |
||
| | `REVIEW_APP_PREFIX` | optional | Override or disambiguate the review app prefix inferred from `controlplane.yml`. | | ||
| | `REVIEW_APP_DEPLOYING_ICON_URL` | optional, advanced | Cosmetic custom image URL for the animated deploying icon in review-app PR comments. Set to `none` to use the text fallback icon. | | ||
| | `STAGING_APP_BRANCH` | optional | Custom staging branch. Custom branches must also appear in `cpflow-deploy-staging.yml`'s push filter. | | ||
| | `PRIMARY_WORKLOAD` | optional | Workload polled for health and rollback (defaults to `rails`). | | ||
| | `DOCKER_BUILD_EXTRA_ARGS` | optional | Newline-delimited extra docker build tokens (e.g. `--build-arg=FOO=bar`). | | ||
| | `DOCKER_BUILD_SSH_KNOWN_HOSTS` | optional | SSH known_hosts entries when SSH build hosts are not GitHub.com. | | ||
| | `HEALTH_CHECK_ACCEPTED_STATUSES` | optional | Space-separated HTTP statuses considered healthy on promote (default `200 301 302`). | | ||
| | `CPLN_CLI_VERSION` | optional | Pin a specific `@controlplane/cli` version; falls back to the action default when unset. | | ||
| | `CPFLOW_VERSION` | optional | Runtime gem-install override. When unset, cpflow is built from the pinned upstream workflow ref. When set, use the RubyGems version without a leading `v`. | | ||
| | `CPFLOW_VERSION` | optional | Pin a published RubyGems version such as `5.0.0` or `5.0.0.rc.1`. Leave unset for normal generated workflows so the setup action builds `cpflow` from the same `control-plane-flow` GitHub ref used by the reusable workflow. | | ||
|
|
||
| </details> | ||
|
|
||
| <details> | ||
| <summary>Advanced: testing unreleased control-plane-flow changes</summary> | ||
|
|
||
| Generated workflow wrappers have two related pins: | ||
|
|
||
| - The `uses: shakacode/control-plane-flow/...@<ref>` GitHub ref selects the reusable workflow code. | ||
| - The `control_plane_flow_ref: <ref>` input tells the setup action which `control-plane-flow` source to check out and build when `CPFLOW_VERSION` is empty. | ||
|
|
||
| The GitHub ref is the runtime lock for workflow and action behavior. The | ||
| RubyGems version is used to generate/update these wrappers and, only when | ||
| `CPFLOW_VERSION` is set, to install the `cpflow` CLI at runtime. A downstream | ||
| repo cannot rely on the gem alone because GitHub loads reusable workflow YAML | ||
| from `shakacode/control-plane-flow`, not from RubyGems. | ||
|
|
||
| For normal releases, point both pins at a release tag such as `v5.0.0`. | ||
| You may leave `CPFLOW_VERSION` unset, or set it to the matching RubyGems version | ||
| without the leading `v`, such as `5.0.0`. If you set `CPFLOW_VERSION` for a | ||
| prerelease, use RubyGems dot syntax such as `5.0.0.rc.1`; the release tag may | ||
| use either `v5.0.0.rc.1` or `v5.0.0-rc.1`. | ||
|
|
||
| To update to a new stable release, install or bundle the new `cpflow` gem, run | ||
| `cpflow generate-github-actions`, and commit the regenerated wrappers. Use | ||
| `bin/pin-cpflow-github-ref vX.Y.Z` only when the generated files are already | ||
| current and you only need to move the upstream GitHub ref. | ||
|
|
||
| For temporary downstream testing of an upstream PR before a gem is released, pin | ||
| both values to the exact 40-character commit SHA and leave `CPFLOW_VERSION` | ||
| unset: | ||
|
|
||
| ```sh | ||
| bin/pin-cpflow-github-ref <40-character-control-plane-flow-commit-sha> | ||
| bin/test-cpflow-github-flow ruby /path/to/control-plane-flow/bin/cpflow | ||
| ``` | ||
|
|
||
| Do not leave downstream apps pinned to a moving branch such as `main`. A branch | ||
| can pick up beta or work-in-progress changes without a downstream PR changing. | ||
| Use commit SHAs for short-lived PR testing, then switch to the release tag once | ||
| the gem and tag exist. | ||
|
|
||
| </details> | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,12 +9,24 @@ on: | |
| type: string | ||
|
|
||
| permissions: | ||
| # The upstream reusable workflow's create-github-release job needs | ||
| # contents: write, and callers must grant the union of callee permissions. | ||
| contents: write | ||
|
|
||
| jobs: | ||
| promote-to-production: | ||
| if: github.event.inputs.confirm_promotion == 'promote' | ||
| uses: shakacode/control-plane-flow/.github/workflows/cpflow-promote-staging-to-production.yml@3e0e7e1f0a35c15648cc9254b573b058d77ca8c4 | ||
| # Keep the @ref in `uses:` and `control_plane_flow_ref` below in sync: the | ||
| # first selects the reusable workflow, the second selects its shared actions. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| uses: shakacode/control-plane-flow/.github/workflows/cpflow-promote-staging-to-production.yml@db013e139af4ee8741f791c14ff825f13c0a1021 | ||
| with: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good pattern. One thing to confirm: the upstream reusable workflow's production job reads |
||
| control_plane_flow_ref: 3e0e7e1f0a35c15648cc9254b573b058d77ca8c4 | ||
| control_plane_flow_ref: db013e139af4ee8741f791c14ff825f13c0a1021 | ||
| # Keep CPLN_TOKEN_PRODUCTION as a secret on this protected GitHub | ||
| # Environment. Required reviewers approve the job before GitHub exposes | ||
| # environment secrets to the upstream reusable workflow. | ||
| production_environment: production | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good approach — passing One runtime risk: if the |
||
| # `secrets: inherit` passes all caller repository secrets to the trusted | ||
| # upstream workflow. The upstream workflow only reads the named secrets it | ||
| # references, but GitHub does not enforce that boundary. Strict consumers can | ||
| # set CPFLOW_GITHUB_ACTIONS_REF to an immutable commit SHA. | ||
| secrets: inherit | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment mentions Consider referencing the correct mechanism (the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The inline comment correctly notes that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment says the upstream workflow "only reads the named secrets it references," which is accurate for repository secrets. Worth clarifying here that environment secrets (e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If the upstream |
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -15,4 +15,4 @@ permissions: | |||||
| jobs: | ||||||
| show-help: | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||||||
| if: vars.REVIEW_APP_PREFIX != '' | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This guard contradicts the new documentation. The README and If the upstream reusable workflow now supports inferring the prefix, this guard should be removed (or updated to a condition that always evaluates to
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The updated docs explicitly say There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removing this guard makes the help workflow post a review-app comment on every PR open, including in forks that have never configured Control Plane. The old The docs mention removing this file or adding an |
||||||
| uses: shakacode/control-plane-flow/.github/workflows/cpflow-review-app-help.yml@3e0e7e1f0a35c15648cc9254b573b058d77ca8c4 | ||||||
| uses: shakacode/control-plane-flow/.github/workflows/cpflow-review-app-help.yml@db013e139af4ee8741f791c14ff825f13c0a1021 | ||||||
|
cursor[bot] marked this conversation as resolved.
Outdated
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This inference assumption is fragile: if
controlplane.ymlever gains a second app entry withmatch_if_app_name_starts_with: true, the inference will fail (or pick the wrong one) with no clear error. Consider adding a sentence here directing readers to setCPLN_ORG_STAGINGandREVIEW_APP_PREFIXexplicitly if they hit ambiguous inference, so the failure mode is less opaque.