refactor(P06): rename milestone type schema-breaking → major, reinforce release flow
---ci---
phase: 6
milestone: v0.10
status: execute
decisions:
- id: D-001
decision: Rename MilestoneType schema-breaking to major for clarity
rationale: Major better describes the semver impact (major version bump) and aligns with standard semver terminology
confidence: 0.95
alternatives: [schema-breaking, breaking, major-change]
- id: D-002
decision: Add autopilot rules, PR+QA gates, and merge validation to ship workflow
rationale: Release flow was documented but not enforced in the workflow. Zero-HITL rules, branch hierarchy validation, and coreci packaging steps ensure consistent releases
confidence: 0.90
alternatives: [keep-as-documentation-only, add-to-AGENTS.md-only]
---/ci---
This commit is contained in:
@@ -106,20 +106,27 @@ Phase branches can be deleted after merge if desired.
|
||||
|
||||
**Every merge to main creates a release. No exceptions.** Versioning follows a 3-tier model based on milestone type:
|
||||
|
||||
### 3-Tier Versioning Model
|
||||
### Milestone Type and Versioning
|
||||
|
||||
The milestone type is determined **before any development work** and governs all versioning for the entire milestone.
|
||||
|
||||
**Define semver at milestone start:** establish the version and milestone type before writing code.
|
||||
|
||||
Determine milestone type via `getMilestoneType()` which returns `"nfr" | "feature" | "major"`:
|
||||
|
||||
| Milestone Type | Condition | Phase release | Milestone release |
|
||||
|---------------|-----------|---------------|-------------------|
|
||||
| **NFR** | All phases: fix/chore/docs/perf/refactor/test | Patch (`vX.Y.Z`) | None |
|
||||
| **Feature** | Any phase is `feat`, no schema break | Patch (`vX.Y.Z`) | Minor — `vX.(Y+1).0` |
|
||||
| **Schema-breaking** | Refactor/schema break/new direction | Minor — `vX.(Y+N).0` per phase | Major — `v(X+1).0.0` |
|
||||
| **NFR** | All phases are fix/chore/docs/perf/refactor/test | Patch — `v1.8.1`, `v1.8.2`, ... | None — final patch IS the deliverable |
|
||||
| **Feature** | At least one phase has new features (`feat`) | Patch — `v1.8.1`, `v1.8.2`, ... | Next minor — `v1.9.0` |
|
||||
| **Major** | Breaking schema changes or complete refactor | Minor — `v2.1.0`, `v2.2.0`, ... | Major — `v3.0.0` |
|
||||
|
||||
**IMPORTANT:** Milestone tags are always the NEXT version, never the base:
|
||||
- Feature: patches v0.5.1–v0.5.5 → milestone tag is v0.6.0 (NOT v0.5.0)
|
||||
- Schema-breaking: minors v0.3.0, v0.4.0, v0.5.0 → milestone tag is v1.0.0
|
||||
- NFR: no milestone tag — the milestone is implicit from the patch sequence
|
||||
|
||||
Determine milestone type via `getMilestoneType()` which returns `"nfr" | "feature" | "schema-breaking"`.
|
||||
**Tag rules (CRITICAL):**
|
||||
- Milestone tags are always the NEXT version, never the base:
|
||||
- Feature: patches v0.5.1–v0.5.5 → milestone tag is v0.6.0 (NOT v0.5.0)
|
||||
- Major: minors v0.3.0, v0.4.0, v0.5.0 → milestone tag is v1.0.0
|
||||
- NFR: no milestone tag — the final patch release IS the deliverable
|
||||
- Tags must be strictly greater than all existing tags on the same major.minor line
|
||||
- NEVER create a milestone tag that is semantically below existing phase tags
|
||||
|
||||
### Phase completion
|
||||
|
||||
@@ -135,7 +142,7 @@ git push origin main --tags
|
||||
|
||||
Phase number within the milestone determines the patch version (1st phase = .1, 2nd phase = .2, etc.)
|
||||
|
||||
**Schema-breaking (minor release per phase):**
|
||||
**Major (minor release per phase):**
|
||||
```bash
|
||||
git checkout milestone/v0.5-schema-rewrite
|
||||
git merge --squash phase/01-core-refactor
|
||||
@@ -145,7 +152,7 @@ git push origin main --tags
|
||||
# Create Gitea release for v0.5.0
|
||||
```
|
||||
|
||||
Each schema-breaking phase bumps the minor. 1st phase = next available minor, 2nd = minor+1, etc.
|
||||
Each major phase bumps the minor. 1st phase = next available minor, 2nd = minor+1, etc.
|
||||
|
||||
### Milestone completion
|
||||
|
||||
@@ -160,7 +167,7 @@ git push origin main --tags
|
||||
# Create Gitea release for v0.6.0 with full milestone summary
|
||||
```
|
||||
|
||||
**Schema-breaking (major release):**
|
||||
**Major (major release):**
|
||||
```bash
|
||||
# All phases already merged into milestone branch
|
||||
git checkout main
|
||||
@@ -177,9 +184,20 @@ git push origin main --tags
|
||||
|
||||
Before creating any tag:
|
||||
1. Tag must be strictly greater than all existing tags on the same major.minor line
|
||||
2. Milestone completion tag must be next minor (feature) or next major (schema-breaking)
|
||||
2. Milestone completion tag must be next minor (feature) or next major (major)
|
||||
3. NEVER create a tag that is semantically below existing phase tags
|
||||
|
||||
### Merge Validation Gates
|
||||
|
||||
The branch hierarchy `main > milestone/vX.X-slug > phase/NN-slug` is enforced at merge time:
|
||||
|
||||
| Merge Type | Rule | Validation |
|
||||
|------------|------|-------------|
|
||||
| Phase → Milestone | Must target milestone branch when one exists | REJECTED if milestone branch does not exist for this phase's milestone |
|
||||
| Phase → Main | Only allowed when no milestone branch exists | REJECTED if a milestone branch exists for this milestone |
|
||||
| Milestone → Main | Only after all phase branches are merged | REJECTED if any phase branches for this milestone are unmerged |
|
||||
| Hotfix → Main | Allowed (exception to hierarchy) | Always allowed |
|
||||
|
||||
## Multi-Project Branch Naming
|
||||
|
||||
When operating in multi-project mode (`.ciagent/config.json` has `projects[]` with length > 0):
|
||||
|
||||
Reference in New Issue
Block a user