package-versioner 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,165 @@
1
+ # CI/CD Integration
2
+
3
+ `package-versioner` is designed to work seamlessly in CI/CD pipelines, making it easy to automate versioning as part of your release workflow.
4
+
5
+ ## JSON Output Mode
6
+
7
+ For programmatic consumption in CI/CD scripts, `package-versioner` provides a structured JSON output option:
8
+
9
+ ```bash
10
+ # Output results in JSON format
11
+ npx package-versioner --json
12
+
13
+ # Combine with dry-run for planning
14
+ npx package-versioner --dry-run --json
15
+ ```
16
+
17
+ This will suppress all normal console output and instead output a single JSON object containing:
18
+
19
+ ```json
20
+ {
21
+ "dryRun": false, // Whether this was a dry run
22
+ "updates": [ // Array of packages that were updated
23
+ {
24
+ "packageName": "@scope/package-a", // Package name
25
+ "newVersion": "1.2.3", // New version number
26
+ "filePath": "/path/to/package.json" // Path to the updated package.json
27
+ }
28
+ ],
29
+ "commitMessage": "chore(release): v1.2.3", // The commit message that was used
30
+ "tags": [ // Array of tags that were created
31
+ "v1.2.3" // or package-specific tags in targeted mode
32
+ ]
33
+ }
34
+ ```
35
+
36
+ ### Benefits of JSON Output
37
+
38
+ The structured JSON output provides several advantages for CI/CD integration:
39
+
40
+ - **Reliable Parsing**: Unlike text logs that might change format or include ANSI color codes, the JSON structure remains consistent
41
+ - **Programmatic Access**: Easily extract specific values like version numbers for subsequent steps
42
+ - **Conditional Workflows**: Trigger different CI actions based on the presence of updates or specific version changes
43
+ - **Audit Trail**: Store the JSON output as artifacts for version change tracking
44
+ - **Error Handling**: Better detect and respond to versioning issues in your pipeline
45
+
46
+ ## Sample CI/CD Integration Patterns
47
+
48
+ Here are some common ways to incorporate `package-versioner` into your CI/CD pipeline:
49
+
50
+ ### GitHub Actions Workflow Example
51
+
52
+ ```yaml
53
+ name: Release
54
+
55
+ on:
56
+ push:
57
+ branches: [main]
58
+
59
+ jobs:
60
+ version:
61
+ runs-on: ubuntu-latest
62
+ outputs:
63
+ changes_detected: ${{ steps.version.outputs.changes_detected }}
64
+ new_version: ${{ steps.version.outputs.new_version }}
65
+
66
+ steps:
67
+ - uses: actions/checkout@v3
68
+ with:
69
+ fetch-depth: 0 # Important for git history
70
+
71
+ - name: Setup Node.js
72
+ uses: actions/setup-node@v3
73
+ with:
74
+ node-version: '18'
75
+
76
+ - name: Install dependencies
77
+ run: npm ci
78
+
79
+ - name: Determine version
80
+ id: version
81
+ run: |
82
+ # Run in JSON mode for parsing
83
+ VERSION_OUTPUT=$(npx package-versioner --json)
84
+ echo "Version output: $VERSION_OUTPUT"
85
+
86
+ # Use jq to parse the JSON output
87
+ CHANGES_DETECTED=$(echo "$VERSION_OUTPUT" | jq -r '.updates | length > 0')
88
+ echo "changes_detected=$CHANGES_DETECTED" >> $GITHUB_OUTPUT
89
+
90
+ if [ "$CHANGES_DETECTED" = "true" ]; then
91
+ # Extract the first package's new version as representative version
92
+ NEW_VERSION=$(echo "$VERSION_OUTPUT" | jq -r '.updates[0].newVersion')
93
+ echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
94
+ fi
95
+
96
+ publish:
97
+ needs: version
98
+ if: needs.version.outputs.changes_detected == 'true'
99
+ runs-on: ubuntu-latest
100
+ steps:
101
+ # Publishing steps using the detected version
102
+ - run: echo "Would publish version ${{ needs.version.outputs.new_version }}"
103
+ ```
104
+
105
+ ### GitLab CI Pipeline Example
106
+
107
+ ```yaml
108
+ stages:
109
+ - version
110
+ - publish
111
+
112
+ determine_version:
113
+ stage: version
114
+ script:
115
+ - npm ci
116
+ - |
117
+ VERSION_OUTPUT=$(npx package-versioner --json)
118
+ echo "VERSION_OUTPUT=$VERSION_OUTPUT" >> version.env
119
+
120
+ # Parse values for use in later stages
121
+ CHANGES_DETECTED=$(echo "$VERSION_OUTPUT" | jq -r '.updates | length > 0')
122
+ echo "CHANGES_DETECTED=$CHANGES_DETECTED" >> version.env
123
+
124
+ if [ "$CHANGES_DETECTED" = "true" ]; then
125
+ NEW_VERSION=$(echo "$VERSION_OUTPUT" | jq -r '.updates[0].newVersion')
126
+ echo "NEW_VERSION=$NEW_VERSION" >> version.env
127
+ fi
128
+ artifacts:
129
+ reports:
130
+ dotenv: version.env
131
+
132
+ publish:
133
+ stage: publish
134
+ needs: determine_version
135
+ script:
136
+ - echo "Publishing version $NEW_VERSION"
137
+ rules:
138
+ - if: $CHANGES_DETECTED == "true"
139
+ ```
140
+
141
+ ## Working with Tags in CI
142
+
143
+ When using the targeted mode with `-t` flag, `package-versioner` creates package-specific tags (e.g., `@scope/package-a@1.2.0`) but not a global tag. If your release process needs a global tag, you can add a step to your CI/CD pipeline:
144
+
145
+ ```bash
146
+ # Create a global tag based on the representative version
147
+ NEW_VERSION=$(echo "$VERSION_OUTPUT" | jq -r '.updates[0].newVersion')
148
+ git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION"
149
+ git push origin "v$NEW_VERSION"
150
+ ```
151
+
152
+ ## Environment Variables
153
+
154
+ `package-versioner` respects the following environment variables:
155
+
156
+ - `NO_COLOR=1`: Disables colored output in logs (automatically detected in CI environments)
157
+ - `CI=true`: Most CI environments set this automatically, which helps the tool adjust its output behavior
158
+
159
+ ## Tips for Reliable CI/CD Integration
160
+
161
+ 1. **Always use `--json`** in CI/CD pipelines for consistent output parsing
162
+ 2. **Use the `fetch-depth: 0`** option in GitHub Actions (or equivalent in other CIs) to ensure access to the full Git history
163
+ 3. **Store the JSON output** as a build artifact for debugging and auditing
164
+ 4. **Consider dry runs** in your preview/staging branches to validate version changes before they're applied
165
+ 5. **Be mindful of Git credentials** - ensure your CI has proper permissions for creating commits and tags
@@ -0,0 +1,96 @@
1
+ # Versioning Strategies and Concepts
2
+
3
+ `package-versioner` offers flexible ways to determine the next version for your project based on its history and your configuration.
4
+
5
+ ## How the Next Version is Calculated
6
+
7
+ There are two primary methods the tool uses to decide the version bump (e.g., patch, minor, major), configured via the `versionStrategy` option in `version.config.json`:
8
+
9
+ ### 1. Conventional Commits (`versionStrategy: "conventional"`)
10
+
11
+ This is the default strategy. `package-versioner` analyzes Git commit messages since the last Git tag that follows semver patterns. It uses the [conventional-commits](https://www.conventionalcommits.org/) specification to determine the bump:
12
+
13
+ - **Patch Bump (e.g., 1.2.3 -> 1.2.4):** Triggered by `fix:` commit types.
14
+ - **Minor Bump (e.g., 1.2.3 -> 1.3.0):** Triggered by `feat:` commit types.
15
+ - **Major Bump (e.g., 1.2.3 -> 2.0.0):** Triggered by commits with `BREAKING CHANGE:` in the footer or `feat!:`, `fix!:` etc. in the header.
16
+
17
+ The specific preset used for analysis (e.g., "angular", "conventional") can be set using the `preset` option in `version.config.json`.
18
+
19
+ **Format:** `<type>(<scope>): <subject>`
20
+
21
+ `<scope>` is optional.
22
+
23
+ **Example Commit Types:**
24
+
25
+ - `feat:` (new feature for the user)
26
+ - `fix:` (bug fix for the user)
27
+ - `docs:` (changes to the documentation)
28
+ - `style:` (formatting, missing semi-colons, etc; no production code change)
29
+ - `refactor:` (refactoring production code, e.g. renaming a variable)
30
+ - `test:` (adding missing tests, refactoring tests; no production code change)
31
+ - `chore:` (updating build tasks etc; no production code change)
32
+
33
+ **References:**
34
+
35
+ - [https://www.conventionalcommits.org/](https://www.conventionalcommits.org/)
36
+ - [https://github.com/conventional-changelog/conventional-changelog](https://github.com/conventional-changelog/conventional-changelog)
37
+
38
+ ### 2. Branch Pattern (`versionStrategy: "branchPattern"`)
39
+
40
+ This strategy uses the name of the current Git branch (or the most recently merged branch matching a pattern, if applicable) to determine the version bump.
41
+
42
+ You define patterns in the `branchPattern` array in `version.config.json`. Each pattern is a string like `"prefix:bumptype"`.
43
+
44
+ **Example `version.config.json`:**
45
+
46
+ ```json
47
+ {
48
+ "versionStrategy": "branchPattern",
49
+ "branchPattern": [
50
+ "feature:minor",
51
+ "hotfix:patch",
52
+ "fix:patch",
53
+ "release:major"
54
+ ],
55
+ "baseBranch": "main"
56
+ }
57
+ ```
58
+
59
+ **How it works:**
60
+
61
+ 1. The tool checks the current branch name.
62
+ 2. It might also look for the most recently merged branch into `baseBranch` that matches any pattern in `branchPattern`.
63
+ 3. It compares the relevant branch name (current or last merged) against the prefixes in `branchPattern`.
64
+ 4. If a match is found (e.g., current branch is `feature/add-login`), it applies the corresponding bump type (`minor` in this case).
65
+
66
+ This allows you to enforce version bumps based on your branching workflow (e.g., all branches starting with `feature/` result in a minor bump).
67
+
68
+ ## Monorepo Versioning Modes
69
+
70
+ While primarily used for single packages now, `package-versioner` retains options for monorepo workflows, controlled mainly by the `synced` flag in `version.config.json`.
71
+
72
+ ### Synced Mode (`synced: true`)
73
+
74
+ This is the default if the `synced` flag is present and true.
75
+
76
+ - **Behavior:** The tool calculates **one** version bump based on the overall history (or branch pattern). This single new version is applied to **all** packages within the repository (or just the root `package.json` if not a structured monorepo). A single Git tag is created (e.g., `v1.2.3`).
77
+ - **Use Case:** Suitable for monorepos where all packages are tightly coupled and released together with the same version number. Also the effective mode for single-package repositories.
78
+
79
+ ### Async Mode (`synced: false`)
80
+
81
+ *(Note: This mode relies heavily on monorepo tooling and structure, like `pnpm workspaces` and correctly configured package dependencies.)*
82
+
83
+ - **Behavior (Default - No `-t` flag):** The tool analyzes commits to determine which specific packages within the monorepo have changed since the last relevant commit/tag.
84
+ - It calculates an appropriate version bump **independently for each changed package** based on the commits affecting that package.
85
+ - Only the `package.json` files of the changed packages are updated.
86
+ - A **single commit** is created grouping all the version bumps, using the commit message template. **No Git tags are created** in this mode.
87
+ - **Use Case:** Suitable for monorepos where packages are versioned independently, but a single commit represents the batch of updates for traceability.
88
+
89
+ - **Behavior (Targeted - With `-t` flag):** When using the `-t, --target <targets>` flag:
90
+ - Only the specified packages (respecting the `skip` list) are considered for versioning.
91
+ - It calculates an appropriate version bump **independently for each targeted package** based on its commit history.
92
+ - The `package.json` file of each successfully updated targeted package is modified.
93
+ - An **individual Git tag** (e.g., `packageName@1.2.3`) is created **for each successfully updated package** immediately after its version is bumped.
94
+ - Finally, a **single commit** is created including all the updated `package.json` files, using a summary commit message (e.g., `chore(release): pkg-a, pkg-b 1.2.3 [skip-ci]`).
95
+ - **Important:** Only package-specific tags are created. The global tag (e.g., `v1.2.3`) is **not** automatically generated in this mode. If your release process (like GitHub Releases) depends on a global tag, you'll need to create it manually in your CI/CD script *after* `package-versioner` completes.
96
+ - **Use Case:** Releasing specific packages independently while still tagging each released package individually.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "package-versioner",
3
- "description": "A powerful CLI tool for automated semantic versioning based on Git history and conventional commits. Supports monorepos with synchronized or independent package versioning strategies.",
4
- "version": "0.1.1",
3
+ "description": "A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits.",
4
+ "version": "0.3.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
@@ -24,6 +24,7 @@
24
24
  "license": "MIT",
25
25
  "files": [
26
26
  "dist/**",
27
+ "docs/**",
27
28
  "package-versioner.schema.json"
28
29
  ],
29
30
  "bin": {
@@ -38,11 +39,11 @@
38
39
  "devDependencies": {
39
40
  "@biomejs/biome": "^1.9.4",
40
41
  "@types/figlet": "^1.5.5",
41
- "@types/node": "^22.14.0",
42
+ "@types/node": "^22.14.1",
42
43
  "@types/semver": "^7.3.13",
43
44
  "@vitest/coverage-v8": "^3.1.1",
44
45
  "husky": "^9.1.7",
45
- "lint-staged": "^15.5.0",
46
+ "lint-staged": "^15.5.1",
46
47
  "tsup": "^8.4.0",
47
48
  "typescript": "^5.8.3",
48
49
  "vitest": "^3.1.1"
@@ -53,7 +54,7 @@
53
54
  "commander": "^13.1.0",
54
55
  "conventional-changelog-angular": "^8.0.0",
55
56
  "conventional-recommended-bump": "^11.0.0",
56
- "figlet": "^1.8.0",
57
+ "figlet": "^1.8.1",
57
58
  "git-semver-tags": "^8.0.0",
58
59
  "semver": "^7.7.1"
59
60
  },