cpflow 4.2.0 → 5.0.0.rc.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.
- checksums.yaml +4 -4
- data/.claude/commands/update-changelog.md +367 -0
- data/.github/workflows/claude.yml +5 -0
- data/.overcommit.yml +43 -3
- data/.rubocop.yml +3 -3
- data/CHANGELOG.md +28 -4
- data/CONTRIBUTING.md +6 -0
- data/Gemfile +8 -7
- data/Gemfile.lock +92 -72
- data/README.md +43 -15
- data/cpflow.gemspec +5 -5
- data/docs/ai-github-flow-prompt.md +61 -0
- data/docs/ci-automation.md +335 -28
- data/docs/commands.md +65 -4
- data/docs/releasing.md +153 -0
- data/lib/command/ai_github_flow_prompt.rb +47 -0
- data/lib/command/base.rb +14 -0
- data/lib/command/cleanup_images.rb +1 -1
- data/lib/command/cleanup_stale_apps.rb +1 -1
- data/lib/command/copy_image_from_upstream.rb +14 -3
- data/lib/command/exists.rb +13 -2
- data/lib/command/generate.rb +153 -4
- data/lib/command/generate_github_actions.rb +170 -0
- data/lib/command/generator_helpers.rb +31 -0
- data/lib/command/github_flow_readiness.rb +37 -0
- data/lib/command/run.rb +1 -1
- data/lib/command/terraform/generate.rb +1 -0
- data/lib/command/version.rb +1 -0
- data/lib/constants/exit_code.rb +1 -0
- data/lib/core/controlplane.rb +9 -7
- data/lib/core/controlplane_api_direct.rb +3 -3
- data/lib/core/github_flow_readiness/checks.rb +143 -0
- data/lib/core/github_flow_readiness_service.rb +453 -0
- data/lib/core/repo_introspection.rb +118 -0
- data/lib/core/terraform_config/dsl.rb +1 -1
- data/lib/core/terraform_config/local_variable.rb +1 -1
- data/lib/cpflow/version.rb +1 -1
- data/lib/cpflow.rb +65 -3
- data/lib/generator_templates/Dockerfile +59 -3
- data/lib/generator_templates/controlplane.yml +27 -39
- data/lib/generator_templates/entrypoint.sh +1 -1
- data/lib/generator_templates/release_script.sh +23 -0
- data/lib/generator_templates/templates/app.yml +5 -8
- data/lib/generator_templates/templates/rails.yml +2 -11
- data/lib/generator_templates_sqlite/controlplane.yml +46 -0
- data/lib/generator_templates_sqlite/release_script.sh +25 -0
- data/lib/generator_templates_sqlite/templates/app.yml +15 -0
- data/lib/generator_templates_sqlite/templates/db.yml +6 -0
- data/lib/generator_templates_sqlite/templates/rails.yml +32 -0
- data/lib/generator_templates_sqlite/templates/storage.yml +6 -0
- data/lib/github_flow_templates/.github/actions/cpflow-build-docker-image/action.yml +131 -0
- data/lib/github_flow_templates/.github/actions/cpflow-delete-control-plane-app/action.yml +24 -0
- data/lib/github_flow_templates/.github/actions/cpflow-delete-control-plane-app/delete-app.sh +50 -0
- data/lib/github_flow_templates/.github/actions/cpflow-detect-release-phase/action.yml +62 -0
- data/lib/github_flow_templates/.github/actions/cpflow-setup-environment/action.yml +98 -0
- data/lib/github_flow_templates/.github/actions/cpflow-validate-config/action.yml +85 -0
- data/lib/github_flow_templates/.github/actions/cpflow-wait-for-health/action.yml +92 -0
- data/lib/github_flow_templates/.github/cpflow-help.md +47 -0
- data/lib/github_flow_templates/.github/workflows/cpflow-cleanup-stale-review-apps.yml +56 -0
- data/lib/github_flow_templates/.github/workflows/cpflow-delete-review-app.yml +142 -0
- data/lib/github_flow_templates/.github/workflows/cpflow-deploy-review-app.yml +445 -0
- data/lib/github_flow_templates/.github/workflows/cpflow-deploy-staging.yml +140 -0
- data/lib/github_flow_templates/.github/workflows/cpflow-help-command.yml +53 -0
- data/lib/github_flow_templates/.github/workflows/cpflow-promote-staging-to-production.yml +490 -0
- data/lib/github_flow_templates/.github/workflows/cpflow-review-app-help.yml +46 -0
- data/rakelib/create_release.rake +662 -37
- data/script/check_command_docs +4 -2
- data/script/check_cpln_links +25 -11
- data/script/precommit/check_command_docs +22 -0
- data/script/precommit/check_cpln_links +21 -0
- data/script/precommit/check_trailing_newlines +68 -0
- data/script/precommit/get_changed_files +49 -0
- data/script/precommit/ruby_autofix +52 -0
- data/script/precommit/ruby_lint +33 -0
- metadata +52 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e14982bee2d97f3eb32cc1d9927989313b7a91b025c4096d062360353822aa65
|
|
4
|
+
data.tar.gz: 29b22bf0f213441d8ee82d115c84c13fa6bd9306b86ca1618a2540a45a1d389e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 993fe9b78e665e737aab285e5bafd066f523c58f4f7cfcdebc3a829293aeb2d700d65ac731ab533cda9ec51d2c0c06f953712cf66ca6ee3d5007ba5501fcee0f
|
|
7
|
+
data.tar.gz: b3dee476a72d21cfdbfa9032c3d249c8cc3c15bb1b297b7a4c2103be30ef5b167648aacf592d3c866b65a256cf09eff0ac4c502931e1d9451915633ff4fa7172
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
# Update Changelog
|
|
2
|
+
|
|
3
|
+
You are helping to add an entry to the CHANGELOG.md file for the cpflow gem (the `shakacode/control-plane-flow` repository).
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
This command accepts an optional argument: `$ARGUMENTS`
|
|
8
|
+
|
|
9
|
+
- **No argument** (`/update-changelog`): Add entries to `[Unreleased]` without stamping a version header. Use this during development.
|
|
10
|
+
- **`release`** (`/update-changelog release`): Add entries and stamp a version header. Auto-compute the next version based on changes (breaking -> major, added features -> minor, fixes -> patch). Then `bundle exec rake release` (with no args) will pick up this version automatically.
|
|
11
|
+
- **`rc`** (`/update-changelog rc`): Same as `release`, but stamps an RC prerelease version (e.g., `5.0.0.rc.0`). Auto-increments the RC index if prior RCs exist for the same base version.
|
|
12
|
+
- **`beta`** (`/update-changelog beta`): Same as `rc`, but stamps a beta prerelease version (e.g., `5.0.0.beta.0`).
|
|
13
|
+
- **Explicit version** (`/update-changelog 5.0.0.rc.10`): Add entries and stamp the exact version provided. Skips auto-computation — use this when you already know the target version. The version string must look like a RubyGems-style version (with optional `.rc.N`, `.beta.N`, `.alpha.N`, `.pre.N`, or `.test.N` suffix).
|
|
14
|
+
|
|
15
|
+
## When to Use This
|
|
16
|
+
|
|
17
|
+
This command serves three use cases at different points in the release lifecycle:
|
|
18
|
+
|
|
19
|
+
**During development** -- Add entries to `[Unreleased]` as PRs merge:
|
|
20
|
+
|
|
21
|
+
- Run `/update-changelog` to find merged PRs missing from the changelog
|
|
22
|
+
- Entries accumulate under `## [Unreleased]`
|
|
23
|
+
|
|
24
|
+
**Before a release** -- Stamp a version header and prepare for release:
|
|
25
|
+
|
|
26
|
+
- Run `/update-changelog release` (or `rc`, `beta`, or an explicit version like `5.0.0.rc.10`) to add entries AND stamp the version header
|
|
27
|
+
- The version is auto-computed from changes (breaking -> major, features -> minor, fixes -> patch) — skipped when an explicit version is provided
|
|
28
|
+
- The command automatically commits, pushes, and opens a PR — review and merge it
|
|
29
|
+
- Then run `bundle exec rake release` (no args needed -- it reads the version from CHANGELOG.md)
|
|
30
|
+
- The release task automatically creates a GitHub release from the changelog section
|
|
31
|
+
|
|
32
|
+
**After a release you forgot to update the changelog for** -- Catch-up mode:
|
|
33
|
+
|
|
34
|
+
- The command can retroactively find commits between tags and add missing entries
|
|
35
|
+
- Ask the user whether to stamp a version header or add to `[Unreleased]`
|
|
36
|
+
|
|
37
|
+
### Why changelog comes BEFORE the release
|
|
38
|
+
|
|
39
|
+
- `bundle exec rake release` automatically creates a GitHub release if a changelog section exists -- no separate `sync_github_release` step needed
|
|
40
|
+
- The release task warns if no changelog section is found for the target version
|
|
41
|
+
- A premature version header (if release fails) is harmless -- you'll release eventually
|
|
42
|
+
- A missing changelog after release means the GitHub release must be created manually via `bundle exec rake "sync_github_release[X.Y.Z]"`
|
|
43
|
+
|
|
44
|
+
## Auto-Computing the Next Version
|
|
45
|
+
|
|
46
|
+
When stamping a version header (`release`, `rc`, or `beta`), compute the next version as follows:
|
|
47
|
+
|
|
48
|
+
1. **Find the latest stable version tag** using semver sort:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git tag -l 'v*' --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
2. **Determine bump type from changelog content**:
|
|
55
|
+
- If changes include `### Breaking Changes` (or `#### Breaking Changes`) -> **major** bump
|
|
56
|
+
- If changes include `### Added`, `### New Features`, `### Features`, or `### Enhancements` -> **minor** bump
|
|
57
|
+
- If changes only include `### Fixed`, `### Security`, `### Improved`, `### Changed`, `### Deprecated`, or `### Removed` -> **patch** bump
|
|
58
|
+
|
|
59
|
+
Note: the `rake release` task validates the bump level against these headings via `expected_bump_type_from_changelog_section` in `rakelib/create_release.rake`. If the bump does not match, the release is aborted unless `RELEASE_VERSION_POLICY_OVERRIDE=true` is set.
|
|
60
|
+
|
|
61
|
+
3. **Compute the version**:
|
|
62
|
+
- For `release`: Apply the bump to the latest stable tag (e.g., `4.2.0` + minor -> `4.3.0`; `4.2.0` + major -> `5.0.0`)
|
|
63
|
+
- For `rc`: Apply the bump, then find the next RC index based **only on git tags** (e.g., if `v5.0.0.rc.0` tag exists -> `5.0.0.rc.1`). **Do NOT use changelog headers** to determine the next index — a version header in the changelog is a draft that may not have been released yet. Only git tags represent shipped versions.
|
|
64
|
+
- For `beta`: Same as RC but with beta suffix
|
|
65
|
+
|
|
66
|
+
4. **Verify**: Check that the computed version is newer than ALL existing tags (stable and prerelease). If not, ask the user what to do.
|
|
67
|
+
|
|
68
|
+
5. **Show the computed version to the user and ask for confirmation** before stamping the header. If the bump type is ambiguous (e.g., changes could reasonably be classified as patch vs minor, or the changelog headings don't clearly signal the bump level), explain your reasoning for the suggested bump and ask the user to confirm or override before proceeding.
|
|
69
|
+
|
|
70
|
+
## Critical Requirements
|
|
71
|
+
|
|
72
|
+
1. **User-visible changes only**: Only add changelog entries for user-visible changes:
|
|
73
|
+
- New features and CLI commands
|
|
74
|
+
- Bug fixes
|
|
75
|
+
- Breaking changes (CLI behavior, exit codes, generator output, configuration schema)
|
|
76
|
+
- Deprecations
|
|
77
|
+
- Performance improvements
|
|
78
|
+
- Security fixes
|
|
79
|
+
- Changes to public APIs, command flags, or configuration options
|
|
80
|
+
|
|
81
|
+
2. **Do NOT add entries for**:
|
|
82
|
+
- Linting fixes
|
|
83
|
+
- Code formatting / RuboCop changes
|
|
84
|
+
- Internal refactoring
|
|
85
|
+
- Test updates
|
|
86
|
+
- Documentation fixes (unless they fix incorrect docs about behavior)
|
|
87
|
+
- CI/CD-only changes (workflow tweaks that don't affect users)
|
|
88
|
+
|
|
89
|
+
## Formatting Requirements
|
|
90
|
+
|
|
91
|
+
### Entry Format
|
|
92
|
+
|
|
93
|
+
Each changelog entry MUST follow this exact format:
|
|
94
|
+
|
|
95
|
+
```markdown
|
|
96
|
+
- **Bold description of change**. [PR 278](https://github.com/shakacode/control-plane-flow/pull/278) by [Justin Gordon](https://github.com/justin808). Optional additional context or details.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Important formatting rules**:
|
|
100
|
+
|
|
101
|
+
- Start with a dash and space: `- `
|
|
102
|
+
- Use **bold** for the main description (or for breaking-change scope labels — see below)
|
|
103
|
+
- End the bold description with a period before the link
|
|
104
|
+
- Always link to the PR: `[PR 278](https://github.com/shakacode/control-plane-flow/pull/278)` - **NO hash symbol**
|
|
105
|
+
- Always link to the author by their display name: `by [Justin Gordon](https://github.com/justin808)`. Match the existing style in `CHANGELOG.md` — full name preferred when known, GitHub handle as a fallback.
|
|
106
|
+
- End with a period after the author link
|
|
107
|
+
- Additional details can be added after the main entry, using proper indentation for multi-line entries
|
|
108
|
+
|
|
109
|
+
### Breaking Changes Format
|
|
110
|
+
|
|
111
|
+
Breaking changes in this repo typically open with the literal phrase `BREAKING CHANGE:` to maximize visibility (see existing entries in `## [Unreleased]`). Example:
|
|
112
|
+
|
|
113
|
+
```markdown
|
|
114
|
+
- 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](https://github.com/shakacode/control-plane-flow/pull/278) by [Justin Gordon](https://github.com/justin808).
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For breaking changes that warrant a step-by-step migration guide, append it inline:
|
|
118
|
+
|
|
119
|
+
```markdown
|
|
120
|
+
- BREAKING CHANGE: Description of the breaking change. See migration guide below. [PR 278](https://github.com/shakacode/control-plane-flow/pull/278) by [Justin Gordon](https://github.com/justin808).
|
|
121
|
+
|
|
122
|
+
**Migration Guide:**
|
|
123
|
+
|
|
124
|
+
1. Step one
|
|
125
|
+
2. Step two
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Category Organization
|
|
129
|
+
|
|
130
|
+
Entries should be organized under these section headings **in the following order** (most critical first):
|
|
131
|
+
|
|
132
|
+
**Preferred section order:**
|
|
133
|
+
|
|
134
|
+
1. `### Breaking Changes` - Breaking changes (FIRST - most critical for upgrading users)
|
|
135
|
+
2. `### Added` - New features
|
|
136
|
+
3. `### Changed` - Changes to existing functionality
|
|
137
|
+
4. `### Improved` - Improvements to existing features
|
|
138
|
+
5. `### Fixed` - Bug fixes
|
|
139
|
+
6. `### Deprecated` - Deprecation notices
|
|
140
|
+
7. `### Removed` - Removed features
|
|
141
|
+
8. `### Security` - Security-related changes
|
|
142
|
+
|
|
143
|
+
**Rationale:** Breaking changes come first because they are the most critical information for anyone upgrading. Users need to know immediately if their code will break before seeing what new features are available.
|
|
144
|
+
|
|
145
|
+
**Note**: This project uses `###` (three hashes) for category headings because version headers use `##` (two hashes). Do not use `####` for category headings — that pattern belongs to projects whose version headers are `###`.
|
|
146
|
+
|
|
147
|
+
**Only include section headings that have entries.**
|
|
148
|
+
|
|
149
|
+
### Version Stamping
|
|
150
|
+
|
|
151
|
+
This repo does **not** have an `update_changelog` rake task — the slash command itself performs the stamping. After adding entries, do the following manually:
|
|
152
|
+
|
|
153
|
+
1. **Insert the version header** immediately after `## [Unreleased]` (and any short prose under it that belongs to Unreleased), in the form:
|
|
154
|
+
|
|
155
|
+
```markdown
|
|
156
|
+
## [4.3.0] - 2026-05-05
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Use today's date in `YYYY-MM-DD` form.
|
|
160
|
+
|
|
161
|
+
2. **Update the compare links** at the bottom of the file:
|
|
162
|
+
- The `[unreleased]` link must compare from the new version tag to `HEAD`:
|
|
163
|
+
|
|
164
|
+
```markdown
|
|
165
|
+
[Unreleased]: https://github.com/shakacode/control-plane-flow/compare/v4.3.0...HEAD
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Note: this repo uses `...HEAD`, not `...main`. Match the existing convention.
|
|
169
|
+
- Add a new compare link for the stamped version, comparing the previous tag to the new one:
|
|
170
|
+
|
|
171
|
+
```markdown
|
|
172
|
+
[4.3.0]: https://github.com/shakacode/control-plane-flow/compare/v4.2.0...v4.3.0
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
3. **For `rc`/`beta` modes**: collapse prior prerelease sections of the same base version into a single section (see "For Prerelease Versions" below). Remove the orphaned compare links for the collapsed prerelease versions.
|
|
176
|
+
|
|
177
|
+
The `rake release` task reads the first `## [VERSION]` header (skipping `Unreleased`) and uses it as the target version when newer than the current gem version. So once the changelog PR merges, `bundle exec rake release` (no args) will pick up the version automatically.
|
|
178
|
+
|
|
179
|
+
### Finding the Most Recent Version
|
|
180
|
+
|
|
181
|
+
To determine the most recent version:
|
|
182
|
+
|
|
183
|
+
1. **Check git tags** to find the latest released version:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
git tag --sort=-v:refname | head -10
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
This shows tags like `v4.2.0`, `v4.1.1`, etc.
|
|
190
|
+
|
|
191
|
+
2. **Check the CHANGELOG.md** for version headers (note: changelog uses versions WITHOUT the `v` prefix):
|
|
192
|
+
- `## [4.2.0] - 2026-04-15` (stable version)
|
|
193
|
+
- `## [4.2.0.rc.0] - 2026-04-10` (prerelease, if/when used)
|
|
194
|
+
|
|
195
|
+
3. **Use this regex pattern** to find version headers in the changelog:
|
|
196
|
+
|
|
197
|
+
```regex
|
|
198
|
+
^## \[([^\]]+)\]( - \d{4}-\d{2}-\d{2})?
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
4. **The first match after `## [Unreleased]`** is the most recent version in the changelog.
|
|
202
|
+
|
|
203
|
+
**IMPORTANT**: Git tags use `v` prefix (e.g., `v4.2.0`). Changelog **headers** use versions WITHOUT the `v` prefix (e.g., `## [4.2.0]`), but compare **links** at the bottom of the file MUST use the `v` prefix to match the git tag (e.g., `.../compare/v4.1.1...v4.2.0`). Strip the `v` only for changelog headers, not for compare link URLs.
|
|
204
|
+
|
|
205
|
+
## Process
|
|
206
|
+
|
|
207
|
+
### For Regular Changelog Updates
|
|
208
|
+
|
|
209
|
+
#### Step 1: Fetch and read current state
|
|
210
|
+
|
|
211
|
+
- **CRITICAL**: Run `git fetch origin main` to ensure you have the latest commits
|
|
212
|
+
- After fetching, use `origin/main` for all comparisons, NOT local `main` branch
|
|
213
|
+
- Read the current CHANGELOG.md to understand the existing structure
|
|
214
|
+
|
|
215
|
+
#### Step 2: Reconcile tags with changelog sections (DO THIS FIRST)
|
|
216
|
+
|
|
217
|
+
**This step catches missing version sections and is the #1 source of errors when skipped.**
|
|
218
|
+
|
|
219
|
+
1. Get the latest git tag: `git tag --sort=-v:refname | head -5`
|
|
220
|
+
2. Get the most recent version header in CHANGELOG.md (the first `## [VERSION] - DATE` after `## [Unreleased]`)
|
|
221
|
+
3. **Compare them.** If the latest git tag (minus the `v` prefix) does NOT appear anywhere in the changelog version headers, there are tagged releases missing from the changelog. **Important**: Don't just compare against the _top_ changelog header — a version header may exist _above_ the latest tag if it was stamped as a draft before tagging. Check whether the tag's version appears in _any_ `## [X.Y.Z]` header. For example:
|
|
222
|
+
- Latest tag: `v4.2.0`, and no `## [4.2.0]` header exists anywhere in CHANGELOG.md
|
|
223
|
+
- **Result: `4.2.0` is missing and needs its own section**
|
|
224
|
+
- But if `## [5.0.0]` is the top header (a draft, not yet tagged) and `## [4.2.0]` exists below it, then nothing is missing — the top header is simply a pre-release draft
|
|
225
|
+
|
|
226
|
+
4. For EACH missing tagged version (there may be multiple):
|
|
227
|
+
a. Find commits in that tag vs the previous tag: `git log --oneline PREV_TAG..MISSING_TAG`
|
|
228
|
+
b. Extract PR numbers and fetch details for user-visible changes
|
|
229
|
+
c. Check which entries currently in `## [Unreleased]` actually belong to this tagged version (compare PR numbers against the commit list)
|
|
230
|
+
d. **Create a new version section** immediately before the previous version section:
|
|
231
|
+
|
|
232
|
+
```markdown
|
|
233
|
+
## [4.2.0] - 2026-04-15
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
e. **Move** matching entries from Unreleased into the new section
|
|
237
|
+
f. **Add** any new entries for PRs in that tag that aren't in the changelog at all
|
|
238
|
+
g. **Update version diff links** at the bottom of the file:
|
|
239
|
+
- Update `[unreleased]` to compare from the newest tag to `HEAD`
|
|
240
|
+
- Add a link for each new version section
|
|
241
|
+
|
|
242
|
+
5. Get the tag date with: `git log -1 --format="%Y-%m-%d" TAG_NAME`
|
|
243
|
+
|
|
244
|
+
#### Step 3: Add new entries for post-tag commits
|
|
245
|
+
|
|
246
|
+
1. Run `git log --oneline LATEST_TAG..origin/main` to find commits after the latest tag (LATEST_TAG is the most recent git tag, i.e., the same one identified in Step 2)
|
|
247
|
+
2. Extract PR numbers: `git log --oneline LATEST_TAG..origin/main | grep -oE "#[0-9]+" | sort -u`
|
|
248
|
+
3. If Step 2 found no missing tagged versions, verify no tag is ahead of main: `git log --oneline origin/main..LATEST_TAG` should be empty. If not, entries in "Unreleased" may belong to that tagged version — Step 2 should have caught this, so re-check.
|
|
249
|
+
4. For each PR number, check if it's already in CHANGELOG.md: `grep "PR XXX" CHANGELOG.md`
|
|
250
|
+
5. For PRs not yet in the changelog:
|
|
251
|
+
- Get PR details: `gh pr view NUMBER --json title,body,author --repo shakacode/control-plane-flow`
|
|
252
|
+
- **Never ask the user for PR details** - get them from git history or the GitHub API
|
|
253
|
+
- Validate that the change is user-visible (per the criteria above). Skip CI, lint, refactoring, test-only changes.
|
|
254
|
+
- Add the entry to `## [Unreleased]` under the appropriate category heading
|
|
255
|
+
|
|
256
|
+
#### Step 4: Stamp version header (only when a version mode or explicit version is given)
|
|
257
|
+
|
|
258
|
+
If the user passed `release`, `rc`, `beta`, or an explicit version string as an argument:
|
|
259
|
+
|
|
260
|
+
1. Determine the target version (auto-computed for `release`/`rc`/`beta`, exact for an explicit version) using the rules in "Auto-Computing the Next Version" above.
|
|
261
|
+
|
|
262
|
+
2. Confirm the version with the user.
|
|
263
|
+
|
|
264
|
+
3. **Stamp the header** by inserting `## [TARGET_VERSION] - YYYY-MM-DD` immediately after the `## [Unreleased]` block (after any short prose lines under Unreleased that should remain there).
|
|
265
|
+
|
|
266
|
+
4. **Update compare links** at the bottom of the file:
|
|
267
|
+
- Update `[Unreleased]` to compare from the new tag to `HEAD`
|
|
268
|
+
- Add a new compare link for the stamped version
|
|
269
|
+
|
|
270
|
+
5. **For `rc`/`beta`**: collapse prior prerelease sections of the same base version (see below) and remove their orphaned compare links.
|
|
271
|
+
|
|
272
|
+
6. **Verify** the stamped header and diff links match the requested version. If anything looks off, fix it before continuing.
|
|
273
|
+
|
|
274
|
+
If no argument was passed, skip this step -- entries stay in `## [Unreleased]`.
|
|
275
|
+
|
|
276
|
+
#### Step 5: Verify and finalize
|
|
277
|
+
|
|
278
|
+
1. **Verify formatting**:
|
|
279
|
+
- Bold description with period (or `BREAKING CHANGE:` prefix for breaking changes)
|
|
280
|
+
- Proper PR link (NO hash symbol)
|
|
281
|
+
- Proper author link
|
|
282
|
+
- Consistent with existing entries
|
|
283
|
+
- File ends with a newline character
|
|
284
|
+
- **No duplicate section headings** (e.g., don't create two `### Fixed` sections — merge entries into the existing heading)
|
|
285
|
+
2. **Verify version sections are in order** (Unreleased -> newest tag -> older tags)
|
|
286
|
+
3. **Verify version diff links** at the bottom of the file are correct (compare links MUST use the `v` prefix to match git tags; the `[Unreleased]` target is `HEAD`, not `main`)
|
|
287
|
+
4. **Show the user** a summary of what was done:
|
|
288
|
+
- Which version sections were created
|
|
289
|
+
- Which entries were moved from Unreleased
|
|
290
|
+
- Which new entries were added
|
|
291
|
+
- Which PRs were skipped (and why)
|
|
292
|
+
5. If in `release`/`rc`/`beta` mode or explicit-version mode, **automatically commit, push, and open a PR**:
|
|
293
|
+
- Verify the working tree only has `CHANGELOG.md` changes; if there are other uncommitted changes, warn the user and stop
|
|
294
|
+
- Verify the current branch is `main` (`git branch --show-current`); if not, warn the user and stop
|
|
295
|
+
- Create a feature branch following the user's branch-naming convention (e.g., `jg/changelog-4.3.0` or `changelog-4.3.0`)
|
|
296
|
+
- Stage only `CHANGELOG.md` (`git add CHANGELOG.md`) and commit with message `Update CHANGELOG.md for VERSION` (using the stamped version)
|
|
297
|
+
- Push and open a PR with the changelog diff as the body
|
|
298
|
+
- If the push or PR creation fails, the CHANGELOG is already stamped locally — fix the issue (e.g., authentication, branch protection), then run `git push -u origin <branch>` and `gh pr create` manually
|
|
299
|
+
- Remind the user to run `bundle exec rake release` (no args) after the PR merges to publish and auto-create the GitHub release
|
|
300
|
+
|
|
301
|
+
### For Prerelease Versions (RC and Beta)
|
|
302
|
+
|
|
303
|
+
When the user passes `rc` or `beta` as an argument:
|
|
304
|
+
|
|
305
|
+
1. **Find the latest tag** (stable or prerelease) using semver sort:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
git tag -l 'v*' --sort=-v:refname | head -10
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
2. **Auto-compute the next prerelease version** using the process in "Auto-Computing the Next Version" above. Use RubyGems format (`5.0.0.rc.0`), not `5.0.0-rc.0`.
|
|
312
|
+
|
|
313
|
+
3. **Always collapse prior prereleases into the current prerelease** (this is the default behavior):
|
|
314
|
+
- Combine all prior prerelease changelog entries into the new prerelease version section
|
|
315
|
+
- Remove previous prerelease version sections (e.g., remove `## [5.0.0.rc.0]` when creating `## [5.0.0.rc.1]`)
|
|
316
|
+
- When collapsing, **consolidate duplicate category headings** — if both the Unreleased section and a prior prerelease section have `### Fixed`, merge all entries under a single `### Fixed` heading
|
|
317
|
+
- **Remove orphaned version diff links** at the bottom of the file for collapsed prerelease sections
|
|
318
|
+
- Add any new user-visible changes from commits since the last prerelease
|
|
319
|
+
- Update version diff links to point from the last stable version to the new prerelease
|
|
320
|
+
- This keeps the changelog clean with a single prerelease section that accumulates all changes since the last stable release
|
|
321
|
+
|
|
322
|
+
**Note**: The new version header must be inserted **immediately after `## [Unreleased]`** (see Step 4). This ensures correct ordering of version headers.
|
|
323
|
+
|
|
324
|
+
### For Prerelease to Stable Version Release
|
|
325
|
+
|
|
326
|
+
When releasing from prerelease to a stable version (e.g., `v5.0.0.rc.1` -> `v5.0.0`):
|
|
327
|
+
|
|
328
|
+
1. **Remove all prerelease version labels** from the changelog:
|
|
329
|
+
- Change `## [5.0.0.rc.0]`, `## [5.0.0.rc.1]`, etc. to a single `## [5.0.0]` section
|
|
330
|
+
- Also handle beta versions: `## [5.0.0.beta.1]` etc.
|
|
331
|
+
- Combine all prerelease entries into the stable release section
|
|
332
|
+
|
|
333
|
+
2. **Consolidate duplicate entries**:
|
|
334
|
+
- If bug fixes or changes were made to features introduced in earlier prereleases, keep only the final state
|
|
335
|
+
- Remove redundant changelog entries for fixes to prerelease features
|
|
336
|
+
- Keep the most recent/accurate description of each change
|
|
337
|
+
|
|
338
|
+
3. **Update version diff links** at the bottom to point to the stable version (and remove the orphaned prerelease compare links)
|
|
339
|
+
|
|
340
|
+
## Examples
|
|
341
|
+
|
|
342
|
+
Run this command to see real formatting examples from the codebase:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
grep -B 1 -A 3 "^### " CHANGELOG.md | head -40
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Good Entry Example
|
|
349
|
+
|
|
350
|
+
```markdown
|
|
351
|
+
- Added the GitHub Actions flow generator and readiness checks for staging, review-app, and production-promotion workflows. [PR 278](https://github.com/shakacode/control-plane-flow/pull/278) by [Justin Gordon](https://github.com/justin808).
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Breaking Change Example
|
|
355
|
+
|
|
356
|
+
```markdown
|
|
357
|
+
- 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](https://github.com/shakacode/control-plane-flow/pull/278) by [Justin Gordon](https://github.com/justin808).
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Additional Notes
|
|
361
|
+
|
|
362
|
+
- Keep descriptions concise but informative
|
|
363
|
+
- Focus on the "what" and "why", not the "how"
|
|
364
|
+
- Use past tense for the description
|
|
365
|
+
- Be consistent with existing formatting in the changelog
|
|
366
|
+
- Always ensure the file ends with a trailing newline
|
|
367
|
+
- See `docs/releasing.md` for the full release process this command feeds into
|
|
@@ -24,6 +24,8 @@ jobs:
|
|
|
24
24
|
issues: read
|
|
25
25
|
id-token: write
|
|
26
26
|
actions: read # Required for Claude to read CI results on PRs
|
|
27
|
+
checks: read
|
|
28
|
+
statuses: read
|
|
27
29
|
steps:
|
|
28
30
|
- name: Checkout repository
|
|
29
31
|
uses: actions/checkout@v4
|
|
@@ -34,11 +36,14 @@ jobs:
|
|
|
34
36
|
id: claude
|
|
35
37
|
uses: anthropics/claude-code-action@v1
|
|
36
38
|
with:
|
|
39
|
+
github_token: ${{ github.token }}
|
|
37
40
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
38
41
|
|
|
39
42
|
# This is an optional setting that allows Claude to read CI results on PRs
|
|
40
43
|
additional_permissions: |
|
|
41
44
|
actions: read
|
|
45
|
+
checks: read
|
|
46
|
+
statuses: read
|
|
42
47
|
|
|
43
48
|
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
|
44
49
|
# prompt: 'Update the pull request description to include a summary of changes.'
|
data/.overcommit.yml
CHANGED
|
@@ -1,14 +1,54 @@
|
|
|
1
1
|
PreCommit:
|
|
2
|
+
RubyAutoFix:
|
|
3
|
+
enabled: true
|
|
4
|
+
parallelize: false
|
|
5
|
+
required_executable: "./script/precommit/ruby_autofix"
|
|
6
|
+
command: ["./script/precommit/ruby_autofix", "staged"]
|
|
7
|
+
requires_files: true
|
|
8
|
+
include:
|
|
9
|
+
- "**/*.rb"
|
|
10
|
+
- "**/*.rake"
|
|
11
|
+
- "**/*.ru"
|
|
12
|
+
|
|
13
|
+
TrailingNewlines:
|
|
14
|
+
enabled: true
|
|
15
|
+
parallelize: false
|
|
16
|
+
required_executable: "./script/precommit/check_trailing_newlines"
|
|
17
|
+
command: ["./script/precommit/check_trailing_newlines", "staged"]
|
|
18
|
+
requires_files: true
|
|
19
|
+
include:
|
|
20
|
+
- "**/*"
|
|
21
|
+
|
|
2
22
|
ValidateLinks:
|
|
3
23
|
enabled: true
|
|
4
|
-
|
|
24
|
+
required_executable: "./script/precommit/check_cpln_links"
|
|
25
|
+
command: ["./script/precommit/check_cpln_links", "staged"]
|
|
26
|
+
requires_files: true
|
|
27
|
+
include:
|
|
28
|
+
- "**/*.md"
|
|
29
|
+
|
|
5
30
|
CommandDocs:
|
|
6
31
|
enabled: true
|
|
7
|
-
|
|
32
|
+
required_executable: "./script/precommit/check_command_docs"
|
|
33
|
+
command: ["./script/precommit/check_command_docs", "staged"]
|
|
34
|
+
requires_files: true
|
|
35
|
+
include:
|
|
36
|
+
- "lib/command/**/*.rb"
|
|
37
|
+
- "docs/commands.md"
|
|
38
|
+
- "script/update_command_docs"
|
|
39
|
+
- "script/check_command_docs"
|
|
40
|
+
- "Rakefile"
|
|
41
|
+
|
|
8
42
|
RuboCop:
|
|
9
43
|
enabled: true
|
|
10
44
|
on_warn: fail
|
|
11
|
-
|
|
45
|
+
required_executable: "./script/precommit/ruby_lint"
|
|
46
|
+
command: ["./script/precommit/ruby_lint", "staged"]
|
|
47
|
+
requires_files: true
|
|
48
|
+
include:
|
|
49
|
+
- "**/*.rb"
|
|
50
|
+
- "**/*.rake"
|
|
51
|
+
- "**/*.ru"
|
|
12
52
|
|
|
13
53
|
# PrePush:
|
|
14
54
|
# RSpec:
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -6,19 +6,41 @@ All notable changes to this project's source code will be documented in this fil
|
|
|
6
6
|
|
|
7
7
|
Please follow the recommendations outlined at [keepachangelog.com](https://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.
|
|
8
8
|
|
|
9
|
+
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`).
|
|
10
|
+
|
|
9
11
|
## Versions
|
|
10
12
|
|
|
11
13
|
## [Unreleased]
|
|
12
14
|
|
|
13
|
-
Changes since the last non-beta release.
|
|
14
|
-
|
|
15
15
|
_Please add entries here for your pull requests that have not yet been released._
|
|
16
16
|
|
|
17
|
+
## [5.0.0.rc.0] - 2026-05-05
|
|
18
|
+
|
|
19
|
+
### Breaking Changes
|
|
20
|
+
|
|
21
|
+
- 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](https://github.com/shakacode/control-plane-flow/pull/258) by [Justin Gordon](https://github.com/justin808).
|
|
22
|
+
- 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](https://github.com/shakacode/control-plane-flow/pull/278) by [Justin Gordon](https://github.com/justin808).
|
|
23
|
+
- 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](https://github.com/shakacode/control-plane-flow/pull/278) by [Justin Gordon](https://github.com/justin808).
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Added the GitHub Actions flow generator and readiness checks for staging, review-app, and production-promotion workflows. [PR 278](https://github.com/shakacode/control-plane-flow/pull/278) by [Justin Gordon](https://github.com/justin808).
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- 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](https://github.com/shakacode/control-plane-flow/pull/258) by [Justin Gordon](https://github.com/justin808).
|
|
32
|
+
|
|
33
|
+
## [4.2.0] - 2026-02-19
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Suppress Node.js deprecation warnings from internal `cpln` calls by setting `NODE_NO_WARNINGS=1`, producing cleaner cpflow output. [PR 256](https://github.com/shakacode/control-plane-flow/pull/256) by [Judah Meek](https://github.com/Judahmeek).
|
|
38
|
+
|
|
17
39
|
### Fixed
|
|
18
40
|
|
|
19
41
|
- Fixed issue where `run` command could hang indefinitely when updating runner workload. [PR 260](https://github.com/shakacode/control-plane-flow/pull/260) by [Sergey Tarasov](https://github.com/dzirtusss).
|
|
20
42
|
|
|
21
|
-
###
|
|
43
|
+
### Security
|
|
22
44
|
|
|
23
45
|
- Redact sensitive data (Authorization headers, tokens) from `--trace` output. [PR 261](https://github.com/shakacode/control-plane-flow/pull/261) by [Sergey Tarasov](https://github.com/dzirtusss).
|
|
24
46
|
|
|
@@ -291,7 +313,9 @@ Deprecated `cpl` gem. New gem is `cpflow`.
|
|
|
291
313
|
|
|
292
314
|
First release.
|
|
293
315
|
|
|
294
|
-
[Unreleased]: https://github.com/shakacode/control-plane-flow/compare/
|
|
316
|
+
[Unreleased]: https://github.com/shakacode/control-plane-flow/compare/v5.0.0.rc.0...HEAD
|
|
317
|
+
[5.0.0.rc.0]: https://github.com/shakacode/control-plane-flow/compare/v4.2.0...v5.0.0.rc.0
|
|
318
|
+
[4.2.0]: https://github.com/shakacode/control-plane-flow/compare/v4.1.1...v4.2.0
|
|
295
319
|
[4.1.1]: https://github.com/shakacode/control-plane-flow/compare/v4.1.0...v4.1.1
|
|
296
320
|
[4.1.0]: https://github.com/shakacode/control-plane-flow/compare/v4.0.0...v4.1.0
|
|
297
321
|
[4.0.0]: https://github.com/shakacode/control-plane-flow/compare/v3.0.1...v4.0.0
|
data/CONTRIBUTING.md
CHANGED
|
@@ -71,3 +71,9 @@ CPLN_ORG=your-org-for-tests bundle exec rspec --tag slow
|
|
|
71
71
|
```sh
|
|
72
72
|
cpflow test
|
|
73
73
|
```
|
|
74
|
+
|
|
75
|
+
## Releasing
|
|
76
|
+
|
|
77
|
+
See [Releasing the Gem](./docs/releasing.md) for the changelog-first Ruby gem release process. In short: run
|
|
78
|
+
`/update-changelog release`, merge the generated changelog PR, then run `bundle exec rake release`. This project
|
|
79
|
+
releases only the `cpflow` RubyGem; there is no npm publishing step.
|
data/Gemfile
CHANGED
|
@@ -5,13 +5,14 @@ source "https://rubygems.org"
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
7
7
|
gem "debug", "~> 1"
|
|
8
|
-
gem "
|
|
8
|
+
gem "gem-release", "~> 2.2"
|
|
9
|
+
gem "overcommit", "~> 0.69.0"
|
|
9
10
|
gem "rake", "~> 13.0"
|
|
10
|
-
gem "rspec", "~> 3.
|
|
11
|
+
gem "rspec", "~> 3.13"
|
|
11
12
|
gem "rspec-retry", "~> 0.6.2"
|
|
12
|
-
gem "rubocop", "~> 1.
|
|
13
|
-
gem "rubocop-rake", "~> 0.
|
|
14
|
-
gem "rubocop-rspec", "~> 3.
|
|
13
|
+
gem "rubocop", "~> 1.81"
|
|
14
|
+
gem "rubocop-rake", "~> 0.7.1"
|
|
15
|
+
gem "rubocop-rspec", "~> 3.8"
|
|
15
16
|
gem "simplecov", "~> 0.22.0"
|
|
16
|
-
gem "timecop", "~> 0.9.
|
|
17
|
-
gem "webmock", "~> 3.
|
|
17
|
+
gem "timecop", "~> 0.9.10"
|
|
18
|
+
gem "webmock", "~> 3.26"
|