Skip to content

Commit 088085e

Browse files
authored
feat: implement zerv flow integration tests (#118)
1 parent d62c535 commit 088085e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+7780
-1685
lines changed

.claude/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ Input → VCS Detection → Version Parsing → Transformation → Format Output
126126
- **Environment variables**: `ZERV_TEST_NATIVE_GIT`, `ZERV_TEST_DOCKER`
127127
- **Git operations**: Always use `get_git_impl()`
128128
- **Docker tests**: Always use `should_run_docker_tests()` gating
129+
- **CRITICAL**: For Git-related tests, **ALWAYS use `ZERV_TEST_NATIVE_GIT=false ZERV_TEST_DOCKER=true`**
129130
- **Integration tests**: Prefer `TestCommand::run_with_stdin()` (90% of cases)
130131

131132
**For detailed testing patterns:**

.claude/plan/32-zerv-flow-implementation-plan.md

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,18 @@ This section demonstrates how Zerv Flow works across different branching strateg
103103
**Scenario Overview**:
104104

105105
- Development starts from `v1.0.0` on main
106-
- Three feature branches created in parallel: `feature-1`, `feature-2`, and later `feature-3`
106+
- Two feature branches created in parallel: `feature-1` and `feature-2`
107107
- `feature-1` gets completed and released first (`v1.0.1`)
108108
- `feature-2` syncs with main to get `feature-1` changes, then continues development
109-
- `feature-3` branches from `feature-2` to implement a sub-feature
110-
- `feature-3` merges back to `feature-2`, which then releases as `v1.1.0`
109+
- `feature-3` branches from `feature-2` to implement a sub-feature (nested feature branch)
110+
- `feature-3` merges back to `feature-2`, which then completes development and releases as `v1.1.0`
111111

112112
**Key Zerv Flow behaviors demonstrated**:
113113

114114
- **Uncommitted changes**: Shows dirty state with `.dev.timestamp` suffix
115-
- **Parallel development**: Different branches get unique hash-based IDs (`12345`, `54321`, `98765`)
115+
- **Parallel development**: Different branches get unique hash-based IDs (`68031`, `42954`, `14698`)
116116
- **Version progression**: Base version updates when syncing with main (`1.0.1``1.0.2`)
117-
- **Post-release distance resets**: Counters reset to `.post.1` after syncing with new base version
117+
- **Post-release distance continuity**: Distance counters continue accumulating across branches and merges
118118
- **Nested feature branches**: `feature-3` branching from `feature-2` with independent versioning
119119
- **Merge handling**: Clean version progression through complex merge scenarios
120120
- **Alpha pre-releases**: All development branches use `alpha` pre-release identifiers
@@ -126,36 +126,56 @@ config:
126126
theme: 'base'
127127
---
128128
gitGraph
129+
%% Step 1: Initial commit on main with v1.0.0 tag
129130
commit id: "1.0.0"
130131
132+
%% Step 2: Create parallel feature branches feature-1 and feature-2 from main
131133
branch feature-1 order: 2
132134
branch feature-2 order: 3
133135
136+
%% Step 3: feature-2: Start development with dirty state
134137
checkout feature-2
135-
commit type:REVERSE id: "1.0.1-alpha.12345.post.0.dev.1729924622" tag: "uncommitted"
136-
commit id: "1.0.1-alpha.12345.post.1"
138+
commit type:REVERSE id: "1.0.1-alpha.68031.post.0.dev.{timestamp}" tag: "uncommitted"
137139
140+
%% Step 4: feature-2: Create first commit
141+
commit id: "1.0.1-alpha.68031.post.1"
142+
143+
%% Step 5: feature-1: Create commits (parallel development)
138144
checkout feature-1
139-
commit id: "1.0.1-alpha.54321.post.1"
140-
commit id: "1.0.1-alpha.54321.post.2"
145+
commit id: "1.0.1-alpha.42954.post.1"
146+
commit id: "1.0.1-alpha.42954.post.2"
141147
148+
%% Step 6: feature-1: Merge to main and release v1.0.1
142149
checkout main
143150
merge feature-1 id: "1.0.1" tag: "feature-1 released"
144151
152+
%% Step 7: feature-2: Sync with main to get feature-1 changes
145153
checkout feature-2
146-
merge main id: "1.0.2-alpha.12345.post.1"
147-
commit id: "1.0.2-alpha.12345.post.2"
154+
merge main id: "1.0.2-alpha.68031.post.2"
155+
156+
%% Step 8: feature-2: Create additional commit
157+
commit id: "1.0.2-alpha.68031.post.3"
148158
159+
%% Step 9: feature-3: Branch from feature-2 for sub-feature development
149160
branch feature-3 order: 4
150161
checkout feature-3
151-
commit id: "1.0.2-alpha.98765.post.3"
152-
commit type:REVERSE id: "1.0.2-alpha.98765.post.3.dev.1729924622" tag: "uncommitted"
153-
commit id: "1.0.2-alpha.98765.post.4"
162+
commit id: "1.0.2-alpha.14698.post.4"
163+
164+
%% Step 10: feature-3: Continue development with dirty state
165+
commit type:REVERSE id: "1.0.2-alpha.14698.post.4.dev.{timestamp}" tag: "uncommitted"
154166
167+
%% Step 11: feature-3: Continue development with commits
168+
commit id: "1.0.2-alpha.14698.post.5"
169+
commit id: "1.0.2-alpha.14698.post.6"
170+
171+
%% Step 12: feature-2: Merge feature-3 back to continue development
155172
checkout feature-2
156-
merge feature-3 id: "1.0.2-alpha.12345.post.3" tag: "feature-3 merged"
173+
merge feature-3 id: "1.0.2-alpha.68031.post.6" tag: "feature-3 merged"
174+
175+
%% Step 13: feature-2: Final development before release
176+
commit id: "1.0.2-alpha.68031.post.7"
157177
158-
commit id: "1.0.2-alpha.12345.post.4"
178+
%% Step 14: Final release: feature-2 merges to main and releases v1.1.0
159179
checkout main
160180
merge feature-2 id: "1.1.0" tag: "feature-2 released"
161181
```
@@ -179,7 +199,8 @@ gitGraph
179199
- **RC pre-releases**: Release branches use `rc` identifier for release candidates
180200
- **Clean releases**: Main branch maintains clean versions without pre-release suffixes
181201
- **Hotfix emergency flow**: Critical fixes from main with proper version propagation
182-
- **Post-release resolution**: Correct post counting based on pre-release type changes
202+
- **Release branch post mode**: `release/*` branches use post distance from release tag (commit distance)
203+
- **Trunk-based post mode**: Other branches use post distance from branch point (for parallel development)
183204
- **Base version propagation**: Version bumps when syncing branches with newer main releases
184205

185206
```mermaid
@@ -189,43 +210,57 @@ config:
189210
theme: 'base'
190211
---
191212
gitGraph
213+
%% Step 1: Initial state: main and develop branches
192214
commit id: "1.0.0"
193215
216+
%% Step 2: Create develop branch with initial development commit
194217
branch develop order: 3
195218
checkout develop
196219
commit id: "1.0.1-beta.1.post.1"
197220
221+
%% Step 3: Feature development from develop branch (trunk-based post mode)
198222
branch feature/auth order: 4
199223
checkout feature/auth
200-
commit id: "1.0.1-alpha.12345.post.1"
201-
commit id: "1.0.1-alpha.12345.post.2"
224+
commit id: "1.0.1-alpha.92409.post.2"
225+
commit id: "1.0.1-alpha.92409.post.3"
202226
203227
checkout develop
204-
merge feature/auth id: "1.0.1-beta.1.post.2" tag: "feature merged"
228+
%% Step 4: Merge feature/auth back to develop
229+
merge feature/auth id: "1.0.1-beta.1.post.3" tag: "feature merged"
205230
231+
%% Step 5: Hotfix emergency flow from main
206232
checkout main
207233
branch hotfix/critical order: 1
208234
checkout hotfix/critical
209-
commit id: "1.0.1-alpha.54321.post.1"
235+
commit id: "1.0.1-alpha.11477.post.1"
210236
211237
checkout main
212-
merge hotfix/critical id: "1.0.1" tag: "tagged"
238+
%% Step 6: Merge hotfix to main and release v1.0.1
239+
merge hotfix/critical id: "1.0.1" tag: "hotfix released"
213240
241+
%% Step 7: Sync develop with main changes and continue development
214242
checkout develop
215-
merge main id: "1.0.2-beta.1.post.3" tag: "update main"
216-
commit id: "1.0.2-beta.1.post.4"
243+
merge main id: "1.0.2-beta.1.post.4" tag: "sync main"
244+
245+
%% Step 8: Continue development on develop branch
246+
commit id: "1.0.2-beta.1.post.5"
217247
248+
%% Step 9: Release branch preparation (release/* uses commit distance from tag)
218249
branch release/1 order: 2
219250
checkout release/1
220251
commit id: "1.0.2-rc.1.post.1" tag: "tagged"
221252
commit id: "1.0.2-rc.1.post.2" tag: "tagged"
222-
commit id: "1.0.2-rc.1.post.2.dev.1729924622"
253+
commit type:REVERSE id: "1.0.2-rc.1.post.2.dev.{timestamp1}" tag: "uncommit"
254+
commit id: "1.0.2-rc.1.post.2.dev.{timestamp2}" tag: "untagged"
255+
commit id: "1.0.2-rc.1.post.3" tag: "tagged"
223256
224257
checkout main
225-
merge release/1 id: "1.1.0" tag: "tagged"
258+
%% Step 10: Final release: merge release/1 to main
259+
merge release/1 id: "1.1.0" tag: "release 1.1.0"
226260
261+
%% Step 11: Sync develop with release and prepare for next cycle
227262
checkout develop
228-
merge main id: "1.1.1-beta.1.post.1" tag: "update main"
263+
merge main id: "1.1.1-beta.1.post.1" tag: "sync release"
229264
```
230265

231266
## Scope and Limitations

.claude/plan/33-zerv-flow-cli-command-design.md

Lines changed: 97 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,62 @@ zerv flow [OPTIONS]
3939
--bumped-branch <BRANCH> Override branch name for pre-release resolution (same as zerv version)
4040
--bumped-branch-hash-length <LENGTH> Branch hash length for pre-release numbers [default: 5] [range: 4..16]
4141
--post-mode <TYPE> Post calculation mode [default: tag] [possible values: tag, commit]
42-
--build-context Include build context (+branch.commit) in output [default: true]
43-
--no-build-context Exclude build context from output
44-
--dev-ts Include dev timestamp for dirty working directory [default: auto-detect]
45-
--no-dev-ts Exclude dev timestamp from output
46-
--with-pre-release Include pre-release/post-release but no build context
47-
--base-only Base version only (major.minor.patch)
42+
--schema <SCHEMA> Schema variant for output components [default: standard] [possible values: standard, standard-no-context, standard-context, standard-base, standard-base-prerelease, standard-base-prerelease-post, standard-base-prerelease-post-dev]
4843
-v, --verbose Show verbose output including version resolution details
4944
-h, --help Print help
5045
-V, --version Print version
5146
```
5247

48+
### Schema System
49+
50+
**zerv flow uses the flexible schema system from zerv version but restricted to standard schema family only.**
51+
52+
#### Available Standard Schema Variants
53+
54+
- **`standard`** (default) - Smart context: includes context only for dirty/distance states, excludes for clean tagged
55+
- **`standard-no-context`** - Never includes build context (branch.commit info)
56+
- **`standard-context`** - Always includes build context
57+
- **`standard-base`** - Base version only (e.g., `1.2.3`)
58+
- **`standard-base-prerelease`** - Base + prerelease (e.g., `1.2.3-alpha.1`)
59+
- **`standard-base-prerelease-post`** - Base + prerelease + post (e.g., `1.2.3-alpha.1.post.2`)
60+
- **`standard-base-prerelease-post-dev`** - Base + prerelease + post + dev (e.g., `1.2.3-alpha.1.post.2.dev.123`)
61+
62+
#### Schema Behavior Examples
63+
64+
**Smart Context (`standard` - default):**
65+
66+
- Clean tagged commit: `1.0.1-rc.1.post.1`
67+
- Dirty working directory: `1.0.1-rc.1.post.1.dev.1729924622+feature.auth.1.a1b2c3d`
68+
- Distance from tag: `1.0.1-rc.1.post.2+feature.auth.2.c2d3e4f`
69+
70+
**No Context (`standard-no-context`):**
71+
72+
- Any state: `1.0.1-rc.1.post.1` (never includes +branch.commit)
73+
74+
**Always Context (`standard-context`):**
75+
76+
- Any state: `1.0.1-rc.1.post.1+feature.auth.1.a1b2c3d` (always includes context)
77+
78+
**Base Components:**
79+
80+
- `standard-base`: `1.2.3`
81+
- `standard-base-prerelease`: `1.2.3-alpha.1`
82+
- `standard-base-prerelease-post`: `1.2.3-alpha.1.post.2`
83+
- `standard-base-prerelease-post-dev`: `1.2.3-alpha.1.post.2.dev.123`
84+
85+
#### Schema Validation
86+
87+
**Only standard schema family supported in zerv flow:**
88+
89+
-**Valid**: `standard`, `standard-no-context`, `standard-context`, `standard-base`, `standard-base-prerelease`, `standard-base-prerelease-post`, `standard-base-prerelease-post-dev`
90+
-**Invalid**: Any `calver*` schema variants will produce error
91+
-**Invalid**: Any deprecated tier-based schemas will produce error
92+
93+
**Error handling:**
94+
95+
- Non-standard schemas will result in: `Error: zerv flow only supports standard schema variants, got: 'calver'`
96+
- Invalid schema names will result in: `Error: Unknown schema variant: 'invalid-schema'`
97+
5398
## Pre-release Resolution Logic
5499

55100
### Default Behavior (no flags)
@@ -162,43 +207,54 @@ zerv flow --branch-rules
162207

163208
### Manual Override
164209

165-
**Mutually exclusive with `--pre-release-from-branch`:**
210+
**Schema can be combined with manual pre-release overrides:**
166211

167212
```bash
168-
# Force specific pre-release type and number
169-
zerv flow --pre-release-label beta --pre-release-num 1
213+
# Force specific pre-release type and number with context
214+
zerv flow --pre-release-label beta --pre-release-num 1 --schema standard-context
215+
216+
# Force rc for release-like branches, no context
217+
zerv flow --pre-release-label rc --pre-release-num 2 --schema standard-base-prerelease-post
170218

171-
# Force rc for release-like branches
172-
zerv flow --pre-release-label rc --pre-release-num 2
219+
# Force alpha for feature branches with full context
220+
zerv flow --pre-release-label alpha --schema standard-base-prerelease-post-dev-context
173221

174-
# Force alpha for feature branches (uses hash by default)
175-
zerv flow --pre-release-label alpha
222+
# Manual overrides with different schema levels
223+
zerv flow --pre-release-label beta --schema standard-base-prerelease
224+
zerv flow --pre-release-label rc --schema standard-base
176225
```
177226

178227
### Branch Override
179228

180229
**Test different branch scenarios without switching branches:**
181230

182231
```bash
183-
zerv flow --bumped-branch develop --pre-release-from-branch
184-
zerv flow --bumped-branch release/1 --pre-release-from-branch
232+
# Test develop branch with different schemas
233+
zerv flow --bumped-branch develop --schema standard
234+
zerv flow --bumped-branch develop --schema standard-no-context
235+
236+
# Test release branch with specific schema
237+
zerv flow --bumped-branch release/1 --schema standard-base-prerelease-post-context
238+
239+
# Test feature branch scenarios
240+
zerv flow --bumped-branch feature/auth --schema standard-base-prerelease-post-dev
185241
```
186242

187243
## Output Modes
188244

189-
### Full Output (default)
245+
### Full Output (default - `standard` schema)
190246

191247
```
192248
1.0.1-alpha.12345.post.2.dev.1729924622+feature.auth.2.a1b2c3d
193249
```
194250

195-
### Pre-release Output (`--with-pre-release`)
251+
### Pre-release Output (`--schema standard-base-prerelease-post`)
196252

197253
```
198254
1.0.1-alpha.12345.post.2
199255
```
200256

201-
### Base-Only Output (`--base-only`)
257+
### Base-Only Output (`--schema standard-base`)
202258

203259
```
204260
1.0.1
@@ -235,36 +291,42 @@ zerv flow --bumped-branch release/1 --pre-release-from-branch
235291
### Basic Usage
236292

237293
```bash
238-
# Generate flow version with automatic pre-release
294+
# Generate flow version with smart context (default schema)
239295
zerv flow
240296

241-
# Enable branch pattern detection (GitFlow)
242-
zerv flow --pre-release-from-branch
243-
244297
# Force specific pre-release type
245298
zerv flow --pre-release-label beta
246299

247300
# Include pre-release/post-release but no build context
248-
zerv flow --with-pre-release
301+
zerv flow --schema standard-base-prerelease-post
249302

250303
# Base version only
251-
zerv flow --base-only
304+
zerv flow --schema standard-base
305+
306+
# Never include build context
307+
zerv flow --schema standard-no-context
308+
309+
# Always include build context
310+
zerv flow --schema standard-context
252311
```
253312

254313
### Advanced Usage
255314

256315
```bash
257-
# Complete control over pre-release
258-
zerv flow --bumped-branch release/1 --pre-release-from-branch
316+
# Complete control over pre-release with schema
317+
zerv flow --bumped-branch release/1 --schema standard-base-prerelease-post-context
259318

260-
# Custom template output
261-
zerv flow --output-template "v{{version}}-{{pre_release}}"
319+
# Custom template output with specific schema
320+
zerv flow --schema standard-base --output-template "v{{version}}-{{pre_release}}"
262321

263322
# Different repository directory
264-
zerv flow --directory ../other-repo
323+
zerv flow --directory ../other-repo --schema standard
265324

266325
# Verbose output
267-
zerv flow --verbose
326+
zerv flow --verbose --schema standard-base-prerelease-post-dev
327+
328+
# Error case - this will fail with calver schema
329+
zerv flow --schema calver # Error: zerv flow only supports standard schema variants
268330
```
269331

270332
## Future Configuration
@@ -291,11 +353,11 @@ zerv flow --config .zerv.ron
291353

292354
## Key Design Principles
293355

294-
1. **Mirror zerv version**: Same output/input options structure
295-
2. **Intelligent defaults**: Smart branch-based pre-release detection
296-
3. **Flexible overrides**: Manual control when needed
297-
4. **Honest versioning**: Never hides Git state, always accurate
298-
5. **Clean alternatives**: `--with-pre-release` and `--base-only` for simplified output
356+
1. **Mirror zerv version**: Same output/input options structure with shared schema system
357+
2. **Intelligent defaults**: Smart branch-based pre-release detection with smart context schema
358+
3. **Flexible overrides**: Manual control when needed, including schema selection
359+
4. **Honest versioning**: Never hides Git state, always accurate (unless explicitly requested via schema)
360+
5. **Schema-based flexibility**: Single `--schema` argument replaces multiple context/control flags
299361

300362
---
301363

0 commit comments

Comments
 (0)