@oorabona/release-it-preset 0.6.0 â 0.7.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 +60 -0
- package/bin/cli.js +42 -5
- package/bin/validators.js +121 -0
- package/config/base-config.js +77 -0
- package/config/constants.js +76 -0
- package/config/default.js +5 -23
- package/config/helpers.js +1 -14
- package/config/hotfix.js +9 -24
- package/config/manual-changelog.js +5 -23
- package/config/no-changelog.js +8 -20
- package/config/republish.js +7 -22
- package/config/retry-publish.js +4 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -579,6 +579,40 @@ You can override any configuration in your project's `.release-it.json`:
|
|
|
579
579
|
}
|
|
580
580
|
```
|
|
581
581
|
|
|
582
|
+
### CLI Behavior with User Configuration
|
|
583
|
+
|
|
584
|
+
**Important:** The CLI now intelligently detects and respects your `.release-it.json` file:
|
|
585
|
+
|
|
586
|
+
- **With `.release-it.json` present:**
|
|
587
|
+
- The CLI runs `release-it` without `--config` flag
|
|
588
|
+
- release-it naturally merges your config with the preset via the `extends` field
|
|
589
|
+
- **Your settings have priority** over preset defaults
|
|
590
|
+
- Perfect for customizing tag names, commit messages, branch requirements, etc.
|
|
591
|
+
|
|
592
|
+
- **Without `.release-it.json`:**
|
|
593
|
+
- The CLI runs `release-it --config <preset-path>`
|
|
594
|
+
- Uses preset configuration directly
|
|
595
|
+
- Works exactly as before
|
|
596
|
+
|
|
597
|
+
**Example of customizing the default preset:**
|
|
598
|
+
|
|
599
|
+
```json
|
|
600
|
+
{
|
|
601
|
+
"extends": "@oorabona/release-it-preset/config/default",
|
|
602
|
+
"git": {
|
|
603
|
+
"tagName": "release-${version}",
|
|
604
|
+
"requireBranch": "develop"
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Then run:
|
|
610
|
+
```bash
|
|
611
|
+
pnpm release-it-preset default
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
The CLI will use your customized settings instead of the preset defaults!
|
|
615
|
+
|
|
582
616
|
## Borrowing Scripts & Workflows
|
|
583
617
|
|
|
584
618
|
- The root `package.json` of this repository shows how to expose convenient `pnpm run release:*` shortcuts. Feel free to copy that block into your own project (adjust the commands if you only need a subset).
|
|
@@ -1138,6 +1172,32 @@ graph TB
|
|
|
1138
1172
|
6. **Use CI for publishing** - Let GitHub Actions handle GitHub releases and npm publishing with provenance
|
|
1139
1173
|
7. **Local runs are for prep** - Keep local runs focused on changelog, versioning, and tagging unless you explicitly opt in to publish
|
|
1140
1174
|
|
|
1175
|
+
## Security
|
|
1176
|
+
|
|
1177
|
+
This preset implements OWASP security best practices:
|
|
1178
|
+
|
|
1179
|
+
### Input Validation
|
|
1180
|
+
|
|
1181
|
+
All CLI inputs are validated before execution:
|
|
1182
|
+
- **Whitelist validation**: Config names and commands are validated against allowed lists
|
|
1183
|
+
- **Argument sanitization**: All arguments are checked for dangerous characters (`;`, `&`, `|`, `` ` ``, `$()`, etc.)
|
|
1184
|
+
- **Path traversal protection**: File paths are validated to prevent directory traversal attacks
|
|
1185
|
+
|
|
1186
|
+
### Command Injection Prevention
|
|
1187
|
+
|
|
1188
|
+
- All `spawn()` calls use `shell: false` to prevent command injection
|
|
1189
|
+
- Arguments are passed as arrays, not concatenated strings
|
|
1190
|
+
- No user input is ever executed in a shell context
|
|
1191
|
+
|
|
1192
|
+
### Architecture
|
|
1193
|
+
|
|
1194
|
+
The preset follows SOLID principles:
|
|
1195
|
+
- **Single Responsibility**: Each module has one clear purpose
|
|
1196
|
+
- **DRY**: Shared configuration builders eliminate code duplication
|
|
1197
|
+
- **Dependency Inversion**: User configs have priority over preset defaults
|
|
1198
|
+
|
|
1199
|
+
All 213 unit tests verify functionality and security boundaries.
|
|
1200
|
+
|
|
1141
1201
|
## Troubleshooting
|
|
1142
1202
|
|
|
1143
1203
|
### Changelog not updating
|
package/bin/cli.js
CHANGED
|
@@ -24,8 +24,10 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { spawn } from 'node:child_process';
|
|
27
|
+
import { existsSync } from 'node:fs';
|
|
27
28
|
import { fileURLToPath } from 'node:url';
|
|
28
29
|
import { dirname, join } from 'node:path';
|
|
30
|
+
import { validateConfigName, validateUtilityCommand, sanitizeArgs } from './validators.js';
|
|
29
31
|
|
|
30
32
|
const __filename = fileURLToPath(import.meta.url);
|
|
31
33
|
const __dirname = dirname(__filename);
|
|
@@ -91,19 +93,45 @@ For environment variables, see: https://github.com/oorabona/release-it-preset#en
|
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
function handleReleaseCommand(configName, args) {
|
|
96
|
+
// Validate inputs
|
|
97
|
+
try {
|
|
98
|
+
validateConfigName(configName, new Set(Object.keys(RELEASE_CONFIGS)));
|
|
99
|
+
sanitizeArgs(args);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error(`â Validation error: ${error.message}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
|
|
94
105
|
const configPath = join(__dirname, '..', RELEASE_CONFIGS[configName]);
|
|
106
|
+
const userConfigPath = join(process.cwd(), '.release-it.json');
|
|
107
|
+
const hasUserConfig = existsSync(userConfigPath);
|
|
95
108
|
|
|
96
|
-
console.log(`đ Running release-it with
|
|
97
|
-
console.log(`đ Config file: ${configPath}`);
|
|
109
|
+
console.log(`đ Running release-it with preset: ${configName}`);
|
|
98
110
|
|
|
99
111
|
const releaseItCommand = 'release-it';
|
|
100
|
-
|
|
112
|
+
let fullArgs;
|
|
113
|
+
let strategyMessage;
|
|
114
|
+
|
|
115
|
+
if (hasUserConfig) {
|
|
116
|
+
// User has .release-it.json - let release-it handle the merge naturally
|
|
117
|
+
// The user config should have "extends": "@oorabona/release-it-preset/config/<preset>"
|
|
118
|
+
fullArgs = [...args];
|
|
119
|
+
strategyMessage = `đ Using user config: ${userConfigPath}\n (should extend preset: ${configName})`;
|
|
120
|
+
console.log(strategyMessage);
|
|
121
|
+
console.log(`âšī¸ Ensure your .release-it.json contains: "extends": "@oorabona/release-it-preset/config/${configName}"`);
|
|
122
|
+
} else {
|
|
123
|
+
// No user config - use preset directly
|
|
124
|
+
fullArgs = ['--config', configPath, ...args];
|
|
125
|
+
strategyMessage = `đ Using preset config directly: ${configPath}`;
|
|
126
|
+
console.log(strategyMessage);
|
|
127
|
+
console.log(`âšī¸ Tip: Create .release-it.json with "extends" to customize the preset`);
|
|
128
|
+
}
|
|
101
129
|
|
|
102
130
|
console.log(`đĄ Command: ${releaseItCommand} ${fullArgs.join(' ')}\n`);
|
|
103
131
|
|
|
104
132
|
const child = spawn(releaseItCommand, fullArgs, {
|
|
105
133
|
stdio: 'inherit',
|
|
106
|
-
shell:
|
|
134
|
+
shell: false, // Security: disable shell to prevent command injection
|
|
107
135
|
});
|
|
108
136
|
|
|
109
137
|
child.on('error', (error) => {
|
|
@@ -119,6 +147,15 @@ function handleReleaseCommand(configName, args) {
|
|
|
119
147
|
}
|
|
120
148
|
|
|
121
149
|
function handleUtilityCommand(commandName, args) {
|
|
150
|
+
// Validate inputs
|
|
151
|
+
try {
|
|
152
|
+
validateUtilityCommand(commandName, new Set(Object.keys(UTILITY_COMMANDS)));
|
|
153
|
+
sanitizeArgs(args);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error(`â Validation error: ${error.message}`);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
|
|
122
159
|
const base = UTILITY_COMMANDS[commandName];
|
|
123
160
|
const compiledPath = join(__dirname, '..', 'dist', 'scripts', `${base}.js`);
|
|
124
161
|
const sourcePath = join(__dirname, '..', 'scripts', `${base}.ts`);
|
|
@@ -136,7 +173,7 @@ function handleUtilityCommand(commandName, args) {
|
|
|
136
173
|
|
|
137
174
|
const child = spawn(runner, [target, ...args], {
|
|
138
175
|
stdio: 'inherit',
|
|
139
|
-
shell:
|
|
176
|
+
shell: false, // Security: disable shell to prevent command injection
|
|
140
177
|
});
|
|
141
178
|
|
|
142
179
|
child.on('error', (error) => {
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation and security utilities for CLI
|
|
3
|
+
*
|
|
4
|
+
* This module provides validation functions to prevent security issues
|
|
5
|
+
* like command injection, path traversal, and invalid input.
|
|
6
|
+
*
|
|
7
|
+
* OWASP Security Principles Applied:
|
|
8
|
+
* - Input Validation
|
|
9
|
+
* - Whitelist validation
|
|
10
|
+
* - Fail securely
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Validates that a config name is in the allowed list
|
|
15
|
+
*
|
|
16
|
+
* @param {string} configName - The configuration name to validate
|
|
17
|
+
* @param {Set<string>} allowedConfigs - Set of allowed configuration names
|
|
18
|
+
* @throws {Error} If config name is not in the allowed list
|
|
19
|
+
* @returns {string} The validated config name
|
|
20
|
+
*/
|
|
21
|
+
export function validateConfigName(configName, allowedConfigs) {
|
|
22
|
+
if (!allowedConfigs.has(configName)) {
|
|
23
|
+
const allowed = Array.from(allowedConfigs).join(', ');
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Invalid configuration name: "${configName}"\n` +
|
|
26
|
+
`Allowed configurations: ${allowed}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return configName;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Validates that a utility command name is in the allowed list
|
|
34
|
+
*
|
|
35
|
+
* @param {string} commandName - The command name to validate
|
|
36
|
+
* @param {Set<string>} allowedCommands - Set of allowed command names
|
|
37
|
+
* @throws {Error} If command name is not in the allowed list
|
|
38
|
+
* @returns {string} The validated command name
|
|
39
|
+
*/
|
|
40
|
+
export function validateUtilityCommand(commandName, allowedCommands) {
|
|
41
|
+
if (!allowedCommands.has(commandName)) {
|
|
42
|
+
const allowed = Array.from(allowedCommands).join(', ');
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Invalid utility command: "${commandName}"\n` +
|
|
45
|
+
`Allowed commands: ${allowed}`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return commandName;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Dangerous patterns that could indicate command injection attempts
|
|
53
|
+
* Includes shell metacharacters and control operators
|
|
54
|
+
*/
|
|
55
|
+
const DANGEROUS_PATTERNS = [
|
|
56
|
+
/[;&|`$()]/, // Shell control operators
|
|
57
|
+
/\$\{[^}]*\}/, // Variable substitution
|
|
58
|
+
/\$\([^)]*\)/, // Command substitution
|
|
59
|
+
/[<>]/, // Redirection operators
|
|
60
|
+
/\n|\r/, // Line breaks (can chain commands)
|
|
61
|
+
/\\\\/, // Backslash escaping
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Sanitizes command arguments to prevent injection attacks
|
|
66
|
+
*
|
|
67
|
+
* This function validates each argument against dangerous patterns.
|
|
68
|
+
* It uses a whitelist approach: only safe characters are allowed.
|
|
69
|
+
*
|
|
70
|
+
* @param {string[]} args - Array of command arguments
|
|
71
|
+
* @throws {Error} If any argument contains dangerous patterns
|
|
72
|
+
* @returns {string[]} The validated arguments
|
|
73
|
+
*/
|
|
74
|
+
export function sanitizeArgs(args) {
|
|
75
|
+
return args.map((arg, index) => {
|
|
76
|
+
// Check each dangerous pattern
|
|
77
|
+
for (const pattern of DANGEROUS_PATTERNS) {
|
|
78
|
+
if (pattern.test(arg)) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Argument ${index + 1} contains potentially dangerous characters: "${arg}"\n` +
|
|
81
|
+
`Matched pattern: ${pattern.toString()}\n` +
|
|
82
|
+
`This could be a security risk and has been blocked.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Additional check for null bytes (common in exploits)
|
|
88
|
+
if (arg.includes('\0')) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Argument ${index + 1} contains null bytes, which is not allowed for security reasons.`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return arg;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Validates that a path does not contain directory traversal attempts
|
|
100
|
+
*
|
|
101
|
+
* @param {string} path - The path to validate
|
|
102
|
+
* @throws {Error} If path contains traversal patterns
|
|
103
|
+
* @returns {string} The validated path
|
|
104
|
+
*/
|
|
105
|
+
export function validatePath(path) {
|
|
106
|
+
// Check for directory traversal patterns
|
|
107
|
+
if (path.includes('..')) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`Path contains directory traversal pattern (..) which is not allowed: "${path}"`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Check for absolute paths (we expect relative paths)
|
|
114
|
+
if (path.startsWith('/') || /^[a-zA-Z]:/.test(path)) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
`Absolute paths are not allowed: "${path}"`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return path;
|
|
121
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base configuration builders for release-it presets
|
|
3
|
+
*
|
|
4
|
+
* This module provides reusable configuration builders to eliminate code duplication
|
|
5
|
+
* across all preset configuration files. Each builder function creates a configuration
|
|
6
|
+
* object with environment variable support and sensible defaults.
|
|
7
|
+
*
|
|
8
|
+
* All builders support overrides to allow preset-specific customization while
|
|
9
|
+
* maintaining DRY principles.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { createReleaseNotesGenerator, getGitChangelogCommand } from './helpers.js';
|
|
13
|
+
import { GIT_DEFAULTS, NPM_DEFAULTS } from './constants.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates base git configuration
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} overrides - Properties to override in the base config
|
|
19
|
+
* @returns {Object} Git configuration object
|
|
20
|
+
*/
|
|
21
|
+
export function createBaseGitConfig(overrides = {}) {
|
|
22
|
+
const defaults = {
|
|
23
|
+
changelog: getGitChangelogCommand(),
|
|
24
|
+
commitMessage: process.env.GIT_COMMIT_MESSAGE || GIT_DEFAULTS.COMMIT_MESSAGE,
|
|
25
|
+
tagName: process.env.GIT_TAG_NAME || GIT_DEFAULTS.TAG_NAME,
|
|
26
|
+
requireBranch: process.env.GIT_REQUIRE_BRANCH || GIT_DEFAULTS.REQUIRE_BRANCH,
|
|
27
|
+
requireUpstream: process.env.GIT_REQUIRE_UPSTREAM === 'true',
|
|
28
|
+
requireCleanWorkingDir: process.env.GIT_REQUIRE_CLEAN === 'true',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
...defaults,
|
|
33
|
+
...overrides,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates base npm configuration
|
|
39
|
+
*
|
|
40
|
+
* @param {Object} overrides - Properties to override in the base config
|
|
41
|
+
* @returns {Object} Npm configuration object
|
|
42
|
+
*/
|
|
43
|
+
export function createBaseNpmConfig(overrides = {}) {
|
|
44
|
+
const defaults = {
|
|
45
|
+
skipChecks: process.env.NPM_SKIP_CHECKS === 'true',
|
|
46
|
+
publish: process.env.NPM_PUBLISH === 'true',
|
|
47
|
+
versionArgs: NPM_DEFAULTS.VERSION_ARGS,
|
|
48
|
+
publishArgs: [
|
|
49
|
+
...NPM_DEFAULTS.PUBLISH_ARGS_BASE,
|
|
50
|
+
'--access',
|
|
51
|
+
process.env.NPM_ACCESS || NPM_DEFAULTS.ACCESS,
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
...defaults,
|
|
57
|
+
...overrides,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates base GitHub configuration
|
|
63
|
+
*
|
|
64
|
+
* @param {Object} overrides - Properties to override in the base config
|
|
65
|
+
* @returns {Object} GitHub configuration object
|
|
66
|
+
*/
|
|
67
|
+
export function createBaseGitHubConfig(overrides = {}) {
|
|
68
|
+
const defaults = {
|
|
69
|
+
release: process.env.GITHUB_RELEASE === 'true',
|
|
70
|
+
releaseNotes: createReleaseNotesGenerator(),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
...defaults,
|
|
75
|
+
...overrides,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration constants and defaults
|
|
3
|
+
*
|
|
4
|
+
* This module centralizes all default values used across the preset configurations.
|
|
5
|
+
* By centralizing these values, we ensure consistency and make it easier to update
|
|
6
|
+
* defaults in the future.
|
|
7
|
+
*
|
|
8
|
+
* IMPORTANT: These are ONLY fallback values when environment variables are not set.
|
|
9
|
+
* All configuration should be driven by environment variables in production.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Git configuration defaults
|
|
14
|
+
*/
|
|
15
|
+
export const GIT_DEFAULTS = {
|
|
16
|
+
COMMIT_MESSAGE: 'release: bump v${version}',
|
|
17
|
+
HOTFIX_COMMIT_MESSAGE: 'hotfix: bump v${version}',
|
|
18
|
+
TAG_NAME: 'v${version}',
|
|
19
|
+
REQUIRE_BRANCH: 'main',
|
|
20
|
+
REMOTE: 'origin',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Default git changelog command
|
|
25
|
+
* Filters out commits matching release/hotfix/ci patterns
|
|
26
|
+
*/
|
|
27
|
+
export const DEFAULT_CHANGELOG_COMMAND = [
|
|
28
|
+
'git log',
|
|
29
|
+
'--pretty=format:"* %s (%h)"',
|
|
30
|
+
'${from}..${to}',
|
|
31
|
+
'--grep="^release"',
|
|
32
|
+
'--grep="^Release"',
|
|
33
|
+
'--grep="^release-"',
|
|
34
|
+
'--grep="^Release-"',
|
|
35
|
+
'--grep="^hotfix"',
|
|
36
|
+
'--grep="^Hotfix"',
|
|
37
|
+
'--grep="^ci"',
|
|
38
|
+
'--grep="^CI"',
|
|
39
|
+
'--invert-grep',
|
|
40
|
+
].join(' ');
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* npm configuration defaults
|
|
44
|
+
*/
|
|
45
|
+
export const NPM_DEFAULTS = {
|
|
46
|
+
ACCESS: 'public',
|
|
47
|
+
VERSION_ARGS: ['--allow-same-version'],
|
|
48
|
+
PUBLISH_ARGS_BASE: ['--provenance'],
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Changelog configuration defaults
|
|
53
|
+
*/
|
|
54
|
+
export const CHANGELOG_DEFAULTS = {
|
|
55
|
+
FILE: 'CHANGELOG.md',
|
|
56
|
+
UNRELEASED_SECTION: '## [Unreleased]',
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Keep a Changelog section headers
|
|
61
|
+
*/
|
|
62
|
+
export const CHANGELOG_SECTIONS = {
|
|
63
|
+
ADDED: '### Added',
|
|
64
|
+
FIXED: '### Fixed',
|
|
65
|
+
CHANGED: '### Changed',
|
|
66
|
+
REMOVED: '### Removed',
|
|
67
|
+
SECURITY: '### Security',
|
|
68
|
+
BREAKING: '### â ī¸ BREAKING CHANGES',
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Hotfix configuration defaults
|
|
73
|
+
*/
|
|
74
|
+
export const HOTFIX_DEFAULTS = {
|
|
75
|
+
INCREMENT: 'patch',
|
|
76
|
+
};
|
package/config/default.js
CHANGED
|
@@ -17,17 +17,11 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { runScriptCommand } from './helpers.js';
|
|
21
|
+
import { createBaseGitConfig, createBaseGitHubConfig, createBaseNpmConfig } from './base-config.js';
|
|
21
22
|
|
|
22
23
|
const config = {
|
|
23
|
-
git:
|
|
24
|
-
changelog: getGitChangelogCommand(),
|
|
25
|
-
commitMessage: process.env.GIT_COMMIT_MESSAGE || 'release: bump v${version}',
|
|
26
|
-
tagName: process.env.GIT_TAG_NAME || 'v${version}',
|
|
27
|
-
requireBranch: process.env.GIT_REQUIRE_BRANCH || 'main',
|
|
28
|
-
requireUpstream: process.env.GIT_REQUIRE_UPSTREAM === 'true',
|
|
29
|
-
requireCleanWorkingDir: process.env.GIT_REQUIRE_CLEAN === 'true',
|
|
30
|
-
},
|
|
24
|
+
git: createBaseGitConfig(),
|
|
31
25
|
hooks: {
|
|
32
26
|
'before:bump': [
|
|
33
27
|
runScriptCommand('populate-unreleased-changelog'),
|
|
@@ -36,20 +30,8 @@ const config = {
|
|
|
36
30
|
runScriptCommand('republish-changelog'),
|
|
37
31
|
],
|
|
38
32
|
},
|
|
39
|
-
github:
|
|
40
|
-
|
|
41
|
-
releaseNotes: createReleaseNotesGenerator(),
|
|
42
|
-
},
|
|
43
|
-
npm: {
|
|
44
|
-
skipChecks: process.env.NPM_SKIP_CHECKS === 'true',
|
|
45
|
-
publish: process.env.NPM_PUBLISH === 'true',
|
|
46
|
-
versionArgs: ['--allow-same-version'],
|
|
47
|
-
publishArgs: [
|
|
48
|
-
'--provenance',
|
|
49
|
-
'--access',
|
|
50
|
-
process.env.NPM_ACCESS || 'public',
|
|
51
|
-
],
|
|
52
|
-
},
|
|
33
|
+
github: createBaseGitHubConfig(),
|
|
34
|
+
npm: createBaseNpmConfig(),
|
|
53
35
|
};
|
|
54
36
|
|
|
55
37
|
export default config;
|
package/config/helpers.js
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { DEFAULT_CHANGELOG_COMMAND } from './constants.js';
|
|
4
5
|
|
|
5
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
7
|
const __dirname = dirname(__filename);
|
|
7
8
|
const RUN_SCRIPT_PATH = join(__dirname, '..', 'bin', 'run-script.js');
|
|
8
|
-
const DEFAULT_CHANGELOG_COMMAND = [
|
|
9
|
-
'git log',
|
|
10
|
-
'--pretty=format:"* %s (%h)"',
|
|
11
|
-
'${from}..${to}',
|
|
12
|
-
'--grep="^release"',
|
|
13
|
-
'--grep="^Release"',
|
|
14
|
-
'--grep="^release-"',
|
|
15
|
-
'--grep="^Release-"',
|
|
16
|
-
'--grep="^hotfix"',
|
|
17
|
-
'--grep="^Hotfix"',
|
|
18
|
-
'--grep="^ci"',
|
|
19
|
-
'--grep="^CI"',
|
|
20
|
-
'--invert-grep',
|
|
21
|
-
].join(' ');
|
|
22
9
|
|
|
23
10
|
const DOUBLE_QUOTE = /["\\]/g;
|
|
24
11
|
|
package/config/hotfix.js
CHANGED
|
@@ -14,38 +14,23 @@
|
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { runScriptCommand } from './helpers.js';
|
|
18
|
+
import { createBaseGitConfig, createBaseGitHubConfig, createBaseNpmConfig } from './base-config.js';
|
|
19
|
+
import { GIT_DEFAULTS, HOTFIX_DEFAULTS } from './constants.js';
|
|
18
20
|
|
|
19
21
|
const config = {
|
|
20
|
-
increment: process.env.HOTFIX_INCREMENT ||
|
|
21
|
-
git: {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
tagName: process.env.GIT_TAG_NAME || 'v${version}',
|
|
25
|
-
requireBranch: process.env.GIT_REQUIRE_BRANCH || 'main',
|
|
26
|
-
requireUpstream: process.env.GIT_REQUIRE_UPSTREAM === 'true',
|
|
27
|
-
requireCleanWorkingDir: process.env.GIT_REQUIRE_CLEAN === 'true',
|
|
28
|
-
},
|
|
22
|
+
increment: process.env.HOTFIX_INCREMENT || HOTFIX_DEFAULTS.INCREMENT,
|
|
23
|
+
git: createBaseGitConfig({
|
|
24
|
+
commitMessage: process.env.GIT_COMMIT_MESSAGE || GIT_DEFAULTS.HOTFIX_COMMIT_MESSAGE,
|
|
25
|
+
}),
|
|
29
26
|
hooks: {
|
|
30
27
|
'before:bump': [
|
|
31
28
|
'echo "Creating hotfix release..."',
|
|
32
29
|
runScriptCommand('populate-unreleased-changelog'),
|
|
33
30
|
],
|
|
34
31
|
},
|
|
35
|
-
github:
|
|
36
|
-
|
|
37
|
-
releaseNotes: createReleaseNotesGenerator(),
|
|
38
|
-
},
|
|
39
|
-
npm: {
|
|
40
|
-
skipChecks: process.env.NPM_SKIP_CHECKS === 'true',
|
|
41
|
-
publish: process.env.NPM_PUBLISH === 'true',
|
|
42
|
-
versionArgs: ['--allow-same-version'],
|
|
43
|
-
publishArgs: [
|
|
44
|
-
'--provenance',
|
|
45
|
-
'--access',
|
|
46
|
-
process.env.NPM_ACCESS || 'public',
|
|
47
|
-
],
|
|
48
|
-
},
|
|
32
|
+
github: createBaseGitHubConfig(),
|
|
33
|
+
npm: createBaseNpmConfig(),
|
|
49
34
|
};
|
|
50
35
|
|
|
51
36
|
export default config;
|
|
@@ -29,37 +29,19 @@
|
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
import {
|
|
32
|
+
import { runScriptCommand } from './helpers.js';
|
|
33
|
+
import { createBaseGitConfig, createBaseGitHubConfig, createBaseNpmConfig } from './base-config.js';
|
|
33
34
|
|
|
34
35
|
const config = {
|
|
35
|
-
git:
|
|
36
|
-
changelog: getGitChangelogCommand(),
|
|
37
|
-
commitMessage: process.env.GIT_COMMIT_MESSAGE || 'release: bump v${version}',
|
|
38
|
-
tagName: process.env.GIT_TAG_NAME || 'v${version}',
|
|
39
|
-
requireBranch: process.env.GIT_REQUIRE_BRANCH || 'main',
|
|
40
|
-
requireUpstream: process.env.GIT_REQUIRE_UPSTREAM === 'true',
|
|
41
|
-
requireCleanWorkingDir: process.env.GIT_REQUIRE_CLEAN === 'true',
|
|
42
|
-
},
|
|
36
|
+
git: createBaseGitConfig(),
|
|
43
37
|
hooks: {
|
|
44
38
|
// No before:bump - preserve manual changelog edits
|
|
45
39
|
'after:bump': [
|
|
46
40
|
runScriptCommand('republish-changelog'),
|
|
47
41
|
],
|
|
48
42
|
},
|
|
49
|
-
github:
|
|
50
|
-
|
|
51
|
-
releaseNotes: createReleaseNotesGenerator(),
|
|
52
|
-
},
|
|
53
|
-
npm: {
|
|
54
|
-
skipChecks: process.env.NPM_SKIP_CHECKS === 'true',
|
|
55
|
-
publish: process.env.NPM_PUBLISH === 'true',
|
|
56
|
-
versionArgs: ['--allow-same-version'],
|
|
57
|
-
publishArgs: [
|
|
58
|
-
'--provenance',
|
|
59
|
-
'--access',
|
|
60
|
-
process.env.NPM_ACCESS || 'public',
|
|
61
|
-
],
|
|
62
|
-
},
|
|
43
|
+
github: createBaseGitHubConfig(),
|
|
44
|
+
npm: createBaseNpmConfig(),
|
|
63
45
|
};
|
|
64
46
|
|
|
65
47
|
export default config;
|
package/config/no-changelog.js
CHANGED
|
@@ -13,28 +13,16 @@
|
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
import { createBaseGitConfig, createBaseGitHubConfig, createBaseNpmConfig } from './base-config.js';
|
|
17
|
+
|
|
16
18
|
const config = {
|
|
17
|
-
git: {
|
|
19
|
+
git: createBaseGitConfig({
|
|
18
20
|
changelog: false,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
github: {
|
|
26
|
-
release: process.env.GITHUB_RELEASE === 'true',
|
|
27
|
-
},
|
|
28
|
-
npm: {
|
|
29
|
-
skipChecks: process.env.NPM_SKIP_CHECKS === 'true',
|
|
30
|
-
publish: process.env.NPM_PUBLISH === 'true',
|
|
31
|
-
versionArgs: ['--allow-same-version'],
|
|
32
|
-
publishArgs: [
|
|
33
|
-
'--provenance',
|
|
34
|
-
'--access',
|
|
35
|
-
process.env.NPM_ACCESS || 'public',
|
|
36
|
-
],
|
|
37
|
-
},
|
|
21
|
+
}),
|
|
22
|
+
github: createBaseGitHubConfig({
|
|
23
|
+
releaseNotes: undefined, // No release notes without changelog
|
|
24
|
+
}),
|
|
25
|
+
npm: createBaseNpmConfig(),
|
|
38
26
|
};
|
|
39
27
|
|
|
40
28
|
export default config;
|
package/config/republish.js
CHANGED
|
@@ -18,19 +18,15 @@
|
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import {
|
|
21
|
+
import { runScriptCommand } from './helpers.js';
|
|
22
|
+
import { createBaseGitConfig, createBaseGitHubConfig, createBaseNpmConfig } from './base-config.js';
|
|
22
23
|
|
|
23
24
|
const config = {
|
|
24
25
|
increment: false,
|
|
25
|
-
git: {
|
|
26
|
-
changelog: getGitChangelogCommand(),
|
|
26
|
+
git: createBaseGitConfig({
|
|
27
27
|
commitMessage: process.env.GIT_COMMIT_MESSAGE || 'chore: republish v${version}',
|
|
28
|
-
tagName: process.env.GIT_TAG_NAME || 'v${version}',
|
|
29
28
|
tagAnnotation: 'Release ${version} (republished)',
|
|
30
|
-
|
|
31
|
-
requireUpstream: process.env.GIT_REQUIRE_UPSTREAM === 'true',
|
|
32
|
-
requireCleanWorkingDir: process.env.GIT_REQUIRE_CLEAN === 'true',
|
|
33
|
-
},
|
|
29
|
+
}),
|
|
34
30
|
hooks: {
|
|
35
31
|
'before:init': [
|
|
36
32
|
'echo "â ī¸ WARNING: You are about to MOVE an existing tag!"',
|
|
@@ -41,21 +37,10 @@ const config = {
|
|
|
41
37
|
runScriptCommand('republish-changelog'),
|
|
42
38
|
],
|
|
43
39
|
},
|
|
44
|
-
npm:
|
|
45
|
-
|
|
46
|
-
publish: process.env.NPM_PUBLISH === 'true',
|
|
47
|
-
versionArgs: ['--allow-same-version'],
|
|
48
|
-
publishArgs: [
|
|
49
|
-
'--provenance',
|
|
50
|
-
'--access',
|
|
51
|
-
process.env.NPM_ACCESS || 'public',
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
github: {
|
|
55
|
-
release: process.env.GITHUB_RELEASE === 'true',
|
|
40
|
+
npm: createBaseNpmConfig(),
|
|
41
|
+
github: createBaseGitHubConfig({
|
|
56
42
|
update: true,
|
|
57
|
-
|
|
58
|
-
},
|
|
43
|
+
}),
|
|
59
44
|
};
|
|
60
45
|
|
|
61
46
|
export default config;
|
package/config/retry-publish.js
CHANGED
|
@@ -15,26 +15,15 @@
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import { createBaseGitHubConfig, createBaseNpmConfig } from './base-config.js';
|
|
19
19
|
|
|
20
20
|
const config = {
|
|
21
21
|
increment: false,
|
|
22
22
|
git: false,
|
|
23
|
-
npm:
|
|
24
|
-
|
|
25
|
-
publish: process.env.NPM_PUBLISH === 'true',
|
|
26
|
-
versionArgs: ['--allow-same-version'],
|
|
27
|
-
publishArgs: [
|
|
28
|
-
'--provenance',
|
|
29
|
-
'--access',
|
|
30
|
-
process.env.NPM_ACCESS || 'public',
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
github: {
|
|
34
|
-
release: process.env.GITHUB_RELEASE === 'true',
|
|
23
|
+
npm: createBaseNpmConfig(),
|
|
24
|
+
github: createBaseGitHubConfig({
|
|
35
25
|
update: true,
|
|
36
|
-
|
|
37
|
-
},
|
|
26
|
+
}),
|
|
38
27
|
};
|
|
39
28
|
|
|
40
29
|
export default config;
|