@teambit/ci 1.0.382 → 1.0.384
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/commands/pr.cmd.ts +7 -0
- package/dist/ci.main.runtime.d.ts +87 -4
- package/dist/ci.main.runtime.js +514 -10
- package/dist/ci.main.runtime.js.map +1 -1
- package/dist/commands/pr.cmd.d.ts +1 -0
- package/dist/commands/pr.cmd.js +3 -2
- package/dist/commands/pr.cmd.js.map +1 -1
- package/dist/{preview-1779983783175.js → preview-1779999088763.js} +1 -1
- package/package.json +16 -11
package/commands/pr.cmd.ts
CHANGED
|
@@ -9,6 +9,7 @@ type Options = {
|
|
|
9
9
|
lane?: string;
|
|
10
10
|
strict?: boolean;
|
|
11
11
|
dryRun?: boolean;
|
|
12
|
+
keepLane?: boolean;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
export class CiPrCmd implements Command {
|
|
@@ -23,6 +24,11 @@ export class CiPrCmd implements Command {
|
|
|
23
24
|
['b', 'build', 'Set to true to build the app locally, false (default) will build on Ripple CI'],
|
|
24
25
|
['s', 'strict', 'Set to true to fail on warnings as well as errors, false (default) only fails on errors'],
|
|
25
26
|
['d', 'dry-run', 'Run the full pipeline but skip exporting to remote (build runs only if --build is set)'],
|
|
27
|
+
[
|
|
28
|
+
'',
|
|
29
|
+
'keep-lane',
|
|
30
|
+
'Reuse the same remote lane across PR commits (preserves lane history and cloud UI edits) instead of recreating it on every run',
|
|
31
|
+
],
|
|
26
32
|
];
|
|
27
33
|
|
|
28
34
|
constructor(
|
|
@@ -67,6 +73,7 @@ export class CiPrCmd implements Command {
|
|
|
67
73
|
build: options.build,
|
|
68
74
|
strict: options.strict,
|
|
69
75
|
dryRun: options.dryRun,
|
|
76
|
+
keepLane: options.keepLane,
|
|
70
77
|
});
|
|
71
78
|
|
|
72
79
|
if (results) {
|
|
@@ -113,17 +113,99 @@ export declare class CiMain {
|
|
|
113
113
|
private getCustomCommitMessage;
|
|
114
114
|
private verifyWorkspaceStatusInternal;
|
|
115
115
|
private switchToLane;
|
|
116
|
+
/**
|
|
117
|
+
* Sync *config-only* changes from main onto the lane — without a full `bit lane merge`.
|
|
118
|
+
*
|
|
119
|
+
* In this workflow git is the source of truth for files: the PR author merges the default branch
|
|
120
|
+
* into their PR branch, so source changes arrive via git. The one thing git can't carry is
|
|
121
|
+
* config that's already been *tagged into objects* on main — e.g. another PR ran `bit env set` /
|
|
122
|
+
* `bit deps set`; those records lived in `.bitmap`, rode git into main, and `bit ci merge` baked
|
|
123
|
+
* them into the component's Version (clearing them from `.bitmap`). A long-running PR's lane
|
|
124
|
+
* would otherwise miss them.
|
|
125
|
+
*
|
|
126
|
+
* A full lane merge is the wrong tool here: it does a 3-way *file* merge and refuses to run while
|
|
127
|
+
* the workspace has modified components — but in `bit ci pr` the workspace is always dirty (the
|
|
128
|
+
* PR's changes, not yet snapped). So instead we do a per-component 3-way merge of the aspect
|
|
129
|
+
* *config only* (base = common ancestor, ours = lane, theirs = main), keeping the PR's config on
|
|
130
|
+
* conflict, and stash the result on an `unmergedComponents` entry's `mergedConfig`. The
|
|
131
|
+
* subsequent `snap` reads it (via the aspects-merger on component load) and bakes main's config
|
|
132
|
+
* into the new snap, while the snap's files still come from the workspace (git). No file
|
|
133
|
+
* checkout, so no clean-workspace requirement.
|
|
134
|
+
*/
|
|
135
|
+
private syncConfigFromMain;
|
|
136
|
+
/**
|
|
137
|
+
* Copied from `merging.main.runtime` (`filterDeletedDependenciesFromConfig`): the config merge
|
|
138
|
+
* can emit deletion markers (`version: '-'`) for deps removed on main. The aspects-merger applies
|
|
139
|
+
* `mergedConfig` verbatim, so strip those here to avoid writing a policy entry with version '-'.
|
|
140
|
+
*/
|
|
141
|
+
private filterDeletedDependenciesFromConfig;
|
|
142
|
+
/**
|
|
143
|
+
* Best-effort, fetch-free check for whether the current (PR) branch is *behind* the default
|
|
144
|
+
* branch — i.e. the default branch has commits the PR branch doesn't contain.
|
|
145
|
+
*
|
|
146
|
+
* We intentionally do NOT `git fetch` here (a fetch in CI can hang on an interactive SSH
|
|
147
|
+
* host-key prompt — that's why `isStaleCiRun` was removed in #10300). We compare against
|
|
148
|
+
* whatever `origin/<default>` ref the checkout already has, which reflects the state the default
|
|
149
|
+
* branch was in when this CI run started — exactly the reference point we care about.
|
|
150
|
+
*
|
|
151
|
+
* Returns true only when we can *confirm* the branch is behind. If the ref can't be resolved or
|
|
152
|
+
* anything else goes wrong, returns false (treat as "not behind" / proceed) so we never silently
|
|
153
|
+
* disable the main→lane config propagation.
|
|
154
|
+
*/
|
|
155
|
+
private isBranchBehindDefaultBranch;
|
|
116
156
|
verifyWorkspaceStatus(): Promise<{
|
|
117
157
|
code: number;
|
|
118
158
|
data: string;
|
|
119
159
|
}>;
|
|
120
|
-
snapPrCommit({ laneIdStr, message, build, strict, dryRun, }: {
|
|
160
|
+
snapPrCommit({ laneIdStr, message, build, strict, dryRun, keepLane, }: {
|
|
121
161
|
laneIdStr: string;
|
|
122
162
|
message: string;
|
|
123
163
|
build: boolean | undefined;
|
|
124
164
|
strict: boolean | undefined;
|
|
125
165
|
dryRun?: boolean;
|
|
166
|
+
keepLane?: boolean;
|
|
126
167
|
}): Promise<string | undefined>;
|
|
168
|
+
/**
|
|
169
|
+
* `--keep-lane` flow: reuse the existing remote lane (or create it on the first run), merge main
|
|
170
|
+
* into it to pick up config changes that landed since the fork, snap, and export with
|
|
171
|
+
* adopt-on-conflict recovery for concurrent CI pushes. The lane object is preserved across PR
|
|
172
|
+
* commits, so its history and lane-based UI edits on Bit Cloud survive.
|
|
173
|
+
*/
|
|
174
|
+
private snapAndExportReusingLane;
|
|
175
|
+
/**
|
|
176
|
+
* Default flow: snap onto a uniquely-named temporary lane, then at export time delete any
|
|
177
|
+
* existing remote lane and rename the temp lane to the final name. The temp name minimizes the
|
|
178
|
+
* race window when multiple CI jobs run concurrently on the same branch. Trade-off: the final
|
|
179
|
+
* lane is recreated on every PR commit, so its history and any lane-based UI edits on Bit Cloud
|
|
180
|
+
* don't survive across commits — use `--keep-lane` for that.
|
|
181
|
+
*/
|
|
182
|
+
private snapAndExportWithTempLane;
|
|
183
|
+
/**
|
|
184
|
+
* Export with a recovery path for the two concurrent-CI conflicts that can surface from the
|
|
185
|
+
* remote (see the marker constants at the top of the file): lane-hash mismatch (both runners
|
|
186
|
+
* created fresh lane objects when the lane didn't yet exist on the remote) and per-component
|
|
187
|
+
* divergence (both reused the existing lane but snapped the same component with different
|
|
188
|
+
* content).
|
|
189
|
+
*
|
|
190
|
+
* Recovery: adopt-the-winner. The remote lane (whoever pushed first) becomes canonical. We
|
|
191
|
+
* drop our local lane object, fetch the remote, rebase our snapped Version objects so each
|
|
192
|
+
* one's parent points to the remote head for that component, then swap those rebased Versions
|
|
193
|
+
* in as the new lane heads and re-export. Build artifacts are preserved — only the parent
|
|
194
|
+
* pointers on the Version objects change. Result: both runners' snaps end up chained on a
|
|
195
|
+
* single lane object (last-writer-wins on content for any contested component, with the
|
|
196
|
+
* winner's snap preserved in history as the parent).
|
|
197
|
+
*/
|
|
198
|
+
private exportWithAdoptOnConflict;
|
|
199
|
+
/**
|
|
200
|
+
* Wrap `exporter.export()` with retry on the "server is busy" error. The retried export's
|
|
201
|
+
* pending-dir lands behind whichever concurrent client is still in the remote's queue (we
|
|
202
|
+
* arrived second by definition — we're the loser of the original race). The 60s wait inside
|
|
203
|
+
* `export-validate.waitIfNeeded` covers the common case, but on slow CI hosts or large pushes
|
|
204
|
+
* we sometimes time out before the other client finishes its persist. A short sleep + retry
|
|
205
|
+
* here just gives the queue room to drain.
|
|
206
|
+
*/
|
|
207
|
+
private exportWithBusyRetry;
|
|
208
|
+
private rebaseOntoRemoteLane;
|
|
127
209
|
mergePr({ message: argMessage, build, strict, releaseType, preReleaseId, incrementBy, explicitVersionBump, verbose, versionsFile, autoMergeResolve, forceTheirs, laneName, skipPush, noBitmapCommit, }: {
|
|
128
210
|
message?: string;
|
|
129
211
|
build?: boolean;
|
|
@@ -163,9 +245,10 @@ export declare class CiMain {
|
|
|
163
245
|
/**
|
|
164
246
|
* Export with retry on lane hash-mismatch, caused by a concurrent `bit ci pr` run pushing the
|
|
165
247
|
* same lane id between our pre-export delete and the hub's merge (the export takes 1-2 minutes,
|
|
166
|
-
* plenty of time to race).
|
|
167
|
-
*
|
|
168
|
-
*
|
|
248
|
+
* plenty of time to race). Used by the default (temp-lane) flow. On mismatch we delete the
|
|
249
|
+
* remote lane and retry — the temp-lane flow recreates the lane on every run anyway, so there's
|
|
250
|
+
* no lane history to preserve. (The `--keep-lane` flow instead adopts the remote lane and
|
|
251
|
+
* rebases onto it; see `exportWithAdoptOnConflict`.)
|
|
169
252
|
*/
|
|
170
253
|
private exportWithRetryOnLaneHashMismatch;
|
|
171
254
|
/**
|