Skip to content

Commit 0c7afed

Browse files
authored
Harden production promotion workflow
Harden generated production promotion workflows with upstream control-plane-flow changes through 2d8225572edd6f54c83ba9c51bd2983546989e93, including workload env parity, Buildx image copy, readyLatest readiness, restored help guidance, and commit-suffix warning visibility.
1 parent 08cdb0f commit 0c7afed

13 files changed

Lines changed: 214 additions & 80 deletions

.controlplane/docs/testing-cpflow-github-actions.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ bin/pin-cpflow-github-ref <40-character-control-plane-flow-commit-sha>
2929
bin/conductor-exec bin/test-cpflow-github-flow ruby /path/to/control-plane-flow/bin/cpflow
3030
```
3131

32-
Leave `CPFLOW_VERSION` unset while testing a commit SHA. After the upstream gem
33-
and tag ship, repin wrappers to the release tag, such as `v5.0.4`.
32+
Leave `CPFLOW_VERSION` unset while testing a commit SHA. After the upstream PR
33+
ships in a release tag, repin wrappers to that tag. Use `v5.1.0` only for
34+
changes already included in that tag; keep this promotion-hardening canary on an
35+
immutable commit SHA until the upstream hardening PR is released.
3436

3537
## Review App Canary
3638

.controlplane/readme.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,16 @@ The matching Control Plane resources are:
122122
| Production app secret dictionary | `react-webpack-rails-tutorial-production-secrets` |
123123

124124
Bootstrap production the same way before the first promotion, using the
125-
production org and production-only secret values.
125+
production org and production-only secret values. After bootstrap or any
126+
template change, re-apply the persistent production templates so the `rails`
127+
and `daily-task` workloads keep the same secret-backed env names as staging:
128+
129+
```sh
130+
cpflow apply-template app postgres redis daily-task rails \
131+
-a react-webpack-rails-tutorial-production \
132+
--org shakacode-open-source-examples-production \
133+
--yes --add-app-identity
134+
```
126135

127136
All review, staging, and production secret dictionaries need these app runtime
128137
secrets:
@@ -529,8 +538,10 @@ If staging moves off `master`, update both the `STAGING_APP_BRANCH` repository
529538
variable and the `branches:` filter in `.github/workflows/cpflow-deploy-staging.yml`;
530539
GitHub does not allow repository variables in trigger branch filters.
531540
The production promotion workflow checks that production has all environment
532-
variable names present in staging; it does not compare secret values, workload
533-
environment variables, or Control Plane secret references.
541+
variable names present in staging at both the GVC level and each configured app
542+
workload's container level. It does not compare secret values. The health check
543+
waits for Control Plane to report both `status.ready` and `status.readyLatest`
544+
before probing the public endpoint.
534545

535546
The GitHub settings and Control Plane resources must match the app names in
536547
`.controlplane/controlplane.yml`. For the standard review-app path, leave
@@ -564,9 +575,11 @@ Keep the reusable-workflow mechanics in the upstream
564575
For this repo, the update loop is:
565576

566577
1. Generate from the desired `cpflow` release with `--staging-branch master`.
567-
2. Keep generated refs on a release tag such as `v5.0.4`. Use a full upstream
568-
commit SHA only for short-lived downstream testing of an unreleased upstream
569-
PR, and leave `CPFLOW_VERSION` unset in that case.
578+
2. Keep generated refs on a release tag once the upstream hardening changes ship.
579+
This branch temporarily pins refs to
580+
`2d8225572edd6f54c83ba9c51bd2983546989e93` to test upstream promotion
581+
hardening before the next release tag. Leave `CPFLOW_VERSION` unset while
582+
testing a commit SHA.
570583
3. Keep app names and GitHub settings aligned with `.controlplane/controlplane.yml`.
571584
4. Validate locally:
572585

.controlplane/shakacode-team.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,27 @@ cpflow setup-app -a react-webpack-rails-tutorial-production --org shakacode-open
102102

103103
Use `setup-app` for first-time bootstrap because it creates the app secret
104104
policy and identity binding. Use `cpflow apply-template` for later template
105-
updates to existing persistent apps.
105+
updates to existing persistent apps. Production promotion compares both GVC env
106+
names and app workload container env names against staging before copying the
107+
image, so keep production `rails` and `daily-task` env references in sync with
108+
the templates:
109+
110+
```sh
111+
cpflow apply-template app postgres redis daily-task rails \
112+
-a react-webpack-rails-tutorial-production \
113+
--org shakacode-open-source-examples-production \
114+
--yes --add-app-identity
115+
```
106116

107117
Advanced optional settings are documented upstream in the
108118
[`control-plane-flow` CI automation guide](https://github.com/shakacode/control-plane-flow/blob/main/docs/ci-automation.md).
109119

110-
Current workflow wrappers are pinned to the upstream `control-plane-flow`
111-
release tag `v5.0.4`. Keep release tags as the steady-state configuration; use
112-
a full commit SHA only for short-lived upstream PR testing.
120+
Current workflow wrappers are temporarily pinned to upstream
121+
`control-plane-flow` commit `2d8225572edd6f54c83ba9c51bd2983546989e93` to test
122+
promotion hardening before it ships in a release tag. Keep release tags as the
123+
steady-state configuration once the upstream PR is released; use a full commit
124+
SHA only for short-lived upstream PR testing and leave `CPFLOW_VERSION` unset in
125+
that case.
113126

114127
If staging moves off `master`, update both `STAGING_APP_BRANCH` and the branch
115128
filter in `.github/workflows/cpflow-deploy-staging.yml`.
@@ -119,8 +132,8 @@ filter in `.github/workflows/cpflow-deploy-staging.yml`.
119132
When the upstream `control-plane-flow` repo changes the generated GitHub Actions
120133
flow, regenerate from the target `cpflow` version with `--staging-branch master`,
121134
review the diff, and validate with `bin/test-cpflow-github-flow` plus the normal
122-
CI checks. Stable automation should use release tags such as `v5.0.4`, not
123-
`main` or a feature branch.
135+
CI checks. Stable automation should use a release tag that includes the upstream
136+
hardening changes, not `main` or a feature branch.
124137

125138
See [readme.md](readme.md) and
126139
[Testing cpflow GitHub Actions Changes](docs/testing-cpflow-github-actions.md)

.github/cpflow-help.md

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
These commands are generated by [cpflow](https://github.com/shakacode/control-plane-flow).
44
For full setup, version-pinning, and troubleshooting details, see the upstream
5-
[CI automation guide](https://github.com/shakacode/control-plane-flow/blob/v5.0.4/docs/ci-automation.md).
5+
[CI automation guide](https://github.com/shakacode/control-plane-flow/blob/2d8225572edd6f54c83ba9c51bd2983546989e93/docs/ci-automation.md).
66

77
## Pull Request Commands
88

@@ -89,7 +89,7 @@ normal environment-gated job cannot tell which secret scope supplied a nonempty
8989
value, so a broader secret with the same name can mask a missing environment
9090
secret.
9191

92-
If promotion fails with
92+
If the promotion workflow fails with
9393
`CPLN_TOKEN_PRODUCTION is not set. Add it as a secret on the 'production' GitHub Environment.`,
9494
the token is missing from the environment scope or the workflow job is no longer
9595
declaring `environment: production`. Create or verify the environment secret
@@ -98,27 +98,32 @@ You need permission to manage repository environments and secrets to run these
9898
commands.
9999

100100
```sh
101-
gh secret set CPLN_TOKEN_PRODUCTION --repo shakacode/react-webpack-rails-tutorial --env production
102-
gh secret list --repo shakacode/react-webpack-rails-tutorial --env production
103-
gh secret list --repo shakacode/react-webpack-rails-tutorial
104-
gh secret list --org shakacode | grep '^CPLN_TOKEN_PRODUCTION[[:space:]]' || true
101+
gh secret set CPLN_TOKEN_PRODUCTION --repo OWNER/REPO --env production
102+
# Paste the token value when prompted.
103+
gh secret list --repo OWNER/REPO --env production
104+
gh secret list --repo OWNER/REPO
105+
gh secret list --org OWNER | grep '^CPLN_TOKEN_PRODUCTION[[:space:]]' || true
105106
```
106107

107108
Before the first promotion, bootstrap the production app the same way in the
108109
production org, using production-only secrets and values.
109110

110111
## Version Locking
111112

112-
Generated wrappers pin Control Plane Flow with a release tag, for example
113-
`v5.0.4`. Reusable review-app, staging, cleanup, and helper workflows pin the
114-
tag in their `uses:` ref. Production promotion pins the same tag in the
115-
`Checkout control-plane-flow actions` step so the caller-owned job can keep
116-
`environment: production` and receive production environment secrets directly.
113+
Generated wrappers normally pin Control Plane Flow with a release tag, for
114+
example `v5.1.0`. This branch temporarily pins the wrappers to upstream commit
115+
`2d8225572edd6f54c83ba9c51bd2983546989e93` while testing
116+
merged-but-unreleased production promotion hardening. Reusable review-app,
117+
staging, cleanup, and helper workflows pin that ref in their `uses:` entry.
118+
Production promotion pins the same ref in its control-plane-flow checkout step
119+
so the caller-owned job can keep `environment: production` and receive
120+
production environment secrets directly.
117121

118122
Leave `CPFLOW_VERSION` unset so the workflow builds cpflow from the same
119123
checked-out upstream source. If you set `CPFLOW_VERSION`, it must match the
120-
release tag, for example `CPFLOW_VERSION=5.0.4` with a wrapper pinned to
121-
`uses: ...@v5.0.4`.
124+
release tag your wrappers are pinned to: a `CPFLOW_VERSION=5.1.x` runtime
125+
override goes with a wrapper pinned to `uses: ...@v5.1.x` (substitute the
126+
release you pinned above).
122127

123128
After updating the `cpflow` gem in this repo, update the generated wrappers in
124129
the same PR:

.github/workflows/cpflow-cleanup-stale-review-apps.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ jobs:
1212
cleanup:
1313
# Cleanup targets the current inferred review-app prefix. If you changed
1414
# naming conventions, manually delete review apps under the old prefix.
15-
uses: shakacode/control-plane-flow/.github/workflows/cpflow-cleanup-stale-review-apps.yml@v5.0.4
15+
uses: shakacode/control-plane-flow/.github/workflows/cpflow-cleanup-stale-review-apps.yml@2d8225572edd6f54c83ba9c51bd2983546989e93
1616
secrets:
1717
CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}

.github/workflows/cpflow-delete-review-app.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ jobs:
3131
github.event_name == 'workflow_dispatch'
3232
# This `if:` mirrors the upstream job guard to avoid a billable workflow_call
3333
# when the event does not match. Keep both conditions in sync.
34-
uses: shakacode/control-plane-flow/.github/workflows/cpflow-delete-review-app.yml@v5.0.4
34+
uses: shakacode/control-plane-flow/.github/workflows/cpflow-delete-review-app.yml@2d8225572edd6f54c83ba9c51bd2983546989e93
3535
secrets:
3636
CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}

.github/workflows/cpflow-deploy-review-app.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
github.event.issue.pull_request &&
3131
contains(fromJson('["+review-app-deploy","+review-app-deploy\n","+review-app-deploy\r\n"]'), github.event.comment.body) &&
3232
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association))
33-
uses: shakacode/control-plane-flow/.github/workflows/cpflow-deploy-review-app.yml@v5.0.4
33+
uses: shakacode/control-plane-flow/.github/workflows/cpflow-deploy-review-app.yml@2d8225572edd6f54c83ba9c51bd2983546989e93
3434
secrets:
3535
CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}
3636
DOCKER_BUILD_SSH_KEY: ${{ secrets.DOCKER_BUILD_SSH_KEY }}

.github/workflows/cpflow-deploy-staging.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ permissions:
1616

1717
jobs:
1818
deploy-staging:
19-
uses: shakacode/control-plane-flow/.github/workflows/cpflow-deploy-staging.yml@v5.0.4
19+
uses: shakacode/control-plane-flow/.github/workflows/cpflow-deploy-staging.yml@2d8225572edd6f54c83ba9c51bd2983546989e93
2020
with:
2121
staging_app_branch_default: "master"
2222
secrets:

.github/workflows/cpflow-help-command.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ jobs:
2323
contains(fromJson('["+review-app-help","+review-app-help\n","+review-app-help\r\n"]'), github.event.comment.body) &&
2424
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
2525
github.event_name == 'workflow_dispatch'
26-
uses: shakacode/control-plane-flow/.github/workflows/cpflow-help-command.yml@v5.0.4
26+
uses: shakacode/control-plane-flow/.github/workflows/cpflow-help-command.yml@2d8225572edd6f54c83ba9c51bd2983546989e93

0 commit comments

Comments
 (0)