Skip to content

v2: TypeScript rewrite — git-first, .tagyrc config, safe-by-default - #5

Open
awps wants to merge 13 commits into
masterfrom
v2
Open

v2: TypeScript rewrite — git-first, .tagyrc config, safe-by-default#5
awps wants to merge 13 commits into
masterfrom
v2

Conversation

@awps

@awps awps commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Summary

Rewrites tagy as a general-purpose, git-first release tool that is no longer coupled to package.json, and ports the codebase to TypeScript. Implemented from the approved design spec + plan in docs/superpowers/ via task-by-task TDD with per-task review and a final whole-branch review.

Defining shifts from v1

  • Not tied to package.json. Config moves to a standalone .tagyrc (JSON, zero-dep parse). Resolution order: .tagyrc.tagyrc.json → legacy package.json.tagy (offers one-time migration) → interactive wizard.
  • Git-first version source. The current version comes from the latest git tag (prefix-aware); file versions are written unprefixed.
  • Safe by default. With no/minimal config, tagy verifies it's a git repo then tags + pushes — it touches no files unless bump/replace are configured.
  • Interactive wizard when no config exists: asks branch, tag prefix, which known manifest(s) to bump, and offers to save a .tagyrc.

Architecture

TypeScript under src/, compiled with plain tsc to dist/ (published artifact). Modular, DI-friendly, one responsibility per file:

  • lib.ts — pure helpers (color, semver, substitute, replace) · git.ts — command builders + injectable shelljs wrappers · bump.ts — structural JSON bumpers (package.json, composer.json) + replace rules + .tagyrc writer · config.ts — load/normalize/migrate · wizard.ts — interactive prompts · index.ts — thin orchestration · cli.ts — shim.
  • 45 unit tests (one suite per module); index.ts orchestration verified manually (build + --info + soft e2e).

.tagyrc schema

{
  "branch": null,        // null = silent on master/main, confirm otherwise; string = require this branch
  "tagPrefix": "",       // e.g. "v" -> tag "v1.2.3"; file versions stay unprefixed
  "bump": [],            // structural bumps: ["package.json", "composer.json"]
  "replace": [],         // regex rules: { files, from, to, flags }  (__VERSION__ / __CURRENT_TAG__)
  "autoRelease": false   // gh release without prompting
}

Other manifests (Cargo.toml, etc.) are handled via replace rules. The tagy.js hook still runs before push.

CI / packaging

  • Publish workflow runs npm run build before npm publish; PR CI adds npx tsc --noEmit (Node 20 + 22 matrix).
  • files: ["dist"] — only compiled output ships.

Breaking changes (v1 → v2)

  1. Config no longer read from package.json.tagy — moved to .tagyrc (one-time migrator offered on first run; preserves the implicit package.json bump).
  2. package.json bump is no longer automatic — it must be listed in bump (migrator adds it for upgraders).
  3. tagy.soft / method:"soft" config keys removed; --soft flag remains.
  4. Published artifact is compiled dist/.

CLI flags are unchanged from v1.

Review notes

  • Final whole-branch review: Ready to merge, no blockers.
  • Conscious design choices applied from review: the wizard saves branch: null (documented default, not pinned); --soft skips the branch-confirm prompt; --info/--reverse short-circuit before any config/wizard (read-only --info never launches the wizard); --custom keeps the previous tag for __CURRENT_TAG__.

Not included

  • Version is not bumped here — v2.0.0 is cut later via tagy itself.
  • Removing the remaining runtime deps (shelljs/prompts/semver/fs-extra/yargs) toward true zero-deps is a separate follow-up (eased by these module boundaries).

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant