@tablation/crew 0.19.0 → 0.19.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 +54 -9
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2735,7 +2735,20 @@ function patchIdOf(cwd, from, to) {
|
|
|
2735
2735
|
return null;
|
|
2736
2736
|
}
|
|
2737
2737
|
}
|
|
2738
|
+
var BRANCH_TIP_TRAILER = "Branch-tip";
|
|
2739
|
+
function findSquashByBranchTip(cwd, key, branch, range) {
|
|
2740
|
+
const tip = gitOk(cwd, ["rev-parse", "--verify", "-q", `${branch}^{commit}`]);
|
|
2741
|
+
if (!tip) return null;
|
|
2742
|
+
const wanted = `${BRANCH_TIP_TRAILER}: ${tip}`;
|
|
2743
|
+
for (const sha of keyCommitsInRange(cwd, key, range)) {
|
|
2744
|
+
const body = gitOk(cwd, ["show", "-s", "--format=%B", sha]) ?? "";
|
|
2745
|
+
if (body.split("\n").some((l) => l.trim() === wanted)) return sha;
|
|
2746
|
+
}
|
|
2747
|
+
return null;
|
|
2748
|
+
}
|
|
2738
2749
|
function findSquashOfBranch(cwd, key, branch, base, range) {
|
|
2750
|
+
const byTip = findSquashByBranchTip(cwd, key, branch, range);
|
|
2751
|
+
if (byTip) return byTip;
|
|
2739
2752
|
const candidates = keyCommitsInRange(cwd, key, range);
|
|
2740
2753
|
if (candidates.length === 0) return null;
|
|
2741
2754
|
const mb = gitOk(cwd, ["merge-base", base, branch]);
|
|
@@ -6478,14 +6491,9 @@ function planMerge(cwd, tickets, contract, lastReleased, branchFor = (t) => bran
|
|
|
6478
6491
|
skipReason: "never-built"
|
|
6479
6492
|
};
|
|
6480
6493
|
}
|
|
6481
|
-
const squash = findSquashOfBranch(
|
|
6482
|
-
cwd,
|
|
6483
|
-
referenceKeys(ticket),
|
|
6484
|
-
branch,
|
|
6485
|
-
base,
|
|
6486
|
-
lastReleased ? `${lastReleased}..${base}` : base
|
|
6487
|
-
);
|
|
6494
|
+
const squash = findSquashOfBranch(cwd, referenceKeys(ticket), branch, base, base);
|
|
6488
6495
|
if (squash) {
|
|
6496
|
+
const released = !!lastReleased && isAncestor(cwd, squash, lastReleased);
|
|
6489
6497
|
return {
|
|
6490
6498
|
ticket,
|
|
6491
6499
|
branch,
|
|
@@ -6493,7 +6501,7 @@ function planMerge(cwd, tickets, contract, lastReleased, branchFor = (t) => bran
|
|
|
6493
6501
|
usedFallback: false,
|
|
6494
6502
|
bump: "patch",
|
|
6495
6503
|
majorRequested: false,
|
|
6496
|
-
skipReason: "already-merged",
|
|
6504
|
+
skipReason: released ? "already-released" : "already-merged",
|
|
6497
6505
|
mergedSha: squash
|
|
6498
6506
|
};
|
|
6499
6507
|
}
|
|
@@ -6511,6 +6519,20 @@ function planMerge(cwd, tickets, contract, lastReleased, branchFor = (t) => bran
|
|
|
6511
6519
|
};
|
|
6512
6520
|
});
|
|
6513
6521
|
}
|
|
6522
|
+
function planReleasedBranches(cwd, tickets, contract, branchFor, base = "main", tagPattern = "v*") {
|
|
6523
|
+
const eligible = /* @__PURE__ */ new Set([contract.statuses.building, contract.statuses.needsHuman]);
|
|
6524
|
+
const out = [];
|
|
6525
|
+
for (const ticket of tickets) {
|
|
6526
|
+
if (!eligible.has(ticket.status)) continue;
|
|
6527
|
+
const branch = branchFor(ticket);
|
|
6528
|
+
if (!branch) continue;
|
|
6529
|
+
const sha = findSquashByBranchTip(cwd, referenceKeys(ticket), branch, base);
|
|
6530
|
+
if (!sha) continue;
|
|
6531
|
+
const tag = firstReleaseTagContaining(cwd, sha, tagPattern);
|
|
6532
|
+
if (tag) out.push({ ticket, sha, tag });
|
|
6533
|
+
}
|
|
6534
|
+
return out;
|
|
6535
|
+
}
|
|
6514
6536
|
function requestedBump(bodies) {
|
|
6515
6537
|
const asks = [...bodies.matchAll(BUMP_LINE)].map((m) => m[1].toLowerCase());
|
|
6516
6538
|
const majorRequested = asks.includes("major");
|
|
@@ -6973,9 +6995,13 @@ function mergeOne(o, c) {
|
|
|
6973
6995
|
);
|
|
6974
6996
|
return "noop";
|
|
6975
6997
|
}
|
|
6998
|
+
const tip = gitOk(o.cwd, ["rev-parse", "--verify", "-q", `${c.branch}^{commit}`]);
|
|
6999
|
+
const trailer = tip ? `
|
|
7000
|
+
|
|
7001
|
+
${BRANCH_TIP_TRAILER}: ${tip}` : "";
|
|
6976
7002
|
git(o.cwd, ["commit", "-m", `${subject}
|
|
6977
7003
|
|
|
6978
|
-
Closes ${c.ticket.issue_id}
|
|
7004
|
+
Closes ${c.ticket.issue_id}.${trailer}`]);
|
|
6979
7005
|
const sha = headSha(o.cwd);
|
|
6980
7006
|
o.emit.emit(`merged ${c.branch}`, { ticket: c.ticket.issue_id });
|
|
6981
7007
|
return { applied: true, sha };
|
|
@@ -10990,6 +11016,25 @@ ${changed2.map((c) => ` - ${c}
|
|
|
10990
11016
|
target.dir
|
|
10991
11017
|
);
|
|
10992
11018
|
}
|
|
11019
|
+
for (const r of planReleasedBranches(
|
|
11020
|
+
target.dir,
|
|
11021
|
+
tickets,
|
|
11022
|
+
tracker.contract,
|
|
11023
|
+
(t) => locateBranchForTicket(target.dir, repo, t)?.branch ?? null,
|
|
11024
|
+
repo.branch.base,
|
|
11025
|
+
repo.release.tagPattern ?? "v*"
|
|
11026
|
+
)) {
|
|
11027
|
+
remit.enter("reconcile");
|
|
11028
|
+
await applyStamp(
|
|
11029
|
+
tracker,
|
|
11030
|
+
[{ ticket: r.ticket, reason: `branch already released in ${r.tag}`, sha: r.sha }],
|
|
11031
|
+
r.tag.replace(/^v/, ""),
|
|
11032
|
+
tracker.contract,
|
|
11033
|
+
remit,
|
|
11034
|
+
dryRun,
|
|
11035
|
+
target.dir
|
|
11036
|
+
);
|
|
11037
|
+
}
|
|
10993
11038
|
if (outcome.gateRed && !dryRun) {
|
|
10994
11039
|
try {
|
|
10995
11040
|
const g = outcome.gateRed;
|
package/package.json
CHANGED