fix(P02): mandatory releases for every phase and milestone — correct versioning
---ci---
phase: 2
milestone: v0.2
status: execute
decisions:
- id: D-016
decision: Every ship creates a release — phases get patch, milestones get minor/major
rationale: Releases are not optional. Every phase must be tagged and released. Milestone completion also gets a release. Major for schema changes, Minor for milestones, Patch for phases.
confidence: 0.99
alternatives: [optional releases, phase-only releases]
---/ci---
- ship.md: rewritten with mandatory release flow and versioning table (Major/Minor/Patch)
- run.md: COMPLETE stage now includes tag + release as mandatory steps
- branch-strategy.md: added Versioning and Releases section with merge→tag→release examples
This commit is contained in:
@@ -77,6 +77,44 @@ gitBranch.mergePhaseBranch("phase/01-git-native-architecture", "main", true);
|
|||||||
|
|
||||||
Squash merge keeps main clean while preserving full development history in the phase branch. Phase branches can be deleted after merge if desired.
|
Squash merge keeps main clean while preserving full development history in the phase branch. Phase branches can be deleted after merge if desired.
|
||||||
|
|
||||||
|
## Versioning and Releases
|
||||||
|
|
||||||
|
**Every merge to main creates a release. No exceptions.** Versioning maps to project structure:
|
||||||
|
|
||||||
|
| Version Part | When | Example |
|
||||||
|
|-------------|------|---------|
|
||||||
|
| **Major** (X.0.0) | Project-level refactor or schema change | `v1.0.0` |
|
||||||
|
| **Minor** (0.X.0) | Every milestone completion | `v0.3.0` |
|
||||||
|
| **Patch** (0.0.X) | Every phase completion | `v0.2.3` |
|
||||||
|
|
||||||
|
### Phase completion (patch release)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout main
|
||||||
|
git merge --squash phase/01-git-native-architecture
|
||||||
|
git commit -m "docs(P01): complete git-native-architecture phase"
|
||||||
|
git tag -a v0.2.1 -m "v0.2.1: git-native-architecture"
|
||||||
|
git push origin main --tags
|
||||||
|
# Create Gitea release for v0.2.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Phase number within the milestone determines the patch version (1st phase = .1, 2nd phase = .2, etc.)
|
||||||
|
|
||||||
|
### Milestone completion (minor release)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout main
|
||||||
|
git merge --squash milestone/v0.2-git-native
|
||||||
|
git commit -m "docs(milestone): complete git-native"
|
||||||
|
git tag -a v0.2.0 -m "v0.2.0: git-native"
|
||||||
|
git push origin main --tags
|
||||||
|
# Create Gitea release for v0.2.0 with full milestone summary
|
||||||
|
```
|
||||||
|
|
||||||
|
### Major release
|
||||||
|
|
||||||
|
When the project undergoes a schema-breaking change (e.g., switching from file-based to git-native architecture), bump the major version. Major releases follow the same merge → tag → release flow.
|
||||||
|
|
||||||
## Phase Discovery
|
## Phase Discovery
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@@ -117,6 +155,8 @@ status: execute
|
|||||||
git checkout main
|
git checkout main
|
||||||
git merge --squash phase/01-git-native-architecture
|
git merge --squash phase/01-git-native-architecture
|
||||||
git commit -m "docs(P01): complete git-native-architecture phase"
|
git commit -m "docs(P01): complete git-native-architecture phase"
|
||||||
|
git tag -a v0.2.1 -m "v0.2.1: git-native-architecture"
|
||||||
|
git push origin main --tags
|
||||||
```
|
```
|
||||||
|
|
||||||
</branch_strategy>
|
</branch_strategy>
|
||||||
@@ -68,10 +68,14 @@ For each stage in order (starting from current or from `specify`):
|
|||||||
|
|
||||||
### COMPLETE
|
### COMPLETE
|
||||||
- Merge phase branch into main (squash)
|
- Merge phase branch into main (squash)
|
||||||
|
- Tag with patch version (e.g., `v0.2.3` — 3rd phase in milestone v0.2)
|
||||||
|
- Create Gitea release for the tag
|
||||||
- Update `.ci/REQUIREMENTS.md` requirement statuses
|
- Update `.ci/REQUIREMENTS.md` requirement statuses
|
||||||
- Update `.ci/ROADMAP.md` phase status
|
- Update `.ci/ROADMAP.md` phase status
|
||||||
- Commit: `docs(P##): complete [phase-name] phase`
|
- Commit: `docs(P##): complete [phase-name] phase`
|
||||||
|
|
||||||
|
Versioning: Major = project-level refactor/schema change, Minor = milestone completion, Patch = every phase.
|
||||||
|
|
||||||
## Step 4: Error Recovery
|
## Step 4: Error Recovery
|
||||||
|
|
||||||
On stage failure:
|
On stage failure:
|
||||||
@@ -82,6 +86,9 @@ On stage failure:
|
|||||||
## Step 5: Advance or Complete
|
## Step 5: Advance or Complete
|
||||||
|
|
||||||
If more phases remain: advance to next phase, return to Step 3.
|
If more phases remain: advance to next phase, return to Step 3.
|
||||||
If all phases complete: report project completion.
|
If all phases complete:
|
||||||
|
- Tag milestone with minor version (e.g., `v0.3.0`)
|
||||||
|
- Create Gitea release for the milestone with full phase summary
|
||||||
|
- Report project completion
|
||||||
|
|
||||||
Error handling: commit escalations as `---ci---` blocks with `escalation` type.
|
Error handling: commit escalations as `---ci---` blocks with `escalation` type.
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
---
|
---
|
||||||
description: Ship CI phase — test, commit, tag, and optionally create release. Full autopilot: zero HITL after milestone setup.
|
description: Ship CI phase or milestone — test, tag, release. Every phase gets a patch release. Every milestone gets a minor (or major) release. Full autopilot.
|
||||||
---
|
---
|
||||||
|
|
||||||
# CI Ship
|
# CI Ship
|
||||||
|
|
||||||
Ship a CI phase or milestone. Full autopilot: test, commit, tag, push, and release without human intervention.
|
Ship a CI phase or milestone. Every ship creates a release — no exceptions.
|
||||||
|
|
||||||
|
**Versioning rule:**
|
||||||
|
- **Major** (X.0.0): Project-level refactor or schema changes
|
||||||
|
- **Minor** (0.X.0): Every milestone completion
|
||||||
|
- **Patch** (0.0.X): Every phase completion
|
||||||
|
|
||||||
**Usage:** `ci-ship [phase_number|milestone]`
|
**Usage:** `ci-ship [phase_number|milestone]`
|
||||||
|
|
||||||
@@ -15,7 +20,12 @@ git log --max-count=10
|
|||||||
git branch -a
|
git branch -a
|
||||||
```
|
```
|
||||||
|
|
||||||
Determine what is being shipped (specific phase or entire milestone).
|
Determine what is being shipped: a single phase (patch release) or an entire milestone (minor/major release).
|
||||||
|
|
||||||
|
Read `.ci/ROADMAP.md` to determine:
|
||||||
|
- Current milestone version (e.g., `v0.2`)
|
||||||
|
- Phase number within the milestone
|
||||||
|
- Whether this is the last phase in the milestone
|
||||||
|
|
||||||
Read `.ci/config.json` for autonomy level.
|
Read `.ci/config.json` for autonomy level.
|
||||||
|
|
||||||
@@ -29,9 +39,21 @@ npm run build
|
|||||||
|
|
||||||
If any fail: iterate autonomously until tests pass. Do NOT ask the user for guidance — debug and fix.
|
If any fail: iterate autonomously until tests pass. Do NOT ask the user for guidance — debug and fix.
|
||||||
|
|
||||||
## Step 3: Merge Phase Branch
|
## Step 3: Compute Version
|
||||||
|
|
||||||
If shipping a single phase:
|
Determine the release version from what is being shipped:
|
||||||
|
|
||||||
|
| What's shipping | Version bump | Tag format | Example |
|
||||||
|
|----------------|-------------|------------|---------|
|
||||||
|
| Single phase | Patch | `vX.Y.Z` | `v0.2.3` (3rd phase in milestone v0.2) |
|
||||||
|
| Milestone completion | Minor | `vX.Y.0` | `v0.3.0` (milestone v0.3 complete) |
|
||||||
|
| Project refactor/schema change | Major | `vX.0.0` | `v1.0.0` (breaking schema) |
|
||||||
|
|
||||||
|
Count completed phases in the current milestone to determine the patch number. If this is the last phase in the milestone, the version bumps to minor instead of patch.
|
||||||
|
|
||||||
|
## Step 4: Merge Branch
|
||||||
|
|
||||||
|
### Phase ship (patch release)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git checkout main
|
git checkout main
|
||||||
@@ -40,7 +62,7 @@ git commit -m "docs(P##): complete [phase-name] phase
|
|||||||
|
|
||||||
---ci---
|
---ci---
|
||||||
phase: [N]
|
phase: [N]
|
||||||
milestone: [vX.X]
|
milestone: [vX.Y]
|
||||||
status: complete
|
status: complete
|
||||||
requirements:
|
requirements:
|
||||||
covered: [REQ-01, REQ-02]
|
covered: [REQ-01, REQ-02]
|
||||||
@@ -48,34 +70,56 @@ requirements:
|
|||||||
---/ci---"
|
---/ci---"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 4: Tag Release
|
### Milestone ship (minor/major release)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git tag -a vX.X.X -m "vX.X.X: [phase-name]"
|
git checkout main
|
||||||
|
git merge --squash milestone/vX.Y-slug
|
||||||
|
git commit -m "docs(milestone): complete [milestone-name]
|
||||||
|
|
||||||
|
---ci---
|
||||||
|
phase: 0
|
||||||
|
milestone: [vX.Y]
|
||||||
|
status: complete
|
||||||
|
---/ci---"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 5: Tag and Push
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git tag -a vX.Y.Z -m "vX.Y.Z: [phase-name or milestone-name]"
|
||||||
git push origin main --tags
|
git push origin main --tags
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 5: Create Release (if milestone)
|
## Step 6: Create Release
|
||||||
|
|
||||||
If shipping an entire milestone:
|
**Every ship creates a Gitea release. No exceptions.**
|
||||||
1. Merge milestone branch to main
|
|
||||||
2. Tag with milestone version
|
Generate release notes from git log:
|
||||||
3. Generate release notes from git log
|
|
||||||
4. Create release via Gitea API
|
```bash
|
||||||
|
git log v[previous_tag]..vX.Y.Z --oneline
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the release via Gitea API:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST "https://git.cloudinit.dev/api/v1/repos/continuous-intelligence/ci/releases" \
|
curl -X POST "https://git.cloudinit.dev/api/v1/repos/continuous-intelligence/ci/releases" \
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
-H "Authorization: token $GITEA_TOKEN" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{"tag_name":"vX.X.X","name":"vX.X.X","body":"[release notes]"}'
|
-d '{"tag_name":"vX.Y.Z","name":"vX.Y.Z","body":"[release notes from git log]"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 6: Update .ci/ Files
|
For milestone releases, include a summary of all phases completed and requirements covered.
|
||||||
|
|
||||||
|
## Step 7: Update .ci/ Files
|
||||||
|
|
||||||
- Update `.ci/REQUIREMENTS.md` — mark shipped requirements as complete
|
- Update `.ci/REQUIREMENTS.md` — mark shipped requirements as complete
|
||||||
- Update `.ci/ROADMAP.md` — mark shipped phase as complete
|
- Update `.ci/ROADMAP.md` — mark shipped phase as complete
|
||||||
|
|
||||||
## Step 7: Report
|
Commit the file updates.
|
||||||
|
|
||||||
|
## Step 8: Report
|
||||||
|
|
||||||
```
|
```
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
@@ -83,8 +127,9 @@ curl -X POST "https://git.cloudinit.dev/api/v1/repos/continuous-intelligence/ci/
|
|||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
|
||||||
Phase [N]: [name]
|
Phase [N]: [name]
|
||||||
Milestone: [vX.X]
|
Milestone: [vX.Y]
|
||||||
Tag: vX.X.X
|
Version: vX.Y.Z
|
||||||
|
Release: https://git.cloudinit.dev/continuous-intelligence/ci/releases/tag/vX.Y.Z
|
||||||
Status: complete
|
Status: complete
|
||||||
|
|
||||||
Tests: PASS
|
Tests: PASS
|
||||||
@@ -93,5 +138,8 @@ Build: PASS
|
|||||||
|
|
||||||
Requirements covered: [N]
|
Requirements covered: [N]
|
||||||
Commits: [N]
|
Commits: [N]
|
||||||
|
|
||||||
|
[If milestone complete:]
|
||||||
|
All phases in milestone v0.2 complete. Milestone released.
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
```
|
```
|
||||||
Reference in New Issue
Block a user