@treeseed/cli 0.1.1 → 0.4.0

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 (200) hide show
  1. package/README.md +27 -26
  2. package/dist/cli/handlers/auth-login.d.ts +2 -0
  3. package/dist/cli/handlers/auth-login.js +67 -0
  4. package/dist/cli/handlers/auth-logout.d.ts +2 -0
  5. package/dist/cli/handlers/auth-logout.js +20 -0
  6. package/dist/cli/handlers/auth-whoami.d.ts +2 -0
  7. package/dist/cli/handlers/auth-whoami.js +24 -0
  8. package/dist/cli/handlers/close.js +19 -53
  9. package/dist/cli/handlers/config.js +33 -53
  10. package/dist/cli/handlers/destroy.js +34 -79
  11. package/dist/{src/cli/handlers/ship.d.ts → cli/handlers/dev.d.ts} +1 -1
  12. package/dist/cli/handlers/dev.js +19 -0
  13. package/dist/cli/handlers/doctor.js +13 -6
  14. package/dist/cli/handlers/init.js +32 -8
  15. package/dist/cli/handlers/release.js +21 -53
  16. package/dist/cli/handlers/rollback.js +8 -8
  17. package/dist/cli/handlers/save.js +21 -79
  18. package/dist/cli/handlers/stage.d.ts +2 -0
  19. package/dist/cli/handlers/stage.js +28 -0
  20. package/dist/cli/handlers/status.js +35 -26
  21. package/dist/{src/cli/handlers/deploy.d.ts → cli/handlers/switch.d.ts} +1 -1
  22. package/dist/cli/handlers/switch.js +29 -0
  23. package/dist/{src/cli/handlers/next.d.ts → cli/handlers/sync.d.ts} +1 -1
  24. package/dist/cli/handlers/sync.js +26 -0
  25. package/dist/cli/handlers/tasks.d.ts +2 -0
  26. package/dist/cli/handlers/tasks.js +31 -0
  27. package/dist/cli/handlers/template.d.ts +2 -0
  28. package/dist/cli/handlers/template.js +27 -0
  29. package/dist/cli/handlers/workflow.d.ts +6 -0
  30. package/dist/cli/handlers/workflow.js +71 -0
  31. package/dist/{src/cli → cli}/help.d.ts +2 -2
  32. package/dist/cli/help.js +36 -24
  33. package/dist/cli/main.d.ts +6 -0
  34. package/dist/cli/main.js +14 -19
  35. package/dist/cli/operations-help.d.ts +1 -0
  36. package/dist/cli/operations-help.js +1 -0
  37. package/dist/cli/operations-parser.d.ts +1 -0
  38. package/dist/cli/operations-parser.js +1 -0
  39. package/dist/cli/operations-registry.d.ts +5 -0
  40. package/dist/cli/operations-registry.js +260 -0
  41. package/dist/cli/operations-types.d.ts +72 -0
  42. package/dist/cli/parser.d.ts +3 -0
  43. package/dist/cli/parser.js +1 -6
  44. package/dist/cli/registry.d.ts +25 -0
  45. package/dist/cli/registry.js +28 -416
  46. package/dist/cli/repair.js +6 -4
  47. package/dist/cli/runtime.d.ts +31 -0
  48. package/dist/cli/runtime.js +240 -111
  49. package/dist/cli/types.d.ts +1 -0
  50. package/dist/{src/cli → cli}/workflow-state.d.ts +9 -0
  51. package/dist/cli/workflow-state.js +45 -21
  52. package/package.json +13 -13
  53. package/dist/cli/handlers/continue.js +0 -23
  54. package/dist/cli/handlers/deploy.js +0 -139
  55. package/dist/cli/handlers/next.js +0 -27
  56. package/dist/cli/handlers/prepare.js +0 -8
  57. package/dist/cli/handlers/promote.js +0 -8
  58. package/dist/cli/handlers/publish.js +0 -8
  59. package/dist/cli/handlers/setup.js +0 -48
  60. package/dist/cli/handlers/ship.js +0 -49
  61. package/dist/cli/handlers/start.js +0 -97
  62. package/dist/cli/handlers/teardown.js +0 -50
  63. package/dist/cli/handlers/work.js +0 -85
  64. package/dist/scripts/aggregate-book.d.ts +0 -1
  65. package/dist/scripts/aggregate-book.js +0 -121
  66. package/dist/scripts/assert-release-tag-version.d.ts +0 -1
  67. package/dist/scripts/assert-release-tag-version.js +0 -21
  68. package/dist/scripts/build-dist.d.ts +0 -1
  69. package/dist/scripts/build-dist.js +0 -108
  70. package/dist/scripts/build-tenant-worker.d.ts +0 -1
  71. package/dist/scripts/build-tenant-worker.js +0 -36
  72. package/dist/scripts/cleanup-markdown.d.ts +0 -2
  73. package/dist/scripts/cleanup-markdown.js +0 -373
  74. package/dist/scripts/config-runtime-lib.d.ts +0 -122
  75. package/dist/scripts/config-runtime-lib.js +0 -505
  76. package/dist/scripts/config-treeseed.d.ts +0 -2
  77. package/dist/scripts/config-treeseed.js +0 -81
  78. package/dist/scripts/d1-migration-lib.d.ts +0 -6
  79. package/dist/scripts/d1-migration-lib.js +0 -90
  80. package/dist/scripts/deploy-lib.d.ts +0 -127
  81. package/dist/scripts/deploy-lib.js +0 -841
  82. package/dist/scripts/ensure-mailpit.d.ts +0 -1
  83. package/dist/scripts/ensure-mailpit.js +0 -29
  84. package/dist/scripts/git-workflow-lib.d.ts +0 -25
  85. package/dist/scripts/git-workflow-lib.js +0 -136
  86. package/dist/scripts/github-automation-lib.d.ts +0 -156
  87. package/dist/scripts/github-automation-lib.js +0 -242
  88. package/dist/scripts/local-dev-lib.d.ts +0 -9
  89. package/dist/scripts/local-dev-lib.js +0 -84
  90. package/dist/scripts/local-dev.d.ts +0 -1
  91. package/dist/scripts/local-dev.js +0 -129
  92. package/dist/scripts/logs-mailpit.d.ts +0 -1
  93. package/dist/scripts/logs-mailpit.js +0 -2
  94. package/dist/scripts/mailpit-runtime.d.ts +0 -4
  95. package/dist/scripts/mailpit-runtime.js +0 -57
  96. package/dist/scripts/package-tools.d.ts +0 -22
  97. package/dist/scripts/package-tools.js +0 -255
  98. package/dist/scripts/patch-starlight-content-path.d.ts +0 -1
  99. package/dist/scripts/patch-starlight-content-path.js +0 -172
  100. package/dist/scripts/paths.d.ts +0 -17
  101. package/dist/scripts/paths.js +0 -26
  102. package/dist/scripts/publish-package.d.ts +0 -1
  103. package/dist/scripts/publish-package.js +0 -19
  104. package/dist/scripts/release-verify.d.ts +0 -1
  105. package/dist/scripts/release-verify.js +0 -136
  106. package/dist/scripts/run-fixture-astro-command.d.ts +0 -1
  107. package/dist/scripts/run-fixture-astro-command.js +0 -18
  108. package/dist/scripts/save-deploy-preflight-lib.d.ts +0 -34
  109. package/dist/scripts/save-deploy-preflight-lib.js +0 -69
  110. package/dist/scripts/scaffold-site.d.ts +0 -2
  111. package/dist/scripts/scaffold-site.js +0 -92
  112. package/dist/scripts/stop-mailpit.d.ts +0 -1
  113. package/dist/scripts/stop-mailpit.js +0 -5
  114. package/dist/scripts/sync-dev-vars.d.ts +0 -1
  115. package/dist/scripts/sync-dev-vars.js +0 -6
  116. package/dist/scripts/template-registry-lib.d.ts +0 -47
  117. package/dist/scripts/template-registry-lib.js +0 -137
  118. package/dist/scripts/tenant-astro-command.d.ts +0 -1
  119. package/dist/scripts/tenant-astro-command.js +0 -3
  120. package/dist/scripts/tenant-build.d.ts +0 -1
  121. package/dist/scripts/tenant-build.js +0 -16
  122. package/dist/scripts/tenant-check.d.ts +0 -1
  123. package/dist/scripts/tenant-check.js +0 -7
  124. package/dist/scripts/tenant-d1-migrate-local.d.ts +0 -1
  125. package/dist/scripts/tenant-d1-migrate-local.js +0 -11
  126. package/dist/scripts/tenant-deploy.d.ts +0 -2
  127. package/dist/scripts/tenant-deploy.js +0 -180
  128. package/dist/scripts/tenant-destroy.d.ts +0 -2
  129. package/dist/scripts/tenant-destroy.js +0 -104
  130. package/dist/scripts/tenant-dev.d.ts +0 -1
  131. package/dist/scripts/tenant-dev.js +0 -171
  132. package/dist/scripts/tenant-lint.d.ts +0 -1
  133. package/dist/scripts/tenant-lint.js +0 -4
  134. package/dist/scripts/tenant-test.d.ts +0 -1
  135. package/dist/scripts/tenant-test.js +0 -4
  136. package/dist/scripts/test-cloudflare-local.d.ts +0 -1
  137. package/dist/scripts/test-cloudflare-local.js +0 -212
  138. package/dist/scripts/test-scaffold.d.ts +0 -2
  139. package/dist/scripts/test-scaffold.js +0 -297
  140. package/dist/scripts/treeseed.d.ts +0 -2
  141. package/dist/scripts/treeseed.js +0 -4
  142. package/dist/scripts/validate-templates.d.ts +0 -2
  143. package/dist/scripts/validate-templates.js +0 -4
  144. package/dist/scripts/watch-dev-lib.d.ts +0 -21
  145. package/dist/scripts/watch-dev-lib.js +0 -277
  146. package/dist/scripts/workspace-close.d.ts +0 -2
  147. package/dist/scripts/workspace-close.js +0 -24
  148. package/dist/scripts/workspace-command-e2e.d.ts +0 -2
  149. package/dist/scripts/workspace-command-e2e.js +0 -718
  150. package/dist/scripts/workspace-lint.d.ts +0 -1
  151. package/dist/scripts/workspace-lint.js +0 -9
  152. package/dist/scripts/workspace-preflight-lib.d.ts +0 -36
  153. package/dist/scripts/workspace-preflight-lib.js +0 -179
  154. package/dist/scripts/workspace-preflight.d.ts +0 -2
  155. package/dist/scripts/workspace-preflight.js +0 -22
  156. package/dist/scripts/workspace-publish-changed-packages.d.ts +0 -1
  157. package/dist/scripts/workspace-publish-changed-packages.js +0 -16
  158. package/dist/scripts/workspace-release-verify.d.ts +0 -1
  159. package/dist/scripts/workspace-release-verify.js +0 -81
  160. package/dist/scripts/workspace-release.d.ts +0 -2
  161. package/dist/scripts/workspace-release.js +0 -42
  162. package/dist/scripts/workspace-save-lib.d.ts +0 -42
  163. package/dist/scripts/workspace-save-lib.js +0 -220
  164. package/dist/scripts/workspace-save.d.ts +0 -2
  165. package/dist/scripts/workspace-save.js +0 -124
  166. package/dist/scripts/workspace-start-warning.js +0 -3
  167. package/dist/scripts/workspace-start.d.ts +0 -2
  168. package/dist/scripts/workspace-start.js +0 -71
  169. package/dist/scripts/workspace-test-unit.d.ts +0 -1
  170. package/dist/scripts/workspace-test-unit.js +0 -4
  171. package/dist/scripts/workspace-test.d.ts +0 -1
  172. package/dist/scripts/workspace-test.js +0 -11
  173. package/dist/scripts/workspace-tools.d.ts +0 -13
  174. package/dist/scripts/workspace-tools.js +0 -226
  175. package/dist/src/cli/handlers/continue.d.ts +0 -2
  176. package/dist/src/cli/handlers/prepare.d.ts +0 -2
  177. package/dist/src/cli/handlers/promote.d.ts +0 -2
  178. package/dist/src/cli/handlers/publish.d.ts +0 -2
  179. package/dist/src/cli/handlers/setup.d.ts +0 -2
  180. package/dist/src/cli/handlers/start.d.ts +0 -3
  181. package/dist/src/cli/handlers/teardown.d.ts +0 -2
  182. package/dist/src/cli/handlers/work.d.ts +0 -2
  183. package/dist/src/cli/main.d.ts +0 -6
  184. package/dist/src/cli/parser.d.ts +0 -3
  185. package/dist/src/cli/registry.d.ts +0 -27
  186. package/dist/src/cli/runtime.d.ts +0 -4
  187. package/dist/src/cli/types.d.ts +0 -71
  188. /package/dist/{src/cli → cli}/handlers/close.d.ts +0 -0
  189. /package/dist/{src/cli → cli}/handlers/config.d.ts +0 -0
  190. /package/dist/{src/cli → cli}/handlers/destroy.d.ts +0 -0
  191. /package/dist/{src/cli → cli}/handlers/doctor.d.ts +0 -0
  192. /package/dist/{src/cli → cli}/handlers/init.d.ts +0 -0
  193. /package/dist/{src/cli → cli}/handlers/release.d.ts +0 -0
  194. /package/dist/{src/cli → cli}/handlers/rollback.d.ts +0 -0
  195. /package/dist/{src/cli → cli}/handlers/save.d.ts +0 -0
  196. /package/dist/{src/cli → cli}/handlers/status.d.ts +0 -0
  197. /package/dist/{src/cli → cli}/handlers/utils.d.ts +0 -0
  198. /package/dist/{scripts/workspace-start-warning.d.ts → cli/operations-types.js} +0 -0
  199. /package/dist/{src/cli → cli}/repair.d.ts +0 -0
  200. /package/dist/{src/index.d.ts → index.d.ts} +0 -0
@@ -1 +0,0 @@
1
- export {};
@@ -1,29 +0,0 @@
1
- import { spawnSync } from 'node:child_process';
2
- import { dockerIsAvailable, findRunningMailpitContainer } from './mailpit-runtime.js';
3
- import { mailpitComposeFile, packageRoot } from './paths.js';
4
- if (!dockerIsAvailable()) {
5
- console.error('Docker is required for Treeseed form email testing. Start Docker and rerun the Mailpit command.');
6
- process.exit(1);
7
- }
8
- const existingMailpit = findRunningMailpitContainer();
9
- if (existingMailpit) {
10
- console.log(`Reusing existing Mailpit container "${existingMailpit.name}" on ports 1025 and 8025.`);
11
- process.exit(0);
12
- }
13
- const result = spawnSync('docker', ['compose', '-f', mailpitComposeFile, 'up', '-d', 'mailpit'], {
14
- encoding: 'utf8',
15
- cwd: packageRoot,
16
- env: { ...process.env },
17
- });
18
- if (result.status !== 0) {
19
- const reusedMailpit = findRunningMailpitContainer();
20
- if (reusedMailpit) {
21
- console.log(`Reusing existing Mailpit container "${reusedMailpit.name}" on ports 1025 and 8025.`);
22
- process.exit(0);
23
- }
24
- if (result.stdout)
25
- process.stdout.write(result.stdout);
26
- if (result.stderr)
27
- process.stderr.write(result.stderr);
28
- }
29
- process.exit(result.status ?? 1);
@@ -1,25 +0,0 @@
1
- export declare const STAGING_BRANCH = "staging";
2
- export declare const PRODUCTION_BRANCH = "main";
3
- export declare function gitWorkflowRoot(cwd?: string): string;
4
- export declare function assertCleanWorktree(cwd?: string): string;
5
- export declare function branchExists(repoDir: any, branchName: any): boolean;
6
- export declare function remoteBranchExists(repoDir: any, branchName: any): boolean;
7
- export declare function fetchOrigin(repoDir: any): void;
8
- export declare function ensureLocalBranchTracking(repoDir: any, branchName: any): void;
9
- export declare function checkoutBranch(repoDir: any, branchName: any): void;
10
- export declare function syncBranchWithOrigin(repoDir: any, branchName: any): void;
11
- export declare function createFeatureBranchFromStaging(cwd: any, branchName: any): {
12
- repoDir: string;
13
- baseBranch: string;
14
- branchName: any;
15
- };
16
- export declare function pushBranch(repoDir: any, branchName: any, { setUpstream }?: {
17
- setUpstream?: boolean | undefined;
18
- }): void;
19
- export declare function deleteLocalBranch(repoDir: any, branchName: any): void;
20
- export declare function deleteRemoteBranch(repoDir: any, branchName: any): boolean;
21
- export declare function mergeCurrentBranchIntoStaging(cwd: any, featureBranch: any): string;
22
- export declare function currentManagedBranch(cwd?: string): string;
23
- export declare function assertFeatureBranch(cwd?: string): string;
24
- export declare function prepareReleaseBranches(cwd?: string): string;
25
- export declare function mergeStagingIntoMain(cwd?: string): string;
@@ -1,136 +0,0 @@
1
- import { run, workspaceRoot } from './workspace-tools.js';
2
- import { currentBranch, gitStatusPorcelain, repoRoot } from './workspace-save-lib.js';
3
- export const STAGING_BRANCH = 'staging';
4
- export const PRODUCTION_BRANCH = 'main';
5
- function runGit(args, { cwd, capture = false } = {}) {
6
- return run('git', args, { cwd, capture });
7
- }
8
- export function gitWorkflowRoot(cwd = workspaceRoot()) {
9
- return repoRoot(cwd);
10
- }
11
- export function assertCleanWorktree(cwd = workspaceRoot()) {
12
- const root = gitWorkflowRoot(cwd);
13
- if (gitStatusPorcelain(root).length > 0) {
14
- throw new Error('Treeseed requires a clean git worktree before changing branches.');
15
- }
16
- return root;
17
- }
18
- export function branchExists(repoDir, branchName) {
19
- try {
20
- runGit(['show-ref', '--verify', '--quiet', `refs/heads/${branchName}`], { cwd: repoDir });
21
- return true;
22
- }
23
- catch {
24
- return false;
25
- }
26
- }
27
- export function remoteBranchExists(repoDir, branchName) {
28
- try {
29
- const output = runGit(['ls-remote', '--heads', 'origin', branchName], { cwd: repoDir, capture: true });
30
- return output.trim().length > 0;
31
- }
32
- catch {
33
- return false;
34
- }
35
- }
36
- export function fetchOrigin(repoDir) {
37
- runGit(['fetch', 'origin'], { cwd: repoDir });
38
- }
39
- export function ensureLocalBranchTracking(repoDir, branchName) {
40
- if (branchExists(repoDir, branchName)) {
41
- return;
42
- }
43
- if (remoteBranchExists(repoDir, branchName)) {
44
- runGit(['checkout', '-b', branchName, `origin/${branchName}`], { cwd: repoDir });
45
- return;
46
- }
47
- runGit(['checkout', '--orphan', branchName], { cwd: repoDir });
48
- }
49
- export function checkoutBranch(repoDir, branchName) {
50
- runGit(['checkout', branchName], { cwd: repoDir });
51
- }
52
- export function syncBranchWithOrigin(repoDir, branchName) {
53
- fetchOrigin(repoDir);
54
- if (!branchExists(repoDir, branchName) && remoteBranchExists(repoDir, branchName)) {
55
- runGit(['checkout', '-b', branchName, `origin/${branchName}`], { cwd: repoDir });
56
- }
57
- else {
58
- checkoutBranch(repoDir, branchName);
59
- }
60
- if (remoteBranchExists(repoDir, branchName)) {
61
- runGit(['pull', '--rebase', 'origin', branchName], { cwd: repoDir });
62
- }
63
- }
64
- export function createFeatureBranchFromStaging(cwd, branchName) {
65
- const repoDir = assertCleanWorktree(cwd);
66
- fetchOrigin(repoDir);
67
- if (branchExists(repoDir, branchName) || remoteBranchExists(repoDir, branchName)) {
68
- throw new Error(`Branch "${branchName}" already exists locally or on origin.`);
69
- }
70
- syncBranchWithOrigin(repoDir, STAGING_BRANCH);
71
- runGit(['checkout', '-b', branchName], { cwd: repoDir });
72
- return {
73
- repoDir,
74
- baseBranch: STAGING_BRANCH,
75
- branchName,
76
- };
77
- }
78
- export function pushBranch(repoDir, branchName, { setUpstream = false } = {}) {
79
- const args = setUpstream ? ['push', '-u', 'origin', branchName] : ['push', 'origin', branchName];
80
- runGit(args, { cwd: repoDir });
81
- }
82
- export function deleteLocalBranch(repoDir, branchName) {
83
- if (!branchExists(repoDir, branchName)) {
84
- return;
85
- }
86
- runGit(['branch', '-D', branchName], { cwd: repoDir });
87
- }
88
- export function deleteRemoteBranch(repoDir, branchName) {
89
- if (!remoteBranchExists(repoDir, branchName)) {
90
- return false;
91
- }
92
- runGit(['push', 'origin', '--delete', branchName], { cwd: repoDir });
93
- return true;
94
- }
95
- export function mergeCurrentBranchIntoStaging(cwd, featureBranch) {
96
- const repoDir = assertCleanWorktree(cwd);
97
- fetchOrigin(repoDir);
98
- syncBranchWithOrigin(repoDir, STAGING_BRANCH);
99
- runGit(['merge', '--no-ff', featureBranch, '-m', `merge: ${featureBranch} -> ${STAGING_BRANCH}`], { cwd: repoDir });
100
- pushBranch(repoDir, STAGING_BRANCH);
101
- return repoDir;
102
- }
103
- export function currentManagedBranch(cwd = workspaceRoot()) {
104
- return currentBranch(gitWorkflowRoot(cwd));
105
- }
106
- export function assertFeatureBranch(cwd = workspaceRoot()) {
107
- const branchName = currentManagedBranch(cwd);
108
- if (!branchName) {
109
- throw new Error('Unable to determine the current git branch.');
110
- }
111
- if (branchName === STAGING_BRANCH || branchName === PRODUCTION_BRANCH) {
112
- throw new Error(`Treeseed close only works on feature branches. Current branch: ${branchName}`);
113
- }
114
- return branchName;
115
- }
116
- export function prepareReleaseBranches(cwd = workspaceRoot()) {
117
- const repoDir = assertCleanWorktree(cwd);
118
- fetchOrigin(repoDir);
119
- syncBranchWithOrigin(repoDir, STAGING_BRANCH);
120
- if (remoteBranchExists(repoDir, PRODUCTION_BRANCH) || branchExists(repoDir, PRODUCTION_BRANCH)) {
121
- syncBranchWithOrigin(repoDir, PRODUCTION_BRANCH);
122
- syncBranchWithOrigin(repoDir, STAGING_BRANCH);
123
- }
124
- return repoDir;
125
- }
126
- export function mergeStagingIntoMain(cwd = workspaceRoot()) {
127
- const repoDir = prepareReleaseBranches(cwd);
128
- checkoutBranch(repoDir, PRODUCTION_BRANCH);
129
- if (remoteBranchExists(repoDir, PRODUCTION_BRANCH)) {
130
- runGit(['pull', '--rebase', 'origin', PRODUCTION_BRANCH], { cwd: repoDir });
131
- }
132
- runGit(['merge', '--no-ff', STAGING_BRANCH, '-m', `release: ${STAGING_BRANCH} -> ${PRODUCTION_BRANCH}`], { cwd: repoDir });
133
- pushBranch(repoDir, STAGING_BRANCH);
134
- pushBranch(repoDir, PRODUCTION_BRANCH);
135
- return repoDir;
136
- }
@@ -1,156 +0,0 @@
1
- export declare function getGitHubAutomationMode(): "stub" | "real";
2
- export declare function parseGitHubRepositoryFromRemote(remoteUrl: any): string | null;
3
- export declare function resolveGitHubRepositorySlug(tenantRoot: any): string;
4
- export declare function maybeResolveGitHubRepositorySlug(tenantRoot: any): string | null;
5
- export declare function resolveGitRepositoryRoot(tenantRoot: any): any;
6
- export declare function requiredGitHubEnvironment(tenantRoot: any, { scope, purpose }?: {
7
- scope?: string | undefined;
8
- purpose?: string | undefined;
9
- }): {
10
- secrets: string[];
11
- variables: string[];
12
- };
13
- export declare function requiredGitHubSecrets(tenantRoot: any): string[];
14
- export declare function renderDeployWorkflow({ workingDirectory }: {
15
- workingDirectory: any;
16
- }): string;
17
- export declare function ensureDeployWorkflow(tenantRoot: any): {
18
- workflowPath: string;
19
- changed: boolean;
20
- workingDirectory: string;
21
- mode: string;
22
- } | {
23
- workflowPath: string;
24
- changed: boolean;
25
- workingDirectory: string;
26
- mode?: undefined;
27
- };
28
- export declare function listGitHubSecretNames(repository: any, tenantRoot: any): Set<unknown>;
29
- export declare function listGitHubVariableNames(repository: any, tenantRoot: any): Set<unknown>;
30
- export declare function formatMissingSecretsReport(repository: any, missingSecrets: any, reason?: string): string;
31
- export declare function ensureGitHubSecrets(tenantRoot: any, { dryRun }?: {
32
- dryRun?: boolean | undefined;
33
- }): {
34
- existing: never[];
35
- created: never[];
36
- } | {
37
- existing: never[];
38
- created: never[];
39
- } | {
40
- existing: string[];
41
- created: string[];
42
- };
43
- export declare function ensureGitHubEnvironment(tenantRoot: any, { dryRun, scope, purpose }?: {
44
- dryRun?: boolean | undefined;
45
- scope?: string | undefined;
46
- purpose?: string | undefined;
47
- }): {
48
- repository: string | null;
49
- secrets: {
50
- existing: never[];
51
- created: never[];
52
- };
53
- variables: {
54
- existing: never[];
55
- created: never[];
56
- };
57
- skipped: string;
58
- mode: string;
59
- } | {
60
- repository: null;
61
- secrets: {
62
- existing: never[];
63
- created: never[];
64
- };
65
- variables: {
66
- existing: never[];
67
- created: never[];
68
- };
69
- skipped: string;
70
- mode?: undefined;
71
- } | {
72
- repository: string;
73
- secrets: {
74
- existing: string[];
75
- created: string[];
76
- };
77
- variables: {
78
- existing: string[];
79
- created: string[];
80
- };
81
- skipped?: undefined;
82
- mode?: undefined;
83
- };
84
- export declare function ensureGitHubDeployAutomation(tenantRoot: any, { dryRun }?: {
85
- dryRun?: boolean | undefined;
86
- }): {
87
- mode: string;
88
- workflow: {
89
- workflowPath: string;
90
- changed: boolean;
91
- workingDirectory: string;
92
- mode: string;
93
- } | {
94
- workflowPath: string;
95
- changed: boolean;
96
- workingDirectory: string;
97
- mode?: undefined;
98
- };
99
- secrets: {
100
- existing: never[];
101
- created: never[];
102
- } | {
103
- existing: never[];
104
- created: never[];
105
- } | {
106
- existing: string[];
107
- created: string[];
108
- };
109
- variables: {
110
- existing: never[];
111
- created: never[];
112
- } | {
113
- existing: never[];
114
- created: never[];
115
- } | {
116
- existing: string[];
117
- created: string[];
118
- };
119
- environment: {
120
- repository: string | null;
121
- secrets: {
122
- existing: never[];
123
- created: never[];
124
- };
125
- variables: {
126
- existing: never[];
127
- created: never[];
128
- };
129
- skipped: string;
130
- mode: string;
131
- } | {
132
- repository: null;
133
- secrets: {
134
- existing: never[];
135
- created: never[];
136
- };
137
- variables: {
138
- existing: never[];
139
- created: never[];
140
- };
141
- skipped: string;
142
- mode?: undefined;
143
- } | {
144
- repository: string;
145
- secrets: {
146
- existing: string[];
147
- created: string[];
148
- };
149
- variables: {
150
- existing: string[];
151
- created: string[];
152
- };
153
- skipped?: undefined;
154
- mode?: undefined;
155
- };
156
- };
@@ -1,242 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { dirname, relative, resolve } from 'node:path';
3
- import { spawnSync } from 'node:child_process';
4
- import { resolveTreeseedEnvironmentRegistry } from '@treeseed/core/environment';
5
- import { corePackageRoot, loadCliDeployConfig } from './package-tools.js';
6
- function envOrNull(key) {
7
- const value = process.env[key];
8
- return typeof value === 'string' && value.length > 0 ? value : null;
9
- }
10
- export function getGitHubAutomationMode() {
11
- return process.env.TREESEED_GITHUB_AUTOMATION_MODE === 'stub' ? 'stub' : 'real';
12
- }
13
- function isGitHubAutomationStubbed() {
14
- return getGitHubAutomationMode() === 'stub';
15
- }
16
- export function parseGitHubRepositoryFromRemote(remoteUrl) {
17
- if (!remoteUrl) {
18
- return null;
19
- }
20
- const sshMatch = remoteUrl.match(/^git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
21
- if (sshMatch) {
22
- return `${sshMatch[1]}/${sshMatch[2]}`;
23
- }
24
- const httpsMatch = remoteUrl.match(/^https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/);
25
- if (httpsMatch) {
26
- return `${httpsMatch[1]}/${httpsMatch[2]}`;
27
- }
28
- return null;
29
- }
30
- function runGit(args, { cwd, allowFailure = false, capture = true } = {}) {
31
- const result = spawnSync('git', args, {
32
- cwd,
33
- stdio: capture ? 'pipe' : 'inherit',
34
- encoding: 'utf8',
35
- });
36
- if (result.status !== 0 && !allowFailure) {
37
- throw new Error(result.stderr?.trim() || result.stdout?.trim() || `git ${args.join(' ')} failed`);
38
- }
39
- return result;
40
- }
41
- function runGh(args, { cwd, allowFailure = false, capture = true, input } = {}) {
42
- const result = spawnSync('gh', args, {
43
- cwd,
44
- stdio: capture || input !== undefined ? ['pipe', 'pipe', 'pipe'] : 'inherit',
45
- encoding: 'utf8',
46
- input,
47
- });
48
- if (result.error && result.error.code === 'ENOENT') {
49
- throw new Error('GitHub CLI `gh` is required for Treeseed GitHub automation.');
50
- }
51
- if (result.status !== 0 && !allowFailure) {
52
- throw new Error(result.stderr?.trim() || result.stdout?.trim() || `gh ${args.join(' ')} failed`);
53
- }
54
- return result;
55
- }
56
- export function resolveGitHubRepositorySlug(tenantRoot) {
57
- const remoteResult = runGit(['remote', 'get-url', 'origin'], { cwd: tenantRoot });
58
- const remoteUrl = remoteResult.stdout?.trim() ?? '';
59
- const repository = parseGitHubRepositoryFromRemote(remoteUrl);
60
- if (!repository) {
61
- throw new Error(`Unable to determine GitHub repository from origin remote "${remoteUrl}".`);
62
- }
63
- return repository;
64
- }
65
- export function maybeResolveGitHubRepositorySlug(tenantRoot) {
66
- try {
67
- return resolveGitHubRepositorySlug(tenantRoot);
68
- }
69
- catch {
70
- return null;
71
- }
72
- }
73
- export function resolveGitRepositoryRoot(tenantRoot) {
74
- const result = runGit(['rev-parse', '--show-toplevel'], { cwd: tenantRoot, allowFailure: true });
75
- return result.status === 0 ? result.stdout.trim() : tenantRoot;
76
- }
77
- export function requiredGitHubEnvironment(tenantRoot, { scope = 'prod', purpose = 'save' } = {}) {
78
- const deployConfig = loadCliDeployConfig(tenantRoot);
79
- const registry = resolveTreeseedEnvironmentRegistry({ deployConfig });
80
- const relevant = registry.entries.filter((entry) => entry.scopes.includes(scope)
81
- && entry.purposes.includes(purpose)
82
- && (!entry.isRelevant || entry.isRelevant(registry.context, scope, purpose)));
83
- return {
84
- secrets: [...new Set(relevant.filter((entry) => entry.targets.includes('github-secret')).map((entry) => entry.id))],
85
- variables: [...new Set(relevant.filter((entry) => entry.targets.includes('github-variable')).map((entry) => entry.id))],
86
- };
87
- }
88
- export function requiredGitHubSecrets(tenantRoot) {
89
- return requiredGitHubEnvironment(tenantRoot).secrets;
90
- }
91
- export function renderDeployWorkflow({ workingDirectory }) {
92
- const normalizedWorkingDirectory = workingDirectory && workingDirectory !== '.' ? workingDirectory : '.';
93
- const workingDirectoryLine = normalizedWorkingDirectory === '.'
94
- ? ''
95
- : ` defaults:\n run:\n working-directory: ${normalizedWorkingDirectory}\n`;
96
- const templatePath = resolve(corePackageRoot, 'templates', 'github', 'deploy.workflow.yml');
97
- const template = readFileSync(templatePath, 'utf8');
98
- return template
99
- .replace('__WORKING_DIRECTORY_BLOCK__', workingDirectoryLine)
100
- .replace('__CACHE_DEPENDENCY_PATH__', normalizedWorkingDirectory === '.' ? 'package-lock.json' : `${normalizedWorkingDirectory}/package-lock.json`);
101
- }
102
- export function ensureDeployWorkflow(tenantRoot) {
103
- if (isGitHubAutomationStubbed()) {
104
- return {
105
- workflowPath: resolve(tenantRoot, '.github', 'workflows', 'deploy.yml'),
106
- changed: false,
107
- workingDirectory: '.',
108
- mode: 'stub',
109
- };
110
- }
111
- const repositoryRoot = resolveGitRepositoryRoot(tenantRoot);
112
- const workflowPath = resolve(tenantRoot, '.github', 'workflows', 'deploy.yml');
113
- const workingDirectory = relative(repositoryRoot, tenantRoot).replaceAll('\\', '/') || '.';
114
- const expected = renderDeployWorkflow({ workingDirectory });
115
- const current = existsSync(workflowPath) ? readFileSync(workflowPath, 'utf8') : null;
116
- if (current === expected) {
117
- return { workflowPath, changed: false, workingDirectory };
118
- }
119
- mkdirSync(dirname(workflowPath), { recursive: true });
120
- writeFileSync(workflowPath, expected, 'utf8');
121
- return { workflowPath, changed: true, workingDirectory };
122
- }
123
- export function listGitHubSecretNames(repository, tenantRoot) {
124
- const result = runGh(['secret', 'list', '--repo', repository, '--json', 'name'], {
125
- cwd: tenantRoot,
126
- });
127
- return new Set((JSON.parse(result.stdout || '[]'))
128
- .map((entry) => entry?.name)
129
- .filter((value) => typeof value === 'string' && value.length > 0));
130
- }
131
- export function listGitHubVariableNames(repository, tenantRoot) {
132
- const result = runGh(['variable', 'list', '--repo', repository, '--json', 'name'], {
133
- cwd: tenantRoot,
134
- });
135
- return new Set((JSON.parse(result.stdout || '[]'))
136
- .map((entry) => entry?.name)
137
- .filter((value) => typeof value === 'string' && value.length > 0));
138
- }
139
- export function formatMissingSecretsReport(repository, missingSecrets, reason = 'missing_local_env') {
140
- const lines = [
141
- 'Treeseed GitHub secret sync failed.',
142
- `Repository: ${repository}`,
143
- `Reason: ${reason}`,
144
- 'Missing secrets:',
145
- ];
146
- for (const secret of missingSecrets) {
147
- lines.push(`- ${secret.name}: localEnv=${secret.localEnvPresent ? 'present' : 'missing'} remote=${secret.remotePresent ? 'present' : 'missing'}`);
148
- }
149
- return lines.join('\n');
150
- }
151
- export function ensureGitHubSecrets(tenantRoot, { dryRun = false } = {}) {
152
- return ensureGitHubEnvironment(tenantRoot, { dryRun }).secrets;
153
- }
154
- export function ensureGitHubEnvironment(tenantRoot, { dryRun = false, scope = 'prod', purpose = 'save' } = {}) {
155
- if (isGitHubAutomationStubbed()) {
156
- return {
157
- repository: maybeResolveGitHubRepositorySlug(tenantRoot),
158
- secrets: {
159
- existing: [],
160
- created: [],
161
- },
162
- variables: {
163
- existing: [],
164
- created: [],
165
- },
166
- skipped: 'stubbed',
167
- mode: 'stub',
168
- };
169
- }
170
- const repository = maybeResolveGitHubRepositorySlug(tenantRoot);
171
- if (!repository) {
172
- if (dryRun) {
173
- return {
174
- repository: null,
175
- secrets: { existing: [], created: [] },
176
- variables: { existing: [], created: [] },
177
- skipped: 'missing_repository',
178
- };
179
- }
180
- throw new Error('Unable to determine GitHub repository from the current tenant. Configure an origin remote before syncing GitHub secrets.');
181
- }
182
- const required = requiredGitHubEnvironment(tenantRoot, { scope, purpose });
183
- const requiredSecrets = required.secrets;
184
- const requiredVariables = required.variables;
185
- const existingSecrets = listGitHubSecretNames(repository, tenantRoot);
186
- const existingVariables = listGitHubVariableNames(repository, tenantRoot);
187
- const missingRemote = requiredSecrets.filter((name) => !existingSecrets.has(name));
188
- const missingRemoteVariables = requiredVariables.filter((name) => !existingVariables.has(name));
189
- const missingLocal = missingRemote
190
- .filter((name) => !envOrNull(name))
191
- .map((name) => ({ name, localEnvPresent: false, remotePresent: false }));
192
- const missingLocalVariables = missingRemoteVariables
193
- .filter((name) => !envOrNull(name))
194
- .map((name) => ({ name, localEnvPresent: false, remotePresent: false }));
195
- if (missingLocal.length > 0 || missingLocalVariables.length > 0) {
196
- throw new Error(formatMissingSecretsReport(repository, [...missingLocal, ...missingLocalVariables]));
197
- }
198
- const createdSecrets = [];
199
- for (const name of missingRemote) {
200
- if (dryRun) {
201
- createdSecrets.push(name);
202
- continue;
203
- }
204
- runGh(['secret', 'set', name, '--repo', repository, '--body', envOrNull(name) ?? ''], {
205
- cwd: tenantRoot,
206
- });
207
- createdSecrets.push(name);
208
- }
209
- const createdVariables = [];
210
- for (const name of missingRemoteVariables) {
211
- if (dryRun) {
212
- createdVariables.push(name);
213
- continue;
214
- }
215
- runGh(['variable', 'set', name, '--repo', repository, '--body', envOrNull(name) ?? ''], {
216
- cwd: tenantRoot,
217
- });
218
- createdVariables.push(name);
219
- }
220
- return {
221
- repository,
222
- secrets: {
223
- existing: requiredSecrets.filter((name) => existingSecrets.has(name)),
224
- created: createdSecrets,
225
- },
226
- variables: {
227
- existing: requiredVariables.filter((name) => existingVariables.has(name)),
228
- created: createdVariables,
229
- },
230
- };
231
- }
232
- export function ensureGitHubDeployAutomation(tenantRoot, { dryRun = false } = {}) {
233
- const workflow = ensureDeployWorkflow(tenantRoot);
234
- const environment = ensureGitHubEnvironment(tenantRoot, { dryRun });
235
- return {
236
- mode: getGitHubAutomationMode(),
237
- workflow,
238
- secrets: environment.secrets,
239
- variables: environment.variables,
240
- environment,
241
- };
242
- }
@@ -1,9 +0,0 @@
1
- export declare function runStep(command: any, args: any, options?: {}): void;
2
- export declare function runNodeScript(scriptRelativePath: any, args?: never[], options?: {}): void;
3
- export declare function spawnProcess(command: any, args: any, options?: {}): import("child_process").ChildProcessWithoutNullStreams;
4
- export declare function syncDevVars(overrides?: {}): void;
5
- export declare function runLocalD1Migration(persistTo: any): void;
6
- export declare function prepareCloudflareLocalRuntime({ envOverrides, persistTo, outDir }?: {
7
- envOverrides?: {} | undefined;
8
- }): void;
9
- export declare function startWranglerDev(args?: never[], options?: {}): import("child_process").ChildProcessWithoutNullStreams;
@@ -1,84 +0,0 @@
1
- import { spawn, spawnSync } from 'node:child_process';
2
- import { resolve } from 'node:path';
3
- import { runLocalD1Migrations as applyLocalD1Migrations } from './d1-migration-lib.js';
4
- import { fixtureMigrationsRoot, fixtureRoot, fixtureWranglerConfig, corePackageRoot, } from './paths.js';
5
- function mergeEnv(extraEnv = {}) {
6
- return { ...process.env, ...extraEnv };
7
- }
8
- export function runStep(command, args, options = {}) {
9
- const result = spawnSync(command, args, {
10
- stdio: 'inherit',
11
- shell: process.platform === 'win32',
12
- env: mergeEnv(options.env),
13
- cwd: options.cwd ?? process.cwd(),
14
- });
15
- if (result.status !== 0) {
16
- process.exit(result.status ?? 1);
17
- }
18
- }
19
- export function runNodeScript(scriptRelativePath, args = [], options = {}) {
20
- return runStep(process.execPath, [resolve(corePackageRoot, scriptRelativePath), ...args], {
21
- ...options,
22
- cwd: options.cwd ?? corePackageRoot,
23
- });
24
- }
25
- export function spawnProcess(command, args, options = {}) {
26
- return spawn(command, args, {
27
- stdio: options.stdio ?? 'inherit',
28
- shell: process.platform === 'win32',
29
- env: mergeEnv(options.env),
30
- cwd: options.cwd ?? process.cwd(),
31
- detached: options.detached ?? false,
32
- });
33
- }
34
- export function syncDevVars(overrides = {}) {
35
- const overrideEntries = Object.entries(overrides);
36
- runNodeScript('./scripts/sync-dev-vars.js', overrideEntries.map(([key, value]) => `${key}=${value}`), { cwd: fixtureRoot });
37
- }
38
- export function runLocalD1Migration(persistTo) {
39
- applyLocalD1Migrations({
40
- cwd: fixtureRoot,
41
- wranglerConfig: fixtureWranglerConfig,
42
- migrationsRoot: fixtureMigrationsRoot,
43
- persistTo,
44
- });
45
- }
46
- export function prepareCloudflareLocalRuntime({ envOverrides = {}, persistTo, outDir } = {}) {
47
- const mergedEnvOverrides = {
48
- TREESEED_MAILPIT_SMTP_HOST: '127.0.0.1',
49
- TREESEED_MAILPIT_SMTP_PORT: '1025',
50
- ...envOverrides,
51
- };
52
- runNodeScript('./scripts/patch-starlight-content-path.js');
53
- runNodeScript('./scripts/aggregate-book.js');
54
- runNodeScript('./scripts/ensure-mailpit.js');
55
- syncDevVars({
56
- TREESEED_LOCAL_DEV_MODE: 'cloudflare',
57
- ...mergedEnvOverrides,
58
- });
59
- runLocalD1Migration(persistTo);
60
- const astroArgs = ['astro', 'build', '--root', fixtureRoot];
61
- if (outDir) {
62
- astroArgs.push('--outDir', outDir);
63
- }
64
- runStep('npx', astroArgs, {
65
- env: {
66
- TREESEED_LOCAL_DEV_MODE: 'cloudflare',
67
- ...mergedEnvOverrides,
68
- },
69
- cwd: corePackageRoot,
70
- });
71
- runNodeScript('./scripts/build-tenant-worker.js', [], {
72
- cwd: fixtureRoot,
73
- env: {
74
- TREESEED_LOCAL_DEV_MODE: 'cloudflare',
75
- ...mergedEnvOverrides,
76
- },
77
- });
78
- }
79
- export function startWranglerDev(args = [], options = {}) {
80
- return spawnProcess('wrangler', ['dev', '--local', '--config', fixtureWranglerConfig, ...args], {
81
- ...options,
82
- cwd: options.cwd ?? fixtureRoot,
83
- });
84
- }
@@ -1 +0,0 @@
1
- export {};