@varlock/bumpy 1.13.2 → 1.14.0-rc.1
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 +3 -1
- package/config-schema.json +43 -0
- package/dist/{add-Dt1hddMt.mjs → add-C9rU_89s.mjs} +4 -4
- package/dist/{apply-release-plan-DD2R7SL2.mjs → apply-release-plan-DxTsUSqa.mjs} +11 -2
- package/dist/{bump-file-B7hmXZlB.mjs → bump-file-mRJeReRJ.mjs} +43 -8
- package/dist/{changelog-CbaET5V6.mjs → changelog-DuFhnJRO.mjs} +3 -3
- package/dist/{changelog-github-DXDnWkrB.mjs → changelog-github-jLOtwuWj.mjs} +2 -2
- package/dist/channels-CFXZkyGd.mjs +75 -0
- package/dist/{check-Dvi0DIqC.mjs → check-DIl9Dz68.mjs} +18 -6
- package/dist/{ci-B7gF6CFP.mjs → ci-ChYmDuwy.mjs} +376 -23
- package/dist/cli.mjs +30 -15
- package/dist/{config-D_4GYDJi.mjs → config-0we4ISZX.mjs} +5 -1
- package/dist/{generate-DohUlhu3.mjs → generate-B2OMt_64.mjs} +3 -3
- package/dist/{git-BWPimLgc.mjs → git-DAWj8LyV.mjs} +12 -1
- package/dist/index.d.mts +46 -4
- package/dist/index.mjs +7 -7
- package/dist/prerelease-B2PVfXkm.mjs +205 -0
- package/dist/{publish-VYBhDYFM.mjs → publish-Ak6jmwi_.mjs} +105 -14
- package/dist/{publish-pipeline-BPedWvKS.mjs → publish-pipeline-BD8mLbL9.mjs} +2 -2
- package/dist/{release-plan-mK7iGeGq.mjs → release-plan-C84pcBi-.mjs} +12 -17
- package/dist/status-DIzi-Iai.mjs +232 -0
- package/dist/{types-Bkh-igOJ.mjs → types-lpiG-Zxh.mjs} +1 -0
- package/dist/version-CMJUopVj.mjs +192 -0
- package/package.json +1 -1
- package/dist/status-DxzKPM8d.mjs +0 -129
- package/dist/version-Cm0nRAFF.mjs +0 -123
- /package/dist/{commit-message-CSWVKPJ-.mjs → commit-message-BwsowSds.mjs} +0 -0
- /package/dist/{init-BCkm6Nfa.mjs → init-DkAY5hjc.mjs} +0 -0
package/README.md
CHANGED
|
@@ -54,6 +54,7 @@ Fixed locale fallback logic in utils.
|
|
|
54
54
|
- **Flexible package management** - include/exclude any package individually via per-package config, glob patterns, or `privatePackages` setting
|
|
55
55
|
- **Non-interactive CLI** - `bumpy add` works fully non-interactively for CI/CD and AI-assisted development
|
|
56
56
|
- **Aggregated GitHub releases** - optionally create a single consolidated release instead of one per package
|
|
57
|
+
- **Prerelease channels** - branch-based `@next` / `@beta` release lines where prerelease versions are derived at publish time, never committed to git (see [prerelease channels docs](https://github.com/dmno-dev/bumpy/blob/main/docs/prereleases.md))
|
|
57
58
|
- **Auto-generate from commits** - `bumpy generate` creates bump files from branch commits - works with any commit style, with enhanced detection for conventional commits
|
|
58
59
|
- **Pluggable changelog formatters** - built-in `"default"` and `"github"` formatters, or write your own
|
|
59
60
|
- **Zero runtime dependencies** - dependencies are minimal and bundled at release time
|
|
@@ -119,6 +120,7 @@ The skill teaches the AI to examine git changes, identify affected packages, cho
|
|
|
119
120
|
- [CLI reference](https://github.com/dmno-dev/bumpy/blob/main/docs/cli.md) - every command with flags and examples
|
|
120
121
|
- [GitHub Actions setup](https://github.com/dmno-dev/bumpy/blob/main/docs/github-actions.md) - CI workflows, token setup, trusted publishing
|
|
121
122
|
- [Version propagation](https://github.com/dmno-dev/bumpy/blob/main/docs/version-propagation.md) - how dependency bumps cascade through your graph
|
|
123
|
+
- [Prerelease channels](https://github.com/dmno-dev/bumpy/blob/main/docs/prereleases.md) - branch-based `@next` / `@beta` release lines
|
|
122
124
|
|
|
123
125
|
## Why files instead of conventional commits?
|
|
124
126
|
|
|
@@ -133,6 +135,7 @@ Bumpy is built as a successor to [🦋changesets](https://github.com/changesets/
|
|
|
133
135
|
- **Custom publish commands** - changesets is hardcoded to `npm publish`. Bumpy supports per-package custom publish for VSCode extensions, Docker images, JSR, etc.
|
|
134
136
|
- **Flexible package management** - changesets treats all private packages the same. Bumpy lets you include/exclude any package individually.
|
|
135
137
|
- **CI without a separate action or bot** - changesets requires installing a [GitHub App](https://github.com/apps/changeset-bot) _and_ using a [separate GitHub Action](https://github.com/changesets/action). Bumpy replaces both with two CLI commands (`bumpy ci check` + `bumpy ci release`) that run directly in your workflows - no extra repos to trust, no app installation requiring org admin approval.
|
|
138
|
+
- **Prerelease channels that don't corrupt state** - changesets' prerelease mode is described in [their own docs](https://github.com/changesets/changesets/blob/main/docs/prereleases.md) as "very complicated" with states "very hard to fix." Bumpy uses [branch-based channels](https://github.com/dmno-dev/bumpy/blob/main/docs/prereleases.md) where prerelease versions are never committed - no global mode file to poison unrelated releases.
|
|
136
139
|
- **Automatic migration** - `bumpy init` detects `.changeset/`, renames it to `.bumpy/`, migrates config, keeps pending files, and offers to uninstall `@changesets/cli`.
|
|
137
140
|
|
|
138
141
|
## Development
|
|
@@ -146,7 +149,6 @@ bunx bumpy --help # invoke built cli
|
|
|
146
149
|
|
|
147
150
|
## Roadmap
|
|
148
151
|
|
|
149
|
-
- Prerelease mode (for now, use [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new) for branch preview packages)
|
|
150
152
|
- Standalone binary for use outside of JS projects
|
|
151
153
|
- Better support for versioning non-JS packages and usage without package.json files
|
|
152
154
|
- Plugin system for different publish targets, and support multiple targets per package
|
package/config-schema.json
CHANGED
|
@@ -202,6 +202,49 @@
|
|
|
202
202
|
}
|
|
203
203
|
},
|
|
204
204
|
"additionalProperties": false
|
|
205
|
+
},
|
|
206
|
+
"channels": {
|
|
207
|
+
"type": "object",
|
|
208
|
+
"description": "Prerelease channels, keyed by channel name. Each maps a long-lived branch to a prerelease line (version suffix + npm dist-tag). Prerelease versions are derived at publish time and never committed.",
|
|
209
|
+
"additionalProperties": {
|
|
210
|
+
"type": "object",
|
|
211
|
+
"properties": {
|
|
212
|
+
"branch": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"description": "Branch that triggers this channel (required)"
|
|
215
|
+
},
|
|
216
|
+
"preid": {
|
|
217
|
+
"type": "string",
|
|
218
|
+
"description": "Version suffix (preid), e.g. \"rc\" produces 1.2.0-rc.0. Defaults to the channel name."
|
|
219
|
+
},
|
|
220
|
+
"tag": {
|
|
221
|
+
"type": "string",
|
|
222
|
+
"description": "npm dist-tag for publishes. Defaults to the channel name."
|
|
223
|
+
},
|
|
224
|
+
"versionPr": {
|
|
225
|
+
"type": "object",
|
|
226
|
+
"description": "Release PR overrides for this channel",
|
|
227
|
+
"properties": {
|
|
228
|
+
"title": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"description": "Release PR title. Defaults to \"<base title> (<channel name>)\"."
|
|
231
|
+
},
|
|
232
|
+
"branch": {
|
|
233
|
+
"type": "string",
|
|
234
|
+
"description": "Release PR branch. Defaults to \"<base branch>-<channel name>\"."
|
|
235
|
+
},
|
|
236
|
+
"automerge": {
|
|
237
|
+
"type": "boolean",
|
|
238
|
+
"description": "Enable auto-merge on the release PR",
|
|
239
|
+
"default": false
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
"additionalProperties": false
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
"required": ["branch"],
|
|
246
|
+
"additionalProperties": false
|
|
247
|
+
}
|
|
205
248
|
}
|
|
206
249
|
},
|
|
207
250
|
"additionalProperties": false,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { n as log, r as require_picocolors, s as __toESM } from "./logger-BgksGFuf.mjs";
|
|
2
2
|
import { n as exists, t as ensureDir } from "./fs-CBXKZhoU.mjs";
|
|
3
|
-
import { a as loadConfig, r as getBumpyDir } from "./config-
|
|
4
|
-
import {
|
|
5
|
-
import { a as getChangedFiles } from "./git-
|
|
3
|
+
import { a as loadConfig, r as getBumpyDir } from "./config-0we4ISZX.mjs";
|
|
4
|
+
import { c as discoverWorkspace, i as readBumpFiles, o as writeBumpFile, t as filterBranchBumpFiles } from "./bump-file-mRJeReRJ.mjs";
|
|
5
|
+
import { a as getChangedFiles } from "./git-DAWj8LyV.mjs";
|
|
6
6
|
import { l as pt, o as gt, r as Ot, s as mt, t as unwrap, u as wt } from "./clack-W95rXis0.mjs";
|
|
7
7
|
import { n as slugify, t as randomName } from "./names-COooXAFg.mjs";
|
|
8
|
-
import { n as findChangedPackages } from "./check-
|
|
8
|
+
import { n as findChangedPackages } from "./check-DIl9Dz68.mjs";
|
|
9
9
|
import { resolve } from "node:path";
|
|
10
10
|
import * as readline from "node:readline";
|
|
11
11
|
//#region src/prompts/bump-select.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as readJson, c as removeFile, f as writeText, i as listFiles, l as updateJsonFields, n as exists, s as readText, u as updateJsonNestedField } from "./fs-CBXKZhoU.mjs";
|
|
2
|
-
import { r as getBumpyDir } from "./config-
|
|
3
|
-
import { a as prependToChangelog, i as loadFormatter, n as generateChangelogEntry } from "./changelog-
|
|
2
|
+
import { r as getBumpyDir } from "./config-0we4ISZX.mjs";
|
|
3
|
+
import { a as prependToChangelog, i as loadFormatter, n as generateChangelogEntry } from "./changelog-DuFhnJRO.mjs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
//#region src/core/apply-release-plan.ts
|
|
6
6
|
/** Apply the release plan: bump versions, update changelogs, delete bump files */
|
|
@@ -39,6 +39,15 @@ async function applyReleasePlan(releasePlan, packages, rootDir, config) {
|
|
|
39
39
|
if (file === "README.md") continue;
|
|
40
40
|
await removeFile(resolve(bumpyDir, file));
|
|
41
41
|
}
|
|
42
|
+
const { rmdir } = await import("node:fs/promises");
|
|
43
|
+
for (const channel of Object.keys(config.channels || {})) {
|
|
44
|
+
const channelDir = resolve(bumpyDir, channel);
|
|
45
|
+
const channelFiles = await listFiles(channelDir, ".md");
|
|
46
|
+
for (const file of channelFiles) await removeFile(resolve(channelDir, file));
|
|
47
|
+
try {
|
|
48
|
+
await rmdir(channelDir);
|
|
49
|
+
} catch {}
|
|
50
|
+
}
|
|
42
51
|
}
|
|
43
52
|
/** Update a version range to include a new version, preserving the range prefix */
|
|
44
53
|
function updateRange(range, newVersion) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as readJson, f as writeText, i as listFiles, n as exists, s as readText } from "./fs-CBXKZhoU.mjs";
|
|
2
|
-
import { i as isPackageManaged, o as loadPackageConfig, r as getBumpyDir } from "./config-
|
|
2
|
+
import { i as isPackageManaged, o as loadPackageConfig, r as getBumpyDir } from "./config-0we4ISZX.mjs";
|
|
3
3
|
import { c as jsYaml, r as detectWorkspaces } from "./package-manager-Db_vTztt.mjs";
|
|
4
4
|
import { s as tryRunArgs } from "./shell-C8KgKnMQ.mjs";
|
|
5
5
|
import { relative, resolve } from "node:path";
|
|
@@ -128,18 +128,38 @@ function validatePackageName(name) {
|
|
|
128
128
|
if (name.startsWith("-")) return false;
|
|
129
129
|
return true;
|
|
130
130
|
}
|
|
131
|
-
/** Read all bump files from .bumpy/
|
|
132
|
-
async function readBumpFiles(rootDir) {
|
|
131
|
+
/** Read all bump files from .bumpy/ (and optionally channel subdirs), sorted by git creation order */
|
|
132
|
+
async function readBumpFiles(rootDir, opts = {}) {
|
|
133
133
|
const dir = getBumpyDir(rootDir);
|
|
134
|
-
const files = await listFiles(dir, ".md");
|
|
135
134
|
const bumpFiles = [];
|
|
136
135
|
const errors = [];
|
|
136
|
+
const files = await listFiles(dir, ".md");
|
|
137
137
|
for (const file of files) {
|
|
138
138
|
if (file === "README.md") continue;
|
|
139
139
|
const result = await parseBumpFileFromPath(resolve(dir, file));
|
|
140
140
|
if (result.bumpFile) bumpFiles.push(result.bumpFile);
|
|
141
141
|
errors.push(...result.errors);
|
|
142
142
|
}
|
|
143
|
+
for (const channel of opts.channels ?? []) {
|
|
144
|
+
const channelDir = resolve(dir, channel);
|
|
145
|
+
const channelFiles = await listFiles(channelDir, ".md");
|
|
146
|
+
for (const file of channelFiles) {
|
|
147
|
+
if (file === "README.md") continue;
|
|
148
|
+
const result = await parseBumpFileFromPath(resolve(channelDir, file));
|
|
149
|
+
if (result.bumpFile) {
|
|
150
|
+
const duplicate = bumpFiles.find((bf) => bf.id === result.bumpFile.id);
|
|
151
|
+
if (duplicate) {
|
|
152
|
+
errors.push(`Bump file "${result.bumpFile.id}" exists both ${duplicate.channel ? `in .bumpy/${duplicate.channel}/` : "at .bumpy/ root"} and in .bumpy/${channel}/ — remove one copy (the change likely already shipped on one of them).`);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
bumpFiles.push({
|
|
156
|
+
...result.bumpFile,
|
|
157
|
+
channel
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
errors.push(...result.errors);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
143
163
|
const creationOrder = getBumpFileCreationOrder(rootDir);
|
|
144
164
|
if (creationOrder.size > 0) bumpFiles.sort((a, b) => {
|
|
145
165
|
return (creationOrder.get(a.id) ?? Infinity) - (creationOrder.get(b.id) ?? Infinity) || a.id.localeCompare(b.id);
|
|
@@ -171,7 +191,7 @@ function getBumpFileCreationOrder(rootDir) {
|
|
|
171
191
|
if (!trimmed) continue;
|
|
172
192
|
if (/^\d+$/.test(trimmed)) currentTimestamp = parseInt(trimmed, 10);
|
|
173
193
|
else if (trimmed.startsWith(".bumpy/") && trimmed.endsWith(".md")) {
|
|
174
|
-
const id = trimmed
|
|
194
|
+
const id = fileToId(trimmed);
|
|
175
195
|
order.set(id, currentTimestamp);
|
|
176
196
|
}
|
|
177
197
|
}
|
|
@@ -298,11 +318,26 @@ function recoverDeletedBumpFiles(rootDir) {
|
|
|
298
318
|
`HEAD~1:${filePath}`
|
|
299
319
|
], { cwd: rootDir });
|
|
300
320
|
if (!content) continue;
|
|
301
|
-
const { bumpFile } = parseBumpFile(content, filePath
|
|
321
|
+
const { bumpFile } = parseBumpFile(content, fileToId(filePath));
|
|
302
322
|
if (bumpFile) bumpFiles.push(bumpFile);
|
|
303
323
|
}
|
|
304
324
|
return bumpFiles;
|
|
305
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Move bump files into a channel's shipped directory (`.bumpy/<channel>/`).
|
|
328
|
+
* This is the only thing a channel "version" does — prerelease versions are
|
|
329
|
+
* never written to git. Files already in the target channel dir are left alone.
|
|
330
|
+
*/
|
|
331
|
+
async function moveBumpFilesToChannel(rootDir, bumpFiles, channel) {
|
|
332
|
+
const { rename, mkdir } = await import("node:fs/promises");
|
|
333
|
+
const dir = getBumpyDir(rootDir);
|
|
334
|
+
const channelDir = resolve(dir, channel);
|
|
335
|
+
await mkdir(channelDir, { recursive: true });
|
|
336
|
+
for (const bf of bumpFiles) {
|
|
337
|
+
if (bf.channel === channel) continue;
|
|
338
|
+
await rename(bf.channel ? resolve(dir, bf.channel, `${bf.id}.md`) : resolve(dir, `${bf.id}.md`), resolve(channelDir, `${bf.id}.md`));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
306
341
|
function fileToId(filePath) {
|
|
307
342
|
return filePath.split("/").pop().replace(/\.md$/, "");
|
|
308
343
|
}
|
|
@@ -311,7 +346,7 @@ function fileToId(filePath) {
|
|
|
311
346
|
* of bump files that were added/modified. Shared by `check` and `ci check`.
|
|
312
347
|
*/
|
|
313
348
|
function extractBumpFileIdsFromChangedFiles(changedFiles) {
|
|
314
|
-
return new Set(changedFiles.filter((f) => /^\.bumpy\/.*\.md$/.test(f) && !f.endsWith("README.md")).map(
|
|
349
|
+
return new Set(changedFiles.filter((f) => /^\.bumpy\/.*\.md$/.test(f) && !f.endsWith("README.md")).map(fileToId));
|
|
315
350
|
}
|
|
316
351
|
/**
|
|
317
352
|
* Filter bump files to only those added/modified on the current branch.
|
|
@@ -340,4 +375,4 @@ function filterBranchBumpFiles(allBumpFiles, changedFiles, rootDir, parseErrors
|
|
|
340
375
|
};
|
|
341
376
|
}
|
|
342
377
|
//#endregion
|
|
343
|
-
export {
|
|
378
|
+
export { recoverDeletedBumpFiles as a, discoverWorkspace as c, readBumpFiles as i, moveBumpFilesToChannel as n, writeBumpFile as o, parseBumpFile as r, discoverPackages as s, filterBranchBumpFiles as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as log } from "./logger-BgksGFuf.mjs";
|
|
2
|
-
import { c as maxBump, t as BUMP_LEVELS } from "./types-
|
|
2
|
+
import { c as maxBump, t as BUMP_LEVELS } from "./types-lpiG-Zxh.mjs";
|
|
3
3
|
import { relative, resolve } from "node:path";
|
|
4
4
|
import { realpathSync } from "node:fs";
|
|
5
5
|
//#region src/core/changelog.ts
|
|
@@ -44,7 +44,7 @@ const defaultFormatter = (ctx) => {
|
|
|
44
44
|
const BUILTIN_FORMATTERS = {
|
|
45
45
|
default: defaultFormatter,
|
|
46
46
|
github: async () => {
|
|
47
|
-
const { createGithubFormatter } = await import("./changelog-github-
|
|
47
|
+
const { createGithubFormatter } = await import("./changelog-github-jLOtwuWj.mjs");
|
|
48
48
|
return createGithubFormatter();
|
|
49
49
|
}
|
|
50
50
|
};
|
|
@@ -55,7 +55,7 @@ const BUILTIN_FORMATTERS = {
|
|
|
55
55
|
async function loadFormatter(changelog, rootDir) {
|
|
56
56
|
const [name, options] = Array.isArray(changelog) ? changelog : [changelog, {}];
|
|
57
57
|
if (name === "github") {
|
|
58
|
-
const { createGithubFormatter } = await import("./changelog-github-
|
|
58
|
+
const { createGithubFormatter } = await import("./changelog-github-jLOtwuWj.mjs");
|
|
59
59
|
return createGithubFormatter(options);
|
|
60
60
|
}
|
|
61
61
|
if (typeof name === "string" && BUILTIN_FORMATTERS[name]) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as maxBump } from "./types-
|
|
1
|
+
import { c as maxBump } from "./types-lpiG-Zxh.mjs";
|
|
2
2
|
import { s as tryRunArgs } from "./shell-C8KgKnMQ.mjs";
|
|
3
|
-
import { o as sortBumpFilesByType, r as getBumpTypeForPackage } from "./changelog-
|
|
3
|
+
import { o as sortBumpFilesByType, r as getBumpTypeForPackage } from "./changelog-DuFhnJRO.mjs";
|
|
4
4
|
//#region src/core/changelog-github.ts
|
|
5
5
|
/** Authors filtered from "Thanks" attribution by default (e.g. bots) */
|
|
6
6
|
/** Authors filtered from "Thanks" attribution by default (e.g. AI/automation bots) */
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import "./config-0we4ISZX.mjs";
|
|
2
|
+
import { o as getCurrentBranch } from "./git-DAWj8LyV.mjs";
|
|
3
|
+
import "node:path";
|
|
4
|
+
//#region src/core/channels.ts
|
|
5
|
+
/** Channel names that would collide with reserved `.bumpy/` entries */
|
|
6
|
+
const RESERVED_CHANNEL_NAMES = new Set(["README", "README.md"]);
|
|
7
|
+
/**
|
|
8
|
+
* Resolve all configured channels, applying defaults and validating names.
|
|
9
|
+
* Defaults: preid/tag = channel name; versionPr.title = "<base-title> (<name>)";
|
|
10
|
+
* versionPr.branch = "<base-branch>-<name>".
|
|
11
|
+
*/
|
|
12
|
+
function resolveChannels(config) {
|
|
13
|
+
const channels = /* @__PURE__ */ new Map();
|
|
14
|
+
const seenBranches = /* @__PURE__ */ new Map();
|
|
15
|
+
for (const [name, raw] of Object.entries(config.channels || {})) {
|
|
16
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(name) || name.startsWith("_") || RESERVED_CHANNEL_NAMES.has(name)) throw new Error(`Invalid channel name "${name}" — channel names become .bumpy/ subdirectories and must be alphanumeric (plus ".", "-", "_"), not start with "_", and not collide with reserved entries.`);
|
|
17
|
+
if (!raw.branch || typeof raw.branch !== "string") throw new Error(`Channel "${name}" is missing required "branch" field`);
|
|
18
|
+
if (raw.branch === config.baseBranch) throw new Error(`Channel "${name}" cannot use the base branch ("${config.baseBranch}") as its channel branch`);
|
|
19
|
+
const existing = seenBranches.get(raw.branch);
|
|
20
|
+
if (existing) throw new Error(`Channels "${existing}" and "${name}" both use branch "${raw.branch}"`);
|
|
21
|
+
seenBranches.set(raw.branch, name);
|
|
22
|
+
channels.set(name, {
|
|
23
|
+
name,
|
|
24
|
+
branch: raw.branch,
|
|
25
|
+
preid: raw.preid ?? name,
|
|
26
|
+
tag: raw.tag ?? name,
|
|
27
|
+
versionPr: {
|
|
28
|
+
title: raw.versionPr?.title ?? `${config.versionPr.title} (${name})`,
|
|
29
|
+
branch: raw.versionPr?.branch ?? `${config.versionPr.branch}-${name}`,
|
|
30
|
+
automerge: raw.versionPr?.automerge ?? false
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return channels;
|
|
35
|
+
}
|
|
36
|
+
/** Names of all configured channels (used as `.bumpy/` subdirectory names) */
|
|
37
|
+
function channelNames(config) {
|
|
38
|
+
return Object.keys(config.channels || {});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detect the branch the release flow is running for.
|
|
42
|
+
* In GitHub Actions push events, HEAD is often detached — prefer GITHUB_REF_NAME.
|
|
43
|
+
*/
|
|
44
|
+
function detectReleaseBranch(rootDir) {
|
|
45
|
+
const refName = process.env.GITHUB_REF_NAME;
|
|
46
|
+
const refType = process.env.GITHUB_REF_TYPE;
|
|
47
|
+
if (refName && refType !== "tag") return refName;
|
|
48
|
+
const branch = getCurrentBranch({ cwd: rootDir });
|
|
49
|
+
if (!branch || branch === "HEAD") return null;
|
|
50
|
+
return branch;
|
|
51
|
+
}
|
|
52
|
+
/** Find the channel matching a branch name, if any */
|
|
53
|
+
function matchChannelByBranch(config, branch) {
|
|
54
|
+
if (!branch) return null;
|
|
55
|
+
for (const channel of resolveChannels(config).values()) if (channel.branch === branch) return channel;
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the active channel for a command:
|
|
60
|
+
* an explicit `--channel <name>` override wins, otherwise the current branch is matched.
|
|
61
|
+
* Throws if an explicit override names an unknown channel.
|
|
62
|
+
*/
|
|
63
|
+
function resolveActiveChannel(rootDir, config, override) {
|
|
64
|
+
if (override) {
|
|
65
|
+
const channel = resolveChannels(config).get(override);
|
|
66
|
+
if (!channel) {
|
|
67
|
+
const known = channelNames(config);
|
|
68
|
+
throw new Error(`Unknown channel "${override}"${known.length ? ` — configured channels: ${known.join(", ")}` : " — no channels are configured in .bumpy/_config.json"}`);
|
|
69
|
+
}
|
|
70
|
+
return channel;
|
|
71
|
+
}
|
|
72
|
+
return matchChannelByBranch(config, detectReleaseBranch(rootDir));
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { channelNames, detectReleaseBranch, matchChannelByBranch, resolveActiveChannel, resolveChannels };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { a as __exportAll, i as __commonJSMin, n as log, s as __toESM, t as colorize } from "./logger-BgksGFuf.mjs";
|
|
2
2
|
import { n as exists, s as readText } from "./fs-CBXKZhoU.mjs";
|
|
3
|
-
import { a as DEP_TYPES } from "./types-
|
|
4
|
-
import { a as loadConfig, o as loadPackageConfig, r as getBumpyDir } from "./config-
|
|
3
|
+
import { a as DEP_TYPES } from "./types-lpiG-Zxh.mjs";
|
|
4
|
+
import { a as loadConfig, o as loadPackageConfig, r as getBumpyDir } from "./config-0we4ISZX.mjs";
|
|
5
5
|
import { a as isCatalogRefAffected, i as diffCatalogMaps, n as detectPackageManager, o as parseCatalogs, t as CATALOG_FILES } from "./package-manager-Db_vTztt.mjs";
|
|
6
|
-
import {
|
|
7
|
-
import { a as getChangedFiles,
|
|
6
|
+
import { c as discoverWorkspace, i as readBumpFiles, t as filterBranchBumpFiles } from "./bump-file-mRJeReRJ.mjs";
|
|
7
|
+
import { a as getChangedFiles, d as readFileAtRef, r as getBaseCompareRef, s as getFileStatuses } from "./git-DAWj8LyV.mjs";
|
|
8
8
|
import { relative, resolve } from "node:path";
|
|
9
9
|
//#region ../../node_modules/.bun/picomatch@4.0.4/node_modules/picomatch/lib/constants.js
|
|
10
10
|
var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -1894,8 +1894,20 @@ var import_picomatch = /* @__PURE__ */ __toESM(require_picomatch(), 1);
|
|
|
1894
1894
|
async function checkCommand(rootDir, opts = {}) {
|
|
1895
1895
|
const config = await loadConfig(rootDir);
|
|
1896
1896
|
const { packages } = await discoverWorkspace(rootDir, config);
|
|
1897
|
-
const
|
|
1898
|
-
const
|
|
1897
|
+
const { resolveChannels, detectReleaseBranch } = await import("./channels-CFXZkyGd.mjs");
|
|
1898
|
+
const currentBranch = detectReleaseBranch(rootDir);
|
|
1899
|
+
if (currentBranch) {
|
|
1900
|
+
const skipBranches = new Set([config.versionPr.branch]);
|
|
1901
|
+
for (const channel of resolveChannels(config).values()) {
|
|
1902
|
+
skipBranches.add(channel.branch);
|
|
1903
|
+
skipBranches.add(channel.versionPr.branch);
|
|
1904
|
+
}
|
|
1905
|
+
if (skipBranches.has(currentBranch)) {
|
|
1906
|
+
log.dim(` Skipping check — "${currentBranch}" is a channel or release PR branch.`);
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
const changedFiles = getChangedFiles(rootDir, opts.base || config.baseBranch);
|
|
1899
1911
|
if (changedFiles.length === 0) {
|
|
1900
1912
|
log.info("No changed files detected.");
|
|
1901
1913
|
return;
|