@@ -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