@doryski/release 1.0.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/LICENSE +21 -0
- package/README.md +101 -0
- package/dist/chunk-67J7X3FS.js +255 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +37 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +6 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dominik Rycharski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# @doryski/release
|
|
2
|
+
|
|
3
|
+
A conventional-commit release CLI and a reusable GitHub Actions workflow, shared
|
|
4
|
+
across npm packages. One source of truth for "bump, tag, push, publish".
|
|
5
|
+
|
|
6
|
+
The CLI runs in a consuming repo's root, inspects git history since the latest
|
|
7
|
+
tag, proposes a semver bump derived from conventional commits, bumps
|
|
8
|
+
`package.json`, commits `release: vX.Y.Z`, and pushes the branch then the tag —
|
|
9
|
+
which triggers the reusable workflow to build, test, and publish to npm.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add -D @doryski/release
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Add a `release` script to your `package.json`:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"scripts": {
|
|
22
|
+
"release": "doryski-release"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Then run:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm release
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## CLI flags
|
|
34
|
+
|
|
35
|
+
| Flag | Description |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| `-r, --release-version <ver>` | Exact release version (`0.2.0` or `v0.2.0`). Highest precedence. |
|
|
38
|
+
| `--bump <major\|minor\|patch>` | Force the bump level. Overrides the auto-detected level; ignored when `--release-version` is set. |
|
|
39
|
+
| `-y, --yes` | Skip the confirmation prompt (required for non-interactive runs). |
|
|
40
|
+
| `-n, --dry-run` | Preview actions without modifying files, committing, tagging, or pushing. |
|
|
41
|
+
| `-h, --help` | Show help. |
|
|
42
|
+
|
|
43
|
+
Version precedence: `--release-version` > `--bump` > auto-detected from commits.
|
|
44
|
+
|
|
45
|
+
The auto-detected bump follows conventional commits since the latest tag:
|
|
46
|
+
|
|
47
|
+
- a `!`-marked type (e.g. `feat!:`) or a `BREAKING CHANGE:` footer → **major**
|
|
48
|
+
- any `feat:` → **minor**
|
|
49
|
+
- everything else (`fix`, `chore`, `docs`, …) → **patch**
|
|
50
|
+
|
|
51
|
+
## Programmatic use
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { release } from "@doryski/release";
|
|
55
|
+
|
|
56
|
+
await release({ bump: "minor", yes: true });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Reusable release workflow
|
|
60
|
+
|
|
61
|
+
This package ships a reusable workflow at
|
|
62
|
+
`Doryski/release/.github/workflows/release.yml`. Consumers add a caller workflow
|
|
63
|
+
that triggers on `v*` tags:
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
name: Publish
|
|
67
|
+
|
|
68
|
+
on:
|
|
69
|
+
push:
|
|
70
|
+
tags:
|
|
71
|
+
- "v*"
|
|
72
|
+
|
|
73
|
+
jobs:
|
|
74
|
+
release:
|
|
75
|
+
uses: Doryski/release/.github/workflows/release.yml@v1
|
|
76
|
+
permissions:
|
|
77
|
+
contents: write
|
|
78
|
+
id-token: write
|
|
79
|
+
with:
|
|
80
|
+
run-lint: true
|
|
81
|
+
secrets:
|
|
82
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Workflow inputs:
|
|
86
|
+
|
|
87
|
+
| Input | Type | Default | Description |
|
|
88
|
+
| --- | --- | --- | --- |
|
|
89
|
+
| `node-version` | string | `"20"` | Node version for setup-node. |
|
|
90
|
+
| `run-lint` | boolean | `true` | Whether to run `pnpm lint`. |
|
|
91
|
+
|
|
92
|
+
The workflow runs `install → build → lint (gated) → type-check → test`, verifies
|
|
93
|
+
`package.json` matches the tag, publishes with `npm publish --access public
|
|
94
|
+
--provenance`, and creates a GitHub Release with generated notes.
|
|
95
|
+
|
|
96
|
+
The consuming repo must expose `build`, `type-check`, `test`, and (if
|
|
97
|
+
`run-lint`) `lint` scripts, and provide an `NPM_TOKEN` secret.
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
MIT © Dominik Rycharski
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
// src/release.ts
|
|
2
|
+
import { spawnSync } from "child_process";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { createInterface } from "readline/promises";
|
|
5
|
+
import { stdin, stdout } from "process";
|
|
6
|
+
|
|
7
|
+
// src/git.ts
|
|
8
|
+
import { execSync } from "child_process";
|
|
9
|
+
var sh = (cmd) => execSync(cmd, { encoding: "utf8" }).trim();
|
|
10
|
+
var getRecentTags = () => {
|
|
11
|
+
try {
|
|
12
|
+
const out = sh("git tag --sort=-v:refname");
|
|
13
|
+
return out ? out.split("\n").filter(Boolean) : [];
|
|
14
|
+
} catch {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var getCommitsSince = (ref) => {
|
|
19
|
+
try {
|
|
20
|
+
const range = ref ? `${ref}..HEAD` : "HEAD";
|
|
21
|
+
const out = sh(`git log ${range} --format=%B%x00`);
|
|
22
|
+
return out ? out.split("\0").map((msg) => msg.trim()).filter(Boolean) : [];
|
|
23
|
+
} catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var ensureCleanTree = () => {
|
|
28
|
+
const status = sh("git status --porcelain");
|
|
29
|
+
if (status) {
|
|
30
|
+
console.error(
|
|
31
|
+
"\n\u2717 Working tree is not clean. Commit or stash changes first:\n"
|
|
32
|
+
);
|
|
33
|
+
console.error(status);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var ensureOnDefaultBranch = () => {
|
|
38
|
+
const branch = sh("git rev-parse --abbrev-ref HEAD");
|
|
39
|
+
if (branch !== "main" && branch !== "master") {
|
|
40
|
+
console.warn(`
|
|
41
|
+
\u26A0 You are on branch "${branch}", not main/master.`);
|
|
42
|
+
}
|
|
43
|
+
return branch;
|
|
44
|
+
};
|
|
45
|
+
var parseActionsUrl = (remoteUrl) => {
|
|
46
|
+
const trimmed = remoteUrl.trim();
|
|
47
|
+
if (!trimmed) return null;
|
|
48
|
+
const ssh = /^git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/.exec(trimmed);
|
|
49
|
+
if (ssh) return `https://github.com/${ssh[1]}/${ssh[2]}/actions`;
|
|
50
|
+
const https = /^https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/.exec(trimmed);
|
|
51
|
+
if (https) return `https://github.com/${https[1]}/${https[2]}/actions`;
|
|
52
|
+
return null;
|
|
53
|
+
};
|
|
54
|
+
var getRemoteActionsUrl = () => {
|
|
55
|
+
try {
|
|
56
|
+
const remote = sh("git remote get-url origin");
|
|
57
|
+
return parseActionsUrl(remote);
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// src/pkg.ts
|
|
64
|
+
import { readFile, writeFile } from "fs/promises";
|
|
65
|
+
var readJson = async (file) => JSON.parse(await readFile(file, "utf8"));
|
|
66
|
+
var writeJson = async (file, data) => {
|
|
67
|
+
await writeFile(file, `${JSON.stringify(data, null, 2)}
|
|
68
|
+
`, "utf8");
|
|
69
|
+
};
|
|
70
|
+
var updateVersionFile = async (file, newVersion) => {
|
|
71
|
+
const json = await readJson(file);
|
|
72
|
+
if (json.version === newVersion) return false;
|
|
73
|
+
json.version = newVersion;
|
|
74
|
+
await writeJson(file, json);
|
|
75
|
+
return true;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/semver.ts
|
|
79
|
+
var parseSemver = (tag) => {
|
|
80
|
+
const match = /^v(\d+)\.(\d+)\.(\d+)(?:-([\w.-]+))?$/.exec(tag);
|
|
81
|
+
if (!match) return null;
|
|
82
|
+
const [, major, minor, patch, prerelease] = match;
|
|
83
|
+
return {
|
|
84
|
+
major: Number(major),
|
|
85
|
+
minor: Number(minor),
|
|
86
|
+
patch: Number(patch),
|
|
87
|
+
prerelease: prerelease ?? null
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
var applyBump = (v, type) => {
|
|
91
|
+
if (type === "major") return `v${v.major + 1}.0.0`;
|
|
92
|
+
if (type === "minor") return `v${v.major}.${v.minor + 1}.0`;
|
|
93
|
+
return `v${v.major}.${v.minor}.${v.patch + 1}`;
|
|
94
|
+
};
|
|
95
|
+
var determineBump = (commits) => {
|
|
96
|
+
let bump = "patch";
|
|
97
|
+
const subjectRe = /^(\w+)(?:\([^)]*\))?(!)?:/;
|
|
98
|
+
for (const msg of commits) {
|
|
99
|
+
const subject = msg.split("\n")[0];
|
|
100
|
+
const match = subjectRe.exec(subject);
|
|
101
|
+
const breaking = match?.[2] === "!" || /^BREAKING CHANGE:/m.test(msg);
|
|
102
|
+
if (breaking) return "major";
|
|
103
|
+
if (match?.[1] === "feat") bump = "minor";
|
|
104
|
+
}
|
|
105
|
+
return bump;
|
|
106
|
+
};
|
|
107
|
+
var stripV = (tag) => tag.startsWith("v") ? tag.slice(1) : tag;
|
|
108
|
+
|
|
109
|
+
// src/release.ts
|
|
110
|
+
var PACKAGE_JSON = path.join(process.cwd(), "package.json");
|
|
111
|
+
var makeRunStep = (dryRun) => (label, cmd, args) => {
|
|
112
|
+
if (dryRun) {
|
|
113
|
+
console.log(`\u2192 [dry-run] ${label}`);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
console.log(`\u2192 ${label}`);
|
|
117
|
+
const result = spawnSync(cmd, args, { stdio: "inherit" });
|
|
118
|
+
if (result.status !== 0) process.exit(result.status ?? 1);
|
|
119
|
+
};
|
|
120
|
+
var release = async (options = {}) => {
|
|
121
|
+
const flags = {
|
|
122
|
+
releaseVersion: options.releaseVersion,
|
|
123
|
+
bump: options.bump,
|
|
124
|
+
yes: options.yes ?? false,
|
|
125
|
+
dryRun: options.dryRun ?? false
|
|
126
|
+
};
|
|
127
|
+
ensureCleanTree();
|
|
128
|
+
const branch = ensureOnDefaultBranch();
|
|
129
|
+
const tags = getRecentTags();
|
|
130
|
+
const pkg = await readJson(PACKAGE_JSON);
|
|
131
|
+
console.log(`
|
|
132
|
+
\u{1F4E6} ${pkg.name} \u2014 release
|
|
133
|
+
`);
|
|
134
|
+
console.log(`Package: ${pkg.name}`);
|
|
135
|
+
console.log(`Current branch: ${branch}`);
|
|
136
|
+
console.log(`package.json: ${pkg.version}`);
|
|
137
|
+
console.log(
|
|
138
|
+
`Recent tags: ${tags.length ? tags.slice(0, 5).join(", ") : "(none)"}`
|
|
139
|
+
);
|
|
140
|
+
const latest = tags.find((t) => parseSemver(t));
|
|
141
|
+
const latestParsed = latest ? parseSemver(latest) : null;
|
|
142
|
+
const commitsSinceTag = getCommitsSince(latest ?? null);
|
|
143
|
+
const detectedBump = determineBump(commitsSinceTag);
|
|
144
|
+
const bumpType = flags.bump ?? detectedBump;
|
|
145
|
+
const proposed = latestParsed ? applyBump(latestParsed, bumpType) : `v${stripV(pkg.version)}`;
|
|
146
|
+
const bumpSource = flags.bump ? `${bumpType} bump, forced` : `${bumpType} bump`;
|
|
147
|
+
console.log(`Commits since tag: ${commitsSinceTag.length} (${bumpSource})`);
|
|
148
|
+
console.log(`Proposed new tag: ${proposed}
|
|
149
|
+
`);
|
|
150
|
+
const interactive = stdin.isTTY === true;
|
|
151
|
+
const rl = interactive ? createInterface({ input: stdin, output: stdout }) : null;
|
|
152
|
+
const askVersion = async () => {
|
|
153
|
+
if (flags.releaseVersion) {
|
|
154
|
+
console.log(`Version (from --release-version): ${flags.releaseVersion}`);
|
|
155
|
+
return flags.releaseVersion;
|
|
156
|
+
}
|
|
157
|
+
if (!rl) return proposed;
|
|
158
|
+
return (await rl.question(`Enter version (press Enter to accept ${proposed}): `)).trim();
|
|
159
|
+
};
|
|
160
|
+
const askConfirm = async () => {
|
|
161
|
+
if (flags.yes) {
|
|
162
|
+
console.log(`Proceed? [y/N] y (from --yes)`);
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
if (!rl) {
|
|
166
|
+
console.error(
|
|
167
|
+
"\n\u2717 Non-interactive run: pass --yes to skip the confirmation prompt."
|
|
168
|
+
);
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
const ans = (await rl.question(`Proceed? [y/N] `)).trim().toLowerCase();
|
|
172
|
+
return ans === "y" || ans === "yes";
|
|
173
|
+
};
|
|
174
|
+
const input = await askVersion();
|
|
175
|
+
const chosen = input || proposed;
|
|
176
|
+
const normalized = chosen.startsWith("v") ? chosen : `v${chosen}`;
|
|
177
|
+
const bareVersion = stripV(normalized);
|
|
178
|
+
if (!parseSemver(normalized)) {
|
|
179
|
+
console.error(`
|
|
180
|
+
\u2717 Invalid semver tag: ${normalized}`);
|
|
181
|
+
rl?.close();
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
if (tags.includes(normalized)) {
|
|
185
|
+
console.error(`
|
|
186
|
+
\u2717 Tag ${normalized} already exists.`);
|
|
187
|
+
rl?.close();
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
console.log(`
|
|
191
|
+
This will:`);
|
|
192
|
+
console.log(` 1. Bump package.json ${pkg.version} \u2192 ${bareVersion}`);
|
|
193
|
+
console.log(` 2. Commit on ${branch}`);
|
|
194
|
+
console.log(` 3. Tag ${normalized} and push ${branch} + tag`);
|
|
195
|
+
console.log(` 4. GitHub Actions will build, test, and publish to npm
|
|
196
|
+
`);
|
|
197
|
+
if (flags.dryRun) console.log("Dry-run mode: no changes will be made.\n");
|
|
198
|
+
const confirmed = await askConfirm();
|
|
199
|
+
rl?.close();
|
|
200
|
+
if (!confirmed) {
|
|
201
|
+
console.log("Aborted.");
|
|
202
|
+
process.exit(0);
|
|
203
|
+
}
|
|
204
|
+
const runStep = makeRunStep(flags.dryRun);
|
|
205
|
+
if (flags.dryRun) {
|
|
206
|
+
console.log(`\u2192 [dry-run] would bump package.json to ${bareVersion}`);
|
|
207
|
+
} else {
|
|
208
|
+
const pkgChanged = await updateVersionFile(PACKAGE_JSON, bareVersion);
|
|
209
|
+
if (!pkgChanged) {
|
|
210
|
+
console.warn("\n\u26A0 package.json already at target version.");
|
|
211
|
+
} else {
|
|
212
|
+
runStep(`git add package.json`, "git", ["add", "package.json"]);
|
|
213
|
+
runStep(`git commit -m "release: ${normalized}"`, "git", [
|
|
214
|
+
"commit",
|
|
215
|
+
"-m",
|
|
216
|
+
`release: ${normalized}`
|
|
217
|
+
]);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
runStep(`git tag ${normalized}`, "git", ["tag", normalized]);
|
|
221
|
+
runStep(`git push origin ${branch}`, "git", ["push", "origin", branch]);
|
|
222
|
+
if (!flags.dryRun) {
|
|
223
|
+
const pushTag = spawnSync("git", ["push", "origin", normalized], {
|
|
224
|
+
stdio: "inherit"
|
|
225
|
+
});
|
|
226
|
+
if (pushTag.status !== 0) {
|
|
227
|
+
console.error("\n\u2717 Tag push failed. Clean up local tag with:");
|
|
228
|
+
console.error(` git tag -d ${normalized}`);
|
|
229
|
+
process.exit(pushTag.status ?? 1);
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
runStep(`git push origin ${normalized}`, "git", [
|
|
233
|
+
"push",
|
|
234
|
+
"origin",
|
|
235
|
+
normalized
|
|
236
|
+
]);
|
|
237
|
+
}
|
|
238
|
+
if (flags.dryRun) {
|
|
239
|
+
console.log(
|
|
240
|
+
`
|
|
241
|
+
\u2713 Dry-run complete. Re-run without --dry-run to actually release ${normalized}.`
|
|
242
|
+
);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
console.log(
|
|
246
|
+
`
|
|
247
|
+
\u2713 Tag ${normalized} pushed. GitHub Actions will build, test, and publish to npm.`
|
|
248
|
+
);
|
|
249
|
+
const actionsUrl = getRemoteActionsUrl();
|
|
250
|
+
if (actionsUrl) console.log(` Watch: ${actionsUrl}`);
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export {
|
|
254
|
+
release
|
|
255
|
+
};
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
release
|
|
4
|
+
} from "./chunk-67J7X3FS.js";
|
|
5
|
+
|
|
6
|
+
// src/cli.ts
|
|
7
|
+
import { Command, InvalidArgumentError } from "commander";
|
|
8
|
+
var BUMP_LEVELS = ["major", "minor", "patch"];
|
|
9
|
+
var parseBump = (value) => {
|
|
10
|
+
if (BUMP_LEVELS.includes(value)) {
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
throw new InvalidArgumentError("--bump must be one of: major, minor, patch");
|
|
14
|
+
};
|
|
15
|
+
var program = new Command().name("doryski-release").description("Bump package.json, tag, and push to trigger the npm release.").option(
|
|
16
|
+
"-r, --release-version <ver>",
|
|
17
|
+
"release version (e.g. 0.2.0 or v0.2.0); defaults to a conventional-commit bump of the latest tag"
|
|
18
|
+
).option(
|
|
19
|
+
"--bump <major|minor|patch>",
|
|
20
|
+
"force the bump level (overrides the auto-detected level; ignored when --release-version is set)",
|
|
21
|
+
parseBump
|
|
22
|
+
).option("-y, --yes", "skip the confirmation prompt", false).option(
|
|
23
|
+
"-n, --dry-run",
|
|
24
|
+
"preview the actions without modifying files, committing, tagging, or pushing",
|
|
25
|
+
false
|
|
26
|
+
).helpOption("-h, --help", "show help");
|
|
27
|
+
program.parse();
|
|
28
|
+
var flags = program.opts();
|
|
29
|
+
release({
|
|
30
|
+
releaseVersion: flags.releaseVersion,
|
|
31
|
+
bump: flags.bump,
|
|
32
|
+
yes: flags.yes,
|
|
33
|
+
dryRun: flags.dryRun
|
|
34
|
+
}).catch((err) => {
|
|
35
|
+
console.error(err);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type BumpType = "major" | "minor" | "patch";
|
|
2
|
+
type ParsedSemver = {
|
|
3
|
+
major: number;
|
|
4
|
+
minor: number;
|
|
5
|
+
patch: number;
|
|
6
|
+
prerelease: string | null;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type ReleaseOptions = {
|
|
10
|
+
releaseVersion?: string;
|
|
11
|
+
bump?: BumpType;
|
|
12
|
+
yes?: boolean;
|
|
13
|
+
dryRun?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const release: (options?: ReleaseOptions) => Promise<void>;
|
|
16
|
+
|
|
17
|
+
export { type BumpType, type ParsedSemver, type ReleaseOptions, release };
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@doryski/release",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A conventional-commit release CLI and reusable GitHub Actions workflow for npm packages",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"doryski-release": "dist/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsup src/index.ts src/cli.ts --format esm --dts --clean",
|
|
24
|
+
"dev": "tsup src/index.ts src/cli.ts --format esm --dts --watch",
|
|
25
|
+
"type-check": "tsc --noEmit",
|
|
26
|
+
"lint": "eslint .",
|
|
27
|
+
"test": "vitest run --maxWorkers=1 --bail=5",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"prepublishOnly": "pnpm build",
|
|
30
|
+
"release": "tsx src/cli.ts"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"release",
|
|
34
|
+
"semver",
|
|
35
|
+
"conventional-commits",
|
|
36
|
+
"cli",
|
|
37
|
+
"npm",
|
|
38
|
+
"publish",
|
|
39
|
+
"github-actions",
|
|
40
|
+
"workflow"
|
|
41
|
+
],
|
|
42
|
+
"author": "Dominik Rycharski (https://github.com/Doryski)",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/Doryski/release.git"
|
|
47
|
+
},
|
|
48
|
+
"bugs": {
|
|
49
|
+
"url": "https://github.com/Doryski/release/issues"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/Doryski/release#readme",
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=20"
|
|
54
|
+
},
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public",
|
|
57
|
+
"provenance": true
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"commander": "^14.0.3"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@eslint/js": "^10.0.1",
|
|
64
|
+
"@types/node": "^22.0.0",
|
|
65
|
+
"eslint": "^10.2.0",
|
|
66
|
+
"tsup": "^8.4.0",
|
|
67
|
+
"tsx": "^4.0.0",
|
|
68
|
+
"typescript": "^5.6.0",
|
|
69
|
+
"typescript-eslint": "^8.58.2",
|
|
70
|
+
"vitest": "^4.1.5"
|
|
71
|
+
}
|
|
72
|
+
}
|