Skip to main content

Changelog

All notable changes to this project's source code will be documented in this file. Items under Unreleased are upcoming features that will be out in the next version.

Contributors

Please follow the recommendations outlined at keepachangelog.com. Please use the existing headings and styling as a guide, and add a link for the version diff at the bottom of the file. Also, please update the Unreleased link to compare it to the latest release version.

In addition to the standard keepachangelog.com categories, this project uses a local ### Breaking Changes heading at the top of each version section to surface backwards-incompatible changes. The release tooling treats that heading as a signal to require a major version bump (see expected_bump_type_from_changelog_section in rakelib/create_release.rake).

Versions

Unreleased

6.0.0 - 2026-09-08

Breaking Changes

  • BREAKING CHANGE: Raised the minimum supported Ruby version from 3.0 to 3.2. Users on Ruby 3.0 or 3.1 must upgrade Ruby before installing the next major cpflow release. CI now tests each supported Ruby minor from 3.2 through 3.4. PR 464 by Justin Gordon.

Changed

  • Bumped the pinned GitHub Actions in the generated production-promotion workflow and this repository's reusable workflows to actions/checkout 7.0.1, actions/github-script 9.0.0, and docker/setup-buildx-action 4.3.0. Downstream repositories pick up the template change with cpflow update-github-actions. PR 460 by Justin Gordon. Fixes issue 459.
  • Changed generated GitHub Actions to check in cpflow's composite actions under .github/actions/cpflow-* and refresh them with cpflow update-github-actions. Reusable workflows now load those local actions from the caller repository's trusted event revision, while the separately pinned checkout at .cpflow supplies the cpflow runtime source. Downstream repositories must commit generated workflows and local actions together when upgrading. PR 451 by Justin Gordon. Part of issue 375.
  • Made update-github-actions preserve downstream workflows by default and require explicit --workflows selection to add or replace them. Ambiguous staging configuration and differing legacy validators fail before writes. Downstream checks can use the preserved bin/test-cpflow-github-flow-custom extension. SHA pins require a reviewed --version label, and the migration guide documents generated action allowlists. PR 476 by Justin Gordon. Fixes issue 473.
  • Trimmed the RubyGems post-install message to a three-line generated-workflow reminder with a link to the full update and validation instructions. PR 447 by Justin Gordon. Fixes issue 377.

Fixed

  • Fixed the generated bin/pin-cpflow-github-ref helper so -h and --help print usage and exit successfully before inspecting repository state. PR 474 by Justin Gordon. Fixes issue 473.
  • Kept no-argument releases pinned to the latest changelog version during retries, and blocked implicit prerelease-to-stable promotion. If an interrupted release already bumped the gem version or created its tag, rerunning bundle exec rake release no longer falls through to a stable release that is absent from the changelog. PR 472 by Justin Gordon.
  • Loaded the caller's generated .github/actions/cpflow-* through actions/checkout's trusted default in the reusable review-app deploy, delete, and stale-cleanup workflows. Dropping the explicit ref: still resolves to the revision GitHub already recorded for the triggering event (GITHUB_SHA, the base-branch tip under pull_request_target), and a default checkout is never inspected by the fork-PR checkout guard added in actions/checkout 7.0.0. The previous explicit github.event.pull_request.base.sha pin in the delete workflow could trip that guard, and fail teardown, when a fork PR was closed by a manual fast-forward that left the recorded base SHA equal to the PR head. Review-app teardown consequently runs the base-tip copy of the generated actions rather than the pull request's recorded pre-merge base, which matters only if the merge itself changed those actions. Downstream repositories pick up the change when cpflow update-github-actions bumps the reusable-workflow ref. PR 467 by Justin Gordon. Fixes issue 463.
  • Gave pull_request_target an explicit branch in the reusable review-app deploy source validator. The reusable workflow's event allowlist admits pull_request_target, but the deploy source validator handled only pull_request and issue_comment. It now treats pull_request_target exactly like pull_request, skipping fork pull requests with the documented deploy-skipped summary, as defence-in-depth for callers that rewire the deploy trigger. The shipped caller templates never send that event, so no existing deployment behavior changes and same-repository pull requests are unaffected. PR 467 by Justin Gordon. Fixes issue 462.
  • Prevented shell interpretation of dynamic Control Plane CLI and Docker arguments. Resource names, image references, container names, locations, and other dynamic values now remain literal argv elements; output suppression and stderr capture use process redirection options without rebuilding a shell command. Fixes issue 452. PR 458 by Justin Gordon.
  • Fixed scheduled slow-suite regressions in stale-app workload suspension, invalid upstream-token handling, transient workload image deployment, and delayed one-off job output. cleanup-stale-apps --mode=stop now skips configured workloads absent from a stale app, upstream authorization failures cleanly remove their temporary profile and stderr capture, workload image updates retry for a bounded window before failing, and non-interactive cpflow run commands drain logs for a bounded post-terminal window so delayed ingestion does not drop completed job output. Slow-suite command logs and failure artifacts now redact token options and explicitly supplied sensitive values. PR 413 by Justin Gordon. Addresses issue 409.
  • Queued every pending shared-org Slow and Specific RSpec run instead of letting GitHub replace an older waiter. Fast runs keep their per-PR or per-ref queue, while the domain-mutating suites use GitHub's bounded queue: max behavior in one repository-wide concurrency group. PR 457 by Justin Gordon. Fixes issue 403.
  • Bounded cpflow run status reconciliation after a non-interactive command finishes. When Control Plane keeps reporting a cron job as active or pending after the command completion marker, cpflow run now waits up to a configurable 20-minute grace period and then exits nonzero with the job, replica, and last observed status instead of polling forever. Addresses the bounded-reconciliation portion of HiChee issue 10375. PR 453 by Justin Gordon.

Security

  • Hardened generated Docker builds that use SSH private dependencies. Private keys now enter ssh-agent through standard input instead of being persisted between composite-action steps, invocation-local cleanup runs even when execution stops before the build, and pre-existing known_hosts state is preserved across success and failure. PR 477 and PR 478 by Justin Gordon. Fixes issue 473.

5.3.0 - 2026-09-02

Added

  • Added an early diagnostic warning when a shared_secret_grants target still uses the generated Postgres password placeholder. setup-app and deploy-image now identify the affected grant and secret before release or deployment work without printing secret values. PR 441 by Justin Gordon. Fixes issue 421.
  • Added CPFLOW_GVC_ID and CPFLOW_GVC_CREATED to the environment of one-off jobs started by cpflow run, exposing the app's immutable GVC identity so that a release script can tell which GVC incarnation it is running in. PR 433 by Justin Gordon. Fixes issue 432. Unlike the mutable CPLN_GVC_ALIAS, these values identify the GVC incarnation itself, so they change only when a GVC is deleted and recreated under the same name. CPFLOW_GVC_CREATED is an ISO 8601 UTC timestamp with millisecond precision and a Z suffix. Both variables are always set and are empty when the GVC cannot be read, so a consumer can fail closed; they are never omitted, because the runner inherits the original workload's environment and an omitted variable could otherwise expose a stale inherited value.
  • Added bounded retry with exponential backoff to direct Control Plane API requests. PR 416 by Justin Gordon. Fixes issue 383. With the default request policy, GET requests retry transient network errors and retryable HTTP responses for up to three attempts; another attempt is approved only when the retry decision occurs before a 120-second deadline. Delta-seconds Retry-After values are honored up to a 10-second cap; HTTP-date values fall back to jittered backoff. Under that policy, explicit HTTP 429 responses are retried for every method. Best-effort sensitive requests disable all transient retries. Mutating requests are not retried after ambiguous transport failures once they may have reached the server. Net::HTTP's hidden resend of PUT and DELETE requests is disabled. A failed cpln profile token lookup now raises an actionable error instead of continuing with unusable output.

Changed

  • Simplified generated review-app help comments to a three-command quick reference, moved setup behind expandable details, and clarified GitHub Actions secret and variable terminology. PR 410 by Justin Gordon.
  • Updated reusable GitHub Actions setup to install Control Plane CLI 3.11.0 by default. PR 423 by Justin Gordon.

Fixed

  • Fixed cpflow run runner observation so a missing replica no longer relies on the generic 1,001-poll retry loop or exits without the cron status. PR 435 by Justin Gordon. Replica observation now uses a monotonic deadline capped by the smaller of runner_job_timeout and 1,000 seconds, stops polling when that deadline is reached, fails immediately on terminal non-success, and preserves replica-found and success-before-replica behavior.
  • Fixed review-app deploy and delete authorization failing while recording accepted intent comments. PR 449 by Justin Gordon. The authorization job now has the PR write permission GitHub requires to post bot-owned comments on pull requests. Follow-up to issue 442.
  • Made successful review-app checks report when they skipped the Docker image build. PR 444 by Justin Gordon. Fixes issue 412. The reusable workflow now writes a prominent no-build summary and exposes image_built=false, while generated guidance explains that repositories needing Dockerfile validation should use a separate required build gate.
  • Fixed cpflow run argument corruption and shell interpolation when command arguments contain spaces, quotes, dollar signs, backticks, or semicolons. PR 443 by Justin Gordon. Fixes issue 381. Separately supplied arguments are shell-escaped at the remote runner boundary, while one quoted command string remains an explicit opt-in to shell syntax; the local cpln workload exec invocation now uses process argv instead of a shell-built command string.
  • Fixed generated review-app deploy and delete commands so only the newest accepted operation can mutate an app, even when GitHub replaces a pending concurrency run or authorization finishes out of order. PR 440 by Justin Gordon. Fixes issue 427. GitHub now verifies manual actors have current write, maintain, or admin repository permission both before and after queueing, rejects closed-PR deploys before recording, records accepted triggers as durable bot-owned intents, authenticates each intent against its originating Actions run and successful recording step, binds internal redispatches to the workflow-run ID returned by GitHub and its exact successful dispatch step, and fails closed on lookup or ledger inconsistencies. Edits or deletion of the original command, mixed-case command admission, manual dispatch, and GitHub's single replaceable pending concurrency slot can no longer make an older deploy override a newer delete (or the reverse). After upgrading, run cpflow update-github-actions so the generated deploy and delete caller workflows adopt the new run-name and reconcile_intent_run_id contract; a caller that only bumps the uses: ref is rejected during provenance reconciliation.
  • Fixed direct Control Plane API retries so HTTP 429 responses retry every request method and honor Retry-After, while 5xx retries remain limited to idempotent methods. PR 439 by Justin Gordon. Fixes issue 417.
  • Fixed the spec suite leaking dummy-test-* GVCs that exhausted the CI org's GVC quota and blocked later runs. PR 434 by Justin Gordon. Fixes issue 399. Apps are now registered for after(:suite) cleanup by the command runner before an app-creating command runs, so a command that fails after creating the GVC, or an example that fails before its own teardown, no longer leaves the app behind. A before(:suite) sweep additionally reclaims apps leaked by runs that were killed before cleanup could run. The sweep is confined to the suite's own org and to the anchored dummy-test-* fixture naming boundary, never touches an app younger than 12 hours or one belonging to the current run, keeps anything it cannot positively identify as stale, and reports rather than raises on failure. This change is limited to the spec suite; no gem behavior changes.
  • Fixed review-app deletion leaving successful GitHub deployments active after the Control Plane app was removed. PR 430 by Justin Gordon.
  • Fixed template refreshes for existing apps whose workload-list response omits readiness status by consulting each workload's detailed state before selecting a safe fallback image. PR 429 by Justin Gordon.
  • Fixed reusable deployment health checks on BYOK locations by falling back from a disabled standard workload endpoint only after every location is settled, while preserving configured app_domain review-app links and using the verified location endpoint as the final URL fallback. PR 426 by Justin Gordon.
  • Fixed template refresh recovery for unhealthy or partially deployed review apps by preserving each workload's configured app image independently, while limiting missing-image fallbacks to one unambiguous image from ready workloads. PR 425 by Justin Gordon.
  • Fixed reusable review-app deployments so existing apps receive changes from configured setup_app_templates before the new image is deployed, without deleting the GVC, rerunning post-creation hooks, replacing deployed images before rollout gates pass, or modifying existing secret resources. PR 424 by Justin Gordon.
  • Fixed cpflow deploy-image crashing when an internal-only workload has no public endpoint. Deployments now consult the existing deployment fallback and report when no public endpoint is available. PR 423 by Justin Gordon.
  • Fixed generated review-app status links so reusable deployments prefer the deployed app domain instead of the raw Control Plane workload endpoint. PR 395 by Justin Gordon.

5.2.0 - 2026-07-10

Added

  • Added ordered per-workload deploys with repeatable cpflow deploy-image -w/--workload filtering and optional deploy_order groups in controlplane.yml. PR 397 by Justin Gordon. Fixes issue 396. cpflow deploy-image can now deploy selected app workloads, and production promotion inherits deploy_order so workloads such as a Node renderer can roll out and become ready before Rails.
  • Added generic telemetry documentation for deploying an OpenTelemetry Collector with Control Plane Flow, including collector workload templates, application instrumentation, telemetry pipelines, review-app isolation, and troubleshooting guidance. PR 369 by Justin Gordon.
  • Added a Rails-focused Grafana and OpenTelemetry guide for building Control Plane dashboards from generated span and log metrics, including collector workload guidance, spanmetrics setup, rollout order, alerting, and validation checklists. PR 352 by Justin Gordon.
  • Added review-app security documentation for repositories with external contributors, covering disposable secrets, PR-controlled identity and policy templates, and staging-token least privilege. PR 350 by Justin Gordon.

Changed

  • Removed the generated pre_deletion: rails db:drop example from controlplane.yml so new configurations do not encourage teardown that can fail while app workloads still hold database connections. PR 348 by Justin Gordon.
  • Updated the generated GitHub Actions help and AI rollout prompt to recommend Capacity AI for idle standard workloads and clarify the separate serverless scale-to-zero path. PR 364 by Justin Gordon.
  • Updated cpflow ai-github-flow-prompt so rollout agents install a missing cpflow gem or clearly report the installation blocker. PR 371 by Justin Gordon.

Fixed

  • Fixed doctor and setup-app template validation to inspect only configured setup_app_templates, avoiding duplicate-resource errors from unused alternative templates while preserving the all-template fallback. PR 363 by Justin Gordon.
  • Fixed generated review-app deploy workflows so they wait for workload readiness and an accepted HTTP response before marking a GitHub deployment successful. PR 363 by Justin Gordon.
  • Fixed cpflow crashing at load time with invalid byte sequence in US-ASCII (ArgumentError) on systems without a UTF-8 locale. PR 404 by Justin Gordon. Command::Base.all_commands now reads command files with an explicit UTF-8 encoding instead of relying on Encoding.default_external. Fixes issue 372.

5.1.1 - 2026-06-03

Changed

  • Changed cpflow maintenance:on and cpflow maintenance:off to confirm the domain route has switched by polling the Control Plane API (bounded retry, 30 attempts, 1 second apart) instead of sleeping a fixed 30 seconds. PR 337 by Justin Gordon. Fixes issue 157. If the route never updates within the poll window, the command aborts before stopping workloads so traffic stays on the current workload, and transient API errors during polling are retried rather than aborting the switch. Because the route switch and the workload stop run as separate steps, re-running the command also finishes a switch whose poll timed out after the route had already updated.
  • Reworked generated production-promotion image copy to authenticate directly to the staging and production Docker registries and copy via docker buildx imagetools create, handling digest-pinned, plain numeric, commit-suffixed, and multi-arch image refs. PR 356 by Justin Gordon. Promotion now normalizes Control Plane org variables before each step, preflights environment-variable parity between staging and production at the GVC and app-workload container level (failing before the copy when production is missing names that exist in staging), and requires both status.ready and status.readyLatest before endpoint health checks and rollback polling so a stale ready replica cannot mask a failed latest revision.
  • Generated production promotion now emits a workflow warning when a staging image tag lacks a _<commit> suffix, so production tags without commit traceability are visible in logs, and documents the cpflow-promote-staging-to-production concurrency group in the copy step. PR 360 by Justin Gordon.
  • Restored review-app security guidance in generated .github/cpflow-help.md (public-repo staging-token scoping, fork-PR deploy limits, secret exposure via cpln://secret/..., and read-only deploy keys for DOCKER_BUILD_SSH_KEY), and simplified the promotion workflow's staging image assignment while preserving digest refs. PR 359 by Justin Gordon.

Fixed

  • Fixed cpflow run so short non-interactive runner jobs no longer hang when the Control Plane cron job finishes before a runner replica is visible. PR 361 by Justin Gordon. This prevents generated deploy workflows with release-phase commands from waiting until the GitHub Actions job timeout even though the release job already completed successfully.

5.1.0 - 2026-06-02

Added

  • Added shared_secret_grants configuration so apps can reference org-level Control Plane secrets by name instead of hardcoding them in templates. PR 354 by Justin Gordon. Each grant validates a unique placeholder, a safe Control Plane resource name, and a secret policy that targets exactly that secret; templates gain {{SHARED_SECRET_<NAME>}} substitution, and the shared-policy lifecycle is wired through setup-app, deploy-image, delete, and cleanup-stale-apps. Enables the shared staging-database pattern for cheaper review apps.

Fixed

  • Fixed cpflow generate-github-actions so the generated .github/cpflow-help.md version-locking example derives a CPFLOW_VERSION=<major>.<minor>.x placeholder from the installed gem version instead of a hardcoded release that goes stale against the @v<version> wrapper refs in the same file. PR 343 by Justin Gordon. Fixes issue 341.
  • Fixed generated production promotion so cpflow-promote-staging-to-production.yml runs as a caller-owned job with environment: production, letting GitHub inject the CPLN_TOKEN_PRODUCTION environment secret after the protected gate instead of failing because a cross-repo reusable workflow cannot receive caller environment secrets. PR 353 by Justin Gordon. The job checks out the pinned control-plane-flow ref into .cpflow, and generated help plus docs/ci-automation.md now explain why a same-named repository or organization secret can mask a missing environment secret.
  • Hardened generated production promotion image copy to preflight the staging image, retry the copy via configurable COPY_IMAGE_RETRIES and COPY_IMAGE_RETRY_INTERVAL repo vars, and roll back failed deploys using spec.containers.<name>.image paths instead of unsupported array-index paths. PR 355 by Justin Gordon.

5.0.4 - 2026-05-27

Fixed

  • Fixed cpflow CLI boot order so packaged gems load cpflow/version before command modules, preventing a load-time NameError on Cpflow::VERSION from constants like Command::UpdateGithubActions::LONG_DESCRIPTION. PR 338 by Justin Gordon. Fixes issue 335.

5.0.3 - 2026-05-26

Changed

  • Changed cpflow update-github-actions, cpflow generate-github-actions --force, RubyGems install guidance, and release-task follow-up output so downstream repositories remember to update checked-in generated GitHub Actions wrappers when the cpflow gem version changes. PR 328 by Justin Gordon.

Fixed

  • Fixed cpflow update-github-actions so reordered default staging branches remain defaults, empty or non-hash staging workflow YAML no longer crashes, and fresh repos fail with a clear generate-github-actions instruction instead of silently creating wrappers. PR 331 by Justin Gordon. Clarified the RubyGems post-install message so first-time installers see the generate-github-actions path.

5.0.2 - 2026-05-25

Fixed

  • Fixed generated Dockerfiles so Node package-manager shims (npm, npx, and corepack) remain working symlinks in the final Ruby image instead of broken dereferenced files. PR 322 by Justin Gordon. Generated Dockerfiles now fail fast if the Node shim paths are no longer valid.
  • Fixed generated Control Plane templates so app workloads receive app identity links, templated YAML scalars are parseable, and generated Postgres resources/secrets are app-scoped. PR 322 by Justin Gordon. This lets review apps resolve cpln://secret/... values reliably from Rails, worker, renderer, and release jobs.
  • Fixed cpflow run so existing runner workloads stay in sync with the source workload identityLink. PR 322 by Justin Gordon. Existing runner jobs now gain or drop the app identity as the source workload changes.

5.0.1 - 2026-05-24

Breaking Changes

  • BREAKING CHANGE: Generated GitHub Actions wrappers now pin Control Plane Flow only through the uses: shakacode/control-plane-flow/...@<ref> line and no longer accept downstream control_plane_flow_ref inputs. Repositories with older generated wrappers must regenerate or remove control_plane_flow_ref from with: blocks to avoid validation failures. PR 321 by Justin Gordon.

Changed

  • Simplified generated review-app help docs to a compact command/setup reference and moved extended guidance to upstream CI automation docs. PR 319 by Justin Gordon.
  • Clarified generated PR-open help opt-out guidance for forks and clones, including a sample job if: guard in generated wrappers. PR 323 by Justin Gordon.
  • Improved generated GitHub Actions ref/gem alignment checks so CPFLOW_VERSION must match the ref pinned via uses: shakacode/control-plane-flow/...@<ref>, and setup validates the checked-out action code against the remote tag/commit for that ref. PR 318 by Justin Gordon.
  • Improved review-app workflow config inference so generated deploy/delete/cleanup workflows can derive the review-app prefix and staging Control Plane org from .controlplane/controlplane.yml; testing review apps normally requires only the CPLN_TOKEN_STAGING secret. PR 318 by Justin Gordon.
  • Improved production promotion safety docs and generated workflow validation for using a protected production GitHub Environment with required reviewers and a production-only CPLN_TOKEN_PRODUCTION environment secret. PR 318 by Justin Gordon.

Fixed

  • Fixed generated Control Plane entrypoints so database preparation runs through ./bin/rails, fails fast, and runs only for generated Rails server commands instead of every workload sharing the image. PR 318 by Justin Gordon. Generated Dockerfiles run from WORKDIR /app; apps with custom Dockerfiles that run the entrypoint from another directory should adjust the ./bin/rails db:prepare path after regenerating. Apps with hand-edited .controlplane/entrypoint.sh files should audit custom commands when regenerating, especially Thruster invocations with custom flags and startup paths that relied on continuing after a failed database connection.
  • Fixed generated Dockerfiles so copied Control Plane entrypoints are marked executable inside the image even if the source file mode is lost. PR 318 by Justin Gordon.
  • Fixed generated review-app deploy/delete/cleanup workflows so they use one shared cpflow-resolve-review-config composite action instead of duplicated YAML parsing logic. PR 318 by Justin Gordon.
  • Fixed generated production-promotion caller wrappers so they pass only CPLN_TOKEN_STAGING; CPLN_TOKEN_PRODUCTION remains on the protected GitHub Environment where GitHub exposes it after approval. PR 318 by Justin Gordon.

5.0.0 - 2026-05-23

Breaking Changes

  • Promotes the 5.x release-candidate line to stable. The breaking changes introduced during the 5.0.0 prerelease cycle are documented in 5.0.0.rc.1, including the Ruby 3.0 minimum, cpflow exists not-found exit code change, and generated Dockerfile production-group behavior.

Changed

  • Promoted the 5.0.0 release-candidate line to stable. This release includes the generated GitHub Actions flow, upstream reusable workflow model, Node 24 action updates, richer review-app command feedback, generated downstream pin/validation helpers, and cleanup/run/deploy fixes documented in 5.0.0.rc.3.

Fixed

  • Fixed packaged cpflow gems failing to boot without the development-only debug gem installed. PR 314 by Justin Gordon. The hidden cpflow test command no longer requires debug while loading the CLI, and coverage now exercises loading cpflow with require "debug" blocked.

5.0.0.rc.3 - 2026-05-23

Added

  • Added --mode=stop to cleanup-stale-apps for reversible idle-app handling. PR 302 by Justin Gordon. Suspends all workloads via cpflow ps:stop instead of deleting; restore with cpflow ps:start. Default --mode=delete preserves existing behavior. Fixes issue 295.
  • Added generated local helpers for downstream GitHub Actions ref pinning and validation. PR 308 by Justin Gordon. cpflow generate-github-actions now writes bin/pin-cpflow-github-ref and bin/test-cpflow-github-flow so downstream repos can safely pin wrappers to release tags or full upstream commit SHAs, validate wrapper ref consistency, and test unreleased upstream workflow changes without using moving branch refs.
  • Added richer generated review-app command feedback. PR 304 by Justin Gordon. Generated review-app deploy/delete/help workflows now react promptly to commands, publish structured progress/success/failure comments, and support REVIEW_APP_DEPLOYING_ICON_URL or none for the deploying indicator.

Changed

  • Changed generated GitHub Actions output to thin downstream wrappers backed by upstream reusable workflows and shared composite actions. PR 305 by Justin Gordon. Deployment, deletion, staging, promotion, cleanup, comment formatting, Control Plane setup, and Docker image build logic now live upstream in this repository; CPFLOW_GITHUB_ACTIONS_REF controls which upstream ref generated wrappers use.
  • Documented the downstream testing and release model for reusable GitHub Actions. PR 308 by Justin Gordon. The CI automation docs now spell out what is tied to the upstream GitHub ref, what is tied to the RubyGems version, how CPFLOW_VERSION changes runtime installation, and how to test an unmerged upstream PR from a downstream app.
  • Updated generated GitHub Actions workflow templates to Node 24-compatible action versions. PR 303 by Justin Gordon. Uses actions/checkout@v6 and actions/github-script@v8.
  • Shortened the generated review-app command quick reference. PR 290 by Justin Gordon. Keeps the three +review-app-* commands and the setup-help pointer while reducing repeated wording in the PR-open comment.

Fixed

  • Relaxed the thor runtime dependency from ~> 1.4 to ~> 1.3. PR 291 by Justin Gordon. Allows cpflow to be bundled into Rails 8 apps that pull in solid_queue 1.1.0, which pins thor ~> 1.3.1. Fixes issue 264.
  • Fixed deploy-image showing container names instead of workload names in deploy progress and endpoint summaries. PR 294 by Justin Gordon. Also guards against duplicate work per workload by deploying only the first container whose image matches the app-image pattern. Fixes issue 255.
  • Fixed cpflow run interactive sessions printing a confusing non-zero exit error on command failure or session close. PR 301 by Justin Gordon. cpflow now prints an actionable cpflow ps:stop hint instead; exit code 64 is returned for non-zero exits and 130 for signal termination so scripted callers can still detect failure. Fixes issue 199.
  • Fixed cpflow generate and generated GitHub Actions edge cases. PR 288 by Justin Gordon. Detects nested production SQLite configs, normalizes folded Shakapacker precompile hooks, gates delete-review-app steps on config readiness, routes github-script values through environment variables, and honors HTTPS proxy settings during registry readiness checks.
  • Fixed generated cpflow-setup-environment Ruby setup when downstream apps do not provide a Ruby version file. PR 306 by Justin Gordon. The shared action now auto-detects .ruby-version, .tool-versions, mise.toml, .mise.toml, or a Gemfile Ruby directive and falls back to Ruby 3.2 when none is present.
  • Fixed cpflow-detect-release-phase failing with a raw Ruby traceback when .controlplane/controlplane.yml is missing. PR 299 by Justin Gordon. The generated composite action now exits with a clear missing-config message.
  • Fixed generated review-app delete workflows running cpflow delete from the wrong checkout. PR 307 by Justin Gordon. The generated workflow checks out the downstream repository into app/ and runs setup/delete from that working directory so .controlplane/controlplane.yml is available.
  • Fixed cleanup-stale-apps skipping image-less GVCs indefinitely. PR 310 by Justin Gordon. Image-less GVCs now fall back to the GVC created timestamp for stale-app detection, while GVCs missing created are skipped instead of raising.

5.0.0.rc.1 - 2026-05-11

Breaking Changes

  • BREAKING CHANGE: Bumped minimum Ruby version from 2.7.0 to 3.0.0. Users still on Ruby 2.7 must upgrade to Ruby 3.0 or newer before installing cpflow 5.x. PR 258 by Justin Gordon.
  • BREAKING CHANGE: cpflow exists now returns exit code 3 when the app is not found, preserving 64 for real errors so scripts can distinguish not-found from API/auth failures. Affected callers: only scripts that branched specifically on [ $? -eq 64 ] as a "not found" signal — those will now misroute "not found" into the error branch and must switch to checking for exit 3. Scripts that treat any non-zero exit as "not found" are unaffected. The change is isolated to lib/command/exists.rb and lib/constants/exit_code.rb (NOT_FOUND = 3), so users hitting a regression can bisect by file. PR 278 by Justin Gordon.
  • BREAKING CHANGE: cpflow generate now writes bundle config set with 'production' in the generated Dockerfile, dropping the previous 'staging production' group set. Apps that placed gems specifically under a staging: group in their Gemfile (e.g. APM agents, observability libraries that should ship to staging) must move those gems into the production: group before regenerating, or the regenerated Dockerfile will exclude them at install time. New scaffolds are unaffected. PR 278 by Justin Gordon.

Added

  • Added the GitHub Actions flow generator and readiness checks for staging, review-app, and production-promotion workflows. PR 278 by Justin Gordon.
  • Added use-digest-image-ref (also configurable through use_digest_image_ref in controlplane.yml) option to deploy-image and promote-app-from-upstream commands. PR 249 by Zakir Dzhamaliddinov.

Changed

  • Renamed the generated review-app PR comment commands to a namespaced +review-app-* family. PR 285 by Justin Gordon. /deploy-review-app+review-app-deploy, /delete-review-app+review-app-delete, and /help+review-app-help. The + prefix avoids collision with GitHub's reserved slash-command surface and makes the three commands obviously part of one namespaced family. Repos that ran cpflow generate-github-actions against 5.0.0.rc.0 must regenerate the generated .github/workflows/cpflow-*.yml files and .github/cpflow-help.md, then update saved instructions or runbooks.
  • Updated runtime dependencies: dotenv (~> 2.8.1 → > 3.1), jwt (> 2.8.1 → > 3.1), psych (> 5.1.0 → > 5.2), and thor (> 1.2.1 → ~> 1.4). PR 258 by Justin Gordon.

4.2.0 - 2026-02-19

Added

  • Suppress Node.js deprecation warnings from internal cpln calls by setting NODE_NO_WARNINGS=1, producing cleaner cpflow output. PR 256 by Judah Meek.

Fixed

  • Fixed issue where run command could hang indefinitely when updating runner workload. PR 260 by Sergey Tarasov.

Security

  • Redact sensitive data (Authorization headers, tokens) from --trace output. PR 261 by Sergey Tarasov.

4.1.1 - 2025-03-14

Fixed

  • Fixed issue where ps, ps:start, ps:stop, ps:wait, and run commands fail when trying to fetch replicas with CPLN CLI. PR 254 by Rafael Gomes.

4.1.0 - 2024-12-17

Fixed

  • Fixed issue where run command fails when runner workload has ENV but original workload does not. PR 227 by Rafael Gomes.
  • Fixed potential infinite loop that could occur for a command if one of the execution steps fails and gets stuck. PR 217 by Zakir Dzhamaliddinov.
  • Fixed issue where app cannot be deleted because one of the workloads has a volumeset in-use. PR 245 by Zakir Dzhamaliddinov.
  • Fixed resolv may be not properly required PR 250 by Sergey Tarasov.

Added

4.0.0 - 2024-08-21

Fixed

3.0.1 - 2024-06-26

Fixed

3.0.0 - 2024-06-21

First release of cpflow.

2.2.4 - 2024-06-21

Deprecated cpl gem. New gem is cpflow.

2.2.1 - 2024-06-17

Fixed

  • Fixed issue where latest image may be incorrect. PR 201 by Rafael Gomes.
  • Fixed issue where build-image command hangs forever waiting for image to be available. PR 201 by Rafael Gomes.

2.2.0 - 2024-06-07

Fixed

  • Fixed issue where ps:wait command hangs forever if workloads are suspended. PR 198 by Rafael Gomes.

Added

  • Added a timeout for run jobs (6 hours by default, but configurable through runner_job_timeout in controlplane.yml). PR 194 by Rafael Gomes.

Changed

  • run command now overrides the --image, --cpu, and --memory for each job separately, which completely removes any race conditions when running simultaneous jobs with different overrides. PR 182 by Rafael Gomes.
  • run jobs now use a CPU size of 1 (1 core) and a memory size of 2Gi (2 gibibytes) by default (configurable through runner_job_default_cpu and runner_job_default_memory in controlplane.yml). PR 182 by Rafael Gomes.
  • run command now keeps ENV values synced between original and runner workloads. PR 196 by Rafael Gomes.

2.1.0 - 2024-05-27

Fixed

Added

  • Added post-creation hook to setup-app command (configurable through hooks.post_creation in controlplane.yml). PR 183 by Rafael Gomes.
  • Added pre-deletion hook to delete command (configurable through hooks.pre_deletion in controlplane.yml). PR 183 by Rafael Gomes.
  • Added doctor command to run validations. PR 185 by Rafael Gomes.

Changed

  • cpflow now sets CPLN_SKIP_UPDATE_CHECK to true for all internal cpln calls, which disables the version check and prevents cluttering the logs. PR 180 by Rafael Gomes.
  • setup-app command now automatically creates a secret, policy, and identity for the app if they do not exist. The --skip-secrets-setup option prevents this behavior. PR 181 by Rafael Gomes. PR 190 by Rafael Gomes.
  • Specific validations are now run before commands, and the command will exit with a non-zero code if any validation fails. Can be disabled by setting DISABLE_VALIDATIONS env var to true. PR 185 by Rafael Gomes.
  • Deprecated the --skip-secret-access-binding option in favor of --skip-secrets-setup. This can also now be configured through skip_secrets_setup in controlplane.yml PR 190 by Rafael Gomes.

2.0.2 - 2024-05-18

  • Fixed issue with improper handling of job statuses. Fixed issue with interactive magic string showing and exit code. PR 177 by Sergey Tarasov.

2.0.1 - 2024-05-16

Fixed

  • Fixed issue where cleanup-stale-apps command fails to delete apps with volumesets. PR 175 by Rafael Gomes.

2.0.0 - 2024-05-15

BREAKING CHANGES

  • Commands that finished with a failure now exit with code 64 instead of 1. PR 132 by Rafael Gomes.
  • Bumped minimum cpln version to 2.0.1 (cpln workload cron get is required). PR 171 by Rafael Gomes.
  • run:cleanup command has been removed. PR 151 by Rafael Gomes.
  • deploy-image command now runs the release script in the context of the run command. PR 151 by Rafael Gomes.

Fixed

Added

  • Added options to run command to override the workload container's --cpu, --memory, and --entrypoint. PR 151 by Rafael Gomes.
  • Added --workload option to delete command to delete a specific workload. PR 151 by Rafael Gomes.
  • Added --replica option to logs command to see logs from a specific replica. PR 151 by Rafael Gomes.
  • Added --replica option to ps:stop command to stop a specific replica. PR 151 by Rafael Gomes.
  • Added option to set custom names for secrets and secrets policy, using secrets_name and secrets_policy_name in controlplane.yml. PR 159 by Rafael Gomes.

Changed

  • An error is now raised if the org does not exist. PR 167 by Rafael Gomes.
  • Common options are now shown in help. PR 169 by Rafael Gomes.
  • run command now uses a single reusable cron workload and works for both interactive and non-interactive jobs. PR 151 by Rafael Gomes.
  • run:detached command has been deprecated in favor of run. PR 151 by Rafael Gomes.
  • deploy-image command now raises an error if image does not exist. PR 153 by Rafael Gomes.
  • delete command now unbinds identity from policy (if bound) when deleting app. PR 170 by Rafael Gomes.

1.4.0 - 2024-03-21

Added

  • Added new template substitution variables (used by apply-template and setup-app commands): {{APP_LOCATION_LINK}}, {{APP_IMAGE_LINK}}, {{APP_IDENTITY}}, {{APP_IDENTITY_LINK}}, {{APP_SECRETS}} and {{APP_SECRETS_POLICY}}. PR 146 by Rafael Gomes.
  • Added --run-release-phase option to deploy-image command to run release script before deploying (same step as in promote-app-from-upstream command). PR 146 by Rafael Gomes.

Changed

  • Template substitution (used by apply-template and setup-app commands) now uses double braces (e.g., APP_ORG -> {{APP_ORG}}). This change is backwards compatible. PR 146 by Rafael Gomes.
  • Renamed template substitution variable APP_GVC to {{APP_NAME}} (used by apply-template and setup-app commands). This change is backwards compatible. PR 146 by Rafael Gomes.
  • setup-app command now automatically binds the app to the secrets policy, as long as both the identity and the policy exist. Added --skip-secret-access-binding option to prevent this behavior. PR 146 by Rafael Gomes.
  • Local API token is now refreshed when it is about to expire. PR 146 by Rafael Gomes.
  • apply-template command now exits with non-zero code if failed to apply any templates. PR 146 by Rafael Gomes.

1.3.0 - 2024-03-19

Fixed

  • Fixed issue where cpln profile was not switched back to default if an error happened while running copy-image-from-upstream command. PR 135 by Rafael Gomes.
  • Fixed issue that didn't allow using upstream with match_if_app_name_starts_with set to true in copy-image-from-upstream command. PR 136 by Rafael Gomes.

Added

  • Added --no-clean-on-failure option to run:detached command to skip deletion of failed workload run. PR 133 by Justin Gordon and Rafael Gomes.
  • Added --domain option to maintenance, maintenance:on and maintenance:off commands. PR 131 by Rafael Gomes.
  • Added default_domain config to specify domain for maintenance, maintenance:on and maintenance:off commands. PR 131 by Rafael Gomes.
  • Added option to specify upstream for copy-image-from-upstream command through CPLN_UPSTREAM env var. PR 138 by Rafael Gomes.

Changed

  • build-image command now accepts extra options and passes them to docker build. PR 126 by Rafael Gomes.
  • CPLN_ORG_UPSTREAM env var now takes precedence over config from controlplane.yml in copy-image-from-upstream command. PR 137 by Rafael Gomes.
  • info command now works properly for apps with match_if_app_name_starts_with set to true.PR 139 by Rafael Gomes.
  • info command now lists workloads in the same order as controlplane.yml. PR 139 by Rafael Gomes.
  • Improved domain workload matching for maintenance, maintenance:on and maintenance:off commands (instead of matching only by workload, it now matches by org + app + workload, which is more accurate). PR 140 by Rafael Gomes.

1.2.0 - 2024-01-04

Fixed

  • Fixed issue where info command does not respect CPLN_ORG env var. PR 88 by Rafael Gomes.
  • Fixed issues with running cpflow --version and cpflow --help where no configuration file exists. PR 109 by Mostafa Ahangarha.
  • Fixed issue where delete command fails to delete apps with volumesets. PR 123 by Rafael Gomes.

Added

  • Added --org option to all commands. PR 88 by Rafael Gomes.
  • Added option to set the app with a CPLN_APP env var. PR 88 by Rafael Gomes.
  • Show org and app on every command excluding info, version, maintenance, env, ps, and latest_image. PR 94 by Mostafa Ahangarha.
  • Added option to only use CPLN_ORG and CPLN_APP env vars if allow_org_override_by_env and allow_app_override_by_env configs are set to true in controlplane.yml. PR 109 by Rafael Gomes.
  • Added CPLN_LOCATION env variable and --location option for apply-template, ps, run, run:detached. PR 105 by Mostafa Ahangarha.
  • Added generate command for creating basic Control Plane configuration directory. PR 116 by Mostafa Ahangarhga.
  • Added --trace option to all commands for more detailed logs. PR 124 by Justin Gordon.
  • Added better error message to check the org name in case of a 403 error. PR 124 by Justin Gordon.

Changed

  • --org option now takes precedence over CPLN_ORG env var, which takes precedence over cpln_org from controlplane.yml. PR 88 by Rafael Gomes.
  • Renamed setup config into setup_app_templates. PR 112 by Mostafa Ahangarha.

1.1.2 - 2023-10-25

Fixed

  • Fixed failed build on MacOS by adding platform flag and fixed multiple files in yaml document for template. PR 81 by Justin Gordon.

Added

  • Added open-console command to open the app console on Control Plane. PR 83 by Rafael Gomes.
  • Added option to set the org with a CPLN_ORG/CPLN_ORG_UPSTREAM env var. PR 83 by Rafael Gomes.
  • Added --verbose option to all commands for more detailed logs. PR 83 by Rafael Gomes.

Changed

1.1.1 - 2023-09-21

Fixed

  • Fixed issue where API token is not reset when switching profile. PR 77 by Rafael Gomes.

1.1.0 - 2023-09-20

Fixed

  • Fixed issue where copy-image-from-upstream command does not copy commit. PR 70 by Rafael Gomes.
  • Fixed issue where an error is not raised if the app is not defined. PR 73 by Rafael Gomes.
  • Fixed issue where CPLN_ENDPOINT is not used if available. PR 75 by Rafael Gomes.

Added

  • Added image_retention_max_qty config to clean up images based on max quantity with cleanup-images command. PR 72 by Rafael Gomes.

Changed

  • Updated docs for run commands regarding passing arguments at the end. PR 71 by Rafael Gomes.
  • Renamed cleanup-old-images command to cleanup-images. PR 72 by Rafael Gomes.
  • Renamed old_image_retention_days config to image_retention_days. PR 72 by Rafael Gomes.

1.0.4 - 2023-07-24

Fixed

  • Fixed issue where run commands fail when not providing image. PR 68 by Rafael Gomes.

1.0.3 - 2023-07-07

Fixed

Added

1.0.2 - 2023-07-02

Added

1.0.1 - 2023-06-28

Fixed

  • Fixed cleanup-stale-apps command when app does not have image. PR 55 by Rafael Gomes.

Changed

1.0.0 - 2023-05-29

First release.