@teambit/ci 1.0.485 → 1.0.487
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/ci.docs.mdx +344 -83
- package/commands/sync.cmd.ts +77 -0
- package/dist/ci.docs.mdx +344 -83
- package/dist/ci.main.runtime.d.ts +67 -6
- package/dist/ci.main.runtime.js +152 -25
- package/dist/ci.main.runtime.js.map +1 -1
- package/dist/commands/sync.cmd.d.ts +34 -0
- package/dist/commands/sync.cmd.js +57 -0
- package/dist/commands/sync.cmd.js.map +1 -0
- package/dist/git.d.ts +11 -1
- package/dist/git.js +11 -1
- package/dist/git.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +26 -1
- package/dist/index.js.map +1 -1
- package/dist/{preview-1785858957533.js → preview-1785883495880.js} +1 -1
- package/dist/sync/git-host-provider.d.ts +47 -0
- package/dist/sync/git-host-provider.js +54 -0
- package/dist/sync/git-host-provider.js.map +1 -0
- package/dist/sync/git-host-provider.spec.d.ts +1 -0
- package/dist/sync/git-host-provider.spec.js +171 -0
- package/dist/sync/git-host-provider.spec.js.map +1 -0
- package/dist/sync/git-ops.d.ts +171 -0
- package/dist/sync/git-ops.js +354 -0
- package/dist/sync/git-ops.js.map +1 -0
- package/dist/sync/git-ops.spec.d.ts +1 -0
- package/dist/sync/git-ops.spec.js +476 -0
- package/dist/sync/git-ops.spec.js.map +1 -0
- package/dist/sync/github-client.d.ts +79 -0
- package/dist/sync/github-client.js +198 -0
- package/dist/sync/github-client.js.map +1 -0
- package/dist/sync/github-client.spec.d.ts +1 -0
- package/dist/sync/github-client.spec.js +205 -0
- package/dist/sync/github-client.spec.js.map +1 -0
- package/dist/sync/init-scaffold.d.ts +40 -0
- package/dist/sync/init-scaffold.js +326 -0
- package/dist/sync/init-scaffold.js.map +1 -0
- package/dist/sync/init-scaffold.spec.d.ts +1 -0
- package/dist/sync/init-scaffold.spec.js +169 -0
- package/dist/sync/init-scaffold.spec.js.map +1 -0
- package/dist/sync/lane-sync-executor.d.ts +256 -0
- package/dist/sync/lane-sync-executor.js +1249 -0
- package/dist/sync/lane-sync-executor.js.map +1 -0
- package/dist/sync/lane-sync-executor.spec.d.ts +1 -0
- package/dist/sync/lane-sync-executor.spec.js +416 -0
- package/dist/sync/lane-sync-executor.spec.js.map +1 -0
- package/dist/sync/main-sync-executor.d.ts +62 -0
- package/dist/sync/main-sync-executor.js +305 -0
- package/dist/sync/main-sync-executor.js.map +1 -0
- package/dist/sync/sync-config.d.ts +83 -0
- package/dist/sync/sync-config.js +187 -0
- package/dist/sync/sync-config.js.map +1 -0
- package/dist/sync/sync-config.spec.d.ts +1 -0
- package/dist/sync/sync-config.spec.js +254 -0
- package/dist/sync/sync-config.spec.js.map +1 -0
- package/dist/sync/sync-orchestrator.d.ts +76 -0
- package/dist/sync/sync-orchestrator.js +396 -0
- package/dist/sync/sync-orchestrator.js.map +1 -0
- package/dist/sync/sync-orchestrator.spec.d.ts +1 -0
- package/dist/sync/sync-orchestrator.spec.js +155 -0
- package/dist/sync/sync-orchestrator.spec.js.map +1 -0
- package/dist/sync/sync-planner.d.ts +60 -0
- package/dist/sync/sync-planner.js +114 -0
- package/dist/sync/sync-planner.js.map +1 -0
- package/dist/sync/sync-planner.spec.d.ts +1 -0
- package/dist/sync/sync-planner.spec.js +210 -0
- package/dist/sync/sync-planner.spec.js.map +1 -0
- package/dist/sync/sync-state.d.ts +94 -0
- package/dist/sync/sync-state.js +178 -0
- package/dist/sync/sync-state.js.map +1 -0
- package/dist/sync/sync-state.spec.d.ts +1 -0
- package/dist/sync/sync-state.spec.js +271 -0
- package/dist/sync/sync-state.spec.js.map +1 -0
- package/dist/sync/workspace-lane.d.ts +13 -0
- package/dist/sync/workspace-lane.js +27 -0
- package/dist/sync/workspace-lane.js.map +1 -0
- package/package.json +20 -15
- package/sync/git-host-provider.spec.ts +197 -0
- package/sync/git-host-provider.ts +89 -0
- package/sync/git-ops.spec.ts +506 -0
- package/sync/git-ops.ts +334 -0
- package/sync/github-client.spec.ts +174 -0
- package/sync/github-client.ts +209 -0
- package/sync/init-scaffold.spec.ts +142 -0
- package/sync/init-scaffold.ts +340 -0
- package/sync/lane-sync-executor.spec.ts +389 -0
- package/sync/lane-sync-executor.ts +1363 -0
- package/sync/main-sync-executor.ts +321 -0
- package/sync/sync-config.spec.ts +283 -0
- package/sync/sync-config.ts +214 -0
- package/sync/sync-orchestrator.spec.ts +120 -0
- package/sync/sync-orchestrator.ts +386 -0
- package/sync/sync-planner.spec.ts +126 -0
- package/sync/sync-planner.ts +99 -0
- package/sync/sync-state.spec.ts +263 -0
- package/sync/sync-state.ts +176 -0
- package/sync/workspace-lane.ts +20 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import type { Logger } from '@teambit/logger';
|
|
2
|
+
import type { LanesMain } from '@teambit/lanes';
|
|
3
|
+
import type { LaneData } from '@teambit/legacy.scope';
|
|
4
|
+
import type { CiMain } from '../ci.main.runtime';
|
|
5
|
+
import type { CiSyncConfig, LaneTarget } from './sync-config';
|
|
6
|
+
import type { GitHostProvider } from './git-host-provider';
|
|
7
|
+
import type { BranchKeepReason, LaneSyncAction } from './sync-planner';
|
|
8
|
+
/**
|
|
9
|
+
* Prefix of the summary line for a lane that could not be reconciled. `syncLane` deliberately does
|
|
10
|
+
* NOT throw on halt — one unreconcilable lane must not abort the rest of the run; the command layer
|
|
11
|
+
* scans for this prefix to decide the exit code.
|
|
12
|
+
*/
|
|
13
|
+
export declare const HALT_SUMMARY_PREFIX = "HALTED";
|
|
14
|
+
/**
|
|
15
|
+
* Prefix for a target the reconciler refuses. Unlike a halt, nothing is mid-flight and no PR is
|
|
16
|
+
* annotated — the run exits non-zero, but the command layer reports a plain refusal rather than a
|
|
17
|
+
* sync conflict.
|
|
18
|
+
*/
|
|
19
|
+
export declare const REFUSED_SUMMARY_PREFIX = "REFUSED";
|
|
20
|
+
export type LaneSyncDeps = {
|
|
21
|
+
lanes: LanesMain;
|
|
22
|
+
/** for snapPrCommit + getDefaultBranchName + switchToLaneForSync */
|
|
23
|
+
ci: CiMain;
|
|
24
|
+
logger: Logger;
|
|
25
|
+
/** undefined => PR operations are logged and skipped; the git half of the sync still runs. */
|
|
26
|
+
gitHost?: GitHostProvider;
|
|
27
|
+
cfg: Required<CiSyncConfig>;
|
|
28
|
+
defaultScope: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Fingerprint of a lane's content — same primitive as `branchStateFingerprint`, so "equal" means
|
|
32
|
+
* exactly "the branch records every lane component at the lane's head".
|
|
33
|
+
*
|
|
34
|
+
* We deliberately do NOT use `LaneData.hash`: that hash is minted randomly at lane-creation time
|
|
35
|
+
* and does not change when the lane's components advance. This is derived from content instead.
|
|
36
|
+
*/
|
|
37
|
+
export declare function laneHeadFingerprint(components: LaneData['components']): string;
|
|
38
|
+
/**
|
|
39
|
+
* The lane's components that do not belong to `defaultScope`. A lane may span scopes, and the
|
|
40
|
+
* reconciler acts on a lane whole (fingerprint, materialize, snap, export), so foreign content is
|
|
41
|
+
* refused rather than written into this repository. Soft-deleted components and `updateDependents`
|
|
42
|
+
* entries are deliberately not read — the reconciler never materializes or exports them either.
|
|
43
|
+
*/
|
|
44
|
+
export declare function foreignLaneComponents(components: LaneData['components'], defaultScope: string): string[];
|
|
45
|
+
/**
|
|
46
|
+
* `entries`, capped at `max`, with a final "…and K more" entry. The bound is on entries, not rendered
|
|
47
|
+
* length, so a markdown list is never cut mid-line. `overflowPrefix` carries the caller's list marker
|
|
48
|
+
* onto the summary line.
|
|
49
|
+
*/
|
|
50
|
+
export declare function capEntries(entries: string[], overflowPrefix?: string, max?: number): string[];
|
|
51
|
+
/** The shared clause describing why a lane is cross-scope, used by the skip/refusal/halt outcomes. */
|
|
52
|
+
export declare function crossScopeDescription(foreignIds: string[], defaultScope: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* A cross-scope lane that was merely enumerated: a skip, and the run stays green — a standing, valid
|
|
55
|
+
* lane must not turn every scheduled run permanently red.
|
|
56
|
+
*/
|
|
57
|
+
export declare function crossScopeSkipSummary(laneName: string, foreignIds: string[], defaultScope: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* A cross-scope lane the user named explicitly: exits non-zero with the explanation. A refusal, not a
|
|
60
|
+
* halt — no PR is labelled, no branch is written. `existingBranch` keeps the closing sentence truthful
|
|
61
|
+
* when a branch of that name already exists.
|
|
62
|
+
*/
|
|
63
|
+
export declare function crossScopeRefusal(foreignIds: string[], defaultScope: string, existingBranch?: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Halt reason for a branch that is the live mirror of a different lane — two lanes with the same name
|
|
66
|
+
* in different scopes map to the same branch. Names both ids so the human can tell which owns it.
|
|
67
|
+
*/
|
|
68
|
+
export declare function branchMirrorsOtherLaneReason(branch: string, mirroredLaneIdStr: string, laneIdStr: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* PR comment for the branch-aliasing halt — the one halt whose PR belongs to a DIFFERENT lane. It must
|
|
71
|
+
* not carry the default "import the lane" steps, which would perform the overwrite the halt prevented.
|
|
72
|
+
*/
|
|
73
|
+
export declare function branchMirrorsOtherLaneNote(mirroredLaneIdStr: string, laneIdStr: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* A lane that became cross-scope after this repository had already mirrored it onto a branch — the one
|
|
76
|
+
* cross-scope shape that is a genuine halt: the pair is mid-flight and can no longer converge.
|
|
77
|
+
*/
|
|
78
|
+
export declare function crossScopeMidFlightHaltReason(branch: string, foreignIds: string[], defaultScope: string): string;
|
|
79
|
+
/**
|
|
80
|
+
* Branches `executeClosePr` refuses to delete whatever the ownership evidence concluded — an
|
|
81
|
+
* unconditional guard at the one site that deletes remote branches.
|
|
82
|
+
*/
|
|
83
|
+
export declare function isProtectedBranch(branch: string, defaultBranch: string, mainSyncBranch: string): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* The summary line a dry run reports for a planned action. A planned halt carries the same prefix the
|
|
86
|
+
* real run would: `summarizeSync` recognizes that prefix and nothing else, so without it a `--dry-run`
|
|
87
|
+
* exits 0 on a plan that needs a human. Refusals never reach here — they are returned before planning.
|
|
88
|
+
*/
|
|
89
|
+
export declare function dryRunSummaryLine(laneName: string, action: LaneSyncAction): string;
|
|
90
|
+
/** Why each `BranchKeepReason` withheld the deletion — one wording for the PR comment and the summary. */
|
|
91
|
+
export declare const KEPT_BECAUSE: Record<BranchKeepReason, string>;
|
|
92
|
+
export declare class LaneSyncExecutor {
|
|
93
|
+
private deps;
|
|
94
|
+
constructor(deps: LaneSyncDeps);
|
|
95
|
+
/** Every `origin/<ref>` read assumes current remote refs; fetch once per executor, not per lane. */
|
|
96
|
+
private fetched;
|
|
97
|
+
/**
|
|
98
|
+
* Reconcile one lane with its git branch/PR. Returns a summary line (HALT/REFUSED prefixed on
|
|
99
|
+
* failure) and NEVER throws — the contract the `--all` loop is written against, for every failure
|
|
100
|
+
* mode: the steps route expected failures to `executeHalt`, this wrapper covers the unexpected ones.
|
|
101
|
+
*/
|
|
102
|
+
syncLane(target: LaneTarget, opts?: {
|
|
103
|
+
dryRun?: boolean;
|
|
104
|
+
/** The user named this lane on the command line; decides how a cross-scope lane is reported. */
|
|
105
|
+
explicitTarget?: boolean;
|
|
106
|
+
}): Promise<string>;
|
|
107
|
+
private reconcileLane;
|
|
108
|
+
/**
|
|
109
|
+
* What a cross-scope lane means for this repository: a mid-flight halt when the branch is this
|
|
110
|
+
* lane's live mirror (checked first — the problem is the state of the pair, not the phrasing of the
|
|
111
|
+
* request); a refusal when the user named the lane explicitly; otherwise an enumerated skip that
|
|
112
|
+
* stays green — one standing cross-scope lane must not fail every scheduled run forever.
|
|
113
|
+
*/
|
|
114
|
+
private crossScopeOutcome;
|
|
115
|
+
/**
|
|
116
|
+
* Mirror the remote lane onto the branch: check the branch out, materialize the lane into the
|
|
117
|
+
* workspace, and commit the result. The committed `.bitmap` IS the record of the branch's state.
|
|
118
|
+
*/
|
|
119
|
+
private executeImportLane;
|
|
120
|
+
/**
|
|
121
|
+
* Push the branch's dev commits back onto the lane: snap+export the branch's tree, then commit the
|
|
122
|
+
* resulting `.bitmap` back onto the branch so the next run sees the two sides as converged.
|
|
123
|
+
*/
|
|
124
|
+
private executeExportBranch;
|
|
125
|
+
/**
|
|
126
|
+
* Both sides moved since the last sync. Order is load-bearing: (1) merge the lane into the branch's
|
|
127
|
+
* working tree (`bit checkout head`; conflicts halt or auto-resolve per `sync.onConflict`), (2) snap
|
|
128
|
+
* + export the merged tree — the snap IS the merge, (3) commit the resulting `.bitmap` back onto the
|
|
129
|
+
* branch. The merge cannot be skipped: the export path's switch runs under `forceOurs`, which never
|
|
130
|
+
* touches the filesystem, so a bare export would silently revert every lane-side file edit and then
|
|
131
|
+
* assert convergence over the loss. Never throws; anything unexpected halts.
|
|
132
|
+
*/
|
|
133
|
+
private executeMergeDiverged;
|
|
134
|
+
/**
|
|
135
|
+
* Snap the workspace's current tree onto the lane and export it; returns the error so the caller can
|
|
136
|
+
* halt. Snaps WHATEVER is in the workspace (the switch uses `forceOurs` and never merges files), so
|
|
137
|
+
* a diverged tree must already hold the merged content. `keepLane` preserves the lane's history,
|
|
138
|
+
* `skipCleanup` keeps the snap's `.bitmap` for the caller to commit, `noDestructiveRecovery` turns
|
|
139
|
+
* stale-lane recovery (delete + re-fork the remote lane) into a throw. The lane object must be
|
|
140
|
+
* imported BEFORE delegating: a switch onto the lane the workspace is already on no-ops before any
|
|
141
|
+
* fetch, so it never warms a cold scope.
|
|
142
|
+
*/
|
|
143
|
+
private snapAndExportOntoLane;
|
|
144
|
+
/**
|
|
145
|
+
* Record on the branch which lane state it now mirrors: re-query the lane (the export just moved it,
|
|
146
|
+
* so any earlier fingerprint is stale), commit — crucially the `.bitmap` the snap rewrote — and push.
|
|
147
|
+
* Returns undefined when the lane can no longer be read, in which case the caller halts.
|
|
148
|
+
*/
|
|
149
|
+
private recordLaneHeadOnBranch;
|
|
150
|
+
/**
|
|
151
|
+
* Merge the lane's snaps into the branch's working tree via `bit checkout head` (three-way merge,
|
|
152
|
+
* base = the branch's `.bitmap` version; `workspaceOnly` must stay false so lane-only components are
|
|
153
|
+
* added). Returns conflicted ids + file count rather than throwing. Not `mergeLanes.mergeLane`: both
|
|
154
|
+
* sides here are the same lane id, which `validateMergeFlags` rejects, and `mergeLane` refuses to
|
|
155
|
+
* run with modified components — exactly the branch's state here.
|
|
156
|
+
*/
|
|
157
|
+
private mergeLaneIntoBranchWorkingTree;
|
|
158
|
+
/**
|
|
159
|
+
* Put the working tree on `branch` at a pristine copy of `startPoint` and reload the `.bitmap` it
|
|
160
|
+
* brings (see `checkoutPristine`), so no leftover from a previous lane leaks into this lane's sync
|
|
161
|
+
* commit and the following bit operation resolves against this branch's `.bitmap`. Also the recovery
|
|
162
|
+
* after a merge attempt: resetting to `origin/<branch>` puts both sides back on the fetched tip.
|
|
163
|
+
*/
|
|
164
|
+
private checkoutFromRemote;
|
|
165
|
+
/**
|
|
166
|
+
* The reachability half of `LaneOwnershipEvidence`; the attribution half lives at the call site.
|
|
167
|
+
* An unanswerable question resolves to `inherited-or-none` — every other answer permits deleting a
|
|
168
|
+
* branch, and a failed `merge-base` is not evidence of anything. A foreign-hosted lane's branch
|
|
169
|
+
* reached by branch name attributes as `inherited-or-none` (scope mismatch), which is the safe
|
|
170
|
+
* direction: left alone, never retired.
|
|
171
|
+
*/
|
|
172
|
+
private assessBranchOwnership;
|
|
173
|
+
/**
|
|
174
|
+
* The lane is gone from bit.cloud — close its PR, and retire the branch if the claim on it allows.
|
|
175
|
+
* Deleting the branch is the one irreversible thing this command does; `keepReason` distinguishes
|
|
176
|
+
* "work that exists nowhere else" from "we did not write the tip".
|
|
177
|
+
*/
|
|
178
|
+
private executeClosePr;
|
|
179
|
+
/** Seams for the retirement path, so the one irreversible outcome is unit-testable without a remote. */
|
|
180
|
+
private currentBranchTip;
|
|
181
|
+
private pushBranchDeletion;
|
|
182
|
+
/**
|
|
183
|
+
* Record a halt without touching the PR on a dry run — `--dry-run` promises no PR writes, and
|
|
184
|
+
* labelling freezes a lane's syncs. The line stays HALT-prefixed either way. Every pre-planning halt
|
|
185
|
+
* goes through here so the guard cannot be forgotten at one site.
|
|
186
|
+
*/
|
|
187
|
+
private haltOrReport;
|
|
188
|
+
/**
|
|
189
|
+
* Hand the lane back to a human: label the PR so subsequent runs skip it, and comment the resolution
|
|
190
|
+
* steps. `commentNote` replaces the default steps for halts where they would be wrong.
|
|
191
|
+
*/
|
|
192
|
+
private executeHalt;
|
|
193
|
+
/**
|
|
194
|
+
* Drive the workspace's filesystem to the remote lane's content; returns the error so the caller can
|
|
195
|
+
* halt. Two traps make a plain `switchToLane` insufficient: (1) it defaults to `forceOurs`, which
|
|
196
|
+
* never touches the filesystem — the commit would claim the branch mirrors the lane over the default
|
|
197
|
+
* branch's files — so `forceOurs` is cleared and `forceTheirs` set; (2) switching onto the lane the
|
|
198
|
+
* workspace already sits on throws "already checked out", which `switchToLane` swallows as success
|
|
199
|
+
* and nothing materializes — so step off to main first.
|
|
200
|
+
*/
|
|
201
|
+
private materializeLane;
|
|
202
|
+
private fetchOnce;
|
|
203
|
+
/**
|
|
204
|
+
* The remote lane's data, or undefined when the lane no longer exists. The remote queried must be
|
|
205
|
+
* the lane's HOSTING scope: asking `defaultScope` for a lane it does not host answers "was not
|
|
206
|
+
* found" — the input that drives `close-pr`, which deletes branches.
|
|
207
|
+
*/
|
|
208
|
+
private getRemoteLane;
|
|
209
|
+
/**
|
|
210
|
+
* The open PR for the branch, if any. A git-host API hiccup degrades to "no PR known" rather than
|
|
211
|
+
* failing the lane — the git side of the sync is still correct and the next run re-reads the PR.
|
|
212
|
+
*/
|
|
213
|
+
private findPr;
|
|
214
|
+
/**
|
|
215
|
+
* The subject of the newest commit on the branch that isn't one of our own sync commits — it's
|
|
216
|
+
* the developer's own description of the change, and becomes the snap message on the lane.
|
|
217
|
+
*/
|
|
218
|
+
private lastNonSyncCommitMessage;
|
|
219
|
+
/**
|
|
220
|
+
* Stage everything, commit with the annotated sync message, and push. NEVER force-pushes: a rejected
|
|
221
|
+
* push means someone pushed concurrently and the next run should re-plan rather than clobber.
|
|
222
|
+
* `--allow-empty` is only insurance against `git commit` failing the lane outright.
|
|
223
|
+
*/
|
|
224
|
+
private commitAllAndPush;
|
|
225
|
+
private openPrForLane;
|
|
226
|
+
/**
|
|
227
|
+
* Put the workspace back on main with the default branch checked out. Best-effort, warn-only, so a
|
|
228
|
+
* restore hiccup can't throw out of a `finally` and mask the real error. The checkout is forced
|
|
229
|
+
* (switching back to main rewrites `.bitmap`); the scoped clean discards files a halted lane
|
|
230
|
+
* materialized but never committed, which would otherwise be staged onto the NEXT lane's branch;
|
|
231
|
+
* the reload makes the next lane resolve against the right checkout. This is a checkout, never a
|
|
232
|
+
* push — and `MainSyncExecutor.restoreWorkspace` must not diverge from it.
|
|
233
|
+
*/
|
|
234
|
+
private restoreWorkspace;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The body of the pull request that mirrors a lane onto a branch. The component list is capped so the
|
|
238
|
+
* body stays inside the git host's size limit however large the lane is; the total is not.
|
|
239
|
+
*/
|
|
240
|
+
export declare function laneSyncPrBody({ laneIdStr, laneUrl, branch, laneHead, components, }: {
|
|
241
|
+
laneIdStr: string;
|
|
242
|
+
laneUrl: string;
|
|
243
|
+
branch: string;
|
|
244
|
+
laneHead: string;
|
|
245
|
+
components: LaneData['components'];
|
|
246
|
+
}): string;
|
|
247
|
+
/**
|
|
248
|
+
* Resolution instructions posted on a halted PR. `note` replaces the default steps for halts where
|
|
249
|
+
* they do not apply (the branch-aliasing halt, whose PR belongs to a different lane).
|
|
250
|
+
*/
|
|
251
|
+
export declare function haltCommentBody({ reason, branch, laneId, note, }: {
|
|
252
|
+
reason: string;
|
|
253
|
+
branch: string;
|
|
254
|
+
laneId: string;
|
|
255
|
+
note?: string;
|
|
256
|
+
}): string;
|