@databricks-solutions/lakebase-scm-utils 0.3.10 → 0.3.12

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.
Files changed (49) hide show
  1. package/dist/{pr-e-E4aP4j.d.cts → pr-D-eayWyJ.d.cts} +59 -1
  2. package/dist/{pr-e-E4aP4j.d.ts → pr-D-eayWyJ.d.ts} +59 -1
  3. package/dist/scripts/git/index.cjs +30 -14
  4. package/dist/scripts/git/index.d.cts +32 -1
  5. package/dist/scripts/git/index.d.ts +32 -1
  6. package/dist/scripts/git/index.js +28 -14
  7. package/dist/scripts/github/index.d.cts +2 -60
  8. package/dist/scripts/github/index.d.ts +2 -60
  9. package/dist/scripts/index.cjs +268 -76
  10. package/dist/scripts/index.d.cts +4 -4
  11. package/dist/scripts/index.d.ts +4 -4
  12. package/dist/scripts/index.js +261 -76
  13. package/dist/scripts/lakebase/ci-resolve-branch.cli.cjs +2 -2
  14. package/dist/scripts/lakebase/ci-resolve-branch.cli.js +2 -2
  15. package/dist/scripts/lakebase/collapse-heads.cli.cjs +2 -2
  16. package/dist/scripts/lakebase/collapse-heads.cli.js +2 -2
  17. package/dist/scripts/lakebase/detect-language.cli.cjs +2 -2
  18. package/dist/scripts/lakebase/detect-language.cli.js +2 -2
  19. package/dist/scripts/lakebase/doctor.cli.cjs +2 -2
  20. package/dist/scripts/lakebase/doctor.cli.js +2 -2
  21. package/dist/scripts/lakebase/get-connection.cli.cjs +2 -2
  22. package/dist/scripts/lakebase/get-connection.cli.js +2 -2
  23. package/dist/scripts/lakebase/index.cjs +280 -77
  24. package/dist/scripts/lakebase/index.d.cts +97 -2
  25. package/dist/scripts/lakebase/index.d.ts +97 -2
  26. package/dist/scripts/lakebase/index.js +275 -77
  27. package/dist/scripts/lakebase/infra-runner.cli.cjs +2 -2
  28. package/dist/scripts/lakebase/infra-runner.cli.js +2 -2
  29. package/dist/scripts/lakebase/new-migration.cli.cjs +2 -2
  30. package/dist/scripts/lakebase/new-migration.cli.js +2 -2
  31. package/dist/scripts/lakebase/schema-diff.cli.cjs +2 -2
  32. package/dist/scripts/lakebase/schema-diff.cli.js +2 -2
  33. package/dist/scripts/lakebase/schema-migrate.cli.cjs +2 -2
  34. package/dist/scripts/lakebase/schema-migrate.cli.js +2 -2
  35. package/dist/scripts/lakebase/scm-claim-feature.cli.cjs +2 -2
  36. package/dist/scripts/lakebase/scm-claim-feature.cli.js +2 -2
  37. package/dist/scripts/lakebase/scm-doctor.cli.cjs +2 -2
  38. package/dist/scripts/lakebase/scm-doctor.cli.js +2 -2
  39. package/dist/scripts/lakebase/scm-merge.cli.cjs +2 -2
  40. package/dist/scripts/lakebase/scm-merge.cli.js +2 -2
  41. package/dist/scripts/lakebase/scm-reconcile-tier.cli.cjs +2 -2
  42. package/dist/scripts/lakebase/scm-reconcile-tier.cli.js +2 -2
  43. package/dist/scripts/util/index.cjs +2 -2
  44. package/dist/scripts/util/index.js +2 -2
  45. package/package.json +1 -1
  46. package/scripts/git/commit-push.ts +60 -14
  47. package/scripts/lakebase/create-preflight.ts +213 -1
  48. package/scripts/lakebase/create-project.ts +98 -30
  49. package/scripts/lakebase/scaffold.ts +50 -0
@@ -2554,8 +2554,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
2554
2554
  var cached;
2555
2555
  function substrateSelfVersion() {
2556
2556
  if (cached !== void 0) return cached;
2557
- if ("0.3.10".length > 0) {
2558
- cached = "0.3.10";
2557
+ if ("0.3.12".length > 0) {
2558
+ cached = "0.3.12";
2559
2559
  return cached;
2560
2560
  }
2561
2561
  cached = "unknown";
@@ -11135,6 +11135,26 @@ async function createRepo(name, opts = {}) {
11135
11135
  wrap2(err, `Failed to create repository "${name}"`);
11136
11136
  }
11137
11137
  }
11138
+ async function deleteRepo(name) {
11139
+ try {
11140
+ const { owner, repo } = parseOwnerRepo(name);
11141
+ const ctx = await newContext();
11142
+ await ctx.octokit.rest.repos.delete({ owner, repo });
11143
+ } catch (err) {
11144
+ wrap2(err, `Failed to delete repository "${name}"`);
11145
+ }
11146
+ }
11147
+ async function repoExists(name) {
11148
+ try {
11149
+ const { owner, repo } = parseOwnerRepo(name);
11150
+ const ctx = await newContext();
11151
+ await ctx.octokit.rest.repos.get({ owner, repo });
11152
+ return true;
11153
+ } catch (err) {
11154
+ if (err instanceof RequestError && err.status === 404) return false;
11155
+ wrap2(err, `Failed to check repository "${name}"`);
11156
+ }
11157
+ }
11138
11158
  async function getActionsEnabled(ownerRepo) {
11139
11159
  try {
11140
11160
  const { owner, repo } = parseOwnerRepo(ownerRepo);
@@ -11203,6 +11223,70 @@ async function checkGitHubWorkflowScope(probe = () => checkGitHubScopes(["workfl
11203
11223
  return { ok: true };
11204
11224
  }
11205
11225
  }
11226
+ async function checkGitHubPreflight(input) {
11227
+ const warnings = [];
11228
+ const hard = input.hardScopes ?? ["repo", "workflow"];
11229
+ const advisory = input.advisoryScopes ?? ["delete_repo"];
11230
+ const currentUserProbe = input.currentUser ?? getCurrentUser;
11231
+ const scopesProbe = input.scopes ?? ((req) => checkGitHubScopes(req));
11232
+ const repoExistsProbe = input.repoExists ?? repoExists;
11233
+ let activeUser;
11234
+ try {
11235
+ activeUser = await currentUserProbe();
11236
+ } catch (err) {
11237
+ return {
11238
+ ok: false,
11239
+ warnings,
11240
+ reason: `GitHub authentication failed: ${err instanceof Error ? err.message : String(err)}. Sign in with \`gh auth login\`, or set GITHUB_TOKEN to a valid token, then re-run.`
11241
+ };
11242
+ }
11243
+ if (activeUser.toLowerCase() !== input.owner.toLowerCase()) {
11244
+ warnings.push(
11245
+ `Signed in to GitHub as "${activeUser}" but creating under "${input.owner}" (an org or another account); ensure "${activeUser}" can create repositories there.`
11246
+ );
11247
+ }
11248
+ try {
11249
+ const { granted, missing } = await scopesProbe([...hard, ...advisory]);
11250
+ if (granted !== null) {
11251
+ const missingHard = missing.filter((s) => hard.includes(s));
11252
+ const missingAdvisory = missing.filter((s) => advisory.includes(s));
11253
+ if (missingHard.length > 0) {
11254
+ return {
11255
+ ok: false,
11256
+ warnings,
11257
+ activeUser,
11258
+ reason: `GitHub token missing required scope(s): ${missingHard.join(", ")} (grants [${granted.join(", ") || "none"}]). Fix: gh auth refresh -h github.com -s ${[...hard].join(",")}`
11259
+ };
11260
+ }
11261
+ if (missingAdvisory.length > 0) {
11262
+ warnings.push(
11263
+ `GitHub token missing the ${missingAdvisory.join(", ")} scope \u2014 automatic rollback of the repo on a failed create is unavailable (you would delete it by hand). Grant it with: gh auth refresh -h github.com -s delete_repo`
11264
+ );
11265
+ }
11266
+ } else {
11267
+ warnings.push(
11268
+ "GitHub token scopes are not visible (fine-grained PAT or App token); cannot pre-verify repo/workflow access , the create will surface any gap when it pushes."
11269
+ );
11270
+ }
11271
+ } catch {
11272
+ warnings.push("Could not read GitHub token scopes (probe error); skipping the scope pre-check.");
11273
+ }
11274
+ try {
11275
+ if (await repoExistsProbe(`${input.owner}/${input.repoName}`)) {
11276
+ return {
11277
+ ok: false,
11278
+ warnings,
11279
+ activeUser,
11280
+ reason: `GitHub repo "${input.owner}/${input.repoName}" already exists. Pick a different project name, or delete the existing repo first.`
11281
+ };
11282
+ }
11283
+ } catch {
11284
+ warnings.push(
11285
+ `Could not check whether "${input.owner}/${input.repoName}" already exists (probe error); the create will fail clearly if it does.`
11286
+ );
11287
+ }
11288
+ return { ok: true, warnings, activeUser };
11289
+ }
11206
11290
  function githubWorkflowScopePrereqMessage(reason) {
11207
11291
  return "The GitHub token lacks the `workflow` OAuth scope, required to push the project's `.github/workflows/*` CI files. (Without this check, scaffolding runs all the way to the final push, is rejected, and rolls back.) Grant the scope, then re-run:\n - gh CLI: gh auth refresh -h github.com -s workflow\n - VS Code: re-sign in to GitHub and approve the workflow scope\n - token: set GITHUB_TOKEN to a PAT that includes the `workflow` scope" + (reason ? `
11208
11292
  (${reason})` : "");
@@ -11268,6 +11352,53 @@ async function withLakebaseRollback(opts, fn) {
11268
11352
  throw wrapped;
11269
11353
  }
11270
11354
  }
11355
+ function createRollbackLedger() {
11356
+ const steps = [];
11357
+ return {
11358
+ register: (label, undo) => {
11359
+ steps.push({ label, undo });
11360
+ },
11361
+ steps: () => steps
11362
+ };
11363
+ }
11364
+ async function withCreateRollback(ledger, opts, fn) {
11365
+ try {
11366
+ return await fn();
11367
+ } catch (err) {
11368
+ const report = opts.report ?? (() => {
11369
+ });
11370
+ const steps = [...ledger.steps()].reverse();
11371
+ const rolledBack = [];
11372
+ const failed = [];
11373
+ if (steps.length > 0) report(`Create failed; rolling back ${steps.length} created resource(s)...`);
11374
+ for (const s of steps) {
11375
+ try {
11376
+ report(` rolling back: ${s.label}`);
11377
+ await s.undo();
11378
+ rolledBack.push(s.label);
11379
+ } catch (e) {
11380
+ const m = e instanceof Error ? e.message : String(e);
11381
+ if (/not.?found/i.test(m)) {
11382
+ rolledBack.push(s.label);
11383
+ continue;
11384
+ }
11385
+ failed.push(`${s.label} (${m})`);
11386
+ }
11387
+ }
11388
+ const base = err instanceof Error ? err.message : String(err);
11389
+ const parts = [];
11390
+ if (rolledBack.length) parts.push(`rolled back: ${rolledBack.join(", ")}`);
11391
+ if (failed.length) {
11392
+ parts.push(
11393
+ `COULD NOT roll back: ${failed.join("; ")} , clean these up by hand before retrying the same name`
11394
+ );
11395
+ }
11396
+ const suffix = parts.length ? ` (${parts.join("; ")})` : "";
11397
+ const wrapped = err instanceof Error ? err : new Error(base);
11398
+ wrapped.message = `${base}${suffix}`;
11399
+ throw wrapped;
11400
+ }
11401
+ }
11271
11402
 
11272
11403
  // scripts/lakebase/create-project.ts
11273
11404
  init_esm_shims();
@@ -11335,27 +11466,34 @@ To finish:
11335
11466
  this.name = "WorkflowScopeError";
11336
11467
  }
11337
11468
  };
11338
- async function commitAndPush(args) {
11339
- await exec2("git add -A", { cwd: args.projectDir });
11340
- await exec2(`git commit -m ${JSON.stringify(args.message)}`, {
11341
- cwd: args.projectDir,
11469
+ async function commitInitial(projectDir, message) {
11470
+ await exec2("git add -A", { cwd: projectDir });
11471
+ await exec2(`git commit -m ${JSON.stringify(message)}`, {
11472
+ cwd: projectDir,
11342
11473
  timeout: 3e4
11343
11474
  });
11344
- if (args.push === false) return;
11475
+ }
11476
+ async function pushInitial(args) {
11345
11477
  const remote = args.remote ?? "origin";
11346
11478
  const branch = args.branch ?? "main";
11347
- try {
11348
- await exec2(`git push -u ${remote} ${branch}`, {
11349
- cwd: args.projectDir,
11350
- timeout: 3e4
11351
- });
11352
- } catch (err) {
11353
- const msg = err instanceof Error ? err.message : String(err);
11354
- if (/without `?workflow`? scope|workflow scope/i.test(msg)) {
11355
- throw new WorkflowScopeError(args.projectDir);
11479
+ const attempts = Math.max(1, args.attempts ?? 1);
11480
+ const sleep2 = args.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
11481
+ const run = args.run ?? ((cmd, cwd) => exec2(cmd, { cwd, timeout: 3e4 }).then(() => void 0));
11482
+ let lastErr;
11483
+ for (let i = 1; i <= attempts; i++) {
11484
+ try {
11485
+ await run(`git push -u ${remote} ${branch}`, args.projectDir);
11486
+ return;
11487
+ } catch (err) {
11488
+ const msg = err instanceof Error ? err.message : String(err);
11489
+ if (/without `?workflow`? scope|workflow scope/i.test(msg)) {
11490
+ throw new WorkflowScopeError(args.projectDir);
11491
+ }
11492
+ lastErr = err;
11493
+ if (i < attempts) await sleep2(args.delayMs ?? 1500);
11356
11494
  }
11357
- throw err;
11358
11495
  }
11496
+ throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
11359
11497
  }
11360
11498
 
11361
11499
  // scripts/lakebase/scaffold.ts
@@ -12088,6 +12226,20 @@ async function deployVscodeSettings(targetDir, opts) {
12088
12226
  fs12.mkdirSync(destDir, { recursive: true });
12089
12227
  fs12.copyFileSync(src, path11.join(destDir, "settings.json"));
12090
12228
  }
12229
+ var TEST_CAPTURE_ROOT_FILES = ["consort-capture.ts", "consort-test-reporter.ts"];
12230
+ function deployTestCaptureRoot(targetDir, opts) {
12231
+ const src = commonDir(opts);
12232
+ const written = [];
12233
+ for (const rel of TEST_CAPTURE_ROOT_FILES) {
12234
+ const from = path11.join(src, rel);
12235
+ if (!fs12.existsSync(from)) {
12236
+ throw new Error(`Kit template missing: ${from}`);
12237
+ }
12238
+ fs12.copyFileSync(from, path11.join(targetDir, rel));
12239
+ written.push(rel);
12240
+ }
12241
+ return written;
12242
+ }
12091
12243
  async function deployGitignore(targetDir, language = "java", opts) {
12092
12244
  const base = fs12.readFileSync(path11.join(commonDir(opts), ".gitignore.base"), "utf-8");
12093
12245
  const extraPath = path11.join(langDir(language, opts), ".gitignore.extra");
@@ -12222,6 +12374,12 @@ async function scaffoldAll(args) {
12222
12374
  });
12223
12375
  if (client.length > 0) staticResult.client = client;
12224
12376
  }
12377
+ if (args.clientFramework === "react" || language === "nodejs") {
12378
+ report("Deploying root test-capture modules");
12379
+ staticResult.testCapture = deployTestCaptureRoot(args.targetDir, {
12380
+ templatesDir: args.templatesDir
12381
+ });
12382
+ }
12225
12383
  return staticResult;
12226
12384
  }
12227
12385
 
@@ -13661,64 +13819,72 @@ async function createProject(input, progress) {
13661
13819
  throw new Error(databricksAuthPrereqMessage(host, auth7.reason));
13662
13820
  }
13663
13821
  if (useGithub) {
13664
- report("Checking GitHub token scopes...");
13665
- const scope = await checkGitHubWorkflowScope();
13666
- if (!scope.ok) {
13667
- throw new Error(githubWorkflowScopePrereqMessage(scope.reason));
13668
- }
13669
- }
13670
- if (useGithub) {
13671
- report("Creating GitHub repository...", fullRepoName);
13672
- await createRepo(fullRepoName, {
13673
- private: input.privateRepo !== false,
13674
- description: `Lakebase project: ${input.projectName}`
13675
- });
13676
- report("Waiting for GitHub repo to be visible...", fullRepoName);
13677
- const probeDelays = [1e3, 2e3, 3e3, 5e3, 8e3];
13678
- let probeErr = "";
13679
- let visible = false;
13680
- for (const waitMs of probeDelays) {
13681
- try {
13682
- await getRepoFullName(fullRepoName);
13683
- visible = true;
13684
- break;
13685
- } catch (err) {
13686
- probeErr = err instanceof Error ? err.message : String(err);
13687
- await delay(waitMs);
13688
- }
13689
- }
13690
- if (!visible) {
13691
- let activeUser = "";
13692
- try {
13693
- activeUser = await getCurrentUser();
13694
- } catch {
13695
- }
13696
- const samlHint = /SAML|scope does not match|sso/i.test(probeErr) ? "\n\nThe error mentions SAML \u2013 re-sign in to GitHub and authorize SSO for this org." : "";
13697
- const userHint = activeUser && activeUser !== input.githubOwner ? `
13822
+ report("Checking GitHub account + token requisites...");
13823
+ const gh = await checkGitHubPreflight({ owner: input.githubOwner, repoName: input.projectName });
13824
+ for (const w of gh.warnings) {
13825
+ warnings.push(w);
13826
+ report(`Note: ${w}`);
13827
+ }
13828
+ if (!gh.ok) throw new Error(gh.reason);
13829
+ }
13830
+ const rollback = createRollbackLedger();
13831
+ return await withCreateRollback(
13832
+ rollback,
13833
+ { report },
13834
+ async () => {
13835
+ if (useGithub) {
13836
+ report("Creating GitHub repository...", fullRepoName);
13837
+ await createRepo(fullRepoName, {
13838
+ private: input.privateRepo !== false,
13839
+ description: `Lakebase project: ${input.projectName}`
13840
+ });
13841
+ rollback.register(`GitHub repo ${fullRepoName}`, () => deleteRepo(fullRepoName));
13842
+ report("Waiting for GitHub repo to be visible...", fullRepoName);
13843
+ const probeDelays = [1e3, 2e3, 3e3, 5e3, 8e3];
13844
+ let probeErr = "";
13845
+ let visible = false;
13846
+ for (const waitMs of probeDelays) {
13847
+ try {
13848
+ await getRepoFullName(fullRepoName);
13849
+ visible = true;
13850
+ break;
13851
+ } catch (err) {
13852
+ probeErr = err instanceof Error ? err.message : String(err);
13853
+ await delay(waitMs);
13854
+ }
13855
+ }
13856
+ if (!visible) {
13857
+ let activeUser = "";
13858
+ try {
13859
+ activeUser = await getCurrentUser();
13860
+ } catch {
13861
+ }
13862
+ const samlHint = /SAML|scope does not match|sso/i.test(probeErr) ? "\n\nThe error mentions SAML \u2013 re-sign in to GitHub and authorize SSO for this org." : "";
13863
+ const userHint = activeUser && activeUser !== input.githubOwner ? `
13698
13864
 
13699
13865
  Note: signed in as "${activeUser}", but the repo was created under "${input.githubOwner}".` : "";
13700
- throw new Error(
13701
- `GitHub repo "${fullRepoName}" was created but isn't visible after ~19s of polling.${samlHint}${userHint}
13866
+ throw new Error(
13867
+ `GitHub repo "${fullRepoName}" was created but isn't visible after ~19s of polling.${samlHint}${userHint}
13702
13868
 
13703
13869
  Last probe error:
13704
13870
  ${probeErr.split("\n")[0].slice(0, 200)}`
13705
- );
13706
- }
13707
- report("Cloning repository...", projectDir);
13708
- await cloneRepo({
13709
- repoUrl: `https://github.com/${fullRepoName}.git`,
13710
- parentDir: input.parentDir
13711
- });
13712
- } else {
13713
- report("Creating local project directory...", projectDir);
13714
- fs19.mkdirSync(projectDir, { recursive: true });
13715
- await gitInit(projectDir);
13716
- }
13717
- report("Creating Lakebase database (provisioning Postgres)...", lakebaseProjectId);
13718
- await createLakebaseProject({ projectId: lakebaseProjectId, host });
13719
- return await withLakebaseRollback(
13720
- { projectId: lakebaseProjectId, host, report },
13721
- async () => {
13871
+ );
13872
+ }
13873
+ report("Cloning repository...", projectDir);
13874
+ await cloneRepo({
13875
+ repoUrl: `https://github.com/${fullRepoName}.git`,
13876
+ parentDir: input.parentDir
13877
+ });
13878
+ rollback.register(`local project dir ${projectDir}`, () => fs19.rmSync(projectDir, { recursive: true, force: true }));
13879
+ } else {
13880
+ report("Creating local project directory...", projectDir);
13881
+ fs19.mkdirSync(projectDir, { recursive: true });
13882
+ await gitInit(projectDir);
13883
+ rollback.register(`local project dir ${projectDir}`, () => fs19.rmSync(projectDir, { recursive: true, force: true }));
13884
+ }
13885
+ report("Creating Lakebase database (provisioning Postgres)...", lakebaseProjectId);
13886
+ await createLakebaseProject({ projectId: lakebaseProjectId, host });
13887
+ rollback.register(`Lakebase project ${lakebaseProjectId}`, () => deleteLakebaseProject({ projectId: lakebaseProjectId, host }));
13722
13888
  report("Resolving database endpoint...");
13723
13889
  const defaultBranchId = await getDefaultBranchId({
13724
13890
  projectId: lakebaseProjectId,
@@ -13802,6 +13968,10 @@ Last probe error:
13802
13968
  projectName: input.projectName,
13803
13969
  report: (m) => report(m)
13804
13970
  });
13971
+ rollback.register(
13972
+ `self-hosted runner ${input.projectName}`,
13973
+ () => removeRunner({ fullRepoName, projectName: input.projectName })
13974
+ );
13805
13975
  } catch (err) {
13806
13976
  const msg = err instanceof Error ? err.message : String(err);
13807
13977
  warnings.push(`Runner setup failed: ${msg}`);
@@ -13870,6 +14040,16 @@ Last probe error:
13870
14040
  "The Consort toolkit downloads on first use , run `./scripts/lk --refresh`, or just your first `./scripts/lk` command, and it installs then."
13871
14041
  );
13872
14042
  }
14043
+ if (enableSftdd && useGithub) {
14044
+ report("Warming the Consort toolkit (so the first push doesn't cold-download mid-hook)...");
14045
+ let warm = warmAndVerifyKit(projectDir);
14046
+ if (!warm.ok) warm = warmAndVerifyKit(projectDir);
14047
+ if (!warm.ok) {
14048
+ const m = kitWarmWarning(projectDir, warm.reason);
14049
+ warnings.push(m);
14050
+ report(`Note: ${m}`);
14051
+ }
14052
+ }
13873
14053
  const langLabels = {
13874
14054
  java: "Java/Spring Boot",
13875
14055
  kotlin: "Kotlin/Spring Boot",
@@ -13890,12 +14070,25 @@ Last probe error:
13890
14070
  }
13891
14071
  }
13892
14072
  report("Creating initial commit...");
13893
- await commitAndPush({
13894
- projectDir,
13895
- message: `Initial project scaffold (${langLabel} + Lakebase)`,
13896
- push: useGithub
13897
- });
13898
- if (tiers === 2 || tiers === 3) {
14073
+ await commitInitial(projectDir, `Initial project scaffold (${langLabel} + Lakebase)`);
14074
+ let pushLanded = !useGithub;
14075
+ if (useGithub) {
14076
+ try {
14077
+ await pushInitial({ projectDir, attempts: 2 });
14078
+ pushLanded = true;
14079
+ } catch (err) {
14080
+ if (err instanceof WorkflowScopeError) throw err;
14081
+ const msg = err instanceof Error ? err.message : String(err);
14082
+ const m = `Provisioning is complete, but the initial push did not land after a retry: ${msg}. The project on disk is fine , finish it with: cd ${projectDir} && git push -u origin main`;
14083
+ warnings.push(m);
14084
+ report(`WARNING: ${m}`);
14085
+ }
14086
+ }
14087
+ if ((tiers === 2 || tiers === 3) && !pushLanded) {
14088
+ const m = `INCOMPLETE TIERS: you requested ${tiers} tiers, but the initial push hasn't landed, so the tier branches can't fork off origin yet. After you finish the push (above), cut them with \`./scripts/lk lakebase-cut-tier --name staging --fork-from main\`${tiers === 3 ? " and `--name dev --fork-from staging`" : ""}.`;
14089
+ warnings.push(m);
14090
+ report(`WARNING: ${m}`);
14091
+ } else if (tiers === 2 || tiers === 3) {
13899
14092
  report(`Cutting staging tier (tiers=${tiers}) via createLongRunningBranch...`);
13900
14093
  try {
13901
14094
  await createLongRunningBranch({
@@ -13946,7 +14139,7 @@ Last probe error:
13946
14139
  warnings
13947
14140
  };
13948
14141
  }
13949
- // end withLakebaseRollback closure
14142
+ // end withCreateRollback closure
13950
14143
  );
13951
14144
  }
13952
14145
 
@@ -18725,6 +18918,7 @@ export {
18725
18918
  ScmReleaseError,
18726
18919
  ScmWaitCiError,
18727
18920
  SpringInitializrClient,
18921
+ TEST_CAPTURE_ROOT_FILES,
18728
18922
  _testMakeBrownfieldFixture,
18729
18923
  abandonFeatureBranch,
18730
18924
  addE2eToRunTestsScript,
@@ -18744,6 +18938,7 @@ export {
18744
18938
  catalogExists,
18745
18939
  catalogExplorerUrl,
18746
18940
  checkDatabricksAuth,
18941
+ checkGitHubPreflight,
18747
18942
  checkGitHubWorkflowScope,
18748
18943
  checkoutPaired,
18749
18944
  claimFeatureBranch,
@@ -18757,6 +18952,7 @@ export {
18757
18952
  createPairedBranch,
18758
18953
  createPerfPairedBranch,
18759
18954
  createProject,
18955
+ createRollbackLedger,
18760
18956
  createTestPairedBranch,
18761
18957
  createUatPairedBranch,
18762
18958
  cutBackup,
@@ -18779,6 +18975,7 @@ export {
18779
18975
  deployLanguageProject,
18780
18976
  deployScripts,
18781
18977
  deploySpringStarter,
18978
+ deployTestCaptureRoot,
18782
18979
  deployVscodeSettings,
18783
18980
  deployWorkflows,
18784
18981
  deriveCiAppName,
@@ -18926,6 +19123,7 @@ export {
18926
19123
  waitForBranchReady,
18927
19124
  waitForCi,
18928
19125
  warmAndVerifyKit,
19126
+ withCreateRollback,
18929
19127
  withLakebaseRollback,
18930
19128
  workflowStateFileExists,
18931
19129
  writeEnvFile,
@@ -79290,8 +79290,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
79290
79290
  var cached;
79291
79291
  function substrateSelfVersion() {
79292
79292
  if (cached !== void 0) return cached;
79293
- if ("0.3.10".length > 0) {
79294
- cached = "0.3.10";
79293
+ if ("0.3.12".length > 0) {
79294
+ cached = "0.3.12";
79295
79295
  return cached;
79296
79296
  }
79297
79297
  cached = "unknown";
@@ -393,8 +393,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
393
393
  var cached;
394
394
  function substrateSelfVersion() {
395
395
  if (cached !== void 0) return cached;
396
- if ("0.3.10".length > 0) {
397
- cached = "0.3.10";
396
+ if ("0.3.12".length > 0) {
397
+ cached = "0.3.12";
398
398
  return cached;
399
399
  }
400
400
  cached = "unknown";
@@ -79290,8 +79290,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
79290
79290
  var cached;
79291
79291
  function substrateSelfVersion() {
79292
79292
  if (cached !== void 0) return cached;
79293
- if ("0.3.10".length > 0) {
79294
- cached = "0.3.10";
79293
+ if ("0.3.12".length > 0) {
79294
+ cached = "0.3.12";
79295
79295
  return cached;
79296
79296
  }
79297
79297
  cached = "unknown";
@@ -393,8 +393,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
393
393
  var cached;
394
394
  function substrateSelfVersion() {
395
395
  if (cached !== void 0) return cached;
396
- if ("0.3.10".length > 0) {
397
- cached = "0.3.10";
396
+ if ("0.3.12".length > 0) {
397
+ cached = "0.3.12";
398
398
  return cached;
399
399
  }
400
400
  cached = "unknown";
@@ -79288,8 +79288,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
79288
79288
  var cached;
79289
79289
  function substrateSelfVersion() {
79290
79290
  if (cached !== void 0) return cached;
79291
- if ("0.3.10".length > 0) {
79292
- cached = "0.3.10";
79291
+ if ("0.3.12".length > 0) {
79292
+ cached = "0.3.12";
79293
79293
  return cached;
79294
79294
  }
79295
79295
  cached = "unknown";
@@ -389,8 +389,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
389
389
  var cached;
390
390
  function substrateSelfVersion() {
391
391
  if (cached !== void 0) return cached;
392
- if ("0.3.10".length > 0) {
393
- cached = "0.3.10";
392
+ if ("0.3.12".length > 0) {
393
+ cached = "0.3.12";
394
394
  return cached;
395
395
  }
396
396
  cached = "unknown";
@@ -79324,8 +79324,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
79324
79324
  var cached;
79325
79325
  function substrateSelfVersion() {
79326
79326
  if (cached !== void 0) return cached;
79327
- if ("0.3.10".length > 0) {
79328
- cached = "0.3.10";
79327
+ if ("0.3.12".length > 0) {
79328
+ cached = "0.3.12";
79329
79329
  return cached;
79330
79330
  }
79331
79331
  cached = "unknown";
@@ -427,8 +427,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
427
427
  var cached;
428
428
  function substrateSelfVersion() {
429
429
  if (cached !== void 0) return cached;
430
- if ("0.3.10".length > 0) {
431
- cached = "0.3.10";
430
+ if ("0.3.12".length > 0) {
431
+ cached = "0.3.12";
432
432
  return cached;
433
433
  }
434
434
  cached = "unknown";
@@ -79816,8 +79816,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
79816
79816
  var cached;
79817
79817
  function substrateSelfVersion() {
79818
79818
  if (cached !== void 0) return cached;
79819
- if ("0.3.10".length > 0) {
79820
- cached = "0.3.10";
79819
+ if ("0.3.12".length > 0) {
79820
+ cached = "0.3.12";
79821
79821
  return cached;
79822
79822
  }
79823
79823
  cached = "unknown";
@@ -897,8 +897,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
897
897
  var cached;
898
898
  function substrateSelfVersion() {
899
899
  if (cached !== void 0) return cached;
900
- if ("0.3.10".length > 0) {
901
- cached = "0.3.10";
900
+ if ("0.3.12".length > 0) {
901
+ cached = "0.3.12";
902
902
  return cached;
903
903
  }
904
904
  cached = "unknown";
@@ -88273,8 +88273,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
88273
88273
  var cached;
88274
88274
  function substrateSelfVersion() {
88275
88275
  if (cached !== void 0) return cached;
88276
- if ("0.3.10".length > 0) {
88277
- cached = "0.3.10";
88276
+ if ("0.3.12".length > 0) {
88277
+ cached = "0.3.12";
88278
88278
  return cached;
88279
88279
  }
88280
88280
  cached = "unknown";
@@ -9426,8 +9426,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
9426
9426
  var cached;
9427
9427
  function substrateSelfVersion() {
9428
9428
  if (cached !== void 0) return cached;
9429
- if ("0.3.10".length > 0) {
9430
- cached = "0.3.10";
9429
+ if ("0.3.12".length > 0) {
9430
+ cached = "0.3.12";
9431
9431
  return cached;
9432
9432
  }
9433
9433
  cached = "unknown";
@@ -88825,8 +88825,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
88825
88825
  var cached;
88826
88826
  function substrateSelfVersion() {
88827
88827
  if (cached !== void 0) return cached;
88828
- if ("0.3.10".length > 0) {
88829
- cached = "0.3.10";
88828
+ if ("0.3.12".length > 0) {
88829
+ cached = "0.3.12";
88830
88830
  return cached;
88831
88831
  }
88832
88832
  cached = "unknown";
@@ -9978,8 +9978,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
9978
9978
  var cached;
9979
9979
  function substrateSelfVersion() {
9980
9980
  if (cached !== void 0) return cached;
9981
- if ("0.3.10".length > 0) {
9982
- cached = "0.3.10";
9981
+ if ("0.3.12".length > 0) {
9982
+ cached = "0.3.12";
9983
9983
  return cached;
9984
9984
  }
9985
9985
  cached = "unknown";
@@ -79288,8 +79288,8 @@ var PKG_NAME = "@databricks-solutions/lakebase-scm-utils";
79288
79288
  var cached;
79289
79289
  function substrateSelfVersion() {
79290
79290
  if (cached !== void 0) return cached;
79291
- if ("0.3.10".length > 0) {
79292
- cached = "0.3.10";
79291
+ if ("0.3.12".length > 0) {
79292
+ cached = "0.3.12";
79293
79293
  return cached;
79294
79294
  }
79295
79295
  cached = "unknown";