@teambit/ci 1.0.484 → 1.0.486
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-1785846648967.js → preview-1785864931304.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 +21 -16
- 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
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import type { RuntimeDefinition } from '@teambit/harmony';
|
|
1
|
+
import type { RuntimeDefinition, SlotRegistry } from '@teambit/harmony';
|
|
2
2
|
import { type CLIMain } from '@teambit/cli';
|
|
3
3
|
import { type LoggerMain, type Logger } from '@teambit/logger';
|
|
4
4
|
import { type Workspace } from '@teambit/workspace';
|
|
5
5
|
import { type BuilderMain } from '@teambit/builder';
|
|
6
6
|
import { type StatusMain } from '@teambit/status';
|
|
7
|
-
import type { LanesMain } from '@teambit/lanes';
|
|
7
|
+
import type { SwitchLaneOptions, LanesMain } from '@teambit/lanes';
|
|
8
8
|
import type { SnappingMain } from '@teambit/snapping';
|
|
9
9
|
import { type ExportMain } from '@teambit/export';
|
|
10
10
|
import { type ImporterMain } from '@teambit/importer';
|
|
11
11
|
import { type CheckoutMain } from '@teambit/checkout';
|
|
12
12
|
import type { MergeStrategy } from '@teambit/component.modules.merge-helper';
|
|
13
13
|
import type { ReleaseType } from 'semver';
|
|
14
|
+
import type { CiSyncConfig } from './sync/sync-config';
|
|
15
|
+
import type { GitHostProvider } from './sync/git-host-provider';
|
|
16
|
+
/**
|
|
17
|
+
* Registered git hosts (GitHub ships built-in; others register from their own aspect).
|
|
18
|
+
* @see GitHostProvider
|
|
19
|
+
*/
|
|
20
|
+
export type GitHostProviderSlot = SlotRegistry<GitHostProvider>;
|
|
14
21
|
export interface CiWorkspaceConfig {
|
|
15
22
|
/**
|
|
16
23
|
* Path to a custom script that generates commit messages for `bit ci merge` operations.
|
|
@@ -68,6 +75,12 @@ export interface CiWorkspaceConfig {
|
|
|
68
75
|
* ```
|
|
69
76
|
*/
|
|
70
77
|
useExplicitBumpKeywords?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Configuration for `bit ci sync` — bi-directional lane <-> branch/PR sync.
|
|
80
|
+
* See CiSyncConfig for fields. Example:
|
|
81
|
+
* { "teambit.git/ci": { "sync": { "branchPrefix": "lane/", "lanes": ["*"] } } }
|
|
82
|
+
*/
|
|
83
|
+
sync?: CiSyncConfig;
|
|
71
84
|
}
|
|
72
85
|
export declare class CiMain {
|
|
73
86
|
private workspace;
|
|
@@ -80,10 +93,11 @@ export declare class CiMain {
|
|
|
80
93
|
private checkout;
|
|
81
94
|
private logger;
|
|
82
95
|
private config;
|
|
96
|
+
private gitHostProviderSlot;
|
|
83
97
|
static runtime: RuntimeDefinition;
|
|
84
98
|
static dependencies: any;
|
|
85
|
-
static slots:
|
|
86
|
-
constructor(workspace: Workspace, builder: BuilderMain, status: StatusMain, lanes: LanesMain, snapping: SnappingMain, exporter: ExportMain, importer: ImporterMain, checkout: CheckoutMain, logger: Logger, config: CiWorkspaceConfig);
|
|
99
|
+
static slots: ((registerFn: () => string) => SlotRegistry<GitHostProvider>)[];
|
|
100
|
+
constructor(workspace: Workspace, builder: BuilderMain, status: StatusMain, lanes: LanesMain, snapping: SnappingMain, exporter: ExportMain, importer: ImporterMain, checkout: CheckoutMain, logger: Logger, config: CiWorkspaceConfig, gitHostProviderSlot: GitHostProviderSlot);
|
|
87
101
|
static provider([cli, workspace, loggerAspect, builder, status, lanes, snapping, exporter, importer, checkout]: [
|
|
88
102
|
CLIMain,
|
|
89
103
|
Workspace,
|
|
@@ -95,7 +109,16 @@ export declare class CiMain {
|
|
|
95
109
|
ExportMain,
|
|
96
110
|
ImporterMain,
|
|
97
111
|
CheckoutMain
|
|
98
|
-
], config: CiWorkspaceConfig): Promise<CiMain>;
|
|
112
|
+
], config: CiWorkspaceConfig, [gitHostProviderSlot]: [GitHostProviderSlot]): Promise<CiMain>;
|
|
113
|
+
/**
|
|
114
|
+
* Register a git host (GitHub, GitLab, …) that `bit ci sync` can use for its pull-request
|
|
115
|
+
* operations. Exactly one provider is selected per run, by the `origin` remote (see
|
|
116
|
+
* `selectGitHostProvider`); registering a provider never changes how a repository claimed by a
|
|
117
|
+
* different provider is handled.
|
|
118
|
+
*/
|
|
119
|
+
registerGitHostProvider(provider: GitHostProvider): this;
|
|
120
|
+
/** Every registered git host provider, in registration order (one provider per registration). */
|
|
121
|
+
listGitHostProviders(): GitHostProvider[];
|
|
99
122
|
getBranchName(): Promise<string>;
|
|
100
123
|
private getCirclePullRequestBranchName;
|
|
101
124
|
/**
|
|
@@ -108,7 +131,16 @@ export declare class CiMain {
|
|
|
108
131
|
* @example convertBranchToLaneId("feature/New-Component") => "my-scope/feature-new-component"
|
|
109
132
|
*/
|
|
110
133
|
convertBranchToLaneId(branchName: string): string;
|
|
134
|
+
/**
|
|
135
|
+
* The repository's default branch name, whole — slashes included (see `parseOriginHeadRef`).
|
|
136
|
+
* Local `origin/HEAD` symref first, then the remote's own answer, then the conventional probe.
|
|
137
|
+
*/
|
|
111
138
|
getDefaultBranchName(): Promise<string>;
|
|
139
|
+
/**
|
|
140
|
+
* Last-resort fallback: the two conventional names among the remote branches, then `master`.
|
|
141
|
+
* Deliberately only `main`/`master` — any wider guess risks protecting the wrong branch.
|
|
142
|
+
*/
|
|
143
|
+
private probeDefaultBranchName;
|
|
112
144
|
getGitCommitMessage(): Promise<string | null>;
|
|
113
145
|
private parseVersionBumpFromCommit;
|
|
114
146
|
private getCustomCommitMessage;
|
|
@@ -120,6 +152,27 @@ export declare class CiMain {
|
|
|
120
152
|
* `getCurrentLane()` check.
|
|
121
153
|
*/
|
|
122
154
|
private switchToLane;
|
|
155
|
+
/**
|
|
156
|
+
* Public entry point onto `switchToLane` for the lane-sync executor; returns the error instead of
|
|
157
|
+
* throwing. `switchToLane` spreads caller options AFTER its defaults, so `forceOurs: true` is
|
|
158
|
+
* overridable — the sync import direction depends on that. Do not reorder that spread.
|
|
159
|
+
*/
|
|
160
|
+
switchToLaneForSync(laneName: string, options?: SwitchLaneOptions): Promise<Error | undefined>;
|
|
161
|
+
/**
|
|
162
|
+
* Re-read `.bitmap` from disk into the live workspace. `bit ci sync` moves the git checkout
|
|
163
|
+
* underneath a running process, and until the reload every bit operation resolves against the
|
|
164
|
+
* `.bitmap` loaded at startup — and the next write would persist that stale state.
|
|
165
|
+
*/
|
|
166
|
+
reloadWorkspaceFromDisk(): Promise<void>;
|
|
167
|
+
/** `bit ci sync` — reconcile Bit lanes and the main scope with git branches and PRs (see `SyncOrchestrator`). */
|
|
168
|
+
sync(opts?: {
|
|
169
|
+
lane?: string;
|
|
170
|
+
branch?: string;
|
|
171
|
+
all?: boolean;
|
|
172
|
+
main?: boolean;
|
|
173
|
+
dryRun?: boolean;
|
|
174
|
+
init?: boolean;
|
|
175
|
+
}): Promise<string>;
|
|
123
176
|
/**
|
|
124
177
|
* Sync *config-only* changes from main onto the lane — without a full `bit lane merge`.
|
|
125
178
|
*
|
|
@@ -171,7 +224,7 @@ export declare class CiMain {
|
|
|
171
224
|
code: number;
|
|
172
225
|
data: string;
|
|
173
226
|
}>;
|
|
174
|
-
snapPrCommit({ laneIdStr, message, build, strict, dryRun, keepLane, skipCleanup, skipTasks, }: {
|
|
227
|
+
snapPrCommit({ laneIdStr, message, build, strict, dryRun, keepLane, skipCleanup, skipTasks, noDestructiveRecovery, }: {
|
|
175
228
|
laneIdStr: string;
|
|
176
229
|
message: string;
|
|
177
230
|
build: boolean | undefined;
|
|
@@ -180,6 +233,14 @@ export declare class CiMain {
|
|
|
180
233
|
keepLane?: boolean;
|
|
181
234
|
skipCleanup?: boolean;
|
|
182
235
|
skipTasks?: string;
|
|
236
|
+
/**
|
|
237
|
+
* Opt out of the `--keep-lane` stale-lane recovery that deletes the remote lane and recreates it
|
|
238
|
+
* from main. That trade is fine for a PR lane (a throwaway mirror of a git branch, recreated on
|
|
239
|
+
* every commit) but unacceptable for `bit ci sync`, where the lane is the *authored* artifact and
|
|
240
|
+
* the branch is its mirror — deleting it would destroy the very thing being synced. When set, the
|
|
241
|
+
* stale-lane case throws instead, which the sync executor surfaces as a halt for a human.
|
|
242
|
+
*/
|
|
243
|
+
noDestructiveRecovery?: boolean;
|
|
183
244
|
}): Promise<string | undefined>;
|
|
184
245
|
/**
|
|
185
246
|
* Post-export cleanup: restore the workspace to the original lane / main so an interactive
|
package/dist/ci.main.runtime.js
CHANGED
|
@@ -4,6 +4,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.CiMain = void 0;
|
|
7
|
+
function _harmony() {
|
|
8
|
+
const data = require("@teambit/harmony");
|
|
9
|
+
_harmony = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
7
14
|
function _cli() {
|
|
8
15
|
const data = require("@teambit/cli");
|
|
9
16
|
_cli = function () {
|
|
@@ -144,6 +151,13 @@ function _merge() {
|
|
|
144
151
|
};
|
|
145
152
|
return data;
|
|
146
153
|
}
|
|
154
|
+
function _sync() {
|
|
155
|
+
const data = require("./commands/sync.cmd");
|
|
156
|
+
_sync = function () {
|
|
157
|
+
return data;
|
|
158
|
+
};
|
|
159
|
+
return data;
|
|
160
|
+
}
|
|
147
161
|
function _git() {
|
|
148
162
|
const data = require("./git");
|
|
149
163
|
_git = function () {
|
|
@@ -214,12 +228,45 @@ function _pullRequestRef() {
|
|
|
214
228
|
};
|
|
215
229
|
return data;
|
|
216
230
|
}
|
|
231
|
+
function _syncOrchestrator() {
|
|
232
|
+
const data = require("./sync/sync-orchestrator");
|
|
233
|
+
_syncOrchestrator = function () {
|
|
234
|
+
return data;
|
|
235
|
+
};
|
|
236
|
+
return data;
|
|
237
|
+
}
|
|
238
|
+
function _githubClient() {
|
|
239
|
+
const data = require("./sync/github-client");
|
|
240
|
+
_githubClient = function () {
|
|
241
|
+
return data;
|
|
242
|
+
};
|
|
243
|
+
return data;
|
|
244
|
+
}
|
|
245
|
+
function _gitOps() {
|
|
246
|
+
const data = require("./sync/git-ops");
|
|
247
|
+
_gitOps = function () {
|
|
248
|
+
return data;
|
|
249
|
+
};
|
|
250
|
+
return data;
|
|
251
|
+
}
|
|
252
|
+
function _syncConfig() {
|
|
253
|
+
const data = require("./sync/sync-config");
|
|
254
|
+
_syncConfig = function () {
|
|
255
|
+
return data;
|
|
256
|
+
};
|
|
257
|
+
return data;
|
|
258
|
+
}
|
|
217
259
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
218
260
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
219
261
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
220
262
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
221
263
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
222
264
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
265
|
+
/**
|
|
266
|
+
* Registered git hosts (GitHub ships built-in; others register from their own aspect).
|
|
267
|
+
* @see GitHostProvider
|
|
268
|
+
*/
|
|
269
|
+
|
|
223
270
|
// Two distinct conflicts can surface from the remote on a concurrent `bit ci pr` race.
|
|
224
271
|
// LANE_HASH_MISMATCH fires when both runners called `Lane.create` (the lane didn't exist on
|
|
225
272
|
// the remote yet), so they each minted a random `sha1(v4())` hash — `sources.mergeLane` then
|
|
@@ -232,7 +279,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
232
279
|
const LANE_HASH_MISMATCH_MARKER = 'a lane with the same id already exists with a different hash';
|
|
233
280
|
const COMPONENT_DIVERGENCE_MARKER = 'merge error occurred when exporting';
|
|
234
281
|
class CiMain {
|
|
235
|
-
constructor(workspace, builder, status, lanes, snapping, exporter, importer, checkout, logger, config) {
|
|
282
|
+
constructor(workspace, builder, status, lanes, snapping, exporter, importer, checkout, logger, config, gitHostProviderSlot) {
|
|
236
283
|
this.workspace = workspace;
|
|
237
284
|
this.builder = builder;
|
|
238
285
|
this.status = status;
|
|
@@ -243,15 +290,35 @@ class CiMain {
|
|
|
243
290
|
this.checkout = checkout;
|
|
244
291
|
this.logger = logger;
|
|
245
292
|
this.config = config;
|
|
293
|
+
this.gitHostProviderSlot = gitHostProviderSlot;
|
|
246
294
|
}
|
|
247
|
-
static async provider([cli, workspace, loggerAspect, builder, status, lanes, snapping, exporter, importer, checkout], config) {
|
|
295
|
+
static async provider([cli, workspace, loggerAspect, builder, status, lanes, snapping, exporter, importer, checkout], config, [gitHostProviderSlot]) {
|
|
248
296
|
const logger = loggerAspect.createLogger(_ci().CiAspect.id);
|
|
249
|
-
const ci = new CiMain(workspace, builder, status, lanes, snapping, exporter, importer, checkout, logger, config);
|
|
297
|
+
const ci = new CiMain(workspace, builder, status, lanes, snapping, exporter, importer, checkout, logger, config, gitHostProviderSlot);
|
|
298
|
+
// GitHub ships built-in but is not privileged: registered through the same public slot any other
|
|
299
|
+
// host aspect uses. Credentials resolve lazily, so registering at aspect load is always safe.
|
|
300
|
+
ci.registerGitHostProvider(new (_githubClient().GitHubHostProvider)(message => logger.consoleWarning(message)));
|
|
250
301
|
const ciCmd = new (_ci2().CiCmd)(workspace, logger);
|
|
251
|
-
ciCmd.commands = [new (_verify().CiVerifyCmd)(workspace, logger, ci), new (_pr().CiPrCmd)(workspace, logger, ci), new (_merge().CiMergeCmd)(workspace, logger, ci)];
|
|
302
|
+
ciCmd.commands = [new (_verify().CiVerifyCmd)(workspace, logger, ci), new (_pr().CiPrCmd)(workspace, logger, ci), new (_merge().CiMergeCmd)(workspace, logger, ci), new (_sync().CiSyncCmd)(workspace, logger, ci)];
|
|
252
303
|
cli.register(ciCmd);
|
|
253
304
|
return ci;
|
|
254
305
|
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Register a git host (GitHub, GitLab, …) that `bit ci sync` can use for its pull-request
|
|
309
|
+
* operations. Exactly one provider is selected per run, by the `origin` remote (see
|
|
310
|
+
* `selectGitHostProvider`); registering a provider never changes how a repository claimed by a
|
|
311
|
+
* different provider is handled.
|
|
312
|
+
*/
|
|
313
|
+
registerGitHostProvider(provider) {
|
|
314
|
+
this.gitHostProviderSlot.register(provider);
|
|
315
|
+
return this;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/** Every registered git host provider, in registration order (one provider per registration). */
|
|
319
|
+
listGitHostProviders() {
|
|
320
|
+
return this.gitHostProviderSlot.values();
|
|
321
|
+
}
|
|
255
322
|
async getBranchName() {
|
|
256
323
|
try {
|
|
257
324
|
// if we are running on github, use the GITHUB_HEAD_REF env var
|
|
@@ -315,28 +382,43 @@ class CiMain {
|
|
|
315
382
|
* @example convertBranchToLaneId("feature/New-Component") => "my-scope/feature-new-component"
|
|
316
383
|
*/
|
|
317
384
|
convertBranchToLaneId(branchName) {
|
|
318
|
-
// Sanitize branch name to make it valid for Bit lane IDs by replacing slashes and dots with dashes
|
|
319
|
-
// and converting to lowercase
|
|
320
385
|
const sanitizedBranch = branchName.replace(/[/.]/g, '-').toLowerCase();
|
|
321
386
|
return `${this.workspace.defaultScope}/${sanitizedBranch}`;
|
|
322
387
|
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* The repository's default branch name, whole — slashes included (see `parseOriginHeadRef`).
|
|
391
|
+
* Local `origin/HEAD` symref first, then the remote's own answer, then the conventional probe.
|
|
392
|
+
*/
|
|
323
393
|
async getDefaultBranchName() {
|
|
324
394
|
try {
|
|
325
|
-
// Try to get the default branch from git symbolic-ref
|
|
326
395
|
const result = await _git().git.raw(['symbolic-ref', 'refs/remotes/origin/HEAD']);
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
//
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
396
|
+
const local = (0, _gitOps().parseOriginHeadRef)(result);
|
|
397
|
+
// Every candidate is validated before it is returned: this value becomes a checkout target and a
|
|
398
|
+
// push refspec, and an option-like name ("-x") would be read by git as a flag. An unusable answer
|
|
399
|
+
// falls through to the next source rather than reaching the argv.
|
|
400
|
+
if (local && (0, _syncConfig().isValidGitBranchName)(local)) return local;
|
|
401
|
+
} catch {
|
|
402
|
+
// no local origin/HEAD — normal in a fresh CI clone; ask the remote itself below.
|
|
403
|
+
}
|
|
404
|
+
const remote = await (0, _gitOps().remoteHeadBranch)();
|
|
405
|
+
if (remote && (0, _syncConfig().isValidGitBranchName)(remote)) return remote;
|
|
406
|
+
return this.probeDefaultBranchName();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Last-resort fallback: the two conventional names among the remote branches, then `master`.
|
|
411
|
+
* Deliberately only `main`/`master` — any wider guess risks protecting the wrong branch.
|
|
412
|
+
*/
|
|
413
|
+
async probeDefaultBranchName(originalError) {
|
|
414
|
+
try {
|
|
415
|
+
const branches = await _git().git.branch(['-r']);
|
|
416
|
+
if (branches.all.includes('origin/main')) return 'main';
|
|
417
|
+
if (branches.all.includes('origin/master')) return 'master';
|
|
418
|
+
return 'master';
|
|
419
|
+
} catch {
|
|
420
|
+
this.logger.console(_chalk().default.yellow(`Unable to detect default branch, using 'master'${originalError ? `: ${originalError}` : ''}`));
|
|
421
|
+
return 'master';
|
|
340
422
|
}
|
|
341
423
|
}
|
|
342
424
|
async getGitCommitMessage() {
|
|
@@ -474,6 +556,36 @@ class CiMain {
|
|
|
474
556
|
return undefined;
|
|
475
557
|
}
|
|
476
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Public entry point onto `switchToLane` for the lane-sync executor; returns the error instead of
|
|
561
|
+
* throwing. `switchToLane` spreads caller options AFTER its defaults, so `forceOurs: true` is
|
|
562
|
+
* overridable — the sync import direction depends on that. Do not reorder that spread.
|
|
563
|
+
*/
|
|
564
|
+
async switchToLaneForSync(laneName, options = {}) {
|
|
565
|
+
return this.switchToLane(laneName, options);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Re-read `.bitmap` from disk into the live workspace. `bit ci sync` moves the git checkout
|
|
570
|
+
* underneath a running process, and until the reload every bit operation resolves against the
|
|
571
|
+
* `.bitmap` loaded at startup — and the next write would persist that stale state.
|
|
572
|
+
*/
|
|
573
|
+
async reloadWorkspaceFromDisk() {
|
|
574
|
+
await this.workspace._reloadConsumer();
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/** `bit ci sync` — reconcile Bit lanes and the main scope with git branches and PRs (see `SyncOrchestrator`). */
|
|
578
|
+
async sync(opts = {}) {
|
|
579
|
+
return new (_syncOrchestrator().SyncOrchestrator)({
|
|
580
|
+
ci: this,
|
|
581
|
+
workspace: this.workspace,
|
|
582
|
+
logger: this.logger,
|
|
583
|
+
lanes: this.lanes,
|
|
584
|
+
checkout: this.checkout,
|
|
585
|
+
config: this.config
|
|
586
|
+
}).sync(opts);
|
|
587
|
+
}
|
|
588
|
+
|
|
477
589
|
/**
|
|
478
590
|
* Sync *config-only* changes from main onto the lane — without a full `bit lane merge`.
|
|
479
591
|
*
|
|
@@ -729,7 +841,8 @@ class CiMain {
|
|
|
729
841
|
dryRun,
|
|
730
842
|
keepLane,
|
|
731
843
|
skipCleanup,
|
|
732
|
-
skipTasks
|
|
844
|
+
skipTasks,
|
|
845
|
+
noDestructiveRecovery
|
|
733
846
|
}) {
|
|
734
847
|
// The post-export cleanup switches the workspace back to main, which re-checks-out main's HEAD
|
|
735
848
|
// and re-imports every workspace component — pointless when the workspace is about to be
|
|
@@ -778,7 +891,8 @@ class CiMain {
|
|
|
778
891
|
build,
|
|
779
892
|
dryRun,
|
|
780
893
|
skipCleanup: resolvedSkipCleanup,
|
|
781
|
-
skipTasks: resolvedSkipTasks
|
|
894
|
+
skipTasks: resolvedSkipTasks,
|
|
895
|
+
noDestructiveRecovery
|
|
782
896
|
});
|
|
783
897
|
}
|
|
784
898
|
return this.snapAndExportWithTempLane({
|
|
@@ -850,7 +964,8 @@ class CiMain {
|
|
|
850
964
|
build,
|
|
851
965
|
dryRun,
|
|
852
966
|
skipCleanup,
|
|
853
|
-
skipTasks
|
|
967
|
+
skipTasks,
|
|
968
|
+
noDestructiveRecovery
|
|
854
969
|
}) {
|
|
855
970
|
// Query the remote (by name, to avoid fetching all lanes) so we know whether to reuse or create
|
|
856
971
|
const existingLanes = await this.lanes.getLanes({
|
|
@@ -903,6 +1018,14 @@ class CiMain {
|
|
|
903
1018
|
if (!isStaleLane) {
|
|
904
1019
|
throw new Error(`Failed to switch to remote lane ${laneId.toString()}: ${errMsg || '(no error captured)'}. ` + `Refusing destructive recovery for this failure class — the error doesn't match the ` + `stale-lane marker, so deleting the lane could destroy real history. Investigate or retry.`);
|
|
905
1020
|
}
|
|
1021
|
+
if (noDestructiveRecovery) {
|
|
1022
|
+
// `bit ci sync` mirrors an authored lane onto a branch. Recovering by deleting the remote
|
|
1023
|
+
// lane and re-forking it from main would discard the lane's components and history — the
|
|
1024
|
+
// exact artifact the sync exists to preserve — and the next sync would then happily
|
|
1025
|
+
// mirror the now-empty lane onto the branch. Fail loudly instead; the executor turns this
|
|
1026
|
+
// into a halt so a human resolves the lane on bit.cloud.
|
|
1027
|
+
throw new Error(`Failed to switch to remote lane ${laneId.toString()}: ${errMsg || '(no error captured)'}. ` + `The stale-lane recovery (delete the remote lane and recreate it from main) is disabled ` + `for this caller, because the lane is an authored artifact rather than a throwaway PR ` + `lane. Resolve the lane on bit.cloud and re-run.`);
|
|
1028
|
+
}
|
|
906
1029
|
this.logger.console(_chalk().default.yellow(`Stale remote lane ${laneId.toString()} — switching failed. ` + `Deleting it and creating a fresh lane to recover.`));
|
|
907
1030
|
// Re-check the remote lane's hash immediately before deleting. The central-hub delete
|
|
908
1031
|
// API is name-based — there's no compare-and-swap — so two CI jobs racing the same
|
|
@@ -1512,7 +1635,11 @@ class CiMain {
|
|
|
1512
1635
|
|
|
1513
1636
|
// Stage everything: `bit checkout head` earlier in the flow may modify files
|
|
1514
1637
|
// beyond .bitmap and pnpm-lock.yaml, so a narrow `git add` would miss them.
|
|
1515
|
-
|
|
1638
|
+
// The two exclusions in the shared helper keep the local bit scope (`.bit`) and `node_modules` out
|
|
1639
|
+
// of the commit in a workspace whose `.gitignore` lacks Bit's block — otherwise this stages the
|
|
1640
|
+
// object store into the default branch. Same helper the sync executors use, so all three commit
|
|
1641
|
+
// paths agree on what counts as workspace content.
|
|
1642
|
+
await (0, _gitOps().addAllExceptScopeAndModules)();
|
|
1516
1643
|
const commitMessage = await this.getCustomCommitMessage();
|
|
1517
1644
|
await _git().git.commit(commitMessage);
|
|
1518
1645
|
const statusAfterCommit = await _git().git.status();
|
|
@@ -1705,7 +1832,7 @@ class CiMain {
|
|
|
1705
1832
|
exports.CiMain = CiMain;
|
|
1706
1833
|
_defineProperty(CiMain, "runtime", _cli().MainRuntime);
|
|
1707
1834
|
_defineProperty(CiMain, "dependencies", [_cli().CLIAspect, _workspace().WorkspaceAspect, _logger().LoggerAspect, _builder().BuilderAspect, _status().StatusAspect, _lanes().LanesAspect, _snapping().SnappingAspect, _export().ExportAspect, _importer().ImporterAspect, _checkout().CheckoutAspect]);
|
|
1708
|
-
_defineProperty(CiMain, "slots", []);
|
|
1835
|
+
_defineProperty(CiMain, "slots", [_harmony().Slot.withType()]);
|
|
1709
1836
|
function reportToString(result) {
|
|
1710
1837
|
return typeof result === 'string' ? result : result.data;
|
|
1711
1838
|
}
|