@databricks-solutions/lakebase-scm-utils 0.2.48 → 0.2.49

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 (51) hide show
  1. package/dist/ci-secrets-CnGrdQV-.d.cts +84 -0
  2. package/dist/ci-secrets-CnGrdQV-.d.ts +84 -0
  3. package/dist/scripts/index.cjs +2177 -2052
  4. package/dist/scripts/index.d.cts +2 -1
  5. package/dist/scripts/index.d.ts +2 -1
  6. package/dist/scripts/index.js +253 -134
  7. package/dist/scripts/lakebase/ci-resolve-branch.cli.cjs +2 -2
  8. package/dist/scripts/lakebase/ci-resolve-branch.cli.js +2 -2
  9. package/dist/scripts/lakebase/collapse-heads.cli.cjs +2 -2
  10. package/dist/scripts/lakebase/collapse-heads.cli.js +2 -2
  11. package/dist/scripts/lakebase/detect-language.cli.cjs +2 -2
  12. package/dist/scripts/lakebase/detect-language.cli.js +2 -2
  13. package/dist/scripts/lakebase/doctor.cli.cjs +2 -2
  14. package/dist/scripts/lakebase/doctor.cli.js +2 -2
  15. package/dist/scripts/lakebase/get-connection.cli.cjs +2 -2
  16. package/dist/scripts/lakebase/get-connection.cli.js +2 -2
  17. package/dist/scripts/lakebase/index.cjs +2163 -2050
  18. package/dist/scripts/lakebase/index.d.cts +8 -0
  19. package/dist/scripts/lakebase/index.d.ts +8 -0
  20. package/dist/scripts/lakebase/index.js +243 -130
  21. package/dist/scripts/lakebase/infra-runner.cli.cjs +2 -2
  22. package/dist/scripts/lakebase/infra-runner.cli.js +2 -2
  23. package/dist/scripts/lakebase/new-migration.cli.cjs +2 -2
  24. package/dist/scripts/lakebase/new-migration.cli.js +2 -2
  25. package/dist/scripts/lakebase/schema-diff.cli.cjs +2 -2
  26. package/dist/scripts/lakebase/schema-diff.cli.js +2 -2
  27. package/dist/scripts/lakebase/schema-migrate.cli.cjs +2 -2
  28. package/dist/scripts/lakebase/schema-migrate.cli.js +2 -2
  29. package/dist/scripts/lakebase/scm-claim-feature.cli.cjs +2 -2
  30. package/dist/scripts/lakebase/scm-claim-feature.cli.js +2 -2
  31. package/dist/scripts/lakebase/scm-doctor.cli.cjs +2 -2
  32. package/dist/scripts/lakebase/scm-doctor.cli.js +2 -2
  33. package/dist/scripts/lakebase/scm-merge.cli.cjs +2216 -1994
  34. package/dist/scripts/lakebase/scm-merge.cli.js +296 -74
  35. package/dist/scripts/lakebase/scm-prepare-pr.cli.cjs +479 -86
  36. package/dist/scripts/lakebase/scm-prepare-pr.cli.js +479 -86
  37. package/dist/scripts/lakebase/scm-reconcile-tier.cli.cjs +2 -2
  38. package/dist/scripts/lakebase/scm-reconcile-tier.cli.js +2 -2
  39. package/dist/scripts/lakebase/sync-ci-secrets.cli.cjs +56 -30
  40. package/dist/scripts/lakebase/sync-ci-secrets.cli.js +56 -30
  41. package/dist/scripts/util/index.cjs +142 -25
  42. package/dist/scripts/util/index.d.cts +2 -27
  43. package/dist/scripts/util/index.d.ts +2 -27
  44. package/dist/scripts/util/index.js +136 -25
  45. package/package.json +1 -1
  46. package/scripts/lakebase/create-project.ts +2 -2
  47. package/scripts/lakebase/scm-merge.ts +21 -0
  48. package/scripts/lakebase/scm-prepare-pr.ts +10 -1
  49. package/scripts/lakebase/sync-ci-secrets.cli.ts +2 -2
  50. package/scripts/util/ci-secrets.ts +212 -26
  51. package/templates/project/common/scripts/create-token-and-sync-secrets.sh +9 -86
@@ -0,0 +1,84 @@
1
+ /** The repo Actions secrets CI needs to provision a per-PR Lakebase branch. Missing ANY of
2
+ * these leaves CI unable to produce a DATABASE_URL, so the test step aborts — the failure
3
+ * that otherwise only surfaces at promotion, an entire feature after creation. */
4
+ declare const REQUIRED_CI_SECRETS: readonly ["DATABRICKS_HOST", "LAKEBASE_PROJECT_ID", "DATABRICKS_TOKEN"];
5
+ /** The canonical CI-token lifetime: 90 days. Durable so a CI rerun / downstream migrate that
6
+ * fires long after the push still authenticates (the ~1h OAuth session expiry bug, FEIP-8020). */
7
+ declare const CI_TOKEN_LIFETIME_SECONDS = 7776000;
8
+ /** Default margin: re-mint when the live CI token expires within this window of now, so the
9
+ * about-to-fire CI run gets a token that comfortably outlives it (and a 24h bootstrap token
10
+ * is upgraded to the durable one at the first preflight). */
11
+ declare const CI_TOKEN_REMINT_MARGIN_SECONDS = 86400;
12
+ /** The ONE CI-token comment, project-scoped so it is matchable in `databricks tokens list`
13
+ * (the expiry probe) and distinct per repo. `ownerRepo` is `owner/name`; the repo NAME is used
14
+ * (matching the scaffolded create-token-and-sync-secrets.sh convention). */
15
+ declare function ciTokenComment(ownerRepo: string): string;
16
+ /** Which required CI secrets are NOT present on the repo (empty = fully provisioned). Used to
17
+ * VERIFY a sync landed — a `databricks tokens create` or `gh secret set` that fails must be
18
+ * caught here, not swallowed, so CI-auth is never silently absent. NOTE: this checks the secret
19
+ * NAME exists, not whether the token behind it is still valid — expiry is {@link ciTokenExpiry}. */
20
+ declare function missingCiSecrets(ownerRepo: string): Promise<string[]>;
21
+ interface SyncCiSecretsArgs {
22
+ /** Project root (used to resolve ownerRepo from `git remote` when not given,
23
+ * and as the cwd for the `databricks tokens create` call). */
24
+ projectDir: string;
25
+ /** Workspace host (DATABRICKS_HOST secret). Required. */
26
+ databricksHost: string;
27
+ /** Lakebase project id (LAKEBASE_PROJECT_ID secret). Required. */
28
+ lakebaseProjectId: string;
29
+ /** Token comment for `databricks tokens create`. Default: the canonical {@link ciTokenComment}. */
30
+ comment?: string;
31
+ /** Token lifetime in seconds. Default: {@link CI_TOKEN_LIFETIME_SECONDS} (90 days). */
32
+ lifetimeSeconds?: number;
33
+ /** Override the auto-detected ownerRepo (defaults to origin remote). */
34
+ ownerRepo?: string;
35
+ }
36
+ /** Synchronize Databricks + Lakebase CI secrets to the repo's Actions secrets. Mints a fresh
37
+ * canonical CI credential; a dropped mint is fail-soft (HOST/PROJECT_ID still ship) — the caller
38
+ * verifies via {@link missingCiSecrets} and surfaces the gap. */
39
+ declare function syncCiSecrets(args: SyncCiSecretsArgs): Promise<void>;
40
+ interface CiTokenExpiryArgs {
41
+ /** Project root (cwd for the CLI call + .env-based profile resolution). */
42
+ projectDir: string;
43
+ /** Workspace host the tokens live on. */
44
+ databricksHost: string;
45
+ /** ownerRepo (`owner/name`) — selects the canonical comment to match. */
46
+ ownerRepo: string;
47
+ }
48
+ /** The latest expiry (epoch ms) of a LIVE canonical CI token for this repo, or null if none.
49
+ * `databricks tokens list` returns ONLY valid (unexpired) tokens, so an expired one simply does
50
+ * not appear → null. A no-expiry token (expiry_time -1) reads as Infinity. Fail-soft: any CLI /
51
+ * parse error returns null (→ the preflight re-mints, the safe direction). */
52
+ declare function ciTokenExpiry(args: CiTokenExpiryArgs): Promise<number | null>;
53
+ interface EnsureCiSecretsFreshArgs {
54
+ projectDir: string;
55
+ databricksHost: string;
56
+ lakebaseProjectId: string;
57
+ /** Override the auto-detected ownerRepo (defaults to origin remote). */
58
+ ownerRepo?: string;
59
+ /** Re-mint when the live token expires within this window. Default: {@link CI_TOKEN_REMINT_MARGIN_SECONDS}. */
60
+ marginSeconds?: number;
61
+ /** Injected clock (ms) for tests. Defaults to Date.now. */
62
+ now?: () => number;
63
+ }
64
+ interface CiFreshnessResult {
65
+ action: "ok" | "provisioned" | "reminted" | "skipped" | "failed";
66
+ reason: string;
67
+ }
68
+ /** The expiry-aware preflight: ensure the repo's CI auth is CURRENT before a CI-triggering action
69
+ * (prepare-pr, scm-merge). Re-mints the canonical token when a required secret is missing, when
70
+ * no live canonical token exists (expired / never minted), or when the live token expires within
71
+ * the margin. A fresh token is left untouched. Throws only if a needed re-mint's sync throws;
72
+ * the caller runs it fail-soft (CI would fail anyway, so a mint failure is a loud warning). */
73
+ declare function ensureCiSecretsFresh(args: EnsureCiSecretsFreshArgs): Promise<CiFreshnessResult>;
74
+ /** The fail-soft entry both CI-dispatch seams (prepare-pr, scm-merge) use: resolve host +
75
+ * project-id from the project's `.env`, run {@link ensureCiSecretsFresh}, and NEVER throw —
76
+ * CI auth must never block opening a PR or promoting. Returns a `skipped` result when `.env`
77
+ * lacks the inputs (e.g. the pre-push hook will still refresh on the push) and a `failed` result
78
+ * when a needed re-mint's sync throws (surfaced as a loud note, not a block). */
79
+ declare function ensureCiSecretsFreshFromEnv(projectDir: string, opts?: {
80
+ ownerRepo?: string;
81
+ marginSeconds?: number;
82
+ }): Promise<CiFreshnessResult>;
83
+
84
+ export { CI_TOKEN_LIFETIME_SECONDS as C, type EnsureCiSecretsFreshArgs as E, REQUIRED_CI_SECRETS as R, type SyncCiSecretsArgs as S, CI_TOKEN_REMINT_MARGIN_SECONDS as a, type CiFreshnessResult as b, type CiTokenExpiryArgs as c, ciTokenComment as d, ciTokenExpiry as e, ensureCiSecretsFresh as f, ensureCiSecretsFreshFromEnv as g, missingCiSecrets as m, syncCiSecrets as s };
@@ -0,0 +1,84 @@
1
+ /** The repo Actions secrets CI needs to provision a per-PR Lakebase branch. Missing ANY of
2
+ * these leaves CI unable to produce a DATABASE_URL, so the test step aborts — the failure
3
+ * that otherwise only surfaces at promotion, an entire feature after creation. */
4
+ declare const REQUIRED_CI_SECRETS: readonly ["DATABRICKS_HOST", "LAKEBASE_PROJECT_ID", "DATABRICKS_TOKEN"];
5
+ /** The canonical CI-token lifetime: 90 days. Durable so a CI rerun / downstream migrate that
6
+ * fires long after the push still authenticates (the ~1h OAuth session expiry bug, FEIP-8020). */
7
+ declare const CI_TOKEN_LIFETIME_SECONDS = 7776000;
8
+ /** Default margin: re-mint when the live CI token expires within this window of now, so the
9
+ * about-to-fire CI run gets a token that comfortably outlives it (and a 24h bootstrap token
10
+ * is upgraded to the durable one at the first preflight). */
11
+ declare const CI_TOKEN_REMINT_MARGIN_SECONDS = 86400;
12
+ /** The ONE CI-token comment, project-scoped so it is matchable in `databricks tokens list`
13
+ * (the expiry probe) and distinct per repo. `ownerRepo` is `owner/name`; the repo NAME is used
14
+ * (matching the scaffolded create-token-and-sync-secrets.sh convention). */
15
+ declare function ciTokenComment(ownerRepo: string): string;
16
+ /** Which required CI secrets are NOT present on the repo (empty = fully provisioned). Used to
17
+ * VERIFY a sync landed — a `databricks tokens create` or `gh secret set` that fails must be
18
+ * caught here, not swallowed, so CI-auth is never silently absent. NOTE: this checks the secret
19
+ * NAME exists, not whether the token behind it is still valid — expiry is {@link ciTokenExpiry}. */
20
+ declare function missingCiSecrets(ownerRepo: string): Promise<string[]>;
21
+ interface SyncCiSecretsArgs {
22
+ /** Project root (used to resolve ownerRepo from `git remote` when not given,
23
+ * and as the cwd for the `databricks tokens create` call). */
24
+ projectDir: string;
25
+ /** Workspace host (DATABRICKS_HOST secret). Required. */
26
+ databricksHost: string;
27
+ /** Lakebase project id (LAKEBASE_PROJECT_ID secret). Required. */
28
+ lakebaseProjectId: string;
29
+ /** Token comment for `databricks tokens create`. Default: the canonical {@link ciTokenComment}. */
30
+ comment?: string;
31
+ /** Token lifetime in seconds. Default: {@link CI_TOKEN_LIFETIME_SECONDS} (90 days). */
32
+ lifetimeSeconds?: number;
33
+ /** Override the auto-detected ownerRepo (defaults to origin remote). */
34
+ ownerRepo?: string;
35
+ }
36
+ /** Synchronize Databricks + Lakebase CI secrets to the repo's Actions secrets. Mints a fresh
37
+ * canonical CI credential; a dropped mint is fail-soft (HOST/PROJECT_ID still ship) — the caller
38
+ * verifies via {@link missingCiSecrets} and surfaces the gap. */
39
+ declare function syncCiSecrets(args: SyncCiSecretsArgs): Promise<void>;
40
+ interface CiTokenExpiryArgs {
41
+ /** Project root (cwd for the CLI call + .env-based profile resolution). */
42
+ projectDir: string;
43
+ /** Workspace host the tokens live on. */
44
+ databricksHost: string;
45
+ /** ownerRepo (`owner/name`) — selects the canonical comment to match. */
46
+ ownerRepo: string;
47
+ }
48
+ /** The latest expiry (epoch ms) of a LIVE canonical CI token for this repo, or null if none.
49
+ * `databricks tokens list` returns ONLY valid (unexpired) tokens, so an expired one simply does
50
+ * not appear → null. A no-expiry token (expiry_time -1) reads as Infinity. Fail-soft: any CLI /
51
+ * parse error returns null (→ the preflight re-mints, the safe direction). */
52
+ declare function ciTokenExpiry(args: CiTokenExpiryArgs): Promise<number | null>;
53
+ interface EnsureCiSecretsFreshArgs {
54
+ projectDir: string;
55
+ databricksHost: string;
56
+ lakebaseProjectId: string;
57
+ /** Override the auto-detected ownerRepo (defaults to origin remote). */
58
+ ownerRepo?: string;
59
+ /** Re-mint when the live token expires within this window. Default: {@link CI_TOKEN_REMINT_MARGIN_SECONDS}. */
60
+ marginSeconds?: number;
61
+ /** Injected clock (ms) for tests. Defaults to Date.now. */
62
+ now?: () => number;
63
+ }
64
+ interface CiFreshnessResult {
65
+ action: "ok" | "provisioned" | "reminted" | "skipped" | "failed";
66
+ reason: string;
67
+ }
68
+ /** The expiry-aware preflight: ensure the repo's CI auth is CURRENT before a CI-triggering action
69
+ * (prepare-pr, scm-merge). Re-mints the canonical token when a required secret is missing, when
70
+ * no live canonical token exists (expired / never minted), or when the live token expires within
71
+ * the margin. A fresh token is left untouched. Throws only if a needed re-mint's sync throws;
72
+ * the caller runs it fail-soft (CI would fail anyway, so a mint failure is a loud warning). */
73
+ declare function ensureCiSecretsFresh(args: EnsureCiSecretsFreshArgs): Promise<CiFreshnessResult>;
74
+ /** The fail-soft entry both CI-dispatch seams (prepare-pr, scm-merge) use: resolve host +
75
+ * project-id from the project's `.env`, run {@link ensureCiSecretsFresh}, and NEVER throw —
76
+ * CI auth must never block opening a PR or promoting. Returns a `skipped` result when `.env`
77
+ * lacks the inputs (e.g. the pre-push hook will still refresh on the push) and a `failed` result
78
+ * when a needed re-mint's sync throws (surfaced as a loud note, not a block). */
79
+ declare function ensureCiSecretsFreshFromEnv(projectDir: string, opts?: {
80
+ ownerRepo?: string;
81
+ marginSeconds?: number;
82
+ }): Promise<CiFreshnessResult>;
83
+
84
+ export { CI_TOKEN_LIFETIME_SECONDS as C, type EnsureCiSecretsFreshArgs as E, REQUIRED_CI_SECRETS as R, type SyncCiSecretsArgs as S, CI_TOKEN_REMINT_MARGIN_SECONDS as a, type CiFreshnessResult as b, type CiTokenExpiryArgs as c, ciTokenComment as d, ciTokenExpiry as e, ensureCiSecretsFresh as f, ensureCiSecretsFreshFromEnv as g, missingCiSecrets as m, syncCiSecrets as s };