@bobfrankston/npmglobalize 1.0.160 → 1.0.161
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 +27 -0
- package/cli.js +3 -0
- package/ignorepatterns.json5 +2 -1
- package/lib.js +50 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -189,6 +189,31 @@ npmglobalize -np # --nopublish (formerly --apply)
|
|
|
189
189
|
npmglobalize --cleanup # Restore original file: references
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
+
### 📝 Release Notes via `.commitmsg`
|
|
193
|
+
|
|
194
|
+
For multi-line or reusable release notes, write them to a `.commitmsg` file in the package root instead of passing them on the command line:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
cat > .commitmsg <<'EOF'
|
|
198
|
+
Added foo feature
|
|
199
|
+
Fixed bar regression
|
|
200
|
+
EOF
|
|
201
|
+
npmglobalize
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Behavior:
|
|
205
|
+
- If `-m` / `-message` is **not** given and `.commitmsg` exists, its contents are used as the commit message (and force a release even if the working tree is otherwise clean).
|
|
206
|
+
- After a successful `npm publish`, npmglobalize:
|
|
207
|
+
1. Appends the contents to `npmchanges.md` under a `## v<version> — <YYYY-MM-DD>` header (creating the file if needed)
|
|
208
|
+
2. Deletes `.commitmsg`
|
|
209
|
+
3. Commits both changes as `Log v<version> to npmchanges.md` and pushes
|
|
210
|
+
|
|
211
|
+
Notes:
|
|
212
|
+
- **Git/GitHub only.** npm publish does not consume git commit messages; `npmchanges.md` lives in the git repo and on GitHub but is excluded from the published npm tarball (the standard `*.md` rule keeps only `README.md`).
|
|
213
|
+
- If both `-m` and `.commitmsg` are present, `-m` wins and `.commitmsg` is left alone (not consumed).
|
|
214
|
+
- If publish fails, `.commitmsg` is preserved for the next attempt.
|
|
215
|
+
- `.commitmsg` is auto-added to `.npmignore` (security pattern) so it never leaks into the tarball.
|
|
216
|
+
|
|
192
217
|
### 🔧 Git Integration & Error Recovery
|
|
193
218
|
|
|
194
219
|
**Automatic tag conflict resolution**:
|
|
@@ -288,6 +313,8 @@ Publishing requires being on a branch so commits and tags can be properly tracke
|
|
|
288
313
|
-nopublish, -np Just transform, don't publish (persisted to config)
|
|
289
314
|
-cleanup Restore file: dependencies from .dependencies backup
|
|
290
315
|
-m, -message <msg> Custom commit message (forces release even without changes)
|
|
316
|
+
If -m not given, a `.commitmsg` file (if present) is used instead.
|
|
317
|
+
See "Release Notes via .commitmsg" below.
|
|
291
318
|
```
|
|
292
319
|
|
|
293
320
|
### Dependency Options
|
package/cli.js
CHANGED
|
@@ -27,6 +27,9 @@ Release Options:
|
|
|
27
27
|
-nopublish, -np Just transform, don't publish (persisted to config)
|
|
28
28
|
-cleanup Restore from .dependencies
|
|
29
29
|
-m, -message <msg> Custom commit message (forces release even without changes)
|
|
30
|
+
If -m not given and a .commitmsg file exists in cwd, its
|
|
31
|
+
contents are used. After a successful publish it is appended
|
|
32
|
+
to npmchanges.md (with version header) and deleted.
|
|
30
33
|
|
|
31
34
|
Dependency Options:
|
|
32
35
|
-update-deps, -ud Update package.json to latest (minor/patch only, safe)
|
package/ignorepatterns.json5
CHANGED
package/lib.js
CHANGED
|
@@ -3919,11 +3919,29 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3919
3919
|
}
|
|
3920
3920
|
// Re-check git status after all transformations and potential commits
|
|
3921
3921
|
currentGitStatus = getGitStatus(cwd);
|
|
3922
|
+
// If no -m given, fall back to .commitmsg file contents (one-shot changelog entry).
|
|
3923
|
+
// Consumed (appended to npmchanges.md + deleted) only after a successful publish.
|
|
3924
|
+
const commitMsgPath = path.join(cwd, '.commitmsg');
|
|
3925
|
+
let commitMsgFromFile = null;
|
|
3926
|
+
let effectiveMessage = message;
|
|
3927
|
+
if (!effectiveMessage && fs.existsSync(commitMsgPath)) {
|
|
3928
|
+
try {
|
|
3929
|
+
const content = fs.readFileSync(commitMsgPath, 'utf-8').trim();
|
|
3930
|
+
if (content) {
|
|
3931
|
+
commitMsgFromFile = content;
|
|
3932
|
+
effectiveMessage = content;
|
|
3933
|
+
console.log(colors.cyan(` Using .commitmsg for commit message (${content.split('\n')[0].slice(0, 60)}${content.length > 60 ? '…' : ''})`));
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
catch (err) {
|
|
3937
|
+
console.error(colors.yellow(` Warning: could not read .commitmsg: ${err.message}`));
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3922
3940
|
// Check if there are changes to commit or a custom message
|
|
3923
3941
|
// Skip this check for first publish (currentAccess null) or just-initialized repos
|
|
3924
3942
|
const isFirstPublish = !currentAccess;
|
|
3925
3943
|
let skipVersionBump = false;
|
|
3926
|
-
if (!currentGitStatus.hasUncommitted && !
|
|
3944
|
+
if (!currentGitStatus.hasUncommitted && !effectiveMessage && !justInitialized && !isFirstPublish) {
|
|
3927
3945
|
// Check if the current version is actually on npm (it might have failed to publish previously)
|
|
3928
3946
|
const versionCheck = spawnSafe('npm', ['view', `${pkg.name}@${pkg.version}`, 'version'], {
|
|
3929
3947
|
shell: process.platform === 'win32',
|
|
@@ -4074,7 +4092,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
4074
4092
|
}
|
|
4075
4093
|
// Git operations
|
|
4076
4094
|
if (currentGitStatus.hasUncommitted) {
|
|
4077
|
-
const commitMsg =
|
|
4095
|
+
const commitMsg = effectiveMessage || 'Pre-release commit';
|
|
4078
4096
|
console.log(`${timestamp()} Committing changes: ${commitMsg}`);
|
|
4079
4097
|
if (!dryRun) {
|
|
4080
4098
|
// Remove 'nul' files that break git on Windows
|
|
@@ -4701,6 +4719,36 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
4701
4719
|
const finalAccess = effectiveNpmVisibility || currentAccess || (isScoped ? 'restricted' : 'public');
|
|
4702
4720
|
const accessLabel = (finalAccess === 'restricted' || finalAccess === 'private') ? 'PRIVATE' : 'PUBLIC';
|
|
4703
4721
|
console.log(`${timestamp()} ${colors.green(`✓ Published to npm as ${accessLabel}`)}`);
|
|
4722
|
+
// Consume .commitmsg: append to npmchanges.md, delete the file, commit+push.
|
|
4723
|
+
// Only runs if .commitmsg was actually used as the commit message.
|
|
4724
|
+
if (commitMsgFromFile) {
|
|
4725
|
+
try {
|
|
4726
|
+
const publishedVersion = readPackageJson(cwd).version;
|
|
4727
|
+
const npmChangesPath = path.join(cwd, 'npmchanges.md');
|
|
4728
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
4729
|
+
const header = `## v${publishedVersion} — ${date}\n\n`;
|
|
4730
|
+
const entry = header + commitMsgFromFile.trim() + '\n\n';
|
|
4731
|
+
const existing = fs.existsSync(npmChangesPath)
|
|
4732
|
+
? fs.readFileSync(npmChangesPath, 'utf-8')
|
|
4733
|
+
: '# npm Publish Changes\n\n';
|
|
4734
|
+
const sep = existing.endsWith('\n') ? '' : '\n';
|
|
4735
|
+
fs.writeFileSync(npmChangesPath, existing + sep + entry);
|
|
4736
|
+
try {
|
|
4737
|
+
fs.unlinkSync(commitMsgPath);
|
|
4738
|
+
}
|
|
4739
|
+
catch { /* ignore */ }
|
|
4740
|
+
runCommand('git', ['add', 'npmchanges.md', '.commitmsg'], { cwd, silent: true });
|
|
4741
|
+
const logResult = gitCommit(`Log v${publishedVersion} to npmchanges.md`, cwd);
|
|
4742
|
+
if (logResult.success) {
|
|
4743
|
+
console.log(colors.green(` ✓ Appended to npmchanges.md and removed .commitmsg`));
|
|
4744
|
+
if (currentGitStatus.hasRemote)
|
|
4745
|
+
pushWithProtection(cwd, verbose);
|
|
4746
|
+
}
|
|
4747
|
+
}
|
|
4748
|
+
catch (err) {
|
|
4749
|
+
console.error(colors.yellow(` Warning: could not update npmchanges.md: ${err.message}`));
|
|
4750
|
+
}
|
|
4751
|
+
}
|
|
4704
4752
|
}
|
|
4705
4753
|
else {
|
|
4706
4754
|
console.log(` [dry-run] Would run: npm publish ${quiet ? '--quiet' : ''}`);
|