@releasekit/release 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.
package/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # @releasekit/release
2
+
3
+ Unified release pipeline: version, changelog, and publish in a single command.
4
+
5
+ ## Features
6
+
7
+ - **Single command** — runs version, notes, and publish as one pipeline
8
+ - **Programmatic orchestration** — calls each tool's API directly, no subprocesses
9
+ - **CI-friendly** — exits cleanly (code 0) when there are no releasable changes
10
+ - **Skippable steps** — skip notes, publish, git, or GitHub releases independently
11
+ - **Dry-run mode** — preview the full pipeline without side effects
12
+ - **JSON output** — structured results for scripting and CI integration
13
+ - **Monorepo support** — target specific packages or version all in sync
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install -g @releasekit/release
19
+ # or
20
+ pnpm add -g @releasekit/release
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```bash
26
+ # Preview what would happen
27
+ releasekit release --dry-run
28
+
29
+ # Run a full release
30
+ releasekit release
31
+
32
+ # Force a patch bump
33
+ releasekit release --bump patch
34
+
35
+ # Version and publish, skip changelog generation
36
+ releasekit release --skip-notes
37
+ ```
38
+
39
+ ## Pipeline
40
+
41
+ The release command runs three steps in order:
42
+
43
+ 1. **Version** — analyse conventional commits and calculate the next semver bump
44
+ 2. **Notes** — generate changelog from the version output *(skippable)*
45
+ 3. **Publish** — git commit/tag, npm/cargo publish, GitHub release *(skippable)*
46
+
47
+ If no releasable changes are found after step 1, the command exits with code 0 and skips the remaining steps.
48
+
49
+ ## CLI Reference
50
+
51
+ | Flag | Description | Default |
52
+ |------|-------------|---------|
53
+ | `-c, --config <path>` | Path to config file | `releasekit.config.json` |
54
+ | `-d, --dry-run` | Preview all steps without side effects | `false` |
55
+ | `-b, --bump <type>` | Force bump type: `patch`, `minor`, `major` | auto |
56
+ | `-p, --prerelease [id]` | Create prerelease version | — |
57
+ | `-s, --sync` | Synchronized versioning across all packages | `false` |
58
+ | `-t, --target <packages>` | Target specific packages (comma-separated) | all |
59
+ | `--skip-notes` | Skip changelog generation | `false` |
60
+ | `--skip-publish` | Skip registry publishing and git operations | `false` |
61
+ | `--skip-git` | Skip git commit/tag/push | `false` |
62
+ | `--skip-github-release` | Skip GitHub release creation | `false` |
63
+ | `--skip-verification` | Skip post-publish verification | `false` |
64
+ | `-j, --json` | Output results as JSON | `false` |
65
+ | `-v, --verbose` | Verbose logging | `false` |
66
+ | `-q, --quiet` | Suppress non-error output | `false` |
67
+ | `--project-dir <path>` | Project directory | cwd |
68
+
69
+ ## Usage Examples
70
+
71
+ ### In CI (GitHub Actions)
72
+
73
+ ```yaml
74
+ - name: Release
75
+ run: releasekit release
76
+ env:
77
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
78
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
79
+ ```
80
+
81
+ ### Automated releases on push to main
82
+
83
+ ```yaml
84
+ on:
85
+ push:
86
+ branches: [main]
87
+
88
+ jobs:
89
+ release:
90
+ if: "!contains(github.event.head_commit.message, '[skip ci]')"
91
+ runs-on: ubuntu-latest
92
+ steps:
93
+ - uses: actions/checkout@v4
94
+ with:
95
+ fetch-depth: 0
96
+ - uses: actions/setup-node@v4
97
+ - run: npm install -g @releasekit/release
98
+ - run: releasekit release
99
+ ```
100
+
101
+ ### Monorepo with targeted release
102
+
103
+ ```bash
104
+ # Release only specific packages
105
+ releasekit release --target @myorg/core,@myorg/cli
106
+
107
+ # Release all packages in sync
108
+ releasekit release --sync
109
+ ```
110
+
111
+ ### Prerelease workflow
112
+
113
+ ```bash
114
+ releasekit release --prerelease beta
115
+ ```
116
+
117
+ ## Programmatic API
118
+
119
+ ```typescript
120
+ import { runRelease } from '@releasekit/release';
121
+
122
+ const result = await runRelease({
123
+ dryRun: true,
124
+ bump: 'minor',
125
+ skipNotes: false,
126
+ skipPublish: false,
127
+ skipGit: false,
128
+ skipGithubRelease: false,
129
+ skipVerification: false,
130
+ sync: false,
131
+ json: false,
132
+ verbose: false,
133
+ quiet: false,
134
+ projectDir: process.cwd(),
135
+ });
136
+
137
+ if (result) {
138
+ console.log(`Released ${result.versionOutput.updates.length} packages`);
139
+ } else {
140
+ console.log('No releasable changes');
141
+ }
142
+ ```
143
+
144
+ ## Configuration
145
+
146
+ All configuration is shared via `releasekit.config.json`. The release command reads the `version`, `notes`, and `publish` sections as needed.
147
+
148
+ See the individual package READMEs for configuration details:
149
+
150
+ - [@releasekit/version](../version/README.md) — versioning options
151
+ - [@releasekit/notes](../notes/README.md) — changelog options
152
+ - [@releasekit/publish](../publish/README.md) — publishing options
153
+
154
+ ## License
155
+
156
+ MIT
@@ -0,0 +1,93 @@
1
+ // src/release.ts
2
+ import { info, setJsonMode, setLogLevel, setQuietMode, success } from "@releasekit/core";
3
+ async function runRelease(options) {
4
+ if (options.verbose) setLogLevel("debug");
5
+ if (options.quiet) setQuietMode(true);
6
+ if (options.json) setJsonMode(true);
7
+ info("Running version analysis...");
8
+ const versionOutput = await runVersionStep(options);
9
+ if (versionOutput.updates.length === 0) {
10
+ info("No releasable changes found");
11
+ return null;
12
+ }
13
+ info(`Found ${versionOutput.updates.length} package update(s)`);
14
+ for (const update of versionOutput.updates) {
15
+ info(` ${update.packageName} \u2192 ${update.newVersion}`);
16
+ }
17
+ let notesGenerated = false;
18
+ if (!options.skipNotes) {
19
+ info("Generating release notes...");
20
+ await runNotesStep(versionOutput, options);
21
+ notesGenerated = true;
22
+ success("Release notes generated");
23
+ }
24
+ let publishOutput;
25
+ if (!options.skipPublish) {
26
+ info("Publishing...");
27
+ publishOutput = await runPublishStep(versionOutput, options);
28
+ success("Publish complete");
29
+ }
30
+ return { versionOutput, notesGenerated, publishOutput };
31
+ }
32
+ async function runVersionStep(options) {
33
+ const { loadConfig, VersionEngine, enableJsonOutput, getJsonData } = await import("@releasekit/version");
34
+ enableJsonOutput(options.dryRun);
35
+ const config = loadConfig({ cwd: options.projectDir, configPath: options.config });
36
+ if (options.dryRun) config.dryRun = true;
37
+ if (options.sync) config.sync = true;
38
+ if (options.bump) config.type = options.bump;
39
+ if (options.prerelease) {
40
+ config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
41
+ config.isPrerelease = true;
42
+ }
43
+ const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
44
+ if (cliTargets.length > 0) {
45
+ config.packages = cliTargets;
46
+ }
47
+ const engine = new VersionEngine(config);
48
+ const pkgsResult = await engine.getWorkspacePackages();
49
+ const resolvedCount = pkgsResult.packages.length;
50
+ if (resolvedCount === 0) {
51
+ throw new Error("No packages found in workspace");
52
+ }
53
+ if (config.sync) {
54
+ engine.setStrategy("sync");
55
+ await engine.run(pkgsResult);
56
+ } else if (resolvedCount === 1) {
57
+ engine.setStrategy("single");
58
+ await engine.run(pkgsResult);
59
+ } else {
60
+ engine.setStrategy("async");
61
+ await engine.run(pkgsResult, cliTargets);
62
+ }
63
+ return getJsonData();
64
+ }
65
+ async function runNotesStep(versionOutput, options) {
66
+ const { parsePackageVersioner, runPipeline, loadConfig, getDefaultConfig } = await import("@releasekit/notes");
67
+ const config = loadConfig(options.projectDir, options.config);
68
+ if (config.output.length === 0) {
69
+ config.output = getDefaultConfig().output;
70
+ }
71
+ const input = parsePackageVersioner(JSON.stringify(versionOutput));
72
+ await runPipeline(input, config, options.dryRun);
73
+ }
74
+ async function runPublishStep(versionOutput, options) {
75
+ const { runPipeline, loadConfig } = await import("@releasekit/publish");
76
+ const config = loadConfig({ configPath: options.config });
77
+ const publishOptions = {
78
+ dryRun: options.dryRun,
79
+ registry: "all",
80
+ npmAuth: "auto",
81
+ skipGit: options.skipGit,
82
+ skipPublish: false,
83
+ skipGithubRelease: options.skipGithubRelease,
84
+ skipVerification: options.skipVerification,
85
+ json: options.json,
86
+ verbose: options.verbose
87
+ };
88
+ return runPipeline(versionOutput, config, publishOptions);
89
+ }
90
+
91
+ export {
92
+ runRelease
93
+ };
package/dist/cli.cjs ADDED
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/cli.ts
27
+ var import_core2 = require("@releasekit/core");
28
+ var import_commander = require("commander");
29
+
30
+ // src/release.ts
31
+ var import_core = require("@releasekit/core");
32
+ async function runRelease(options) {
33
+ if (options.verbose) (0, import_core.setLogLevel)("debug");
34
+ if (options.quiet) (0, import_core.setQuietMode)(true);
35
+ if (options.json) (0, import_core.setJsonMode)(true);
36
+ (0, import_core.info)("Running version analysis...");
37
+ const versionOutput = await runVersionStep(options);
38
+ if (versionOutput.updates.length === 0) {
39
+ (0, import_core.info)("No releasable changes found");
40
+ return null;
41
+ }
42
+ (0, import_core.info)(`Found ${versionOutput.updates.length} package update(s)`);
43
+ for (const update of versionOutput.updates) {
44
+ (0, import_core.info)(` ${update.packageName} \u2192 ${update.newVersion}`);
45
+ }
46
+ let notesGenerated = false;
47
+ if (!options.skipNotes) {
48
+ (0, import_core.info)("Generating release notes...");
49
+ await runNotesStep(versionOutput, options);
50
+ notesGenerated = true;
51
+ (0, import_core.success)("Release notes generated");
52
+ }
53
+ let publishOutput;
54
+ if (!options.skipPublish) {
55
+ (0, import_core.info)("Publishing...");
56
+ publishOutput = await runPublishStep(versionOutput, options);
57
+ (0, import_core.success)("Publish complete");
58
+ }
59
+ return { versionOutput, notesGenerated, publishOutput };
60
+ }
61
+ async function runVersionStep(options) {
62
+ const { loadConfig, VersionEngine, enableJsonOutput, getJsonData } = await import("@releasekit/version");
63
+ enableJsonOutput(options.dryRun);
64
+ const config = loadConfig({ cwd: options.projectDir, configPath: options.config });
65
+ if (options.dryRun) config.dryRun = true;
66
+ if (options.sync) config.sync = true;
67
+ if (options.bump) config.type = options.bump;
68
+ if (options.prerelease) {
69
+ config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
70
+ config.isPrerelease = true;
71
+ }
72
+ const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
73
+ if (cliTargets.length > 0) {
74
+ config.packages = cliTargets;
75
+ }
76
+ const engine = new VersionEngine(config);
77
+ const pkgsResult = await engine.getWorkspacePackages();
78
+ const resolvedCount = pkgsResult.packages.length;
79
+ if (resolvedCount === 0) {
80
+ throw new Error("No packages found in workspace");
81
+ }
82
+ if (config.sync) {
83
+ engine.setStrategy("sync");
84
+ await engine.run(pkgsResult);
85
+ } else if (resolvedCount === 1) {
86
+ engine.setStrategy("single");
87
+ await engine.run(pkgsResult);
88
+ } else {
89
+ engine.setStrategy("async");
90
+ await engine.run(pkgsResult, cliTargets);
91
+ }
92
+ return getJsonData();
93
+ }
94
+ async function runNotesStep(versionOutput, options) {
95
+ const { parsePackageVersioner, runPipeline, loadConfig, getDefaultConfig } = await import("@releasekit/notes");
96
+ const config = loadConfig(options.projectDir, options.config);
97
+ if (config.output.length === 0) {
98
+ config.output = getDefaultConfig().output;
99
+ }
100
+ const input = parsePackageVersioner(JSON.stringify(versionOutput));
101
+ await runPipeline(input, config, options.dryRun);
102
+ }
103
+ async function runPublishStep(versionOutput, options) {
104
+ const { runPipeline, loadConfig } = await import("@releasekit/publish");
105
+ const config = loadConfig({ configPath: options.config });
106
+ const publishOptions = {
107
+ dryRun: options.dryRun,
108
+ registry: "all",
109
+ npmAuth: "auto",
110
+ skipGit: options.skipGit,
111
+ skipPublish: false,
112
+ skipGithubRelease: options.skipGithubRelease,
113
+ skipVerification: options.skipVerification,
114
+ json: options.json,
115
+ verbose: options.verbose
116
+ };
117
+ return runPipeline(versionOutput, config, publishOptions);
118
+ }
119
+
120
+ // src/cli.ts
121
+ var program = new import_commander.Command();
122
+ program.name("releasekit").description("Unified release pipeline: version, changelog, and publish").version("0.1.0").command("release", { isDefault: true }).description("Run the full release pipeline").option("-c, --config <path>", "Path to config file").option("-d, --dry-run", "Preview all steps without side effects", false).option("-b, --bump <type>", "Force bump type (patch|minor|major)").option("-p, --prerelease [identifier]", "Create prerelease version").option("-s, --sync", "Use synchronized versioning across all packages", false).option("-t, --target <packages>", "Target specific packages (comma-separated)").option("--skip-notes", "Skip changelog generation", false).option("--skip-publish", "Skip registry publishing and git operations", false).option("--skip-git", "Skip git commit/tag/push", false).option("--skip-github-release", "Skip GitHub release creation", false).option("--skip-verification", "Skip post-publish verification", false).option("-j, --json", "Output results as JSON", false).option("-v, --verbose", "Verbose logging", false).option("-q, --quiet", "Suppress non-error output", false).option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
123
+ const options = {
124
+ config: opts.config,
125
+ dryRun: opts.dryRun,
126
+ bump: opts.bump,
127
+ prerelease: opts.prerelease,
128
+ sync: opts.sync,
129
+ target: opts.target,
130
+ skipNotes: opts.skipNotes,
131
+ skipPublish: opts.skipPublish,
132
+ skipGit: opts.skipGit,
133
+ skipGithubRelease: opts.skipGithubRelease,
134
+ skipVerification: opts.skipVerification,
135
+ json: opts.json,
136
+ verbose: opts.verbose,
137
+ quiet: opts.quiet,
138
+ projectDir: opts.projectDir
139
+ };
140
+ try {
141
+ const result = await runRelease(options);
142
+ if (options.json && result) {
143
+ console.log(JSON.stringify(result, null, 2));
144
+ }
145
+ if (!result) {
146
+ process.exit(0);
147
+ }
148
+ } catch (error) {
149
+ console.error(error instanceof Error ? error.message : String(error));
150
+ process.exit(import_core2.EXIT_CODES.GENERAL_ERROR);
151
+ }
152
+ });
153
+ program.parse();
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runRelease
4
+ } from "./chunk-44AGNIZ7.js";
5
+
6
+ // src/cli.ts
7
+ import { EXIT_CODES } from "@releasekit/core";
8
+ import { Command } from "commander";
9
+ var program = new Command();
10
+ program.name("releasekit").description("Unified release pipeline: version, changelog, and publish").version("0.1.0").command("release", { isDefault: true }).description("Run the full release pipeline").option("-c, --config <path>", "Path to config file").option("-d, --dry-run", "Preview all steps without side effects", false).option("-b, --bump <type>", "Force bump type (patch|minor|major)").option("-p, --prerelease [identifier]", "Create prerelease version").option("-s, --sync", "Use synchronized versioning across all packages", false).option("-t, --target <packages>", "Target specific packages (comma-separated)").option("--skip-notes", "Skip changelog generation", false).option("--skip-publish", "Skip registry publishing and git operations", false).option("--skip-git", "Skip git commit/tag/push", false).option("--skip-github-release", "Skip GitHub release creation", false).option("--skip-verification", "Skip post-publish verification", false).option("-j, --json", "Output results as JSON", false).option("-v, --verbose", "Verbose logging", false).option("-q, --quiet", "Suppress non-error output", false).option("--project-dir <path>", "Project directory", process.cwd()).action(async (opts) => {
11
+ const options = {
12
+ config: opts.config,
13
+ dryRun: opts.dryRun,
14
+ bump: opts.bump,
15
+ prerelease: opts.prerelease,
16
+ sync: opts.sync,
17
+ target: opts.target,
18
+ skipNotes: opts.skipNotes,
19
+ skipPublish: opts.skipPublish,
20
+ skipGit: opts.skipGit,
21
+ skipGithubRelease: opts.skipGithubRelease,
22
+ skipVerification: opts.skipVerification,
23
+ json: opts.json,
24
+ verbose: opts.verbose,
25
+ quiet: opts.quiet,
26
+ projectDir: opts.projectDir
27
+ };
28
+ try {
29
+ const result = await runRelease(options);
30
+ if (options.json && result) {
31
+ console.log(JSON.stringify(result, null, 2));
32
+ }
33
+ if (!result) {
34
+ process.exit(0);
35
+ }
36
+ } catch (error) {
37
+ console.error(error instanceof Error ? error.message : String(error));
38
+ process.exit(EXIT_CODES.GENERAL_ERROR);
39
+ }
40
+ });
41
+ program.parse();
package/dist/index.cjs ADDED
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ runRelease: () => runRelease
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/release.ts
38
+ var import_core = require("@releasekit/core");
39
+ async function runRelease(options) {
40
+ if (options.verbose) (0, import_core.setLogLevel)("debug");
41
+ if (options.quiet) (0, import_core.setQuietMode)(true);
42
+ if (options.json) (0, import_core.setJsonMode)(true);
43
+ (0, import_core.info)("Running version analysis...");
44
+ const versionOutput = await runVersionStep(options);
45
+ if (versionOutput.updates.length === 0) {
46
+ (0, import_core.info)("No releasable changes found");
47
+ return null;
48
+ }
49
+ (0, import_core.info)(`Found ${versionOutput.updates.length} package update(s)`);
50
+ for (const update of versionOutput.updates) {
51
+ (0, import_core.info)(` ${update.packageName} \u2192 ${update.newVersion}`);
52
+ }
53
+ let notesGenerated = false;
54
+ if (!options.skipNotes) {
55
+ (0, import_core.info)("Generating release notes...");
56
+ await runNotesStep(versionOutput, options);
57
+ notesGenerated = true;
58
+ (0, import_core.success)("Release notes generated");
59
+ }
60
+ let publishOutput;
61
+ if (!options.skipPublish) {
62
+ (0, import_core.info)("Publishing...");
63
+ publishOutput = await runPublishStep(versionOutput, options);
64
+ (0, import_core.success)("Publish complete");
65
+ }
66
+ return { versionOutput, notesGenerated, publishOutput };
67
+ }
68
+ async function runVersionStep(options) {
69
+ const { loadConfig, VersionEngine, enableJsonOutput, getJsonData } = await import("@releasekit/version");
70
+ enableJsonOutput(options.dryRun);
71
+ const config = loadConfig({ cwd: options.projectDir, configPath: options.config });
72
+ if (options.dryRun) config.dryRun = true;
73
+ if (options.sync) config.sync = true;
74
+ if (options.bump) config.type = options.bump;
75
+ if (options.prerelease) {
76
+ config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
77
+ config.isPrerelease = true;
78
+ }
79
+ const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
80
+ if (cliTargets.length > 0) {
81
+ config.packages = cliTargets;
82
+ }
83
+ const engine = new VersionEngine(config);
84
+ const pkgsResult = await engine.getWorkspacePackages();
85
+ const resolvedCount = pkgsResult.packages.length;
86
+ if (resolvedCount === 0) {
87
+ throw new Error("No packages found in workspace");
88
+ }
89
+ if (config.sync) {
90
+ engine.setStrategy("sync");
91
+ await engine.run(pkgsResult);
92
+ } else if (resolvedCount === 1) {
93
+ engine.setStrategy("single");
94
+ await engine.run(pkgsResult);
95
+ } else {
96
+ engine.setStrategy("async");
97
+ await engine.run(pkgsResult, cliTargets);
98
+ }
99
+ return getJsonData();
100
+ }
101
+ async function runNotesStep(versionOutput, options) {
102
+ const { parsePackageVersioner, runPipeline, loadConfig, getDefaultConfig } = await import("@releasekit/notes");
103
+ const config = loadConfig(options.projectDir, options.config);
104
+ if (config.output.length === 0) {
105
+ config.output = getDefaultConfig().output;
106
+ }
107
+ const input = parsePackageVersioner(JSON.stringify(versionOutput));
108
+ await runPipeline(input, config, options.dryRun);
109
+ }
110
+ async function runPublishStep(versionOutput, options) {
111
+ const { runPipeline, loadConfig } = await import("@releasekit/publish");
112
+ const config = loadConfig({ configPath: options.config });
113
+ const publishOptions = {
114
+ dryRun: options.dryRun,
115
+ registry: "all",
116
+ npmAuth: "auto",
117
+ skipGit: options.skipGit,
118
+ skipPublish: false,
119
+ skipGithubRelease: options.skipGithubRelease,
120
+ skipVerification: options.skipVerification,
121
+ json: options.json,
122
+ verbose: options.verbose
123
+ };
124
+ return runPipeline(versionOutput, config, publishOptions);
125
+ }
126
+ // Annotate the CommonJS export names for ESM import in node:
127
+ 0 && (module.exports = {
128
+ runRelease
129
+ });
@@ -0,0 +1,29 @@
1
+ import { VersionOutput } from '@releasekit/core';
2
+ import { PublishOutput } from '@releasekit/publish';
3
+
4
+ interface ReleaseOptions {
5
+ config?: string;
6
+ dryRun: boolean;
7
+ bump?: string;
8
+ prerelease?: string | boolean;
9
+ sync: boolean;
10
+ target?: string;
11
+ skipNotes: boolean;
12
+ skipPublish: boolean;
13
+ skipGit: boolean;
14
+ skipGithubRelease: boolean;
15
+ skipVerification: boolean;
16
+ json: boolean;
17
+ verbose: boolean;
18
+ quiet: boolean;
19
+ projectDir: string;
20
+ }
21
+ interface ReleaseOutput {
22
+ versionOutput: VersionOutput;
23
+ notesGenerated: boolean;
24
+ publishOutput?: PublishOutput;
25
+ }
26
+
27
+ declare function runRelease(options: ReleaseOptions): Promise<ReleaseOutput | null>;
28
+
29
+ export { type ReleaseOptions, type ReleaseOutput, runRelease };
@@ -0,0 +1,29 @@
1
+ import { VersionOutput } from '@releasekit/core';
2
+ import { PublishOutput } from '@releasekit/publish';
3
+
4
+ interface ReleaseOptions {
5
+ config?: string;
6
+ dryRun: boolean;
7
+ bump?: string;
8
+ prerelease?: string | boolean;
9
+ sync: boolean;
10
+ target?: string;
11
+ skipNotes: boolean;
12
+ skipPublish: boolean;
13
+ skipGit: boolean;
14
+ skipGithubRelease: boolean;
15
+ skipVerification: boolean;
16
+ json: boolean;
17
+ verbose: boolean;
18
+ quiet: boolean;
19
+ projectDir: string;
20
+ }
21
+ interface ReleaseOutput {
22
+ versionOutput: VersionOutput;
23
+ notesGenerated: boolean;
24
+ publishOutput?: PublishOutput;
25
+ }
26
+
27
+ declare function runRelease(options: ReleaseOptions): Promise<ReleaseOutput | null>;
28
+
29
+ export { type ReleaseOptions, type ReleaseOutput, runRelease };
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import {
2
+ runRelease
3
+ } from "./chunk-44AGNIZ7.js";
4
+ export {
5
+ runRelease
6
+ };
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@releasekit/release",
3
+ "version": "0.1.0",
4
+ "description": "Unified CLI for automated releases: version, changelog, and publish in a single command",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "bin": {
22
+ "releasekit": "./dist/cli.js"
23
+ },
24
+ "scripts": {
25
+ "build": "tsup src/index.ts src/cli.ts --format esm,cjs --dts",
26
+ "dev": "tsup src/index.ts src/cli.ts --format esm,cjs --watch --dts",
27
+ "clean": "rm -rf dist coverage .turbo",
28
+ "test": "vitest run",
29
+ "test:unit": "vitest run --coverage",
30
+ "test:coverage": "vitest run --coverage",
31
+ "lint": "biome check .",
32
+ "typecheck": "tsc --noEmit"
33
+ },
34
+ "keywords": ["release", "version", "changelog", "publish", "cli", "ci"],
35
+ "author": {
36
+ "name": "Sam Maister",
37
+ "email": "goosewobbler@protonmail.com"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/goosewobbler/releasekit",
42
+ "directory": "packages/release"
43
+ },
44
+ "license": "MIT",
45
+ "files": ["dist", "README.md", "LICENSE"],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "dependencies": {
50
+ "@releasekit/config": "workspace:*",
51
+ "@releasekit/core": "workspace:*",
52
+ "@releasekit/notes": "workspace:*",
53
+ "@releasekit/publish": "workspace:*",
54
+ "@releasekit/version": "workspace:*",
55
+ "commander": "catalog:"
56
+ },
57
+ "devDependencies": {
58
+ "@biomejs/biome": "catalog:",
59
+ "@types/node": "catalog:",
60
+ "@types/semver": "catalog:",
61
+ "@vitest/coverage-v8": "catalog:",
62
+ "tsup": "catalog:",
63
+ "typescript": "catalog:",
64
+ "vitest": "catalog:"
65
+ },
66
+ "engines": {
67
+ "node": ">=18 || >=20"
68
+ }
69
+ }