Skip to content

Commit 8424f27

Browse files
committed
Harden cpflow review follow-ups
1 parent 05085b1 commit 8424f27

6 files changed

Lines changed: 66 additions & 53 deletions

File tree

.controlplane/shakacode-team.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Deployments are handled by Control Plane configuration in this repo and GitHub A
2222

2323
### Production Environment
2424
- **Manual**: Run the [cpflow-promote-staging-to-production workflow](https://github.com/shakacode/react-webpack-rails-tutorial/actions/workflows/cpflow-promote-staging-to-production.yml) on GitHub
25+
- Rollback restores workload images only; database migrations and other
26+
`--run-release-phase` side effects are not reversed automatically.
2527
- **URLs**:
2628
- [Control Plane Console - Production](https://console.cpln.io/console/org/shakacode-open-source-examples-production/gvc/react-webpack-rails-tutorial-production/workload/rails/-info)
2729
- [Production App](https://reactrails.com/)

.github/actions/cpflow-build-docker-image/action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,6 @@ runs:
109109
if: ${{ always() }}
110110
shell: bash
111111
run: |
112+
# Defence in depth: the build step also traps EXIT, but this still runs
113+
# if a future refactor exits before that trap is installed.
112114
rm -f "${HOME}/.ssh/cpflow_build_key"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
: "${APP_NAME:?APP_NAME environment variable is required}"
6+
: "${CPLN_ORG:?CPLN_ORG environment variable is required}"
7+
8+
# Contract this relies on from `cpflow exists`:
9+
# - Exit status 0 -> app exists (stdout may contain an informational banner).
10+
# - Exit status non-zero, no
11+
# recognizable error tokens -> app does not exist.
12+
# - Exit status non-zero with
13+
# tokens like "Double check
14+
# your org", "Unknown API
15+
# token format", "ERROR",
16+
# "Error:", "Traceback", or
17+
# "Net::" -> a real failure; surface and exit 2.
18+
# TODO: replace this string-matching with a structured signal once `cpflow exists` exposes one
19+
# (e.g. a distinct exit code for "not found" vs. API/auth errors, or `cpflow exists --json`).
20+
exists_output=""
21+
if exists_output="$(cpflow exists -a "$APP_NAME" --org "$CPLN_ORG" 2>&1)"; then
22+
if [[ -n "$exists_output" ]]; then
23+
printf '%s\n' "$exists_output"
24+
fi
25+
exit 0
26+
fi
27+
28+
case "$exists_output" in
29+
*"Double check your org"*|*"Unknown API token format"*|*"ERROR"*|*"Error:"*|*"Traceback"*|*"Net::"*)
30+
echo "Failed to determine whether application exists: $APP_NAME" >&2
31+
printf '%s\n' "$exists_output" >&2
32+
exit 2
33+
;;
34+
esac
35+
36+
if [[ -n "$exists_output" ]]; then
37+
echo "cpflow exists returned non-zero output that did not match known error patterns:" >&2
38+
printf '%s\n' "$exists_output" >&2
39+
fi
40+
41+
exit 1

.github/actions/cpflow-delete-control-plane-app/delete-app.sh

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,43 +15,18 @@ if [[ "$APP_NAME" != "${expected_prefix}"* ]]; then
1515
fi
1616

1717
echo "🔍 Checking if application exists: $APP_NAME"
18-
# Contract this relies on from `cpflow exists`:
19-
# - Exit status 0 → app exists (stdout may contain an informational banner).
20-
# - Exit status non-zero, no
21-
# recognizable error tokens → app does not exist; treat as a no-op success.
22-
# - Exit status non-zero with
23-
# tokens like "Double check
24-
# your org", "Unknown API
25-
# token format", "ERROR",
26-
# "Error:", "Traceback", or
27-
# "Net::" → a real failure; surface and exit 1.
28-
# TODO: replace this string-matching with a structured signal once `cpflow exists` exposes one
29-
# (e.g. a distinct exit code for "not found" vs. API/auth errors, or `cpflow exists --json`).
30-
# Until then, keep this list in sync if `cpflow exists` starts emitting new error patterns —
31-
# any unmatched error string would otherwise be silently treated as "app not found".
32-
exists_output=""
33-
if ! exists_output="$(cpflow exists -a "$APP_NAME" --org "$CPLN_ORG" 2>&1)"; then
34-
case "$exists_output" in
35-
*"Double check your org"*|*"Unknown API token format"*|*"ERROR"*|*"Error:"*|*"Traceback"*|*"Net::"*)
36-
echo "❌ ERROR: failed to determine whether application exists: $APP_NAME" >&2
37-
printf '%s\n' "$exists_output" >&2
38-
exit 1
39-
;;
40-
esac
41-
42-
if [[ -n "$exists_output" ]]; then
43-
echo "⚠️ cpflow exists returned non-zero output that did not match known error patterns:" >&2
44-
printf '%s\n' "$exists_output" >&2
18+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
19+
if bash "${script_dir}/check-app-exists.sh"; then
20+
:
21+
else
22+
exists_status=$?
23+
if [[ "$exists_status" -ne 1 ]]; then
24+
exit "$exists_status"
4525
fi
46-
4726
echo "⚠️ Application does not exist: $APP_NAME"
4827
exit 0
4928
fi
5029

51-
if [[ -n "$exists_output" ]]; then
52-
printf '%s\n' "$exists_output"
53-
fi
54-
5530
echo "🗑️ Deleting application: $APP_NAME"
5631
cpflow delete -a "$APP_NAME" --org "$CPLN_ORG" --yes
5732

.github/actions/cpflow-detect-release-phase/action.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,15 @@ runs:
2424
run: |
2525
set -euo pipefail
2626
27+
config_output=""
28+
if ! config_output="$(cpflow config -a "${APP_NAME}" 2>&1)"; then
29+
echo "Failed to read cpflow config for app '${APP_NAME}'" >&2
30+
printf '%s\n' "${config_output}" >&2
31+
exit 1
32+
fi
33+
2734
# Anchor to start-of-line so commented-out release_script: entries don't enable --run-release-phase.
28-
if cpflow config -a "${APP_NAME}" | grep -qE '^[[:space:]]*release_script:'; then
35+
if grep -qE '^[[:space:]]*release_script:' <<< "${config_output}"; then
2936
echo "flag=--run-release-phase" >> "$GITHUB_OUTPUT"
3037
else
3138
echo "flag=" >> "$GITHUB_OUTPUT"

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

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ run-name: "Deploy Review App - PR #${{ github.event.pull_request.number || githu
44

55
on:
66
pull_request:
7-
types: [opened, synchronize, reopened]
7+
types: [synchronize, reopened]
88
issue_comment:
99
types: [created]
1010
workflow_dispatch:
@@ -35,7 +35,7 @@ env:
3535

3636
jobs:
3737
deploy:
38-
# Skip synchronize/opened events from fork PRs at the job level — they cannot access
38+
# Skip synchronize/reopened events from fork PRs at the job level — they cannot access
3939
# repository secrets anyway, so running any steps just burns billable minutes. Users
4040
# can still manually deploy a fork PR via `/deploy-review-app` (gated below by
4141
# author_association) or workflow_dispatch.
@@ -185,26 +185,12 @@ jobs:
185185
run: |
186186
set -euo pipefail
187187
188-
# Keep this in sync with delete-app.sh. `cpflow exists` does not yet expose
189-
# distinct structured signals for not-found vs. auth/API failures.
190-
exists_output=""
191-
if exists_output="$(cpflow exists -a "${APP_NAME}" --org "${CPLN_ORG}" 2>&1)"; then
192-
if [[ -n "${exists_output}" ]]; then
193-
printf '%s\n' "${exists_output}"
194-
fi
195-
188+
if bash .github/actions/cpflow-delete-control-plane-app/check-app-exists.sh; then
196189
echo "exists=true" >> "$GITHUB_OUTPUT"
197190
else
198-
case "${exists_output}" in
199-
*"Double check your org"*|*"Unknown API token format"*|*"ERROR"*|*"Error:"*|*"Traceback"*|*"Net::"*)
200-
echo "Failed to determine whether review app exists: ${APP_NAME}" >&2
201-
printf '%s\n' "${exists_output}" >&2
202-
exit 1
203-
;;
204-
esac
205-
206-
if [[ -n "${exists_output}" ]]; then
207-
printf '%s\n' "${exists_output}"
191+
exists_status=$?
192+
if [[ "$exists_status" -ne 1 ]]; then
193+
exit "$exists_status"
208194
fi
209195
210196
echo "exists=false" >> "$GITHUB_OUTPUT"

0 commit comments

Comments
 (0)