@oorabona/release-it-preset 0.7.0 → 0.8.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.
Files changed (3) hide show
  1. package/README.md +121 -24
  2. package/bin/cli.js +50 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -562,56 +562,153 @@ GIT_REQUIRE_CLEAN="true" \
562
562
  pnpm release
563
563
  ```
564
564
 
565
- ## Configuration Override
565
+ ## Configuration Modes
566
566
 
567
- You can override any configuration in your project's `.release-it.json`:
567
+ The preset supports three configuration modes to suit different workflows:
568
+
569
+ ### Mode 1: CLI Only (No Config File)
570
+
571
+ **When to use:** Simple projects with minimal customization needs
572
+
573
+ Don't create `.release-it.json`. Just run the CLI:
574
+
575
+ ```bash
576
+ pnpm release-it-preset hotfix
577
+ ```
578
+
579
+ All configuration comes from the preset and environment variables.
580
+
581
+ **Pros:**
582
+ - ✅ Zero config files
583
+ - ✅ Consistent behavior across projects
584
+ - ✅ Easy to understand
585
+
586
+ ---
587
+
588
+ ### Mode 2: CLI + User Overrides (Recommended)
589
+
590
+ **When to use:** Customize specific options while using CLI presets
591
+
592
+ Create `.release-it.json` **WITHOUT the `extends` field**:
568
593
 
569
594
  ```json
570
595
  {
571
- "extends": "@oorabona/release-it-preset/config/default",
572
596
  "git": {
573
- "requireBranch": "develop",
597
+ "requireBranch": "master",
574
598
  "commitMessage": "chore: release v${version}"
575
599
  },
576
- "github": {
577
- "releaseName": "Release ${version}"
600
+ "npm": {
601
+ "publish": true
578
602
  }
579
603
  }
580
604
  ```
581
605
 
582
- ### CLI Behavior with User Configuration
606
+ Run with CLI preset:
583
607
 
584
- **Important:** The CLI now intelligently detects and respects your `.release-it.json` file:
608
+ ```bash
609
+ pnpm release-it-preset hotfix
610
+ ```
585
611
 
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.
612
+ **How it works:**
613
+ - CLI selects the preset (`hotfix` in this example)
614
+ - release-it merges your overrides on top of the preset
615
+ - **Your values take precedence** over preset defaults
591
616
 
592
- - **Without `.release-it.json`:**
593
- - The CLI runs `release-it --config <preset-path>`
594
- - Uses preset configuration directly
595
- - Works exactly as before
617
+ **Pros:**
618
+ - **Recommended approach** for most use cases
619
+ - CLI controls preset selection
620
+ - Declarative overrides in config file
621
+ - ✅ No `extends` maintenance needed
596
622
 
597
- **Example of customizing the default preset:**
623
+ **Example use case:** You want to use the `hotfix` preset but require releases from `master` instead of `main`:
598
624
 
599
625
  ```json
600
626
  {
601
- "extends": "@oorabona/release-it-preset/config/default",
602
627
  "git": {
603
- "tagName": "release-${version}",
604
- "requireBranch": "develop"
628
+ "requireBranch": "master"
605
629
  }
606
630
  }
607
631
  ```
608
632
 
609
- Then run:
610
633
  ```bash
611
- pnpm release-it-preset default
634
+ pnpm release-it-preset hotfix # Uses hotfix preset + your branch override
635
+ ```
636
+
637
+ ---
638
+
639
+ ### Mode 3: File with Extends (Advanced)
640
+
641
+ **When to use:** Lock a specific preset regardless of CLI command
642
+
643
+ Create `.release-it.json` **WITH the `extends` field**:
644
+
645
+ ```json
646
+ {
647
+ "extends": "@oorabona/release-it-preset/config/hotfix",
648
+ "git": {
649
+ "commitMessage": "custom: ${version}"
650
+ }
651
+ }
652
+ ```
653
+
654
+ Run matching CLI command:
655
+
656
+ ```bash
657
+ pnpm release-it-preset hotfix # Must match the extends!
658
+ ```
659
+
660
+ **How it works:**
661
+ - The `extends` field locks the preset
662
+ - CLI command **must match** the preset in `extends`
663
+ - Mismatch triggers an error
664
+
665
+ **Pros:**
666
+ - ✅ Prevents accidental use of wrong presets
667
+ - ✅ Explicit preset declaration in config
668
+
669
+ **Cons:**
670
+ - ⚠️ Less flexible (preset locked in file)
671
+ - ⚠️ Requires updating `extends` to switch presets
672
+
673
+ ---
674
+
675
+ ### Configuration Error Handling
676
+
677
+ If your `.release-it.json` has an `extends` field that doesn't match the CLI command, you'll get a clear error:
678
+
679
+ ```bash
680
+ # Your config extends "default", but you run:
681
+ pnpm release-it-preset hotfix
682
+
683
+ # ❌ Configuration mismatch error!
684
+ # CLI preset: hotfix
685
+ # .release-it.json extends: default
686
+ #
687
+ # Either:
688
+ # 1. Remove the "extends" field from .release-it.json (recommended)
689
+ # → Your overrides will merge with the CLI preset automatically
690
+ #
691
+ # 2. Run: release-it-preset default
692
+ # → Use the preset specified in your config file
693
+ #
694
+ # 3. Update .release-it.json extends to: "@oorabona/release-it-preset/config/hotfix"
695
+ # → Match your config file to the CLI command
612
696
  ```
613
697
 
614
- The CLI will use your customized settings instead of the preset defaults!
698
+ This prevents silent misconfigurations where the wrong preset runs unexpectedly.
699
+
700
+ ---
701
+
702
+ ### Which Mode Should I Use?
703
+
704
+ | Scenario | Recommended Mode |
705
+ |----------|------------------|
706
+ | Minimal config, trust defaults | **Mode 1** (CLI only) |
707
+ | Customize branch/commit messages | **Mode 2** (CLI + overrides) |
708
+ | Lock preset for safety | **Mode 3** (File with extends) |
709
+ | Monorepo with different presets per package | **Mode 2** (CLI + overrides) |
710
+
711
+ **Most users should use Mode 2** for the best balance of flexibility and clarity.
615
712
 
616
713
  ## Borrowing Scripts & Workflows
617
714
 
package/bin/cli.js CHANGED
@@ -24,7 +24,7 @@
24
24
  */
25
25
 
26
26
  import { spawn } from 'node:child_process';
27
- import { existsSync } from 'node:fs';
27
+ import { existsSync, readFileSync } from 'node:fs';
28
28
  import { fileURLToPath } from 'node:url';
29
29
  import { dirname, join } from 'node:path';
30
30
  import { validateConfigName, validateUtilityCommand, sanitizeArgs } from './validators.js';
@@ -110,25 +110,63 @@ function handleReleaseCommand(configName, args) {
110
110
 
111
111
  const releaseItCommand = 'release-it';
112
112
  let fullArgs;
113
- let strategyMessage;
114
113
 
115
114
  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>"
115
+ // Read and validate user config
116
+ try {
117
+ const userConfigContent = readFileSync(userConfigPath, 'utf8');
118
+ const userConfig = JSON.parse(userConfigContent);
119
+
120
+ const expectedExtends = `@oorabona/release-it-preset/config/${configName}`;
121
+
122
+ if (userConfig.extends) {
123
+ // If extends exists, it MUST match the CLI preset
124
+ const extendsMatch = userConfig.extends.match(/@oorabona\/release-it-preset\/config\/(\w+)/);
125
+ const extendsPreset = extendsMatch?.[1];
126
+
127
+ if (extendsPreset && extendsPreset !== configName) {
128
+ console.error(`\n❌ Configuration mismatch error!`);
129
+ console.error(` CLI preset: ${configName}`);
130
+ console.error(` .release-it.json extends: ${extendsPreset}`);
131
+ console.error(``);
132
+ console.error(`Either:`);
133
+ console.error(` 1. Remove the "extends" field from .release-it.json (recommended)`);
134
+ console.error(` → Your overrides will merge with the CLI preset automatically`);
135
+ console.error(``);
136
+ console.error(` 2. Run: release-it-preset ${extendsPreset}`);
137
+ console.error(` → Use the preset specified in your config file`);
138
+ console.error(``);
139
+ console.error(` 3. Update .release-it.json extends to: "${expectedExtends}"`);
140
+ console.error(` → Match your config file to the CLI command\n`);
141
+ process.exit(1);
142
+ }
143
+
144
+ console.log(`✅ Config file extends matches CLI preset: ${configName}`);
145
+ console.log(`📝 Using: ${userConfigPath}\n`);
146
+ } else {
147
+ // No extends = natural merge (Mode 3 - Hybrid)
148
+ console.log(`📝 Merging CLI preset "${configName}" with user config overrides`);
149
+ console.log(` Config file: ${userConfigPath}`);
150
+ console.log(` User overrides will take precedence\n`);
151
+ }
152
+ } catch (error) {
153
+ if (error instanceof SyntaxError) {
154
+ console.error(`❌ Failed to parse .release-it.json: ${error.message}`);
155
+ } else {
156
+ console.error(`❌ Error reading .release-it.json: ${error.message}`);
157
+ }
158
+ process.exit(1);
159
+ }
160
+
161
+ // Let release-it handle the merge naturally
118
162
  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
163
  } else {
123
164
  // No user config - use preset directly
165
+ console.log(`📝 Using preset config directly: ${configPath}`);
166
+ console.log(` Tip: Create .release-it.json (without "extends") to add overrides\n`);
124
167
  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
168
  }
129
169
 
130
- console.log(`💡 Command: ${releaseItCommand} ${fullArgs.join(' ')}\n`);
131
-
132
170
  const child = spawn(releaseItCommand, fullArgs, {
133
171
  stdio: 'inherit',
134
172
  shell: false, // Security: disable shell to prevent command injection
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oorabona/release-it-preset",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Shared release-it configuration and scripts for the organisation",
5
5
  "type": "module",
6
6
  "keywords": [