cpflow 5.0.0.rc.1 → 5.0.0.rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{lib/github_flow_templates/.github → .github}/actions/cpflow-delete-control-plane-app/action.yml +5 -0
- data/{lib/github_flow_templates/.github → .github}/actions/cpflow-detect-release-phase/action.yml +7 -0
- data/.github/actions/cpflow-setup-environment/action.yml +161 -0
- data/.github/workflows/cpflow-cleanup-stale-review-apps.yml +69 -0
- data/.github/workflows/cpflow-delete-review-app.yml +182 -0
- data/.github/workflows/cpflow-deploy-review-app.yml +507 -0
- data/.github/workflows/cpflow-deploy-staging.yml +168 -0
- data/.github/workflows/cpflow-help-command.yml +78 -0
- data/.github/workflows/cpflow-promote-staging-to-production.yml +510 -0
- data/.github/workflows/cpflow-review-app-help.yml +51 -0
- data/.github/workflows/rspec-shared.yml +3 -0
- data/.github/workflows/trigger-docs-site.yml +90 -0
- data/.rubocop.yml +14 -1
- data/CHANGELOG.md +28 -1
- data/CONTRIBUTING.md +27 -0
- data/Gemfile.lock +2 -2
- data/README.md +7 -3
- data/cpflow.gemspec +1 -1
- data/docs/ai-github-flow-prompt.md +1 -1
- data/docs/assets/cpflow-deploying.svg +46 -0
- data/docs/ci-automation.md +111 -8
- data/docs/commands.md +11 -5
- data/docs/thruster.md +149 -0
- data/docs/troubleshooting.md +8 -0
- data/lib/command/apply_template.rb +6 -2
- data/lib/command/base.rb +1 -0
- data/lib/command/cleanup_stale_apps.rb +53 -14
- data/lib/command/delete.rb +3 -1
- data/lib/command/deploy_image.rb +5 -2
- data/lib/command/generate.rb +7 -3
- data/lib/command/generate_github_actions.rb +21 -9
- data/lib/command/generator_helpers.rb +5 -1
- data/lib/command/info.rb +3 -1
- data/lib/command/run.rb +16 -1
- data/lib/core/controlplane.rb +17 -6
- data/lib/core/controlplane_api.rb +3 -1
- data/lib/core/controlplane_api_direct.rb +50 -27
- data/lib/core/doctor_service.rb +2 -2
- data/lib/core/github_flow_readiness_service.rb +26 -2
- data/lib/core/repo_introspection.rb +41 -3
- data/lib/core/shell.rb +3 -1
- data/lib/core/terraform_config/policy.rb +1 -1
- data/lib/cpflow/version.rb +1 -1
- data/lib/cpflow.rb +27 -13
- data/lib/generator_templates/templates/rails.yml +4 -0
- data/lib/generator_templates_sqlite/templates/rails.yml +4 -0
- data/lib/github_flow_templates/.github/cpflow-help.md +30 -1
- data/lib/github_flow_templates/.github/workflows/cpflow-cleanup-stale-review-apps.yml +10 -44
- data/lib/github_flow_templates/.github/workflows/cpflow-delete-review-app.yml +15 -114
- data/lib/github_flow_templates/.github/workflows/cpflow-deploy-review-app.yml +10 -413
- data/lib/github_flow_templates/.github/workflows/cpflow-deploy-staging.yml +12 -123
- data/lib/github_flow_templates/.github/workflows/cpflow-help-command.yml +10 -33
- data/lib/github_flow_templates/.github/workflows/cpflow-promote-staging-to-production.yml +13 -475
- data/lib/github_flow_templates/.github/workflows/cpflow-review-app-help.yml +12 -30
- data/lib/github_flow_templates/bin/pin-cpflow-github-ref +72 -0
- data/lib/github_flow_templates/bin/test-cpflow-github-flow +89 -0
- data/rakelib/create_release.rake +4 -4
- metadata +26 -17
- data/lib/github_flow_templates/.github/actions/cpflow-setup-environment/action.yml +0 -98
- /data/{lib/github_flow_templates/.github → .github}/actions/cpflow-build-docker-image/action.yml +0 -0
- /data/{lib/github_flow_templates/.github → .github}/actions/cpflow-delete-control-plane-app/delete-app.sh +0 -0
- /data/{lib/github_flow_templates/.github → .github}/actions/cpflow-validate-config/action.yml +0 -0
- /data/{lib/github_flow_templates/.github → .github}/actions/cpflow-wait-for-health/action.yml +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8841c9270ad57971f444915cadf8c8572c815423a82871c8c03d85195a70764f
|
|
4
|
+
data.tar.gz: 9e480ccf6654b9bdd6229816d32ee5a2961607104c71c3b9ead8e263d10b529d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b83fb9da2665e47b6f5e518ab857883d4607f99f401573b5a4967f5050bdf79bd018ff5411b3f01336a26a06274cec42fe10353d83d28d1f725b7f60557df94
|
|
7
|
+
data.tar.gz: fb52b9cc15d8d89685b5830a67ad7bc95f08e128539c6c002a74fcde72691883a5afd40ddb61b3b7eff3695684f7816a2f2db9ca082085bb720e7a3399a98f7e
|
|
@@ -11,12 +11,17 @@ inputs:
|
|
|
11
11
|
review_app_prefix:
|
|
12
12
|
description: Prefix used for review app names
|
|
13
13
|
required: true
|
|
14
|
+
working_directory:
|
|
15
|
+
description: Directory containing the downstream project's .controlplane/controlplane.yml
|
|
16
|
+
required: false
|
|
17
|
+
default: "."
|
|
14
18
|
|
|
15
19
|
runs:
|
|
16
20
|
using: composite
|
|
17
21
|
steps:
|
|
18
22
|
- name: Delete application
|
|
19
23
|
shell: bash
|
|
24
|
+
working-directory: ${{ inputs.working_directory }}
|
|
20
25
|
run: ${{ github.action_path }}/delete-app.sh
|
|
21
26
|
env:
|
|
22
27
|
APP_NAME: ${{ inputs.app_name }}
|
data/{lib/github_flow_templates/.github → .github}/actions/cpflow-detect-release-phase/action.yml
RENAMED
|
@@ -34,6 +34,13 @@ runs:
|
|
|
34
34
|
require "yaml"
|
|
35
35
|
|
|
36
36
|
app_name = ARGV.fetch(0)
|
|
37
|
+
|
|
38
|
+
unless File.file?(".controlplane/controlplane.yml")
|
|
39
|
+
warn "Error: `.controlplane/controlplane.yml` is missing. " \
|
|
40
|
+
"cpflow-detect-release-phase must be invoked from a cpflow-configured project."
|
|
41
|
+
exit 1
|
|
42
|
+
end
|
|
43
|
+
|
|
37
44
|
data = YAML.safe_load(File.read(".controlplane/controlplane.yml"), aliases: true)
|
|
38
45
|
apps = data["apps"] || {}
|
|
39
46
|
app_config = apps[app_name]
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
name: Setup Control Plane Environment
|
|
2
|
+
description: Sets up Ruby, installs the Control Plane CLI and cpflow, and configures a default profile
|
|
3
|
+
|
|
4
|
+
inputs:
|
|
5
|
+
token:
|
|
6
|
+
description: Control Plane token
|
|
7
|
+
required: true
|
|
8
|
+
org:
|
|
9
|
+
description: Control Plane organization
|
|
10
|
+
required: true
|
|
11
|
+
ruby_version:
|
|
12
|
+
description: >-
|
|
13
|
+
Ruby version used for cpflow. When empty (the default), ruby/setup-ruby
|
|
14
|
+
auto-detects from .ruby-version, .tool-versions, mise.toml, or a Gemfile
|
|
15
|
+
ruby directive, then falls back to the action's pinned default.
|
|
16
|
+
required: false
|
|
17
|
+
default: ""
|
|
18
|
+
working_directory:
|
|
19
|
+
description: Directory where ruby/setup-ruby should detect Ruby version files.
|
|
20
|
+
required: false
|
|
21
|
+
default: "."
|
|
22
|
+
# GitHub parses double-brace expression snippets inside action metadata (including
|
|
23
|
+
# `description:`) while loading the composite action, and the `vars` context is not
|
|
24
|
+
# available in that phase. Keep these descriptions in plain prose - reference repo
|
|
25
|
+
# variables by NAME only, never with literal GitHub Actions expression syntax.
|
|
26
|
+
cpln_cli_version:
|
|
27
|
+
description: >-
|
|
28
|
+
@controlplane/cli version. Empty string falls back to the action's pinned default,
|
|
29
|
+
so callers can wire this input to the CPLN_CLI_VERSION repository variable
|
|
30
|
+
unconditionally.
|
|
31
|
+
required: false
|
|
32
|
+
default: ""
|
|
33
|
+
cpflow_version:
|
|
34
|
+
description: >-
|
|
35
|
+
cpflow gem version to install from RubyGems. Empty string installs cpflow from
|
|
36
|
+
the checked-out control-plane-flow repository, so callers can test a GitHub ref
|
|
37
|
+
without publishing a release.
|
|
38
|
+
required: false
|
|
39
|
+
default: ""
|
|
40
|
+
|
|
41
|
+
runs:
|
|
42
|
+
using: composite
|
|
43
|
+
# ruby/setup-ruby tracks Ruby/toolcache updates on a major tag. The privileged
|
|
44
|
+
# reusable workflows pin GitHub-owned actions to immutable SHAs.
|
|
45
|
+
steps:
|
|
46
|
+
- name: Resolve Ruby setup version
|
|
47
|
+
id: ruby-version
|
|
48
|
+
shell: bash
|
|
49
|
+
env:
|
|
50
|
+
INPUT_RUBY_VERSION: ${{ inputs.ruby_version }}
|
|
51
|
+
INPUT_WORKING_DIRECTORY: ${{ inputs.working_directory }}
|
|
52
|
+
run: |
|
|
53
|
+
set -euo pipefail
|
|
54
|
+
|
|
55
|
+
ruby_version="${INPUT_RUBY_VERSION}"
|
|
56
|
+
working_directory="${INPUT_WORKING_DIRECTORY:-.}"
|
|
57
|
+
# Bump when the project's minimum-supported Ruby advances.
|
|
58
|
+
default_ruby_version="3.2"
|
|
59
|
+
|
|
60
|
+
if [[ -z "${ruby_version}" ]]; then
|
|
61
|
+
if [[ -f "${working_directory}/.ruby-version" ]] ||
|
|
62
|
+
{ [[ -f "${working_directory}/.tool-versions" ]] && grep -Eq "^[[:space:]]*ruby[[:space:]]+" "${working_directory}/.tool-versions"; } ||
|
|
63
|
+
{ [[ -f "${working_directory}/mise.toml" ]] && grep -Eq "^[[:space:]]*ruby[[:space:]]*=" "${working_directory}/mise.toml"; } ||
|
|
64
|
+
{ [[ -f "${working_directory}/.mise.toml" ]] && grep -Eq "^[[:space:]]*ruby[[:space:]]*=" "${working_directory}/.mise.toml"; }; then
|
|
65
|
+
: # keep empty; ruby/setup-ruby will auto-detect
|
|
66
|
+
elif [[ -f "${working_directory}/Gemfile" ]] && grep -Eq "^[[:space:]]*ruby[[:space:]]*(\(|file:|['\"])" "${working_directory}/Gemfile"; then
|
|
67
|
+
: # keep empty; ruby/setup-ruby will read Gemfile
|
|
68
|
+
else
|
|
69
|
+
ruby_version="${default_ruby_version}"
|
|
70
|
+
fi
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
echo "ruby_version=${ruby_version}" >> "$GITHUB_OUTPUT"
|
|
74
|
+
|
|
75
|
+
- name: Set up Ruby
|
|
76
|
+
# ruby/setup-ruby intentionally tracks the v1 tag so Ruby/toolcache updates
|
|
77
|
+
# roll out automatically; Dependabot/Renovate can manage this non-GitHub action.
|
|
78
|
+
uses: ruby/setup-ruby@v1
|
|
79
|
+
with:
|
|
80
|
+
ruby-version: ${{ steps.ruby-version.outputs.ruby_version }}
|
|
81
|
+
working-directory: ${{ inputs.working_directory }}
|
|
82
|
+
|
|
83
|
+
- name: Install Control Plane CLI and cpflow gem
|
|
84
|
+
shell: bash
|
|
85
|
+
env:
|
|
86
|
+
CPLN_CLI_VERSION: ${{ inputs.cpln_cli_version }}
|
|
87
|
+
CPFLOW_VERSION: ${{ inputs.cpflow_version }}
|
|
88
|
+
CPFLOW_SOURCE_DIR: ${{ github.action_path }}/../../..
|
|
89
|
+
run: |
|
|
90
|
+
set -euo pipefail
|
|
91
|
+
|
|
92
|
+
# Bump this default when a new Control Plane CLI release should roll out by default.
|
|
93
|
+
# Override per-repo by setting the `CPLN_CLI_VERSION` repo variable.
|
|
94
|
+
default_cpln_cli_version="3.10.2"
|
|
95
|
+
|
|
96
|
+
CPLN_CLI_VERSION="${CPLN_CLI_VERSION:-${default_cpln_cli_version}}"
|
|
97
|
+
|
|
98
|
+
npm_global_prefix="${HOME}/.npm-global"
|
|
99
|
+
mkdir -p "${npm_global_prefix}"
|
|
100
|
+
echo "${npm_global_prefix}/bin" >> "$GITHUB_PATH"
|
|
101
|
+
export PATH="${npm_global_prefix}/bin:${PATH}"
|
|
102
|
+
|
|
103
|
+
npm install --global --prefix "${npm_global_prefix}" "@controlplane/cli@${CPLN_CLI_VERSION}"
|
|
104
|
+
cpln --version
|
|
105
|
+
|
|
106
|
+
if [[ -n "${CPFLOW_VERSION}" ]]; then
|
|
107
|
+
gem install cpflow -v "${CPFLOW_VERSION}" --no-document
|
|
108
|
+
else
|
|
109
|
+
cpflow_source_dir="$(cd "${CPFLOW_SOURCE_DIR}" && pwd)"
|
|
110
|
+
if [[ ! -f "${cpflow_source_dir}/cpflow.gemspec" ]]; then
|
|
111
|
+
echo "::error::CPFLOW_SOURCE_DIR (${cpflow_source_dir}) does not contain cpflow.gemspec" >&2
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
cpflow_gem="$(mktemp -t cpflow-XXXXXX.gem)"
|
|
116
|
+
trap 'rm -f "${cpflow_gem}"' EXIT
|
|
117
|
+
(
|
|
118
|
+
cd "${cpflow_source_dir}"
|
|
119
|
+
gem build cpflow.gemspec --output "${cpflow_gem}"
|
|
120
|
+
)
|
|
121
|
+
gem install "${cpflow_gem}" --no-document
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
cpflow --version
|
|
125
|
+
|
|
126
|
+
- name: Setup Control Plane profile and registry login
|
|
127
|
+
shell: bash
|
|
128
|
+
env:
|
|
129
|
+
# Pass the token via CPLN_TOKEN so cpln picks it up from the environment
|
|
130
|
+
# rather than `--token`, which would leak it into /proc/<pid>/cmdline and ps output.
|
|
131
|
+
CPLN_TOKEN: ${{ inputs.token }}
|
|
132
|
+
ORG: ${{ inputs.org }}
|
|
133
|
+
run: |
|
|
134
|
+
set -euo pipefail
|
|
135
|
+
|
|
136
|
+
if [[ -z "$CPLN_TOKEN" ]]; then
|
|
137
|
+
echo "Error: Control Plane token not provided" >&2
|
|
138
|
+
exit 1
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
if [[ -z "$ORG" ]]; then
|
|
142
|
+
echo "Error: Control Plane organization not provided" >&2
|
|
143
|
+
exit 1
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
# `cpln profile update` lists `create` as an alias (cpln profile --help) and is
|
|
147
|
+
# idempotent: it creates the profile if missing and updates it otherwise. Calling
|
|
148
|
+
# update directly avoids parsing the CLI's "already exists" English error text,
|
|
149
|
+
# which would silently swallow a real failure if the wording ever changed.
|
|
150
|
+
cpln profile update default --org "$ORG"
|
|
151
|
+
cpln image docker-login --org "$ORG"
|
|
152
|
+
|
|
153
|
+
# Keep the token available to later cpflow/cpln steps without passing it
|
|
154
|
+
# on the command line. GitHub masks secret values in logs, and the env file
|
|
155
|
+
# itself is not echoed.
|
|
156
|
+
delim="CPLN_TOKEN_DELIM_$(openssl rand -hex 8)"
|
|
157
|
+
{
|
|
158
|
+
echo "CPLN_TOKEN<<${delim}"
|
|
159
|
+
echo "${CPLN_TOKEN}"
|
|
160
|
+
echo "${delim}"
|
|
161
|
+
} >> "$GITHUB_ENV"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: Cleanup Stale Review Apps
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
control_plane_flow_ref:
|
|
7
|
+
description: Git ref used to load shared cpflow composite actions.
|
|
8
|
+
required: false
|
|
9
|
+
type: string
|
|
10
|
+
default: main
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
# Single global group: only one cleanup sweep at a time. Independent of review-app
|
|
17
|
+
# deploy/delete groups (different keys), so cleanup will not block per-PR work.
|
|
18
|
+
group: cpflow-cleanup-stale-review-apps
|
|
19
|
+
# A cancelled `cpflow cleanup-stale-apps` can leave half-deleted review apps; let
|
|
20
|
+
# the in-flight run finish before the next scheduled tick begins.
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
cleanup:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 30
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout control-plane-flow actions
|
|
29
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
30
|
+
with:
|
|
31
|
+
repository: shakacode/control-plane-flow
|
|
32
|
+
ref: ${{ inputs.control_plane_flow_ref }}
|
|
33
|
+
path: .cpflow
|
|
34
|
+
persist-credentials: false
|
|
35
|
+
|
|
36
|
+
- name: Validate required secrets and variables
|
|
37
|
+
uses: ./.cpflow/.github/actions/cpflow-validate-config
|
|
38
|
+
env:
|
|
39
|
+
CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}
|
|
40
|
+
CPLN_ORG_STAGING: ${{ vars.CPLN_ORG_STAGING }}
|
|
41
|
+
REVIEW_APP_PREFIX: ${{ vars.REVIEW_APP_PREFIX }}
|
|
42
|
+
with:
|
|
43
|
+
required: |
|
|
44
|
+
secret:CPLN_TOKEN_STAGING
|
|
45
|
+
variable:CPLN_ORG_STAGING
|
|
46
|
+
variable:REVIEW_APP_PREFIX
|
|
47
|
+
|
|
48
|
+
- name: Setup environment
|
|
49
|
+
uses: ./.cpflow/.github/actions/cpflow-setup-environment
|
|
50
|
+
with:
|
|
51
|
+
token: ${{ secrets.CPLN_TOKEN_STAGING }}
|
|
52
|
+
org: ${{ vars.CPLN_ORG_STAGING }}
|
|
53
|
+
working_directory: .cpflow
|
|
54
|
+
cpln_cli_version: ${{ vars.CPLN_CLI_VERSION }}
|
|
55
|
+
cpflow_version: ${{ vars.CPFLOW_VERSION }}
|
|
56
|
+
|
|
57
|
+
- name: Checkout caller repository
|
|
58
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
59
|
+
with:
|
|
60
|
+
persist-credentials: false
|
|
61
|
+
|
|
62
|
+
- name: Remove stale review apps
|
|
63
|
+
env:
|
|
64
|
+
REVIEW_APP_PREFIX: ${{ vars.REVIEW_APP_PREFIX }}
|
|
65
|
+
CPLN_ORG_STAGING: ${{ vars.CPLN_ORG_STAGING }}
|
|
66
|
+
shell: bash
|
|
67
|
+
run: |
|
|
68
|
+
set -euo pipefail
|
|
69
|
+
cpflow cleanup-stale-apps -a "${REVIEW_APP_PREFIX}" --org "${CPLN_ORG_STAGING}" --yes
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
name: Delete Review App
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
control_plane_flow_ref:
|
|
7
|
+
description: Git ref used to load shared cpflow composite actions.
|
|
8
|
+
required: false
|
|
9
|
+
type: string
|
|
10
|
+
default: main
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
issues: write
|
|
15
|
+
pull-requests: write
|
|
16
|
+
|
|
17
|
+
concurrency:
|
|
18
|
+
group: cpflow-delete-review-app-${{ github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }}
|
|
19
|
+
# Deletions must not cancel each other mid-flight — a cancelled `cpln` delete can leave
|
|
20
|
+
# partial state behind. Let the in-progress deletion finish before the next run starts.
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
APP_NAME: ${{ vars.REVIEW_APP_PREFIX }}-${{ github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }}
|
|
25
|
+
CPLN_ORG: ${{ vars.CPLN_ORG_STAGING }}
|
|
26
|
+
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }}
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
delete-review-app:
|
|
30
|
+
if: |
|
|
31
|
+
(github.event_name == 'issue_comment' &&
|
|
32
|
+
github.event.issue.pull_request &&
|
|
33
|
+
contains(fromJson('["+review-app-delete","+review-app-delete\n","+review-app-delete\r\n"]'), github.event.comment.body) &&
|
|
34
|
+
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
|
|
35
|
+
(github.event_name == 'pull_request_target' && github.event.action == 'closed') ||
|
|
36
|
+
github.event_name == 'workflow_dispatch'
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
timeout-minutes: 15
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- name: React to delete command
|
|
42
|
+
if: github.event_name == 'issue_comment'
|
|
43
|
+
continue-on-error: true
|
|
44
|
+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
|
|
45
|
+
with:
|
|
46
|
+
script: |
|
|
47
|
+
try {
|
|
48
|
+
await github.rest.reactions.createForIssueComment({
|
|
49
|
+
owner: context.repo.owner,
|
|
50
|
+
repo: context.repo.repo,
|
|
51
|
+
comment_id: context.payload.comment.id,
|
|
52
|
+
content: "eyes"
|
|
53
|
+
});
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (error.status === 422) {
|
|
56
|
+
core.info("Delete command reaction already exists.");
|
|
57
|
+
} else {
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- name: Checkout control-plane-flow actions
|
|
63
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
64
|
+
with:
|
|
65
|
+
repository: shakacode/control-plane-flow
|
|
66
|
+
ref: ${{ inputs.control_plane_flow_ref }}
|
|
67
|
+
path: .cpflow
|
|
68
|
+
persist-credentials: false
|
|
69
|
+
|
|
70
|
+
- name: Validate required secrets and variables
|
|
71
|
+
id: config
|
|
72
|
+
uses: ./.cpflow/.github/actions/cpflow-validate-config
|
|
73
|
+
env:
|
|
74
|
+
CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}
|
|
75
|
+
CPLN_ORG_STAGING: ${{ vars.CPLN_ORG_STAGING }}
|
|
76
|
+
REVIEW_APP_PREFIX: ${{ vars.REVIEW_APP_PREFIX }}
|
|
77
|
+
with:
|
|
78
|
+
required: |
|
|
79
|
+
secret:CPLN_TOKEN_STAGING
|
|
80
|
+
variable:CPLN_ORG_STAGING
|
|
81
|
+
variable:REVIEW_APP_PREFIX
|
|
82
|
+
pull_request_friendly: "true"
|
|
83
|
+
|
|
84
|
+
- name: Checkout repository
|
|
85
|
+
if: steps.config.outputs.ready == 'true'
|
|
86
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
|
87
|
+
with:
|
|
88
|
+
path: app
|
|
89
|
+
persist-credentials: false
|
|
90
|
+
|
|
91
|
+
- name: Setup environment
|
|
92
|
+
if: steps.config.outputs.ready == 'true'
|
|
93
|
+
uses: ./.cpflow/.github/actions/cpflow-setup-environment
|
|
94
|
+
with:
|
|
95
|
+
token: ${{ secrets.CPLN_TOKEN_STAGING }}
|
|
96
|
+
org: ${{ vars.CPLN_ORG_STAGING }}
|
|
97
|
+
working_directory: app
|
|
98
|
+
cpln_cli_version: ${{ vars.CPLN_CLI_VERSION }}
|
|
99
|
+
cpflow_version: ${{ vars.CPFLOW_VERSION }}
|
|
100
|
+
|
|
101
|
+
- name: Set workflow links
|
|
102
|
+
if: steps.config.outputs.ready == 'true'
|
|
103
|
+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
|
|
104
|
+
with:
|
|
105
|
+
script: |
|
|
106
|
+
const workflowUrl = `${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
|
|
107
|
+
core.exportVariable("WORKFLOW_URL", workflowUrl);
|
|
108
|
+
core.exportVariable(
|
|
109
|
+
"CONSOLE_URL",
|
|
110
|
+
`https://console.cpln.io/console/org/${process.env.CPLN_ORG}/-info`
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
- name: Create initial PR comment
|
|
114
|
+
if: steps.config.outputs.ready == 'true'
|
|
115
|
+
id: create-comment
|
|
116
|
+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
|
|
117
|
+
with:
|
|
118
|
+
script: |
|
|
119
|
+
const body = [
|
|
120
|
+
"## 🗑️ Deleting review app...",
|
|
121
|
+
"",
|
|
122
|
+
`_Removing the review app for PR #${process.env.PR_NUMBER}_`
|
|
123
|
+
].join("\n");
|
|
124
|
+
|
|
125
|
+
const comment = await github.rest.issues.createComment({
|
|
126
|
+
owner: context.repo.owner,
|
|
127
|
+
repo: context.repo.repo,
|
|
128
|
+
issue_number: Number(process.env.PR_NUMBER),
|
|
129
|
+
body
|
|
130
|
+
});
|
|
131
|
+
core.setOutput("comment-id", comment.data.id);
|
|
132
|
+
|
|
133
|
+
- name: Delete review app
|
|
134
|
+
if: steps.config.outputs.ready == 'true'
|
|
135
|
+
uses: ./.cpflow/.github/actions/cpflow-delete-control-plane-app
|
|
136
|
+
with:
|
|
137
|
+
app_name: ${{ env.APP_NAME }}
|
|
138
|
+
cpln_org: ${{ vars.CPLN_ORG_STAGING }}
|
|
139
|
+
review_app_prefix: ${{ vars.REVIEW_APP_PREFIX }}
|
|
140
|
+
working_directory: app
|
|
141
|
+
|
|
142
|
+
# Finalizer still runs after delete failures, but only after config validation
|
|
143
|
+
# created the initial PR comment and workflow link env vars it updates.
|
|
144
|
+
- name: Finalize delete status
|
|
145
|
+
if: always() && steps.config.outputs.ready == 'true'
|
|
146
|
+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
|
|
147
|
+
env:
|
|
148
|
+
COMMENT_ID: ${{ steps.create-comment.outputs.comment-id }}
|
|
149
|
+
JOB_STATUS: ${{ job.status }}
|
|
150
|
+
with:
|
|
151
|
+
script: |
|
|
152
|
+
const commentId = Number(process.env.COMMENT_ID);
|
|
153
|
+
const success = process.env.JOB_STATUS === "success";
|
|
154
|
+
const body = success
|
|
155
|
+
? [
|
|
156
|
+
"## ✅ Review App Deleted",
|
|
157
|
+
"",
|
|
158
|
+
`_Review app for PR #${process.env.PR_NUMBER} is deleted_`,
|
|
159
|
+
"",
|
|
160
|
+
`🎮 [Control Plane Console](${process.env.CONSOLE_URL})`,
|
|
161
|
+
`📋 [View Workflow Logs](${process.env.WORKFLOW_URL})`
|
|
162
|
+
].join("\n")
|
|
163
|
+
: [
|
|
164
|
+
"## ❌ Failed to Delete Review App",
|
|
165
|
+
"",
|
|
166
|
+
`_Failed to delete review app for PR #${process.env.PR_NUMBER}_`,
|
|
167
|
+
"",
|
|
168
|
+
`🎮 [Control Plane Console](${process.env.CONSOLE_URL})`,
|
|
169
|
+
`📋 [View Workflow Logs](${process.env.WORKFLOW_URL})`
|
|
170
|
+
].join("\n");
|
|
171
|
+
|
|
172
|
+
if (!Number.isFinite(commentId) || commentId <= 0) {
|
|
173
|
+
core.warning("Skipping delete status comment update because no comment id was created.");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
await github.rest.issues.updateComment({
|
|
178
|
+
owner: context.repo.owner,
|
|
179
|
+
repo: context.repo.repo,
|
|
180
|
+
comment_id: commentId,
|
|
181
|
+
body
|
|
182
|
+
});
|