@releasekit/version 0.1.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,209 @@
1
+ import { LoadOptions } from '@releasekit/config';
2
+ import { ReleaseType } from 'semver';
3
+ import { Packages, Package } from '@manypkg/get-packages';
4
+ import { ReleaseKitError, VersionPackageChangelog } from '@releasekit/core';
5
+
6
+ interface VersionConfigBase {
7
+ versionPrefix: string;
8
+ type?: ReleaseType;
9
+ prereleaseIdentifier?: string;
10
+ branchPattern?: string[];
11
+ baseBranch?: string;
12
+ path?: string;
13
+ name?: string;
14
+ }
15
+ interface Config extends VersionConfigBase {
16
+ tagTemplate: string;
17
+ packageSpecificTags?: boolean;
18
+ preset: string;
19
+ sync: boolean;
20
+ packages: string[];
21
+ mainPackage?: string;
22
+ updateInternalDependencies: 'major' | 'minor' | 'patch' | 'no-internal-update';
23
+ skip?: string[];
24
+ commitMessage?: string;
25
+ versionStrategy?: 'branchPattern' | 'commitMessage';
26
+ branchPatterns?: BranchPattern[];
27
+ defaultReleaseType?: ReleaseType;
28
+ skipHooks?: boolean;
29
+ dryRun?: boolean;
30
+ latestTag?: string;
31
+ isPrerelease?: boolean;
32
+ mismatchStrategy?: 'error' | 'warn' | 'ignore' | 'prefer-package' | 'prefer-git';
33
+ cargo?: {
34
+ enabled?: boolean;
35
+ paths?: string[];
36
+ };
37
+ }
38
+ interface BranchPattern {
39
+ pattern: string;
40
+ releaseType: ReleaseType;
41
+ }
42
+ interface VersionOptions extends VersionConfigBase {
43
+ latestTag: string;
44
+ }
45
+
46
+ declare function loadConfig(options?: LoadOptions): Config;
47
+
48
+ /**
49
+ * Version calculation logic
50
+ */
51
+
52
+ /**
53
+ * Calculates the next version number based on the current version and options
54
+ */
55
+ declare function calculateVersion(config: Config, options: VersionOptions): Promise<string>;
56
+
57
+ /**
58
+ * Strategy functions for versioning using the higher-order function pattern
59
+ */
60
+
61
+ /**
62
+ * Available strategy types
63
+ */
64
+ type StrategyType = 'sync' | 'single' | 'async';
65
+ /**
66
+ * Strategy function type
67
+ */
68
+ type StrategyFunction = (packages: PackagesWithRoot, targets?: string[]) => Promise<void>;
69
+ /**
70
+ * Create a sync versioning strategy function
71
+ */
72
+ declare function createSyncStrategy(config: Config): StrategyFunction;
73
+ /**
74
+ * Create a single package versioning strategy function
75
+ */
76
+ declare function createSingleStrategy(config: Config): StrategyFunction;
77
+ /**
78
+ * Create an async package versioning strategy function
79
+ */
80
+ declare function createAsyncStrategy(config: Config): StrategyFunction;
81
+
82
+ interface PackagesWithRoot extends Packages {
83
+ root: string;
84
+ }
85
+ /**
86
+ * Main versioning engine that uses functional strategies
87
+ */
88
+ declare class VersionEngine {
89
+ private config;
90
+ private workspaceCache;
91
+ private strategies;
92
+ private currentStrategy;
93
+ constructor(config: Config, _jsonMode?: boolean);
94
+ /**
95
+ * Get workspace packages information - with caching for performance
96
+ */
97
+ getWorkspacePackages(): Promise<PackagesWithRoot>;
98
+ /**
99
+ * Run the current strategy
100
+ * @param packages Workspace packages to process
101
+ * @param targets Optional package targets to process (only used by async strategy)
102
+ */
103
+ run(packages: PackagesWithRoot, targets?: string[]): Promise<void>;
104
+ /**
105
+ * Change the current strategy
106
+ * @param strategyType The strategy type to use: 'sync', 'single', or 'async'
107
+ */
108
+ setStrategy(strategyType: StrategyType): void;
109
+ }
110
+
111
+ /**
112
+ * Version-specific base error that bridges the factory pattern
113
+ * used by @releasekit/version with the abstract ReleaseKitError base.
114
+ */
115
+ declare class BaseVersionError extends ReleaseKitError {
116
+ readonly code: string;
117
+ readonly suggestions: string[];
118
+ constructor(message: string, code: string, suggestions?: string[]);
119
+ static isVersionError(error: unknown): error is BaseVersionError;
120
+ }
121
+
122
+ /**
123
+ * Custom error class for versioning operations
124
+ */
125
+ declare class VersionError extends BaseVersionError {
126
+ }
127
+ /**
128
+ * Error codes for versioning operations
129
+ */
130
+ declare enum VersionErrorCode {
131
+ CONFIG_REQUIRED = "CONFIG_REQUIRED",
132
+ PACKAGES_NOT_FOUND = "PACKAGES_NOT_FOUND",
133
+ WORKSPACE_ERROR = "WORKSPACE_ERROR",
134
+ INVALID_CONFIG = "INVALID_CONFIG",
135
+ PACKAGE_NOT_FOUND = "PACKAGE_NOT_FOUND",
136
+ VERSION_CALCULATION_ERROR = "VERSION_CALCULATION_ERROR"
137
+ }
138
+ /**
139
+ * Creates a VersionError with standard error message for common failure scenarios
140
+ * @param code Error code
141
+ * @param details Additional error details
142
+ * @returns VersionError instance
143
+ */
144
+ declare function createVersionError(code: VersionErrorCode, details?: string): VersionError;
145
+
146
+ interface PackageProcessorOptions {
147
+ skip?: string[];
148
+ versionPrefix?: string;
149
+ tagTemplate?: string;
150
+ commitMessageTemplate?: string;
151
+ dryRun?: boolean;
152
+ skipHooks?: boolean;
153
+ getLatestTag: () => Promise<string | null>;
154
+ config: Omit<VersionConfigBase, 'versionPrefix' | 'path' | 'name'>;
155
+ fullConfig: Config;
156
+ }
157
+ interface ProcessResult {
158
+ updatedPackages: Array<{
159
+ name: string;
160
+ version: string;
161
+ path: string;
162
+ }>;
163
+ commitMessage?: string;
164
+ tags: string[];
165
+ }
166
+ declare class PackageProcessor {
167
+ private skip;
168
+ private versionPrefix;
169
+ private tagTemplate?;
170
+ private commitMessageTemplate;
171
+ private dryRun;
172
+ private skipHooks;
173
+ private getLatestTag;
174
+ private config;
175
+ private fullConfig;
176
+ constructor(options: PackageProcessorOptions);
177
+ /**
178
+ * Process packages based on skip list only (targeting handled at discovery time)
179
+ */
180
+ processPackages(packages: Package[]): Promise<ProcessResult>;
181
+ }
182
+
183
+ /**
184
+ * JSON Output service for releasekit-version
185
+ * Centralizes all JSON output handling
186
+ */
187
+
188
+ interface JsonOutputData {
189
+ dryRun: boolean;
190
+ updates: Array<{
191
+ packageName: string;
192
+ newVersion: string;
193
+ filePath: string;
194
+ }>;
195
+ changelogs: VersionPackageChangelog[];
196
+ commitMessage?: string;
197
+ tags: string[];
198
+ }
199
+ /**
200
+ * Enable JSON output mode
201
+ * @param dryRun Whether this is a dry run
202
+ */
203
+ declare function enableJsonOutput(dryRun?: boolean): void;
204
+ /**
205
+ * Get the current JSON output data (for testing)
206
+ */
207
+ declare function getJsonData(): JsonOutputData;
208
+
209
+ export { BaseVersionError, type Config, type JsonOutputData, PackageProcessor, type VersionConfigBase, VersionEngine, VersionErrorCode, calculateVersion, createAsyncStrategy, createSingleStrategy, createSyncStrategy, createVersionError, enableJsonOutput, getJsonData, loadConfig };
@@ -0,0 +1,209 @@
1
+ import { LoadOptions } from '@releasekit/config';
2
+ import { ReleaseType } from 'semver';
3
+ import { Packages, Package } from '@manypkg/get-packages';
4
+ import { ReleaseKitError, VersionPackageChangelog } from '@releasekit/core';
5
+
6
+ interface VersionConfigBase {
7
+ versionPrefix: string;
8
+ type?: ReleaseType;
9
+ prereleaseIdentifier?: string;
10
+ branchPattern?: string[];
11
+ baseBranch?: string;
12
+ path?: string;
13
+ name?: string;
14
+ }
15
+ interface Config extends VersionConfigBase {
16
+ tagTemplate: string;
17
+ packageSpecificTags?: boolean;
18
+ preset: string;
19
+ sync: boolean;
20
+ packages: string[];
21
+ mainPackage?: string;
22
+ updateInternalDependencies: 'major' | 'minor' | 'patch' | 'no-internal-update';
23
+ skip?: string[];
24
+ commitMessage?: string;
25
+ versionStrategy?: 'branchPattern' | 'commitMessage';
26
+ branchPatterns?: BranchPattern[];
27
+ defaultReleaseType?: ReleaseType;
28
+ skipHooks?: boolean;
29
+ dryRun?: boolean;
30
+ latestTag?: string;
31
+ isPrerelease?: boolean;
32
+ mismatchStrategy?: 'error' | 'warn' | 'ignore' | 'prefer-package' | 'prefer-git';
33
+ cargo?: {
34
+ enabled?: boolean;
35
+ paths?: string[];
36
+ };
37
+ }
38
+ interface BranchPattern {
39
+ pattern: string;
40
+ releaseType: ReleaseType;
41
+ }
42
+ interface VersionOptions extends VersionConfigBase {
43
+ latestTag: string;
44
+ }
45
+
46
+ declare function loadConfig(options?: LoadOptions): Config;
47
+
48
+ /**
49
+ * Version calculation logic
50
+ */
51
+
52
+ /**
53
+ * Calculates the next version number based on the current version and options
54
+ */
55
+ declare function calculateVersion(config: Config, options: VersionOptions): Promise<string>;
56
+
57
+ /**
58
+ * Strategy functions for versioning using the higher-order function pattern
59
+ */
60
+
61
+ /**
62
+ * Available strategy types
63
+ */
64
+ type StrategyType = 'sync' | 'single' | 'async';
65
+ /**
66
+ * Strategy function type
67
+ */
68
+ type StrategyFunction = (packages: PackagesWithRoot, targets?: string[]) => Promise<void>;
69
+ /**
70
+ * Create a sync versioning strategy function
71
+ */
72
+ declare function createSyncStrategy(config: Config): StrategyFunction;
73
+ /**
74
+ * Create a single package versioning strategy function
75
+ */
76
+ declare function createSingleStrategy(config: Config): StrategyFunction;
77
+ /**
78
+ * Create an async package versioning strategy function
79
+ */
80
+ declare function createAsyncStrategy(config: Config): StrategyFunction;
81
+
82
+ interface PackagesWithRoot extends Packages {
83
+ root: string;
84
+ }
85
+ /**
86
+ * Main versioning engine that uses functional strategies
87
+ */
88
+ declare class VersionEngine {
89
+ private config;
90
+ private workspaceCache;
91
+ private strategies;
92
+ private currentStrategy;
93
+ constructor(config: Config, _jsonMode?: boolean);
94
+ /**
95
+ * Get workspace packages information - with caching for performance
96
+ */
97
+ getWorkspacePackages(): Promise<PackagesWithRoot>;
98
+ /**
99
+ * Run the current strategy
100
+ * @param packages Workspace packages to process
101
+ * @param targets Optional package targets to process (only used by async strategy)
102
+ */
103
+ run(packages: PackagesWithRoot, targets?: string[]): Promise<void>;
104
+ /**
105
+ * Change the current strategy
106
+ * @param strategyType The strategy type to use: 'sync', 'single', or 'async'
107
+ */
108
+ setStrategy(strategyType: StrategyType): void;
109
+ }
110
+
111
+ /**
112
+ * Version-specific base error that bridges the factory pattern
113
+ * used by @releasekit/version with the abstract ReleaseKitError base.
114
+ */
115
+ declare class BaseVersionError extends ReleaseKitError {
116
+ readonly code: string;
117
+ readonly suggestions: string[];
118
+ constructor(message: string, code: string, suggestions?: string[]);
119
+ static isVersionError(error: unknown): error is BaseVersionError;
120
+ }
121
+
122
+ /**
123
+ * Custom error class for versioning operations
124
+ */
125
+ declare class VersionError extends BaseVersionError {
126
+ }
127
+ /**
128
+ * Error codes for versioning operations
129
+ */
130
+ declare enum VersionErrorCode {
131
+ CONFIG_REQUIRED = "CONFIG_REQUIRED",
132
+ PACKAGES_NOT_FOUND = "PACKAGES_NOT_FOUND",
133
+ WORKSPACE_ERROR = "WORKSPACE_ERROR",
134
+ INVALID_CONFIG = "INVALID_CONFIG",
135
+ PACKAGE_NOT_FOUND = "PACKAGE_NOT_FOUND",
136
+ VERSION_CALCULATION_ERROR = "VERSION_CALCULATION_ERROR"
137
+ }
138
+ /**
139
+ * Creates a VersionError with standard error message for common failure scenarios
140
+ * @param code Error code
141
+ * @param details Additional error details
142
+ * @returns VersionError instance
143
+ */
144
+ declare function createVersionError(code: VersionErrorCode, details?: string): VersionError;
145
+
146
+ interface PackageProcessorOptions {
147
+ skip?: string[];
148
+ versionPrefix?: string;
149
+ tagTemplate?: string;
150
+ commitMessageTemplate?: string;
151
+ dryRun?: boolean;
152
+ skipHooks?: boolean;
153
+ getLatestTag: () => Promise<string | null>;
154
+ config: Omit<VersionConfigBase, 'versionPrefix' | 'path' | 'name'>;
155
+ fullConfig: Config;
156
+ }
157
+ interface ProcessResult {
158
+ updatedPackages: Array<{
159
+ name: string;
160
+ version: string;
161
+ path: string;
162
+ }>;
163
+ commitMessage?: string;
164
+ tags: string[];
165
+ }
166
+ declare class PackageProcessor {
167
+ private skip;
168
+ private versionPrefix;
169
+ private tagTemplate?;
170
+ private commitMessageTemplate;
171
+ private dryRun;
172
+ private skipHooks;
173
+ private getLatestTag;
174
+ private config;
175
+ private fullConfig;
176
+ constructor(options: PackageProcessorOptions);
177
+ /**
178
+ * Process packages based on skip list only (targeting handled at discovery time)
179
+ */
180
+ processPackages(packages: Package[]): Promise<ProcessResult>;
181
+ }
182
+
183
+ /**
184
+ * JSON Output service for releasekit-version
185
+ * Centralizes all JSON output handling
186
+ */
187
+
188
+ interface JsonOutputData {
189
+ dryRun: boolean;
190
+ updates: Array<{
191
+ packageName: string;
192
+ newVersion: string;
193
+ filePath: string;
194
+ }>;
195
+ changelogs: VersionPackageChangelog[];
196
+ commitMessage?: string;
197
+ tags: string[];
198
+ }
199
+ /**
200
+ * Enable JSON output mode
201
+ * @param dryRun Whether this is a dry run
202
+ */
203
+ declare function enableJsonOutput(dryRun?: boolean): void;
204
+ /**
205
+ * Get the current JSON output data (for testing)
206
+ */
207
+ declare function getJsonData(): JsonOutputData;
208
+
209
+ export { BaseVersionError, type Config, type JsonOutputData, PackageProcessor, type VersionConfigBase, VersionEngine, VersionErrorCode, calculateVersion, createAsyncStrategy, createSingleStrategy, createSyncStrategy, createVersionError, enableJsonOutput, getJsonData, loadConfig };
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ import {
2
+ PackageProcessor,
3
+ VersionEngine,
4
+ VersionErrorCode,
5
+ calculateVersion,
6
+ createAsyncStrategy,
7
+ createSingleStrategy,
8
+ createSyncStrategy,
9
+ createVersionError,
10
+ enableJsonOutput,
11
+ getJsonData,
12
+ loadConfig
13
+ } from "./chunk-GLFC564Q.js";
14
+ import {
15
+ BaseVersionError
16
+ } from "./chunk-GQLJ7JQY.js";
17
+ export {
18
+ BaseVersionError,
19
+ PackageProcessor,
20
+ VersionEngine,
21
+ VersionErrorCode,
22
+ calculateVersion,
23
+ createAsyncStrategy,
24
+ createSingleStrategy,
25
+ createSyncStrategy,
26
+ createVersionError,
27
+ enableJsonOutput,
28
+ getJsonData,
29
+ loadConfig
30
+ };
@@ -0,0 +1,197 @@
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
+ "changelogs": [ // Structured changelog data per package
30
+ {
31
+ "packageName": "@scope/package-a", // Package name
32
+ "version": "1.2.3", // New version
33
+ "previousVersion": "v1.2.2", // Previous tag (null if none)
34
+ "revisionRange": "v1.2.2..HEAD", // Git revision range used
35
+ "repoUrl": "https://github.com/org/repo", // Repository URL (null if unknown)
36
+ "entries": [ // Parsed changelog entries
37
+ { "type": "added", "description": "New feature", "scope": "core" },
38
+ { "type": "fixed", "description": "Bug fix" }
39
+ ]
40
+ }
41
+ ],
42
+ "commitMessage": "chore(release): v1.2.3", // The commit message that was used
43
+ "tags": [ // Array of tags that were created
44
+ "v1.2.3" // or package-specific tags in targeted mode
45
+ ]
46
+ }
47
+ ```
48
+
49
+ ### Benefits of JSON Output
50
+
51
+ The structured JSON output provides several advantages for CI/CD integration:
52
+
53
+ - **Reliable Parsing**: Unlike text logs that might change format or include ANSI color codes, the JSON structure remains consistent
54
+ - **Programmatic Access**: Easily extract specific values like version numbers for subsequent steps
55
+ - **Conditional Workflows**: Trigger different CI actions based on the presence of updates or specific version changes
56
+ - **Audit Trail**: Store the JSON output as artifacts for version change tracking
57
+ - **Error Handling**: Better detect and respond to versioning issues in your pipeline
58
+
59
+ ## Sample CI/CD Integration Patterns
60
+
61
+ Here are some common ways to incorporate `package-versioner` into your CI/CD pipeline:
62
+
63
+ ### GitHub Actions Workflow Example
64
+
65
+ ```yaml
66
+ name: Release
67
+
68
+ on:
69
+ push:
70
+ branches: [main]
71
+
72
+ jobs:
73
+ version:
74
+ runs-on: ubuntu-latest
75
+ outputs:
76
+ changes_detected: ${{ steps.version.outputs.changes_detected }}
77
+ new_version: ${{ steps.version.outputs.new_version }}
78
+
79
+ steps:
80
+ - uses: actions/checkout@v3
81
+ with:
82
+ fetch-depth: 0 # Important for git history
83
+
84
+ - name: Setup Node.js
85
+ uses: actions/setup-node@v3
86
+ with:
87
+ node-version: '18'
88
+
89
+ - name: Install dependencies
90
+ run: npm ci
91
+
92
+ - name: Determine version
93
+ id: version
94
+ run: |
95
+ # Run in JSON mode for parsing
96
+ VERSION_OUTPUT=$(npx package-versioner --json)
97
+ echo "Version output: $VERSION_OUTPUT"
98
+
99
+ # Use jq to parse the JSON output
100
+ CHANGES_DETECTED=$(echo "$VERSION_OUTPUT" | jq -r '.updates | length > 0')
101
+ echo "changes_detected=$CHANGES_DETECTED" >> $GITHUB_OUTPUT
102
+
103
+ if [ "$CHANGES_DETECTED" = "true" ]; then
104
+ # Extract the first package's new version as representative version
105
+ NEW_VERSION=$(echo "$VERSION_OUTPUT" | jq -r '.updates[0].newVersion')
106
+ echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
107
+ fi
108
+
109
+ publish:
110
+ needs: version
111
+ if: needs.version.outputs.changes_detected == 'true'
112
+ runs-on: ubuntu-latest
113
+ steps:
114
+ # Publishing steps using the detected version
115
+ - run: echo "Would publish version ${{ needs.version.outputs.new_version }}"
116
+ ```
117
+
118
+ ### GitLab CI Pipeline Example
119
+
120
+ ```yaml
121
+ stages:
122
+ - version
123
+ - publish
124
+
125
+ determine_version:
126
+ stage: version
127
+ script:
128
+ - npm ci
129
+ - |
130
+ VERSION_OUTPUT=$(npx package-versioner --json)
131
+ echo "VERSION_OUTPUT=$VERSION_OUTPUT" >> version.env
132
+
133
+ # Parse values for use in later stages
134
+ CHANGES_DETECTED=$(echo "$VERSION_OUTPUT" | jq -r '.updates | length > 0')
135
+ echo "CHANGES_DETECTED=$CHANGES_DETECTED" >> version.env
136
+
137
+ if [ "$CHANGES_DETECTED" = "true" ]; then
138
+ NEW_VERSION=$(echo "$VERSION_OUTPUT" | jq -r '.updates[0].newVersion')
139
+ echo "NEW_VERSION=$NEW_VERSION" >> version.env
140
+ fi
141
+ artifacts:
142
+ reports:
143
+ dotenv: version.env
144
+
145
+ publish:
146
+ stage: publish
147
+ needs: determine_version
148
+ script:
149
+ - echo "Publishing version $NEW_VERSION"
150
+ rules:
151
+ - if: $CHANGES_DETECTED == "true"
152
+ ```
153
+
154
+ ## Working with Tags in CI
155
+
156
+ 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:
157
+
158
+ ```bash
159
+ # Create a global tag based on the representative version
160
+ NEW_VERSION=$(echo "$VERSION_OUTPUT" | jq -r '.updates[0].newVersion')
161
+ git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION"
162
+ git push origin "v$NEW_VERSION"
163
+ ```
164
+
165
+ ## Environment Variables
166
+
167
+ `package-versioner` respects the following environment variables:
168
+
169
+ - `NO_COLOR=1`: Disables colored output in logs (automatically detected in CI environments)
170
+ - `CI=true`: Most CI environments set this automatically, which helps the tool adjust its output behaviour
171
+
172
+ ## Skipping CI for Version Commits
173
+
174
+ If you want to prevent additional CI runs when version commits are made, you can include CI skip flags in your commit message template in `version.config.json`:
175
+
176
+ ```json
177
+ {
178
+ "commitMessage": "chore(release): ${version} [skip ci]",
179
+ // other configuration options...
180
+ }
181
+ ```
182
+
183
+ Common CI skip patterns include:
184
+ - `[skip ci]` or `[ci skip]` - Works in GitHub Actions, GitLab CI, CircleCI
185
+ - `[skip-ci]` - Alternative format supported by some CI systems
186
+ - `[no ci]` - Another variant
187
+
188
+ Each CI system might have slightly different syntax, so check your CI provider's documentation for the exact skip token to use.
189
+
190
+ ## Tips for Reliable CI/CD Integration
191
+
192
+ 1. **Always use `--json`** in CI/CD pipelines for consistent output parsing
193
+ 2. **Use the `fetch-depth: 0`** option in GitHub Actions (or equivalent in other CIs) to ensure access to the full Git history
194
+ 3. **Store the JSON output** as a build artifact for debugging and auditing
195
+ 4. **Consider dry runs** in your preview/staging branches to validate version changes before they're applied
196
+ 5. **Use `--project-dir`** when running from a different directory than your project root
197
+ 6. **Be mindful of Git credentials** - ensure your CI has proper permissions for creating commits and tags