Skip to content

Commit 7975fee

Browse files
committed
Sanitize Control Plane org names in production promotion
1 parent f364714 commit 7975fee

1 file changed

Lines changed: 48 additions & 11 deletions

File tree

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

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,43 @@ jobs:
109109
variable:STAGING_APP_NAME
110110
variable:PRODUCTION_APP_NAME
111111
112+
- name: Normalize Control Plane org names
113+
id: cpln-orgs
114+
env:
115+
CPLN_ORG_STAGING: ${{ vars.CPLN_ORG_STAGING }}
116+
CPLN_ORG_PRODUCTION: ${{ vars.CPLN_ORG_PRODUCTION }}
117+
shell: bash
118+
run: |
119+
set -euo pipefail
120+
121+
sanitize_control_plane_name() {
122+
local value="$1"
123+
value="${value//$'\r'/}"
124+
value="${value//$'\n'/}"
125+
printf '%s' "${value}"
126+
}
127+
128+
validate_control_plane_org() {
129+
local label="$1"
130+
local value="$2"
131+
132+
if ! [[ "${value}" =~ ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ ]]; then
133+
echo "::error::${label} must be a valid Control Plane org name; remove whitespace, line endings, or unsupported characters."
134+
exit 1
135+
fi
136+
}
137+
138+
staging_org="$(sanitize_control_plane_name "${CPLN_ORG_STAGING}")"
139+
production_org="$(sanitize_control_plane_name "${CPLN_ORG_PRODUCTION}")"
140+
141+
validate_control_plane_org "CPLN_ORG_STAGING" "${staging_org}"
142+
validate_control_plane_org "CPLN_ORG_PRODUCTION" "${production_org}"
143+
144+
{
145+
echo "staging=${staging_org}"
146+
echo "production=${production_org}"
147+
} >> "$GITHUB_OUTPUT"
148+
112149
- name: Capture release context
113150
id: release-context
114151
env:
@@ -127,7 +164,7 @@ jobs:
127164
uses: ./.cpflow/.github/actions/cpflow-setup-environment
128165
with:
129166
token: ${{ secrets.CPLN_TOKEN_PRODUCTION }}
130-
org: ${{ vars.CPLN_ORG_PRODUCTION }}
167+
org: ${{ steps.cpln-orgs.outputs.production }}
131168
working_directory: .cpflow
132169
cpln_cli_version: ${{ vars.CPLN_CLI_VERSION }}
133170
cpflow_version: ${{ vars.CPFLOW_VERSION }}
@@ -200,8 +237,8 @@ jobs:
200237
CPLN_TOKEN_PRODUCTION: ${{ secrets.CPLN_TOKEN_PRODUCTION }}
201238
STAGING_APP_NAME: ${{ vars.STAGING_APP_NAME }}
202239
PRODUCTION_APP_NAME: ${{ vars.PRODUCTION_APP_NAME }}
203-
CPLN_ORG_STAGING: ${{ vars.CPLN_ORG_STAGING }}
204-
CPLN_ORG_PRODUCTION: ${{ vars.CPLN_ORG_PRODUCTION }}
240+
CPLN_ORG_STAGING: ${{ steps.cpln-orgs.outputs.staging }}
241+
CPLN_ORG_PRODUCTION: ${{ steps.cpln-orgs.outputs.production }}
205242
shell: bash
206243
run: |
207244
set -euo pipefail
@@ -235,7 +272,7 @@ jobs:
235272
id: capture-current
236273
env:
237274
PRODUCTION_APP_NAME: ${{ vars.PRODUCTION_APP_NAME }}
238-
CPLN_ORG_PRODUCTION: ${{ vars.CPLN_ORG_PRODUCTION }}
275+
CPLN_ORG_PRODUCTION: ${{ steps.cpln-orgs.outputs.production }}
239276
WORKLOAD_NAMES: ${{ steps.workloads.outputs.names }}
240277
PRIMARY_WORKLOAD: ${{ steps.workloads.outputs.primary }}
241278
shell: bash
@@ -293,7 +330,7 @@ jobs:
293330
env:
294331
CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}
295332
STAGING_APP_NAME: ${{ vars.STAGING_APP_NAME }}
296-
CPLN_ORG_STAGING: ${{ vars.CPLN_ORG_STAGING }}
333+
CPLN_ORG_STAGING: ${{ steps.cpln-orgs.outputs.staging }}
297334
WORKLOAD_NAMES: ${{ steps.workloads.outputs.names }}
298335
PRIMARY_WORKLOAD: ${{ steps.workloads.outputs.primary }}
299336
shell: bash
@@ -342,8 +379,8 @@ jobs:
342379
CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}
343380
CPLN_TOKEN_PRODUCTION: ${{ secrets.CPLN_TOKEN_PRODUCTION }}
344381
PRODUCTION_APP_NAME: ${{ vars.PRODUCTION_APP_NAME }}
345-
CPLN_ORG_STAGING: ${{ vars.CPLN_ORG_STAGING }}
346-
CPLN_ORG_PRODUCTION: ${{ vars.CPLN_ORG_PRODUCTION }}
382+
CPLN_ORG_STAGING: ${{ steps.cpln-orgs.outputs.staging }}
383+
CPLN_ORG_PRODUCTION: ${{ steps.cpln-orgs.outputs.production }}
347384
STAGING_IMAGE: ${{ steps.staging-image.outputs.image }}
348385
shell: bash
349386
run: |
@@ -427,7 +464,7 @@ jobs:
427464
- name: Deploy image to production
428465
env:
429466
PRODUCTION_APP_NAME: ${{ vars.PRODUCTION_APP_NAME }}
430-
CPLN_ORG_PRODUCTION: ${{ vars.CPLN_ORG_PRODUCTION }}
467+
CPLN_ORG_PRODUCTION: ${{ steps.cpln-orgs.outputs.production }}
431468
RELEASE_PHASE_FLAG: ${{ steps.release-phase.outputs.flag }}
432469
shell: bash
433470
run: |
@@ -447,7 +484,7 @@ jobs:
447484
with:
448485
workload_name: ${{ steps.workloads.outputs.primary }}
449486
app_name: ${{ vars.PRODUCTION_APP_NAME }}
450-
org: ${{ vars.CPLN_ORG_PRODUCTION }}
487+
org: ${{ steps.cpln-orgs.outputs.production }}
451488
max_retries: ${{ env.HEALTH_CHECK_RETRIES }}
452489
interval_seconds: ${{ env.HEALTH_CHECK_INTERVAL }}
453490
accepted_statuses: ${{ env.HEALTH_CHECK_ACCEPTED_STATUSES }}
@@ -457,7 +494,7 @@ jobs:
457494
env:
458495
ROLLBACK_STATE: ${{ steps.capture-current.outputs.rollback_state }}
459496
PRODUCTION_APP_NAME: ${{ vars.PRODUCTION_APP_NAME }}
460-
CPLN_ORG_PRODUCTION: ${{ vars.CPLN_ORG_PRODUCTION }}
497+
CPLN_ORG_PRODUCTION: ${{ steps.cpln-orgs.outputs.production }}
461498
shell: bash
462499
run: |
463500
# Best-effort rollback: try every workload, aggregate failures, exit non-zero at the end
@@ -519,7 +556,7 @@ jobs:
519556
env:
520557
ROLLBACK_STATE: ${{ steps.capture-current.outputs.rollback_state }}
521558
PRODUCTION_APP_NAME: ${{ vars.PRODUCTION_APP_NAME }}
522-
CPLN_ORG_PRODUCTION: ${{ vars.CPLN_ORG_PRODUCTION }}
559+
CPLN_ORG_PRODUCTION: ${{ steps.cpln-orgs.outputs.production }}
523560
shell: bash
524561
run: |
525562
set -euo pipefail

0 commit comments

Comments
 (0)