@tablation/crew 0.79.0 → 0.79.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/dist/cli.js +27 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11388,14 +11388,14 @@ function dedupeChangelogEntries(entries, ticket) {
|
|
|
11388
11388
|
return out;
|
|
11389
11389
|
}
|
|
11390
11390
|
var BUMP_LINE = /^Bump:[ \t]*(major|minor|patch)\b/gim;
|
|
11391
|
-
function planMerge(cwd, tickets, contract, lastReleased, branchFor = (t) => branchForIssue(cwd, t.issue_id), base = "main", blockerInfo) {
|
|
11391
|
+
function planMerge(cwd, tickets, contract, lastReleased, branchFor = (t) => branchForIssue(cwd, t.issue_id), base = "main", blockerInfo, ref = "HEAD") {
|
|
11392
11392
|
const held = new Set(heldByBlockers(tickets, contract.statuses.verified, blockerInfo).map((h) => h.ticket.id));
|
|
11393
11393
|
const verified = tickets.filter((t) => t.status === contract.statuses.verified && !held.has(t.id)).sort((a, b) => Number.parseInt(a.issue_id.replace(/^\D+/, ""), 10) - Number.parseInt(b.issue_id.replace(/^\D+/, ""), 10));
|
|
11394
11394
|
return verified.map((ticket) => {
|
|
11395
11395
|
const branch = branchFor(ticket);
|
|
11396
11396
|
if (!branch) {
|
|
11397
11397
|
const keys = referenceKeys(ticket);
|
|
11398
|
-
const unreleased = lastReleased ? findKeyInRange(cwd, keys, `${lastReleased}
|
|
11398
|
+
const unreleased = lastReleased ? findKeyInRange(cwd, keys, `${lastReleased}..${ref}`) : null;
|
|
11399
11399
|
if (unreleased) {
|
|
11400
11400
|
return {
|
|
11401
11401
|
ticket,
|
|
@@ -11407,7 +11407,7 @@ function planMerge(cwd, tickets, contract, lastReleased, branchFor = (t) => bran
|
|
|
11407
11407
|
skipReason: "already-merged"
|
|
11408
11408
|
};
|
|
11409
11409
|
}
|
|
11410
|
-
const anywhere = findKeyInRange(cwd, keys,
|
|
11410
|
+
const anywhere = findKeyInRange(cwd, keys, ref);
|
|
11411
11411
|
if (anywhere) {
|
|
11412
11412
|
return {
|
|
11413
11413
|
ticket,
|
|
@@ -11504,21 +11504,22 @@ ${section}`;
|
|
|
11504
11504
|
return [...lines.slice(0, anchor), section, ...lines.slice(anchor)].join("\n");
|
|
11505
11505
|
}
|
|
11506
11506
|
var RELEASE_COMMIT_SUBJECT = /^Release \S+$/;
|
|
11507
|
-
function subjectsSince(cwd, sha) {
|
|
11508
|
-
if (!isAncestor(cwd, sha,
|
|
11509
|
-
return (gitOk(cwd, ["log", "--format=%h %s", `${sha}
|
|
11507
|
+
function subjectsSince(cwd, sha, ref = "HEAD") {
|
|
11508
|
+
if (!isAncestor(cwd, sha, ref)) return null;
|
|
11509
|
+
return (gitOk(cwd, ["log", "--format=%h %s", `${sha}..${ref}`]) ?? "").split("\n").filter(Boolean);
|
|
11510
11510
|
}
|
|
11511
11511
|
var isReleaseCommitLine = (line) => RELEASE_COMMIT_SUBJECT.test(line.replace(/^\S+ /, ""));
|
|
11512
11512
|
function decideRelease(cwd, tickets, contract, opts = {}) {
|
|
11513
11513
|
const pattern = opts.tagPattern ?? "v*";
|
|
11514
11514
|
const base = opts.base ?? "main";
|
|
11515
|
-
const
|
|
11516
|
-
const
|
|
11515
|
+
const ref = opts.ref ?? "HEAD";
|
|
11516
|
+
const block = opts.guard === false ? null : checkGuards(cwd, base);
|
|
11517
|
+
const lastTag = latestReleaseTag(cwd, pattern, ref);
|
|
11517
11518
|
const lastReleased = lastTag ? tagCommit(cwd, lastTag) : null;
|
|
11518
|
-
const head = resolve2(cwd,
|
|
11519
|
-
const merges = block ? [] : planMerge(cwd, tickets, contract, lastReleased, opts.branchFor ?? ((t) => branchForIssue(cwd, t.issue_id)), base, opts.blockerInfo);
|
|
11520
|
-
const unreleasedCommits = lastReleased ? countCommits(cwd, `${lastReleased}
|
|
11521
|
-
const unreleasedWork = lastReleased ? (gitOk(cwd, ["log", "--format=%s", `${lastReleased}
|
|
11519
|
+
const head = resolve2(cwd, ref) ?? "";
|
|
11520
|
+
const merges = block ? [] : planMerge(cwd, tickets, contract, lastReleased, opts.branchFor ?? ((t) => branchForIssue(cwd, t.issue_id)), opts.ref ?? base, opts.blockerInfo, ref);
|
|
11521
|
+
const unreleasedCommits = lastReleased ? countCommits(cwd, `${lastReleased}..${ref}`) : 0;
|
|
11522
|
+
const unreleasedWork = lastReleased ? (gitOk(cwd, ["log", "--format=%s", `${lastReleased}..${ref}`]) ?? "").split("\n").filter((l) => l && !RELEASE_COMMIT_SUBJECT.test(l)).length : 0;
|
|
11522
11523
|
return {
|
|
11523
11524
|
block,
|
|
11524
11525
|
merges,
|
|
@@ -12233,10 +12234,14 @@ async function runReleaseCycle(o, movedPast2, localRefSkips) {
|
|
|
12233
12234
|
}
|
|
12234
12235
|
if (drop.size) releasable = releasable.filter((t) => !drop.has(t.id));
|
|
12235
12236
|
}
|
|
12237
|
+
const { remote, base } = o.repo.branch;
|
|
12238
|
+
const inPlace = o.dryRun || !!o.mergeOnly || !remoteBranchExists(o.cwd, remote, base);
|
|
12239
|
+
const remoteRef = `${remote}/${base}`;
|
|
12236
12240
|
const decision = decideRelease(o.cwd, releasable, o.contract, {
|
|
12237
12241
|
tagPattern,
|
|
12238
|
-
base
|
|
12242
|
+
base,
|
|
12239
12243
|
blockerInfo: o.blockerInfo,
|
|
12244
|
+
...inPlace ? {} : { ref: remoteRef, guard: false },
|
|
12240
12245
|
// CREW-1364: a branch another ship built and pushed at `fixed` exists
|
|
12241
12246
|
// here only on the remote. Materialize it so the squash below has a ref.
|
|
12242
12247
|
// A dry run only looks.
|
|
@@ -12265,7 +12270,7 @@ async function runReleaseCycle(o, movedPast2, localRefSkips) {
|
|
|
12265
12270
|
o.state?.clearBlocked();
|
|
12266
12271
|
const failedAt = o.state?.deployFailedSha();
|
|
12267
12272
|
if (!o.force && failedAt) {
|
|
12268
|
-
const since2 = failedAt === decision.head ? [] : subjectsSince(o.cwd, failedAt);
|
|
12273
|
+
const since2 = failedAt === decision.head ? [] : subjectsSince(o.cwd, failedAt, inPlace ? "HEAD" : remoteRef);
|
|
12269
12274
|
const real = since2?.filter((l) => !isReleaseCommitLine(l)) ?? null;
|
|
12270
12275
|
if (real && real.length === 0) {
|
|
12271
12276
|
o.emit.warn(
|
|
@@ -12292,10 +12297,13 @@ async function runReleaseCycle(o, movedPast2, localRefSkips) {
|
|
|
12292
12297
|
const review = await reviewHandoff(o, externalClosures, decision.merges, reviewing);
|
|
12293
12298
|
return { merged: [], deployed: false, stopped: "external", decision, externalClosures, review };
|
|
12294
12299
|
}
|
|
12295
|
-
|
|
12296
|
-
if (o.dryRun || o.mergeOnly || !remoteBranchExists(o.cwd, remote, base)) {
|
|
12300
|
+
if (inPlace) {
|
|
12297
12301
|
return mergeAndRelease(o, decision, fresh);
|
|
12298
12302
|
}
|
|
12303
|
+
const primary = checkGuards(o.cwd, base);
|
|
12304
|
+
if (primary) {
|
|
12305
|
+
o.emit.emit(scoped(`primary checkout not fast-forwarded: ${primary.detail}; its dist/ is stale until rebuilt`), { step: "release" });
|
|
12306
|
+
}
|
|
12299
12307
|
let checkout;
|
|
12300
12308
|
const stranded = recoverStrandedReleaseCheckouts(o.cwd);
|
|
12301
12309
|
if (stranded.length > 0) o.emit.warn(scoped(`dropped release checkout(s) stranded by a crash: ${stranded.join(", ")}`));
|
|
@@ -17952,9 +17960,11 @@ ${changed2.map((c) => ` - ${c}
|
|
|
17952
17960
|
preModes
|
|
17953
17961
|
);
|
|
17954
17962
|
reportUnplaceable(c.route, preUnplaceable, tracker.contract.statuses.verified, remit);
|
|
17963
|
+
const remoteBase = remoteBranchExists(target.dir, repo.branch.remote, repo.branch.base);
|
|
17955
17964
|
const d = decideRelease(target.dir, pre, tracker.contract, {
|
|
17956
17965
|
tagPattern: repo.release.tagPattern ?? "v*",
|
|
17957
|
-
base: repo.branch.base
|
|
17966
|
+
base: repo.branch.base,
|
|
17967
|
+
...remoteBase ? { ref: `${repo.branch.remote}/${repo.branch.base}`, guard: false } : {}
|
|
17958
17968
|
});
|
|
17959
17969
|
const unstamped = planReleasedBranches(
|
|
17960
17970
|
target.dir,
|
package/package.json
CHANGED