Skip to content

Commit 5bc5ef8

Browse files
committed
Clarify cpflow production secret docs
1 parent e230f63 commit 5bc5ef8

6 files changed

Lines changed: 49 additions & 14 deletions

File tree

.controlplane/controlplane.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ apps:
5252

5353
react-webpack-rails-tutorial-staging:
5454
<<: *common
55-
# QA Apps are like Heroku review apps, but the use `prefix` so you can run a commmand like
55+
# QA Apps are like Heroku review apps, but they use `prefix` so you can run a command like
5656
# this to create a QA app for the tutorial app.
5757
# `cpflow setup gvc postgres redis rails -a qa-react-webpack-rails-tutorial-1234`
5858
qa-react-webpack-rails-tutorial:

.controlplane/readme.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ For production promotion, configure a protected GitHub Environment named
7171
Protect the `production` environment with required reviewers, enable prevent
7272
self-review, and consider disabling administrator bypass. Only release managers
7373
or similarly trusted maintainers should be able to approve the promotion job.
74-
The promotion workflow uses that environment before it can access
75-
`CPLN_TOKEN_PRODUCTION`, so the production token is not exposed to ordinary
76-
review-app or staging runs.
74+
The generated caller passes `production_environment: production`; the upstream
75+
reusable workflow runs its production job in that environment, so GitHub injects
76+
`CPLN_TOKEN_PRODUCTION` only after the environment approval gate passes. The
77+
production token is not exposed to ordinary review-app or staging runs.
78+
7779
Generated caller workflows pass only the named secrets each upstream workflow
7880
needs. They do not use `secrets: inherit`; `CPLN_TOKEN_PRODUCTION` is supplied
7981
only by the protected `production` Environment after approval.
@@ -502,7 +504,11 @@ The GitHub settings and Control Plane resources must match the app names in
502504
`REVIEW_APP_PREFIX` unset and let the workflow infer
503505
`qa-react-webpack-rails-tutorial`; generated review apps are named
504506
`qa-react-webpack-rails-tutorial-<PR number>`.
505-
If you have older review apps from the previous `qa-react-webpack-rails-tutorial-pr-<PR number>` naming, delete them manually after this flow lands; cleanup targets the current prefix convention.
507+
If you have older review apps from the previous `qa-react-webpack-rails-tutorial-pr-<PR number>` naming, delete them manually after this flow lands; cleanup targets the current prefix convention. To inventory old apps, run:
508+
509+
```sh
510+
cpln gvc query --org shakacode-open-source-examples-staging -o yaml --prop name~qa-react-webpack-rails-tutorial-pr-
511+
```
506512

507513
This allows teams to:
508514
- Preview changes in a production-like environment

.controlplane/shakacode-team.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ Production promotion uses a protected GitHub Environment named `production`:
5454

5555
Protect the `production` environment with required reviewers, enable prevent
5656
self-review, and consider disabling administrator bypass. Do not store
57-
`CPLN_TOKEN_PRODUCTION` as a repository or organization secret.
57+
`CPLN_TOKEN_PRODUCTION` as a repository or organization secret. The caller
58+
passes `production_environment: production`; the upstream reusable workflow runs
59+
its production job in that environment, and GitHub injects the production token
60+
only after approval.
61+
5862
Generated caller workflows pass only the named secrets each upstream workflow
5963
needs. They do not use `secrets: inherit`; `CPLN_TOKEN_PRODUCTION` is supplied
6064
only by the protected `production` Environment after approval.

.github/cpflow-help.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ You asked for review app help. These commands are generated by [cpflow](https://
3535
| Name | Required | Notes |
3636
| --- | --- | --- |
3737
| `CPLN_TOKEN_STAGING` | yes | Service-account token scoped to the staging Control Plane org on controlplane.com. |
38-
| `CPLN_TOKEN_PRODUCTION` | yes for promote, as an environment secret | Store this as a secret on the protected `production` GitHub Environment, not as a repository or organization secret. |
38+
| `CPLN_TOKEN_PRODUCTION` | yes for promote, as a production environment secret | Store this as a secret on the protected `production` GitHub Environment, not as a repository or organization secret. |
3939
| `DOCKER_BUILD_SSH_KEY` | optional | Private SSH key used when Docker builds fetch private deps via `RUN --mount=type=ssh`. |
4040

4141
For normal generated review apps, `CPLN_TOKEN_STAGING` is the only required
4242
GitHub setting. The review app prefix and staging org are inferred from
4343
`.controlplane/controlplane.yml` when it defines exactly one app with
4444
`match_if_app_name_starts_with: true`.
45+
If more than one app has that flag, set `CPLN_ORG_STAGING` and
46+
`REVIEW_APP_PREFIX` explicitly to disambiguate.
4547

4648
Those inferred values come from `.controlplane/controlplane.yml`: `cpln_org`
4749
selects the Control Plane org and the app key with
@@ -52,8 +54,10 @@ expose a different public workload. Leave them unset for the standard setup.
5254

5355
For production promotion, create a GitHub Environment named `production`, add
5456
required reviewers, enable prevent self-review, and store
55-
`CPLN_TOKEN_PRODUCTION` as an environment secret there. The generated promotion
56-
workflow uses that environment before it can access production secrets.
57+
`CPLN_TOKEN_PRODUCTION` as an environment secret there. The generated caller
58+
passes `production_environment: production`; the upstream reusable workflow
59+
runs its production job in that environment, so GitHub injects
60+
`CPLN_TOKEN_PRODUCTION` only after the environment approval gate passes.
5761
Generated caller workflows pass only the named secrets each upstream workflow
5862
needs. They do not use `secrets: inherit`; the production token is supplied by
5963
the protected `production` Environment after approval.
@@ -63,9 +67,9 @@ the protected `production` Environment after approval.
6367
| Name | Required | Notes |
6468
| --- | --- | --- |
6569
| `CPLN_ORG_STAGING` | optional for review apps; yes for staging | Override the staging/review Control Plane org inferred from `controlplane.yml`. |
66-
| `CPLN_ORG_PRODUCTION` | yes for promote, preferably as environment variable | Control Plane org on controlplane.com for production. Prefer a `production` environment variable. |
70+
| `CPLN_ORG_PRODUCTION` | yes for promote, preferably as production environment variable | Control Plane org on controlplane.com for production. Prefer a `production` environment variable. |
6771
| `STAGING_APP_NAME` | yes | App name in `controlplane.yml` used as the staging deploy target. |
68-
| `PRODUCTION_APP_NAME` | yes for promote, preferably as environment variable | App name in `controlplane.yml` used as the production deploy target. Prefer a `production` environment variable. |
72+
| `PRODUCTION_APP_NAME` | yes for promote, preferably as production environment variable | App name in `controlplane.yml` used as the production deploy target. Prefer a `production` environment variable. |
6973
| `REVIEW_APP_PREFIX` | optional | Override the review-app app key inferred from the `match_if_app_name_starts_with: true` entry in `controlplane.yml`. |
7074
| `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. |
7175
| `STAGING_APP_BRANCH` | optional | Custom staging branch. Custom branches must also appear in `cpflow-deploy-staging.yml`'s push filter. |
@@ -81,7 +85,15 @@ the protected `production` Environment after approval.
8185
Generated review app names use `<review-app-prefix>-<PR number>`, for example
8286
`my-app-review-123`. If you are migrating from older local workflow glue that
8387
created names like `<review-app-prefix>-pr-123`, delete those old review apps
84-
manually after merging this flow.
88+
manually after merging this flow. To inventory old apps, run:
89+
90+
```sh
91+
cpln gvc query --org <staging-org> -o yaml --prop name~<review-app-prefix>-pr-
92+
```
93+
94+
The PR-open help workflow posts the short command reference whenever the
95+
generated wrapper exists. Remove `.github/workflows/cpflow-review-app-help.yml`
96+
or add a wrapper-level `if:` guard if a repo should not advertise review apps.
8597

8698
<details>
8799
<summary>Advanced: testing unreleased control-plane-flow changes</summary>

.github/workflows/cpflow-promote-staging-to-production.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ jobs:
2222
with:
2323
control_plane_flow_ref: b0c5759050c5c79a05826cd7a5d3ae711cd22a40
2424
# Keep CPLN_TOKEN_PRODUCTION as a secret on this protected GitHub
25-
# Environment. Required reviewers approve the job before GitHub exposes
26-
# environment secrets to the upstream reusable workflow.
25+
# Environment. The caller passes the environment name, the upstream
26+
# reusable workflow runs its production job in that environment, and
27+
# GitHub exposes environment secrets only after required reviewers approve.
2728
production_environment: production
2829
# Only pass the staging token explicitly. CPLN_TOKEN_PRODUCTION must live on
2930
# the protected production Environment, where GitHub exposes it only after

bin/test-cpflow-github-flow

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ bin/conductor-exec ruby <<'RUBY'
4343
require "yaml"
4444
4545
CONTROL_PLANE_FLOW_WORKFLOW = %r{\Ashakacode/control-plane-flow/\.github/workflows/[^@\s]+@([^\s]+)\z}
46+
PROMOTE_WORKFLOW = "/.github/workflows/cpflow-promote-staging-to-production.yml@"
4647
4748
refs = Hash.new { |hash, key| hash[key] = [] }
4849
@@ -68,6 +69,17 @@ Dir[".github/workflows/cpflow-*.yml"].sort.each do |path|
6869
uses_ref = uses_match[1]
6970
refs[uses_ref] << "#{path}:#{job_name}"
7071
72+
if job["uses"].to_s.include?(PROMOTE_WORKFLOW)
73+
if with["production_environment"].to_s.strip.empty?
74+
abort "#{path}:#{job_name} must set production_environment so GitHub can expose production environment secrets after approval"
75+
end
76+
77+
secrets = job["secrets"].is_a?(Hash) ? job["secrets"] : {}
78+
if secrets.key?("CPLN_TOKEN_PRODUCTION")
79+
abort "#{path}:#{job_name} must not pass CPLN_TOKEN_PRODUCTION as a caller secret; store it on the protected production environment"
80+
end
81+
end
82+
7183
if input_ref
7284
refs[input_ref] << "#{path}:#{job_name}"
7385
abort "#{path}:#{job_name} mismatched cpflow refs: #{uses_ref}, #{input_ref}" if uses_ref != input_ref

0 commit comments

Comments
 (0)