package-versioner 0.2.0 → 0.4.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.
- package/README.md +40 -3
- package/dist/index.cjs +721 -576
- package/dist/index.js +719 -575
- package/docs/CI_CD_INTEGRATION.md +165 -0
- package/docs/VERSIONING_STRATEGIES.md +39 -0
- package/package.json +5 -5
|
@@ -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
|
|
@@ -94,3 +94,42 @@ This is the default if the `synced` flag is present and true.
|
|
|
94
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
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
96
|
- **Use Case:** Releasing specific packages independently while still tagging each released package individually.
|
|
97
|
+
|
|
98
|
+
## Prerelease Handling
|
|
99
|
+
|
|
100
|
+
`package-versioner` provides flexible handling for prerelease versions, allowing both creation of prereleases and promotion to stable releases.
|
|
101
|
+
|
|
102
|
+
### Creating Prereleases
|
|
103
|
+
|
|
104
|
+
Use the `--prerelease` flag with an identifier to create a prerelease version:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Create a beta prerelease
|
|
108
|
+
npx package-versioner --bump minor --prerelease beta
|
|
109
|
+
# Result: 1.0.0 -> 1.1.0-beta.0
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
You can also set a default prerelease identifier in your `version.config.json`:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"prereleaseIdentifier": "beta"
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Promoting Prereleases to Stable Releases
|
|
121
|
+
|
|
122
|
+
When using standard bump types (`major`, `minor`, `patch`) with the `--bump` flag on a prerelease version, `package-versioner` will automatically clean the prerelease identifier:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Starting from version 1.0.0-beta.1
|
|
126
|
+
npx package-versioner --bump major
|
|
127
|
+
# Result: 1.0.0-beta.1 -> 2.0.0 (not 2.0.0-beta.0)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This intuitive behavior means you don't need to use an empty prerelease identifier (`--prerelease ""`) to promote a prerelease to a stable version. Simply specify the standard bump type and the tool will automatically produce a clean version number.
|
|
131
|
+
|
|
132
|
+
This applies to all standard bump types:
|
|
133
|
+
- `--bump major`: 1.0.0-beta.1 -> 2.0.0
|
|
134
|
+
- `--bump minor`: 1.0.0-beta.1 -> 1.1.0
|
|
135
|
+
- `--bump patch`: 1.0.0-beta.1 -> 1.0.1
|
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.
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits.",
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@biomejs/biome": "^1.9.4",
|
|
41
41
|
"@types/figlet": "^1.5.5",
|
|
42
|
-
"@types/node": "^22.14.
|
|
42
|
+
"@types/node": "^22.14.1",
|
|
43
43
|
"@types/semver": "^7.3.13",
|
|
44
44
|
"@vitest/coverage-v8": "^3.1.1",
|
|
45
45
|
"husky": "^9.1.7",
|
|
46
|
-
"lint-staged": "^15.5.
|
|
46
|
+
"lint-staged": "^15.5.1",
|
|
47
47
|
"tsup": "^8.4.0",
|
|
48
48
|
"typescript": "^5.8.3",
|
|
49
49
|
"vitest": "^3.1.1"
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"commander": "^13.1.0",
|
|
55
55
|
"conventional-changelog-angular": "^8.0.0",
|
|
56
56
|
"conventional-recommended-bump": "^11.0.0",
|
|
57
|
-
"figlet": "^1.8.
|
|
57
|
+
"figlet": "^1.8.1",
|
|
58
58
|
"git-semver-tags": "^8.0.0",
|
|
59
59
|
"semver": "^7.7.1"
|
|
60
60
|
},
|