cpflow 5.3.0 → 6.0.0

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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.agents/agent-workflow.yml +16 -25
  3. data/.agents/bin/README.md +19 -9
  4. data/.agents/bin/docs +1 -1
  5. data/.agents/bin/lint +1 -1
  6. data/.agents/bin/setup +1 -1
  7. data/.agents/bin/test +1 -1
  8. data/.agents/bin/validate +2 -1
  9. data/.agents/legacy-workflow-policy.yml +11 -0
  10. data/.agents/shaka.md +20 -0
  11. data/.agents/trusted-actions.yml +12 -0
  12. data/.coderabbit.yaml +14 -0
  13. data/.github/actions/cpflow-build-docker-image/action.yml +153 -22
  14. data/.github/actions/cpflow-delete-control-plane-app/action.yml +2 -1
  15. data/.github/actions/cpflow-delete-control-plane-app/delete-app.sh +3 -0
  16. data/.github/actions/cpflow-preview-promotion/action.yml +82 -0
  17. data/.github/actions/cpflow-preview-promotion/preview-promotion.sh +90 -0
  18. data/.github/actions/cpflow-setup-environment/action.yml +8 -6
  19. data/.github/dependabot.yml +10 -0
  20. data/.github/workflows/check_cpln_links.yml +6 -1
  21. data/.github/workflows/claude-code-review.yml +5 -2
  22. data/.github/workflows/claude.yml +6 -4
  23. data/.github/workflows/coderabbit-lifecycle-review.yml +29 -0
  24. data/.github/workflows/command_docs.yml +7 -2
  25. data/.github/workflows/cpflow-cleanup-stale-review-apps.yml +12 -5
  26. data/.github/workflows/cpflow-delete-review-app.yml +18 -11
  27. data/.github/workflows/cpflow-deploy-review-app.yml +38 -17
  28. data/.github/workflows/cpflow-deploy-staging.yml +28 -11
  29. data/.github/workflows/cpflow-help-command.yml +3 -3
  30. data/.github/workflows/cpflow-promote-staging-to-production.yml +135 -16
  31. data/.github/workflows/cpflow-review-app-help.yml +1 -1
  32. data/.github/workflows/rspec-shared.yml +34 -26
  33. data/.github/workflows/rspec-specific.yml +10 -2
  34. data/.github/workflows/rspec.yml +95 -4
  35. data/.github/workflows/rubocop.yml +9 -2
  36. data/.github/workflows/trigger-docs-site.yml +2 -0
  37. data/.rubocop.yml +6 -1
  38. data/AGENTS.md +18 -3
  39. data/CHANGELOG.md +39 -1
  40. data/CONTRIBUTING.md +39 -2
  41. data/Gemfile.lock +1 -1
  42. data/README.md +10 -2
  43. data/cpflow.gemspec +3 -15
  44. data/docs/ai-github-flow-prompt.md +3 -3
  45. data/docs/ci-automation.md +284 -68
  46. data/docs/commands.md +38 -15
  47. data/docs/postgres-review-apps.md +90 -0
  48. data/docs/postgres.md +233 -375
  49. data/docs/rds-private-networking.md +12 -12
  50. data/docs/releasing.md +15 -4
  51. data/docs/secrets-and-env-values.md +42 -0
  52. data/docs/sidebars.ts +1 -0
  53. data/examples/controlplane.yml +5 -0
  54. data/lib/command/ai_github_flow_prompt.rb +2 -2
  55. data/lib/command/apply_template.rb +36 -4
  56. data/lib/command/base.rb +56 -3
  57. data/lib/command/cleanup_stale_apps.rb +28 -4
  58. data/lib/command/copy_image_from_upstream.rb +3 -0
  59. data/lib/command/delete.rb +174 -4
  60. data/lib/command/deploy_image.rb +44 -1
  61. data/lib/command/generate.rb +247 -3
  62. data/lib/command/generate_github_actions.rb +43 -13
  63. data/lib/command/run.rb +224 -34
  64. data/lib/command/setup_app.rb +92 -10
  65. data/lib/command/update_github_actions.rb +82 -43
  66. data/lib/core/config.rb +73 -0
  67. data/lib/core/controlplane.rb +167 -80
  68. data/lib/core/controlplane_api.rb +28 -2
  69. data/lib/core/controlplane_api_direct.rb +17 -0
  70. data/lib/core/disposable_postgres_helpers.rb +167 -0
  71. data/lib/core/doctor_service.rb +7 -0
  72. data/lib/core/github_flow_readiness/checks.rb +2 -1
  73. data/lib/core/github_flow_readiness_service.rb +4 -0
  74. data/lib/core/repo_introspection.rb +112 -2
  75. data/lib/core/shell.rb +35 -10
  76. data/lib/core/timed_command.rb +111 -0
  77. data/lib/cpflow/version.rb +1 -1
  78. data/lib/cpflow.rb +1 -1
  79. data/lib/generator_templates/.dockerignore +16 -0
  80. data/lib/generator_templates/Dockerfile +9 -5
  81. data/lib/generator_templates/entrypoint.sh +2 -0
  82. data/lib/generator_templates/templates/postgres.yml +9 -0
  83. data/lib/generator_templates_sqlite/controlplane.yml +2 -1
  84. data/lib/generator_templates_sqlite/release_script.sh +1 -1
  85. data/lib/generator_templates_sqlite/templates/rails.yml +2 -1
  86. data/lib/github_flow_templates/.github/cpflow-help.md +39 -12
  87. data/lib/github_flow_templates/.github/workflows/cpflow-deploy-review-app.yml +1 -0
  88. data/lib/github_flow_templates/.github/workflows/cpflow-deploy-staging.yml +1 -0
  89. data/lib/github_flow_templates/.github/workflows/cpflow-promote-staging-to-production.yml +135 -16
  90. data/lib/github_flow_templates/bin/pin-cpflow-github-ref +37 -13
  91. data/lib/github_flow_templates/bin/test-cpflow-github-flow +125 -46
  92. data/lib/patches/hash.rb +2 -2
  93. data/rakelib/create_release.rake +14 -14
  94. data/script/check_shell_scripts +66 -0
  95. metadata +18 -17
data/lib/patches/hash.rb CHANGED
@@ -27,8 +27,8 @@ class Hash
27
27
  private
28
28
 
29
29
  # Copied from Rails
30
- def deep_transform_keys(&block)
31
- deep_transform_keys_in_object(self, &block)
30
+ def deep_transform_keys(&)
31
+ deep_transform_keys_in_object(self, &)
32
32
  end
33
33
 
34
34
  # Copied from Rails
@@ -22,8 +22,9 @@ desc("Releases the cpflow Ruby gem.
22
22
  3. Enter the RubyGems OTP when prompted.
23
23
 
24
24
  With no version argument, the task reads the latest versioned CHANGELOG.md
25
- header and uses it when it is newer than the current gem version. Otherwise,
26
- it falls back to a patch bump.
25
+ header and uses it when it is newer than or equal to the current gem version.
26
+ It falls back to a patch bump only when the current version is stable and the
27
+ changelog does not name the current or a newer version.
27
28
 
28
29
  1st argument: Version (optional). Supported values:
29
30
  patch, minor, major, 4.2.0, or 4.2.0.rc.1
@@ -205,10 +206,15 @@ module Release
205
206
 
206
207
  version = parse_gem_version_components(current_gem_version)
207
208
 
209
+ if version[:prerelease_type] && version_input.to_s.strip.casecmp?("patch")
210
+ abort <<~ERROR
211
+ Automatic patch bumps are not allowed from prerelease version #{current_gem_version}.
212
+ Pass an explicit version instead so a retry cannot accidentally promote a prerelease to stable.
213
+ ERROR
214
+ end
215
+
208
216
  case version_input.to_s.strip.downcase
209
217
  when "patch"
210
- return "#{version[:major]}.#{version[:minor]}.#{version[:patch]}" if version[:prerelease_type]
211
-
212
218
  "#{version[:major]}.#{version[:minor]}.#{version[:patch] + 1}"
213
219
  when "minor"
214
220
  "#{version[:major]}.#{version[:minor] + 1}.0"
@@ -269,10 +275,8 @@ module Release
269
275
  return changelog_version
270
276
  end
271
277
 
272
- if changelog_version &&
273
- Gem::Version.new(changelog_version) == Gem::Version.new(current_version) &&
274
- !version_tagged?(gem_root, changelog_version)
275
- puts "Found untagged CHANGELOG.md version: #{changelog_version} (current: #{current_version})"
278
+ if changelog_version && Gem::Version.new(changelog_version) == Gem::Version.new(current_version)
279
+ puts "Found current CHANGELOG.md version: #{changelog_version}"
276
280
  return changelog_version
277
281
  end
278
282
 
@@ -308,10 +312,6 @@ module Release
308
312
  tags_output.lines.map(&:strip).filter_map { |tag| parse_release_tag_to_gem_version(tag) }.uniq
309
313
  end
310
314
 
311
- def version_tagged?(gem_root, version)
312
- tagged_release_gem_versions(gem_root, fetch_tags: true).include?(version)
313
- end
314
-
315
315
  def version_bump_type(previous_stable_gem_version:, target_gem_version:)
316
316
  previous = parse_gem_version_components(previous_stable_gem_version)
317
317
  target = parse_gem_version_components(target_gem_version)
@@ -479,8 +479,8 @@ module Release
479
479
  match[:repo]
480
480
  end
481
481
 
482
- def capture_gh_output(*args)
483
- Open3.capture2e("gh", *args)
482
+ def capture_gh_output(*)
483
+ Open3.capture2e("gh", *)
484
484
  rescue Errno::ENOENT
485
485
  abort "GitHub CLI (`gh`) is not installed. Install it from https://cli.github.com/ and retry."
486
486
  end
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ repo_root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
5
+ cd "$repo_root"
6
+
7
+ if ! command -v shellcheck >/dev/null 2>&1; then
8
+ echo "ShellCheck is required; install it and ensure shellcheck is on PATH." >&2
9
+ exit 127
10
+ fi
11
+
12
+ # Add, rename, or remove extensionless shell entrypoints here. See .agents/bin/README.md.
13
+ extensionless_shell_files=(
14
+ .agents/bin/docs
15
+ .agents/bin/lint
16
+ .agents/bin/setup
17
+ .agents/bin/test
18
+ .agents/bin/validate
19
+ lib/github_flow_templates/bin/test-cpflow-github-flow
20
+ script/check_command_docs
21
+ script/check_cpln_links
22
+ script/check_shell_scripts
23
+ script/precommit/check_command_docs
24
+ script/precommit/check_cpln_links
25
+ script/precommit/check_trailing_newlines
26
+ script/precommit/get_changed_files
27
+ script/precommit/ruby_autofix
28
+ script/precommit/ruby_lint
29
+ spec/dummy/bin/dev
30
+ )
31
+
32
+ # A file preserves NUL-separated names while letting us check Git's exit status.
33
+ inventory_file=$(mktemp)
34
+ trap 'rm -f -- "$inventory_file"' EXIT
35
+ if ! git ls-files -z -- '*.sh' '*.bash' "${extensionless_shell_files[@]}" >"$inventory_file"; then
36
+ echo "Unable to read tracked shell inventory." >&2
37
+ exit 1
38
+ fi
39
+
40
+ shell_files=()
41
+ while IFS= read -r -d '' file; do
42
+ if [ ! -r "$file" ]; then
43
+ echo "Tracked shell script is not readable: $file" >&2
44
+ exit 1
45
+ fi
46
+ shell_files+=("$file")
47
+ done < "$inventory_file"
48
+
49
+ if [ "${#shell_files[@]}" -eq 0 ]; then
50
+ echo "No tracked shell scripts found." >&2
51
+ exit 1
52
+ fi
53
+
54
+ for file in "${extensionless_shell_files[@]}"; do
55
+ if [ ! -f "$file" ] || [ ! -r "$file" ]; then
56
+ echo "Declared shell entrypoint is not a readable file: $file" >&2
57
+ exit 1
58
+ fi
59
+ done
60
+
61
+ if ! git ls-files --error-unmatch -- "${extensionless_shell_files[@]}" >/dev/null; then
62
+ echo "Declared extensionless shell scripts must be tracked; update the inventory for renamed or removed files." >&2
63
+ exit 1
64
+ fi
65
+
66
+ shellcheck -- "${shell_files[@]}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
@@ -82,23 +82,31 @@ files:
82
82
  - ".agents/bin/setup"
83
83
  - ".agents/bin/test"
84
84
  - ".agents/bin/validate"
85
+ - ".agents/legacy-workflow-policy.yml"
86
+ - ".agents/shaka.md"
87
+ - ".agents/trusted-actions.yml"
85
88
  - ".agents/trusted-github-actors.yml"
86
89
  - ".agents/workflows/address-review.md"
87
90
  - ".agents/workflows/ai-rollout-e2e-test.md"
88
91
  - ".claude/commands/address-review.md"
89
92
  - ".claude/commands/update-changelog.md"
93
+ - ".coderabbit.yaml"
90
94
  - ".github/actions/cpflow-build-docker-image/action.yml"
91
95
  - ".github/actions/cpflow-delete-control-plane-app/action.yml"
92
96
  - ".github/actions/cpflow-delete-control-plane-app/delete-app.sh"
93
97
  - ".github/actions/cpflow-detect-release-phase/action.yml"
98
+ - ".github/actions/cpflow-preview-promotion/action.yml"
99
+ - ".github/actions/cpflow-preview-promotion/preview-promotion.sh"
94
100
  - ".github/actions/cpflow-resolve-review-config/action.yml"
95
101
  - ".github/actions/cpflow-setup-environment/action.yml"
96
102
  - ".github/actions/cpflow-validate-config/action.yml"
97
103
  - ".github/actions/cpflow-wait-for-health/action.yml"
104
+ - ".github/dependabot.yml"
98
105
  - ".github/pull_request_template.md"
99
106
  - ".github/workflows/check_cpln_links.yml"
100
107
  - ".github/workflows/claude-code-review.yml"
101
108
  - ".github/workflows/claude.yml"
109
+ - ".github/workflows/coderabbit-lifecycle-review.yml"
102
110
  - ".github/workflows/command_docs.yml"
103
111
  - ".github/workflows/cpflow-cleanup-stale-review-apps.yml"
104
112
  - ".github/workflows/cpflow-delete-review-app.yml"
@@ -151,6 +159,7 @@ files:
151
159
  - docs/dns.md
152
160
  - docs/grafana-opentelemetry.md
153
161
  - docs/migrating-heroku-to-control-plane.md
162
+ - docs/postgres-review-apps.md
154
163
  - docs/postgres.md
155
164
  - docs/rds-private-networking.md
156
165
  - docs/redis.md
@@ -222,6 +231,7 @@ files:
222
231
  - lib/core/controlplane.rb
223
232
  - lib/core/controlplane_api.rb
224
233
  - lib/core/controlplane_api_direct.rb
234
+ - lib/core/disposable_postgres_helpers.rb
225
235
  - lib/core/doctor_service.rb
226
236
  - lib/core/github_flow_readiness/checks.rb
227
237
  - lib/core/github_flow_readiness_service.rb
@@ -247,9 +257,11 @@ files:
247
257
  - lib/core/terraform_config/workload/main.tf
248
258
  - lib/core/terraform_config/workload/required_providers.tf
249
259
  - lib/core/terraform_config/workload/variables.tf
260
+ - lib/core/timed_command.rb
250
261
  - lib/cpflow.rb
251
262
  - lib/cpflow/version.rb
252
263
  - lib/deprecated_commands.json
264
+ - lib/generator_templates/.dockerignore
253
265
  - lib/generator_templates/Dockerfile
254
266
  - lib/generator_templates/controlplane.yml
255
267
  - lib/generator_templates/entrypoint.sh
@@ -281,6 +293,7 @@ files:
281
293
  - script/add_command
282
294
  - script/check_command_docs
283
295
  - script/check_cpln_links
296
+ - script/check_shell_scripts
284
297
  - script/precommit/check_command_docs
285
298
  - script/precommit/check_cpln_links
286
299
  - script/precommit/check_trailing_newlines
@@ -304,21 +317,9 @@ licenses:
304
317
  metadata:
305
318
  rubygems_mfa_required: 'true'
306
319
  post_install_message: |
307
- cpflow 5.3.0 installed.
308
-
309
- If this repository already uses generated cpflow GitHub Actions, update the
310
- checked-in wrappers so GitHub loads the matching control-plane-flow release tag:
311
-
312
- cpflow update-github-actions
313
- bin/test-cpflow-github-flow
314
-
315
- If you run cpflow through Bundler:
316
-
317
- bundle exec cpflow update-github-actions
318
- bin/test-cpflow-github-flow bundle exec cpflow
319
-
320
- New repository? Run `cpflow generate-github-actions` first to create the
321
- wrappers (and the `bin/test-cpflow-github-flow` script referenced above).
320
+ cpflow 6.0.0 installed.
321
+ Generated GitHub Actions users: run `cpflow update-github-actions` after upgrading.
322
+ Docs: https://github.com/shakacode/control-plane-flow/blob/main/docs/ci-automation.md#updating-generated-github-actions-after-gem-updates
322
323
  rdoc_options: []
323
324
  require_paths:
324
325
  - lib
@@ -326,7 +327,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
326
327
  requirements:
327
328
  - - ">="
328
329
  - !ruby/object:Gem::Version
329
- version: 3.0.0
330
+ version: '3.2'
330
331
  required_rubygems_version: !ruby/object:Gem::Requirement
331
332
  requirements:
332
333
  - - ">="