Skip to content

Commit b2a8b39

Browse files
authored
Merge pull request #3 from unic/feature/roadmap-backlog
chore(spec-15): add spec and roadmap backlog section
2 parents e8caf26 + 3de051e commit b2a8b39

2 files changed

Lines changed: 104 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# 15. Release Tools Test Coverage
2+
**Status: open**
3+
4+
**Priority:** P1
5+
**Effort:** S
6+
**Version impact:** none
7+
**Depends on:** 03
8+
**Touches:** `packages/release-tools/scripts/`
9+
10+
## Context
11+
12+
`verify-changelog.mjs` already has a test file (`verify-changelog.test.mjs`). The other two scripts with non-trivial logic — `bump-version.mjs` and `sync-version.mjs` — have no tests. This spec adds coverage for both, following the same subprocess-based pattern already established by `verify-changelog.test.mjs`.
13+
14+
`tag.mjs` is excluded: its core logic (read name+version, run sync, call `git tag`) is tested indirectly through integration; the git interaction makes unit testing add little value without a real repo context.
15+
16+
## Current behaviour
17+
18+
- `packages/release-tools/scripts/verify-changelog.test.mjs` exists — 9 test cases
19+
- `packages/release-tools/scripts/bump-version.test.mjs` — does not exist
20+
- `packages/release-tools/scripts/sync-version.test.mjs` — does not exist
21+
- `package.json` test script only references `verify-changelog.test.mjs`
22+
23+
## Target behaviour
24+
25+
- `bump-version.test.mjs` covers: invalid type, dirty tree, missing files, malformed version, no real changelog entries, missing [Unreleased] section, patch/minor/major version arithmetic, CHANGELOG promotion
26+
- `sync-version.test.mjs` covers: version sync to marketplace + package.json, no-op when up to date, error on missing files, malformed version, field mirroring (license, homepage, keywords)
27+
- `package.json` test script runs all three test files
28+
29+
## Affected files
30+
31+
| File | Change |
32+
|---|---|
33+
| `packages/release-tools/scripts/bump-version.test.mjs` | Create |
34+
| `packages/release-tools/scripts/sync-version.test.mjs` | Create |
35+
| `packages/release-tools/package.json` | Modify — extend test script |
36+
37+
## Implementation steps
38+
39+
1. Create `packages/release-tools/scripts/bump-version.test.mjs` with test cases listed in Acceptance criteria. Use the same subprocess-based pattern as `verify-changelog.test.mjs`: create a temp dir via `mkdtempSync`, write fixture files, run the script via `spawnSync` with `cwd: tmpDir` (since `bump-version.mjs` resolves paths from `process.cwd()`). For tests that need a clean or dirty git state, inject cross-platform fake `git` stubs into the temp dir: a POSIX shell script (`git`) for macOS/Linux and a CMD batch file (`git.cmd`) for Windows. Prepend the temp dir to PATH using `path.delimiter` (not a hard-coded `:`), matching the approach in `verify-changelog.test.mjs` but extended to cover Windows. Happy-path bump tests also require a `.claude-plugin/marketplace.json` fixture in the temp dir (consumed by `sync-version.mjs`).
40+
41+
2. Create `packages/release-tools/scripts/sync-version.test.mjs` with test cases listed in Acceptance criteria.
42+
43+
3. Update `packages/release-tools/package.json` test script to include all three test files:
44+
```json
45+
"test": "node --test scripts/verify-changelog.test.mjs scripts/bump-version.test.mjs scripts/sync-version.test.mjs"
46+
```
47+
48+
4. Run `pnpm --filter @unic/release-tools test` and verify all tests pass.
49+
50+
5. Commit: `test(release-tools): add bump-version and sync-version tests (spec-15)`
51+
52+
## Verification
53+
54+
```sh
55+
pnpm --filter @unic/release-tools test
56+
# All test cases pass; CI validates macOS, Windows, and Linux
57+
```
58+
59+
## Acceptance criteria
60+
61+
### bump-version.test.mjs
62+
- [ ] `exits 1 with usage message when bump type is invalid`
63+
- [ ] `exits 1 when working tree is dirty`
64+
- [ ] `exits 1 when plugin.json is missing`
65+
- [ ] `exits 1 when version in plugin.json is malformed (e.g. "not-semver")`
66+
- [ ] `exits 1 when CHANGELOG.md is missing`
67+
- [ ] `exits 1 when CHANGELOG.md has no [Unreleased] section`
68+
- [ ] `exits 1 when [Unreleased] has no real entries (only "(none)")`
69+
- [ ] `patch bump: increments patch, resets nothing`
70+
- [ ] `minor bump: increments minor, resets patch to 0`
71+
- [ ] `major bump: increments major, resets minor and patch to 0`
72+
- [ ] `bump promotes [Unreleased] section and leaves a fresh empty [Unreleased] — released section date matches YYYY-MM-DD`
73+
74+
### sync-version.test.mjs
75+
- [ ] `exits 1 when plugin.json is missing`
76+
- [ ] `exits 1 when .version is missing or not a string in plugin.json`
77+
- [ ] `exits 1 when marketplace.json has no plugins[] array`
78+
- [ ] `syncs version from plugin.json to marketplace.json`
79+
- [ ] `syncs version to package.json when it exists`
80+
- [ ] `reports no change when versions already match`
81+
- [ ] `mirrors license, homepage, and keywords fields from plugin.json into marketplace entry`
82+
83+
### package.json
84+
- [ ] test script references all three test files
85+
86+
## Out of scope
87+
88+
- Tests for `tag.mjs` (git-heavy, integration-only)
89+
- Extracting a shared reusable fake-binary helper across test files — each test file can inline its own stubs

docs/plans/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ Individual plugins have their own `docs/plans/` for plugin-specific development.
2323
| 12 | [first-releases](12-first-releases.md) | Cut `pr-review@0.1.1`, `auto-format@0.5.5`, `confluence-publish@2.1.6` | 11 |
2424
| 13 | [archive-old-repos](13-archive-old-repos.md) | Final CHANGELOG entries; archive old GitHub repos | 12 |
2525
| 14 | [fix-release-workflow](14-fix-release-workflow.md) | Fix tag detection to use tag-existence check instead of HEAD~1 diff | 12 |
26+
| 15 | [release-tools-tests](15-release-tools-tests.md) | `bump-version.test.mjs` + `sync-version.test.mjs` for `@unic/release-tools` | 03 |
27+
28+
## Backlog
29+
30+
Ideas that need a spec before Ralph can run them. When you're ready to act on one, ask Claude to write the spec (`NN-name.md`), review it, then hand it to Ralph.
31+
32+
| Idea | Priority | Notes |
33+
|---|---|---|
34+
| Update plugin `CLAUDE.md` files for monorepo context | P1 | All three plugins (`pr-review`, `auto-format`, `confluence-publish`) still have standalone-repo instructions; deferred in specs 05–07 |
35+
| Bake `pnpm format` into `bump-version.mjs` | P2 | Every bump leaves CHANGELOG.md in a state Prettier disagrees with, requiring a manual `pnpm format` step; discovered during spec 14 |
36+
| GitHub Release notes automation | P3 | Auto-generate release notes from CHANGELOG.md when the release workflow fires a tag |
37+
38+
**Manual actions pending (not Ralph specs):**
39+
40+
- Execute smoke test checklist (`docs/process/smoke-test-checklist.md`) — requires a scratch Claude Code environment, an Azure DevOps PR URL, and Confluence credentials
2641

2742
## SemVer policy (per plugin)
2843

0 commit comments

Comments
 (0)