diff --git a/.claude/skills/bump-package-versions/skill.md b/.claude/skills/bump-package-versions/skill.md new file mode 100644 index 0000000..ffa11dd --- /dev/null +++ b/.claude/skills/bump-package-versions/skill.md @@ -0,0 +1,61 @@ +--- +name: bump-package-versions +description: Bump the package.json version (patch/minor/major), commit, push, and open a PR. +--- + +Bump the package version, commit, push, and open a PR. Do NOT ask for confirmation between steps — just execute. + +The user may pass `major`, `minor`, or `patch` as an argument (e.g. `/bump-package-versions patch`). Default to `patch` if no argument is given. + +## Step 0: Preflight checks + +Run these checks before doing anything. If any fail, abort immediately and tell the user why. + +1. **Validate argument.** If an argument is provided, it must be one of `major`, `minor`, or `patch`. If it is anything else, abort with: `Invalid bump type "". Must be one of: major, minor, patch.` +2. **Clean working tree.** Run `git status --porcelain`. If there is any output, abort with: `Working tree is not clean. Please commit or stash your changes first.` +3. **On main branch.** Run `git branch --show-current`. If not on `main`, switch to it with `git checkout main`. +4. **Up to date with remote.** Run `git pull` to ensure main is current before branching. + +## Step 1: Bump the version + +1. Read `package.json` and parse the current `version` field. +2. Increment the version according to the argument: + - `patch`: `0.1.1` → `0.1.2` + - `minor`: `0.1.1` → `0.2.0` + - `major`: `0.1.1` → `1.0.0` +3. Update the `version` field in `package.json` using the Edit tool. Do not change anything else in the file. +4. Run `npm i --package-lock-only` to sync `package-lock.json` with the new version. +5. Store the new version string (e.g. `0.1.2`) for use in later steps. + +## Step 2: Create branch, commit, push, and open PR + +1. **Create a branch** named `pkg/bump-to-v` (e.g. `pkg/bump-to-v0.1.2`). + Use `git checkout -b `. + +2. **Stage** `package.json` and `package-lock.json`. + +3. **Commit** with the message: + + ``` + pkg: Bump pkg versions to v + ``` + + No co-author lines. No multi-line body. + +4. **Push** with `git push -u origin `. + +5. **Open PR** with `gh pr create`: + - Title: `Bump package version to v` + - Body: `Bumps package version from v to v.` + - Use a HEREDOC for the body. + +6. **Switch back to main** with `git checkout main`. + +7. **Return the PR URL** to the user. + +IMPORTANT: + +- Do NOT amend existing commits +- Do NOT add untracked files or files unrelated to the version bump +- Do NOT ask for confirmation at any step +- Do NOT run build or tests — this is a version-only change diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6cb43f..f2c9ab3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,4 +40,4 @@ jobs: BASE_REF="origin/${{ github.base_ref }}" HEAD_REF="HEAD" echo "Comparing API surface: $BASE_REF..$HEAD_REF" - node dist/cli.js "$BASE_REF..$HEAD_REF" --entrypoint src/index.ts || true + node dist/cli.js "$BASE_REF..$HEAD_REF" --entrypoint src/index.ts --check diff --git a/README.md b/README.md index c933e1c..4164367 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,9 @@ npx sigdiff --entrypoint src/index.ts # JSON output npx sigdiff --json + +# Exit with code 1 if breaking changes are detected (useful for CI) +npx sigdiff --check ``` ## Example output @@ -67,6 +70,18 @@ Changes are classified as `major`, `minor`, or `patch` per semver rules. | Config required | None | Yes | Yes | Yes | | Git ref comparison | Any ref | N/A | N/A | Baseline file | +## CI integration + +Use `--check` to fail your pipeline when breaking changes are introduced: + +```yaml +# .github/workflows/ci.yml +- name: API surface check + run: npx sigdiff origin/main..HEAD --entrypoint src/index.ts --check +``` + +Without `--check`, sigdiff always exits 0 and just prints the diff. With `--check`, it exits 1 if any breaking changes are detected, making it easy to gate PRs. + ## Programmatic API ```typescript diff --git a/package-lock.json b/package-lock.json index 602cfbe..f6a6762 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sigdiff", - "version": "0.1.1", + "version": "0.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sigdiff", - "version": "0.1.1", + "version": "0.1.2", "license": "MIT", "dependencies": { "cac": "^6.7.14" diff --git a/package.json b/package.json index b807c45..0bb1288 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sigdiff", - "version": "0.1.1", + "version": "0.1.2", "description": "Changelog from code, not commits. AST-based API surface diffing for TypeScript.", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/cli.ts b/src/cli.ts index d0fda3b..1c135f9 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -14,7 +14,9 @@ cli .command('[range]', 'Diff the public API surface between two git refs') .option('--entrypoint ', 'Scope to a specific file') .option('--json', 'Output as JSON instead of markdown') - .action((range: string | undefined, options: { entrypoint?: string; json?: boolean }) => { + .option('--check', 'Exit with code 1 if breaking changes are detected') + .action( + (range: string | undefined, options: { entrypoint?: string; json?: boolean; check?: boolean }) => { try { assertGitRepo(); @@ -28,6 +30,10 @@ cli const output = format(result, { json: options.json }); process.stdout.write(output); + + if (options.check && result.breaking.length > 0) { + process.exit(1); + } } catch (err) { if (err instanceof SigdiffException) { process.stderr.write(`Error: ${err.error.message}\n`); @@ -35,7 +41,8 @@ cli } throw err; } - }); + }, +); cli.help(); cli.version(pkgVersion);