mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
infra(process): fast-forward merge rebuilds the review index too (#657 r1 H1)
The task branch no longer carries docs/reviews/INDEX.md (1b), and merge-candidate rebuilt it only inside rebaseOnto. When dev did not move the fast-forward pushed the stale index and reviews_index would turn dev red. freshIndex(tip) commits the rebuilt index on top of the material before the push; the merge stays a fast-forward. Real-git test: fast-forward, then reviews-index --check on the dev head is green. Mutant merge-ff-skips-review-index. Issue: #657 User-Visible: no
This commit is contained in:
@@ -167,6 +167,17 @@ export function realOps({
|
||||
must(exec(process.execPath, [REVIEWS_INDEX_SCRIPT, '--dir=docs/reviews', '--commit-if-stale', `--issue=${issue}`]), 'reviews-index --commit-if-stale');
|
||||
return must(git('rev-parse', 'HEAD'), 'rev-parse HEAD');
|
||||
},
|
||||
// #657 (1б) r1 H1: документ ревью ветки задачи больше не несёт индекс —
|
||||
// его пересобирают только коммиты, идущие в dev. Ребейз делает это сам
|
||||
// (выше); fast-forward, когда dev не двигался, ребейза не знает, и без
|
||||
// этого шага в dev уехал бы устаревший INDEX.md — красный `reviews_index`
|
||||
// на голове dev. Коммит индекса — doc-коммит конвейера поверх материала,
|
||||
// слияние остаётся fast-forward.
|
||||
freshIndex: (tip) => {
|
||||
must(git('checkout', '-q', '-B', 'merge-into-dev', tip), 'checkout');
|
||||
must(exec(process.execPath, [REVIEWS_INDEX_SCRIPT, '--dir=docs/reviews', '--commit-if-stale', `--issue=${issue}`]), 'reviews-index --commit-if-stale');
|
||||
return must(git('rev-parse', 'HEAD'), 'rev-parse HEAD');
|
||||
},
|
||||
pushWithLease: (sha, ref, expected) => {
|
||||
const r = git('push', '-q', `--force-with-lease=refs/heads/${ref}:${expected}`, pushUrl, `${sha}:refs/heads/${ref}`);
|
||||
if (r.status === 0) return true;
|
||||
@@ -249,10 +260,11 @@ export async function mergeCandidate({ branch, material, issue, ops, maxAttempts
|
||||
ops.log(`попытка ${attempt}: dev@${devNow.slice(0, 8)}, база материала ${materialBase.slice(0, 8)}, dev ${devMoved ? 'двигался' : 'на месте'}`);
|
||||
|
||||
if (!devMoved) {
|
||||
const pushed = ops.pushWithLease(tip, 'dev', devNow);
|
||||
const target = ops.freshIndex(tip);
|
||||
const pushed = ops.pushWithLease(target, 'dev', devNow);
|
||||
const decision = decideMerge({ fresh: true, devMoved: false, leaseRejected: !pushed });
|
||||
if (decision.action === 'retry') continue;
|
||||
return finish(decision, { candidate: tip, devNow });
|
||||
return finish(decision, { candidate: target, devNow });
|
||||
}
|
||||
|
||||
const candidate = ops.rebaseOnto(tip, 'origin/dev');
|
||||
|
||||
@@ -9497,6 +9497,12 @@ const MUTANT_DEFINITIONS = [
|
||||
because: "#657: the freshness check has to run in the publishing orchestrator, not only in a unit",
|
||||
patches: [{ file: "scripts/release-prerelease.mjs", find: " assertCommittedBundleFresh(manifest, sourceFingerprint(root));\n", replace: "" }],
|
||||
},
|
||||
{
|
||||
id: "merge-ff-skips-review-index",
|
||||
guard: "node --test --test-name-pattern=\"#657 r1 H1\" test/merge-candidate.test.mjs",
|
||||
because: "#657 r1 H1: the task branch no longer carries INDEX.md, so a fast-forward merge must rebuild it or dev turns red on reviews_index",
|
||||
patches: [{ file: "scripts/merge-candidate.mjs", find: " const target = ops.freshIndex(tip);", replace: " const target = tip;" }],
|
||||
},
|
||||
{
|
||||
id: "provenance-skips-bundle-rule",
|
||||
guard: "node --test --test-name-pattern=\"#657 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442 validate-commit-provenance\" test/bundle-policy.test.mjs",
|
||||
|
||||
Reference in New Issue
Block a user