@treeseed/sdk 0.4.12 → 0.5.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.
- package/dist/control-plane-client.d.ts +60 -1
- package/dist/control-plane-client.js +59 -0
- package/dist/control-plane.d.ts +1 -1
- package/dist/control-plane.js +11 -4
- package/dist/d1-store.d.ts +58 -0
- package/dist/d1-store.js +64 -0
- package/dist/dispatch.js +6 -0
- package/dist/graph/schema.js +4 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +32 -0
- package/dist/knowledge-coop.d.ts +223 -0
- package/dist/knowledge-coop.js +82 -0
- package/dist/model-registry.js +79 -0
- package/dist/operations/providers/default.js +128 -7
- package/dist/operations/services/config-runtime.d.ts +102 -24
- package/dist/operations/services/config-runtime.js +896 -160
- package/dist/operations/services/deploy.d.ts +223 -15
- package/dist/operations/services/deploy.js +626 -55
- package/dist/operations/services/git-workflow.d.ts +47 -3
- package/dist/operations/services/git-workflow.js +125 -19
- package/dist/operations/services/github-automation.d.ts +85 -0
- package/dist/operations/services/github-automation.js +220 -1
- package/dist/operations/services/key-agent.d.ts +118 -0
- package/dist/operations/services/key-agent.js +476 -0
- package/dist/operations/services/knowledge-coop-launch.d.ts +90 -0
- package/dist/operations/services/knowledge-coop-launch.js +753 -0
- package/dist/operations/services/knowledge-coop-packaging.d.ts +59 -0
- package/dist/operations/services/knowledge-coop-packaging.js +234 -0
- package/dist/operations/services/local-dev.d.ts +0 -1
- package/dist/operations/services/local-dev.js +1 -14
- package/dist/operations/services/project-platform.d.ts +42 -182
- package/dist/operations/services/project-platform.js +162 -59
- package/dist/operations/services/railway-deploy.d.ts +1 -0
- package/dist/operations/services/railway-deploy.js +31 -13
- package/dist/operations/services/runtime-tools.d.ts +52 -5
- package/dist/operations/services/runtime-tools.js +186 -26
- package/dist/operations/services/watch-dev.js +2 -4
- package/dist/operations/services/workspace-preflight.d.ts +4 -4
- package/dist/operations/services/workspace-preflight.js +22 -20
- package/dist/operations/services/workspace-save.d.ts +10 -1
- package/dist/operations/services/workspace-save.js +54 -3
- package/dist/operations/services/workspace-tools.d.ts +1 -0
- package/dist/operations/services/workspace-tools.js +20 -5
- package/dist/operations-registry.js +15 -8
- package/dist/operations-types.d.ts +2 -2
- package/dist/platform/contracts.d.ts +39 -3
- package/dist/platform/deploy-config.d.ts +12 -1
- package/dist/platform/deploy-config.js +214 -15
- package/dist/platform/deploy-runtime.d.ts +1 -0
- package/dist/platform/deploy-runtime.js +10 -2
- package/dist/platform/env.yaml +93 -61
- package/dist/platform/environment.d.ts +13 -2
- package/dist/platform/environment.js +90 -20
- package/dist/platform/plugins/constants.d.ts +1 -0
- package/dist/platform/plugins/constants.js +7 -6
- package/dist/platform/tenant/runtime-config.js +8 -1
- package/dist/platform/tenant-config.js +4 -0
- package/dist/platform/utils/site-config-schema.js +18 -0
- package/dist/plugin-default.js +2 -2
- package/dist/scripts/key-agent.js +165 -0
- package/dist/scripts/tenant-build.js +4 -1
- package/dist/scripts/tenant-check.js +4 -1
- package/dist/scripts/tenant-deploy.js +43 -4
- package/dist/scripts/tenant-dev.js +0 -1
- package/dist/scripts/workspace-start-warning.js +2 -2
- package/dist/sdk-types.d.ts +2 -2
- package/dist/sdk-types.js +2 -0
- package/dist/sdk.d.ts +13 -0
- package/dist/sdk.js +40 -0
- package/dist/stores/knowledge-coop-store.d.ts +56 -0
- package/dist/stores/knowledge-coop-store.js +482 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/package.json +6 -2
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/api/server.js +4 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/config.yaml +25 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/decisions/adopt-initial-proposal-loop.mdx +22 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/people/starter-steward.mdx +11 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/proposals/establish-initial-proposal-loop.mdx +17 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/manifest.yaml +17 -10
- package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +69 -7
- package/dist/treeseed/template-catalog/templates/starter-basic/template.config.json +1 -0
- package/dist/workflow/operations.d.ts +592 -243
- package/dist/workflow/operations.js +1908 -219
- package/dist/workflow/runs.d.ts +90 -0
- package/dist/workflow/runs.js +242 -0
- package/dist/workflow/session.d.ts +31 -0
- package/dist/workflow/session.js +97 -0
- package/dist/workflow-state.d.ts +88 -2
- package/dist/workflow-state.js +288 -26
- package/dist/workflow-support.d.ts +1 -1
- package/dist/workflow-support.js +32 -2
- package/dist/workflow.d.ts +93 -3
- package/dist/workflow.js +12 -0
- package/package.json +1 -1
- package/templates/github/deploy.workflow.yml +11 -1
- package/dist/scripts/sync-dev-vars.js +0 -6
- package/dist/scripts/workspace-close.js +0 -24
- package/dist/scripts/workspace-release.js +0 -42
- package/dist/scripts/workspace-start.js +0 -71
|
@@ -1,24 +1,55 @@
|
|
|
1
1
|
export declare const STAGING_BRANCH = "staging";
|
|
2
2
|
export declare const PRODUCTION_BRANCH = "main";
|
|
3
|
+
export declare function headCommit(repoDir: any, ref?: string): string;
|
|
3
4
|
export declare function gitWorkflowRoot(cwd?: any): string;
|
|
4
5
|
export declare function assertCleanWorktree(cwd?: any): string;
|
|
6
|
+
export declare function assertCleanWorktrees(repoDirs: any): any;
|
|
5
7
|
export declare function branchExists(repoDir: any, branchName: any): boolean;
|
|
6
8
|
export declare function remoteBranchExists(repoDir: any, branchName: any): boolean;
|
|
7
9
|
export declare function fetchOrigin(repoDir: any): void;
|
|
8
10
|
export declare function ensureLocalBranchTracking(repoDir: any, branchName: any): void;
|
|
9
11
|
export declare function checkoutBranch(repoDir: any, branchName: any): void;
|
|
12
|
+
export declare function checkoutTaskBranchFromStaging(cwd: any, branchName: any, { createIfMissing, pushIfCreated }?: {
|
|
13
|
+
createIfMissing?: boolean | undefined;
|
|
14
|
+
pushIfCreated?: boolean | undefined;
|
|
15
|
+
}): {
|
|
16
|
+
repoDir: string;
|
|
17
|
+
branchName: any;
|
|
18
|
+
baseBranch: string;
|
|
19
|
+
created: boolean;
|
|
20
|
+
resumed: boolean;
|
|
21
|
+
remoteBranch: boolean;
|
|
22
|
+
};
|
|
10
23
|
export declare function syncBranchWithOrigin(repoDir: any, branchName: any): void;
|
|
11
24
|
export declare function createFeatureBranchFromStaging(cwd: any, branchName: any): {
|
|
12
25
|
repoDir: string;
|
|
13
|
-
baseBranch: string;
|
|
14
26
|
branchName: any;
|
|
27
|
+
baseBranch: string;
|
|
28
|
+
created: boolean;
|
|
29
|
+
resumed: boolean;
|
|
30
|
+
remoteBranch: boolean;
|
|
15
31
|
};
|
|
16
32
|
export declare function pushBranch(repoDir: any, branchName: any, { setUpstream }?: {
|
|
17
33
|
setUpstream?: boolean | undefined;
|
|
18
34
|
}): void;
|
|
19
35
|
export declare function deleteLocalBranch(repoDir: any, branchName: any): void;
|
|
20
36
|
export declare function deleteRemoteBranch(repoDir: any, branchName: any): boolean;
|
|
21
|
-
export declare function mergeCurrentBranchIntoStaging(cwd: any, featureBranch: any):
|
|
37
|
+
export declare function mergeCurrentBranchIntoStaging(cwd: any, featureBranch: any): {
|
|
38
|
+
repoDir: string;
|
|
39
|
+
targetBranch: string;
|
|
40
|
+
committed: boolean;
|
|
41
|
+
commitSha: string;
|
|
42
|
+
pushed: boolean;
|
|
43
|
+
};
|
|
44
|
+
export declare function squashMergeBranchIntoStaging(cwd: any, featureBranch: any, message: any, { pushTarget }?: {
|
|
45
|
+
pushTarget?: boolean | undefined;
|
|
46
|
+
}): {
|
|
47
|
+
repoDir: string;
|
|
48
|
+
targetBranch: string;
|
|
49
|
+
committed: boolean;
|
|
50
|
+
commitSha: string;
|
|
51
|
+
pushed: boolean;
|
|
52
|
+
};
|
|
22
53
|
export declare function currentManagedBranch(cwd?: any): string;
|
|
23
54
|
export declare function isTaskBranch(branchName: any): boolean;
|
|
24
55
|
export declare function assertFeatureBranch(cwd?: any): string;
|
|
@@ -46,4 +77,17 @@ export declare function waitForStagingAutomation(repoDir: any): {
|
|
|
46
77
|
reason?: undefined;
|
|
47
78
|
};
|
|
48
79
|
export declare function prepareReleaseBranches(cwd?: any): string;
|
|
49
|
-
export declare function mergeStagingIntoMain(cwd?: any):
|
|
80
|
+
export declare function mergeStagingIntoMain(cwd?: any): {
|
|
81
|
+
repoDir: string;
|
|
82
|
+
targetBranch: any;
|
|
83
|
+
commitSha: string;
|
|
84
|
+
pushed: boolean;
|
|
85
|
+
};
|
|
86
|
+
export declare function mergeBranchIntoTarget(cwd?: any, { sourceBranch, targetBranch, message, pushTarget }?: {
|
|
87
|
+
pushTarget?: boolean | undefined;
|
|
88
|
+
}): {
|
|
89
|
+
repoDir: string;
|
|
90
|
+
targetBranch: any;
|
|
91
|
+
commitSha: string;
|
|
92
|
+
pushed: boolean;
|
|
93
|
+
};
|
|
@@ -6,6 +6,17 @@ const RESERVED_BRANCHES = /* @__PURE__ */ new Set([STAGING_BRANCH, PRODUCTION_BR
|
|
|
6
6
|
function runGit(args, { cwd, capture = false } = {}) {
|
|
7
7
|
return run("git", args, { cwd, capture });
|
|
8
8
|
}
|
|
9
|
+
function repoHasStagedChanges(repoDir) {
|
|
10
|
+
try {
|
|
11
|
+
runGit(["diff", "--cached", "--quiet"], { cwd: repoDir });
|
|
12
|
+
return false;
|
|
13
|
+
} catch {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function headCommit(repoDir, ref = "HEAD") {
|
|
18
|
+
return runGit(["rev-parse", ref], { cwd: repoDir, capture: true }).trim();
|
|
19
|
+
}
|
|
9
20
|
function gitWorkflowRoot(cwd = workspaceRoot()) {
|
|
10
21
|
return repoRoot(cwd);
|
|
11
22
|
}
|
|
@@ -16,6 +27,12 @@ function assertCleanWorktree(cwd = workspaceRoot()) {
|
|
|
16
27
|
}
|
|
17
28
|
return root;
|
|
18
29
|
}
|
|
30
|
+
function assertCleanWorktrees(repoDirs) {
|
|
31
|
+
for (const repoDir of repoDirs) {
|
|
32
|
+
assertCleanWorktree(repoDir);
|
|
33
|
+
}
|
|
34
|
+
return repoDirs;
|
|
35
|
+
}
|
|
19
36
|
function branchExists(repoDir, branchName) {
|
|
20
37
|
try {
|
|
21
38
|
runGit(["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`], { cwd: repoDir });
|
|
@@ -48,6 +65,63 @@ function ensureLocalBranchTracking(repoDir, branchName) {
|
|
|
48
65
|
function checkoutBranch(repoDir, branchName) {
|
|
49
66
|
runGit(["checkout", branchName], { cwd: repoDir });
|
|
50
67
|
}
|
|
68
|
+
function checkoutTaskBranchFromStaging(cwd, branchName, { createIfMissing = true, pushIfCreated = false } = {}) {
|
|
69
|
+
const repoDir = assertCleanWorktree(cwd);
|
|
70
|
+
fetchOrigin(repoDir);
|
|
71
|
+
syncBranchWithOrigin(repoDir, STAGING_BRANCH);
|
|
72
|
+
if (currentBranch(repoDir) === branchName) {
|
|
73
|
+
return {
|
|
74
|
+
repoDir,
|
|
75
|
+
branchName,
|
|
76
|
+
baseBranch: STAGING_BRANCH,
|
|
77
|
+
created: false,
|
|
78
|
+
resumed: true,
|
|
79
|
+
remoteBranch: remoteBranchExists(repoDir, branchName)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (branchExists(repoDir, branchName)) {
|
|
83
|
+
checkoutBranch(repoDir, branchName);
|
|
84
|
+
if (remoteBranchExists(repoDir, branchName)) {
|
|
85
|
+
runGit(["pull", "--rebase", "origin", branchName], { cwd: repoDir });
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
repoDir,
|
|
89
|
+
branchName,
|
|
90
|
+
baseBranch: STAGING_BRANCH,
|
|
91
|
+
created: false,
|
|
92
|
+
resumed: true,
|
|
93
|
+
remoteBranch: remoteBranchExists(repoDir, branchName)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (remoteBranchExists(repoDir, branchName)) {
|
|
97
|
+
runGit(["checkout", "-b", branchName, `origin/${branchName}`], { cwd: repoDir });
|
|
98
|
+
runGit(["pull", "--rebase", "origin", branchName], { cwd: repoDir });
|
|
99
|
+
return {
|
|
100
|
+
repoDir,
|
|
101
|
+
branchName,
|
|
102
|
+
baseBranch: STAGING_BRANCH,
|
|
103
|
+
created: false,
|
|
104
|
+
resumed: true,
|
|
105
|
+
remoteBranch: true
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (!createIfMissing) {
|
|
109
|
+
throw new Error(`Branch "${branchName}" does not exist locally or on origin.`);
|
|
110
|
+
}
|
|
111
|
+
checkoutBranch(repoDir, STAGING_BRANCH);
|
|
112
|
+
runGit(["checkout", "-b", branchName], { cwd: repoDir });
|
|
113
|
+
if (pushIfCreated) {
|
|
114
|
+
pushBranch(repoDir, branchName, { setUpstream: true });
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
repoDir,
|
|
118
|
+
branchName,
|
|
119
|
+
baseBranch: STAGING_BRANCH,
|
|
120
|
+
created: true,
|
|
121
|
+
resumed: false,
|
|
122
|
+
remoteBranch: pushIfCreated
|
|
123
|
+
};
|
|
124
|
+
}
|
|
51
125
|
function syncBranchWithOrigin(repoDir, branchName) {
|
|
52
126
|
fetchOrigin(repoDir);
|
|
53
127
|
if (!branchExists(repoDir, branchName) && remoteBranchExists(repoDir, branchName)) {
|
|
@@ -60,18 +134,14 @@ function syncBranchWithOrigin(repoDir, branchName) {
|
|
|
60
134
|
}
|
|
61
135
|
}
|
|
62
136
|
function createFeatureBranchFromStaging(cwd, branchName) {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
137
|
+
const result = checkoutTaskBranchFromStaging(cwd, branchName, {
|
|
138
|
+
createIfMissing: true,
|
|
139
|
+
pushIfCreated: false
|
|
140
|
+
});
|
|
141
|
+
if (!result.created) {
|
|
66
142
|
throw new Error(`Branch "${branchName}" already exists locally or on origin.`);
|
|
67
143
|
}
|
|
68
|
-
|
|
69
|
-
runGit(["checkout", "-b", branchName], { cwd: repoDir });
|
|
70
|
-
return {
|
|
71
|
-
repoDir,
|
|
72
|
-
baseBranch: STAGING_BRANCH,
|
|
73
|
-
branchName
|
|
74
|
-
};
|
|
144
|
+
return result;
|
|
75
145
|
}
|
|
76
146
|
function pushBranch(repoDir, branchName, { setUpstream = false } = {}) {
|
|
77
147
|
const args = setUpstream ? ["push", "-u", "origin", branchName] : ["push", "origin", branchName];
|
|
@@ -91,12 +161,28 @@ function deleteRemoteBranch(repoDir, branchName) {
|
|
|
91
161
|
return true;
|
|
92
162
|
}
|
|
93
163
|
function mergeCurrentBranchIntoStaging(cwd, featureBranch) {
|
|
164
|
+
return squashMergeBranchIntoStaging(cwd, featureBranch, `stage: ${featureBranch}`);
|
|
165
|
+
}
|
|
166
|
+
function squashMergeBranchIntoStaging(cwd, featureBranch, message, { pushTarget = true } = {}) {
|
|
94
167
|
const repoDir = assertCleanWorktree(cwd);
|
|
95
168
|
fetchOrigin(repoDir);
|
|
96
169
|
syncBranchWithOrigin(repoDir, STAGING_BRANCH);
|
|
97
|
-
runGit(["merge", "--
|
|
98
|
-
|
|
99
|
-
|
|
170
|
+
runGit(["merge", "--squash", featureBranch], { cwd: repoDir });
|
|
171
|
+
let committed = false;
|
|
172
|
+
if (repoHasStagedChanges(repoDir)) {
|
|
173
|
+
runGit(["commit", "-m", message], { cwd: repoDir });
|
|
174
|
+
committed = true;
|
|
175
|
+
}
|
|
176
|
+
if (pushTarget) {
|
|
177
|
+
pushBranch(repoDir, STAGING_BRANCH);
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
repoDir,
|
|
181
|
+
targetBranch: STAGING_BRANCH,
|
|
182
|
+
committed,
|
|
183
|
+
commitSha: headCommit(repoDir),
|
|
184
|
+
pushed: pushTarget
|
|
185
|
+
};
|
|
100
186
|
}
|
|
101
187
|
function currentManagedBranch(cwd = workspaceRoot()) {
|
|
102
188
|
return currentBranch(gitWorkflowRoot(cwd));
|
|
@@ -180,23 +266,40 @@ function prepareReleaseBranches(cwd = workspaceRoot()) {
|
|
|
180
266
|
return repoDir;
|
|
181
267
|
}
|
|
182
268
|
function mergeStagingIntoMain(cwd = workspaceRoot()) {
|
|
269
|
+
return mergeBranchIntoTarget(cwd, {
|
|
270
|
+
sourceBranch: STAGING_BRANCH,
|
|
271
|
+
targetBranch: PRODUCTION_BRANCH,
|
|
272
|
+
message: `release: ${STAGING_BRANCH} -> ${PRODUCTION_BRANCH}`,
|
|
273
|
+
pushTarget: true
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
function mergeBranchIntoTarget(cwd = workspaceRoot(), { sourceBranch, targetBranch, message, pushTarget = true } = {}) {
|
|
183
277
|
const repoDir = prepareReleaseBranches(cwd);
|
|
184
|
-
checkoutBranch(repoDir,
|
|
185
|
-
if (remoteBranchExists(repoDir,
|
|
186
|
-
runGit(["pull", "--rebase", "origin",
|
|
278
|
+
checkoutBranch(repoDir, targetBranch);
|
|
279
|
+
if (remoteBranchExists(repoDir, targetBranch)) {
|
|
280
|
+
runGit(["pull", "--rebase", "origin", targetBranch], { cwd: repoDir });
|
|
187
281
|
}
|
|
188
|
-
runGit(["merge", "--no-ff",
|
|
282
|
+
runGit(["merge", "--no-ff", sourceBranch, "-m", message], { cwd: repoDir });
|
|
189
283
|
pushBranch(repoDir, STAGING_BRANCH);
|
|
190
|
-
|
|
191
|
-
|
|
284
|
+
if (pushTarget) {
|
|
285
|
+
pushBranch(repoDir, targetBranch);
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
repoDir,
|
|
289
|
+
targetBranch,
|
|
290
|
+
commitSha: headCommit(repoDir),
|
|
291
|
+
pushed: pushTarget
|
|
292
|
+
};
|
|
192
293
|
}
|
|
193
294
|
export {
|
|
194
295
|
PRODUCTION_BRANCH,
|
|
195
296
|
STAGING_BRANCH,
|
|
196
297
|
assertCleanWorktree,
|
|
298
|
+
assertCleanWorktrees,
|
|
197
299
|
assertFeatureBranch,
|
|
198
300
|
branchExists,
|
|
199
301
|
checkoutBranch,
|
|
302
|
+
checkoutTaskBranchFromStaging,
|
|
200
303
|
createDeprecatedTaskTag,
|
|
201
304
|
createFeatureBranchFromStaging,
|
|
202
305
|
currentManagedBranch,
|
|
@@ -205,13 +308,16 @@ export {
|
|
|
205
308
|
ensureLocalBranchTracking,
|
|
206
309
|
fetchOrigin,
|
|
207
310
|
gitWorkflowRoot,
|
|
311
|
+
headCommit,
|
|
208
312
|
isTaskBranch,
|
|
209
313
|
listTaskBranches,
|
|
314
|
+
mergeBranchIntoTarget,
|
|
210
315
|
mergeCurrentBranchIntoStaging,
|
|
211
316
|
mergeStagingIntoMain,
|
|
212
317
|
prepareReleaseBranches,
|
|
213
318
|
pushBranch,
|
|
214
319
|
remoteBranchExists,
|
|
320
|
+
squashMergeBranchIntoStaging,
|
|
215
321
|
syncBranchWithOrigin,
|
|
216
322
|
taskTagSlug,
|
|
217
323
|
waitForStagingAutomation
|
|
@@ -1,7 +1,67 @@
|
|
|
1
|
+
export interface GitHubRepositoryProvisionInput {
|
|
2
|
+
owner: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description?: string | null;
|
|
5
|
+
visibility?: 'private' | 'public' | 'internal';
|
|
6
|
+
homepageUrl?: string | null;
|
|
7
|
+
topics?: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface GitHubProvisionedRepository {
|
|
10
|
+
slug: string;
|
|
11
|
+
owner: string;
|
|
12
|
+
name: string;
|
|
13
|
+
url: string;
|
|
14
|
+
sshUrl: string;
|
|
15
|
+
httpsUrl: string;
|
|
16
|
+
visibility: 'private' | 'public' | 'internal';
|
|
17
|
+
defaultBranch: string;
|
|
18
|
+
}
|
|
1
19
|
export declare function getGitHubAutomationMode(): "stub" | "real";
|
|
2
20
|
export declare function parseGitHubRepositoryFromRemote(remoteUrl: any): string | null;
|
|
3
21
|
export declare function resolveGitHubRepositorySlug(tenantRoot: any): string;
|
|
4
22
|
export declare function maybeResolveGitHubRepositorySlug(tenantRoot: any): string | null;
|
|
23
|
+
export declare function resolveDefaultGitHubOwner(): string;
|
|
24
|
+
export declare function createGitHubRepository(input: any): {
|
|
25
|
+
visibility: any;
|
|
26
|
+
defaultBranch: string;
|
|
27
|
+
mode: string;
|
|
28
|
+
slug: string;
|
|
29
|
+
owner: string;
|
|
30
|
+
name: string;
|
|
31
|
+
sshUrl: string;
|
|
32
|
+
httpsUrl: string;
|
|
33
|
+
url: string;
|
|
34
|
+
} | {
|
|
35
|
+
owner: string;
|
|
36
|
+
name: string;
|
|
37
|
+
url: string;
|
|
38
|
+
visibility: string;
|
|
39
|
+
defaultBranch: string;
|
|
40
|
+
slug: string;
|
|
41
|
+
sshUrl: string;
|
|
42
|
+
httpsUrl: string;
|
|
43
|
+
};
|
|
44
|
+
export declare function initializeGitHubRepositoryWorkingTree(cwd: any, repository: any, { defaultBranch, createStaging, commitMessage, remoteName, push, }?: {
|
|
45
|
+
defaultBranch?: string | undefined;
|
|
46
|
+
createStaging?: boolean | undefined;
|
|
47
|
+
commitMessage?: string | undefined;
|
|
48
|
+
remoteName?: string | undefined;
|
|
49
|
+
push?: boolean | undefined;
|
|
50
|
+
}): {
|
|
51
|
+
repository: any;
|
|
52
|
+
remoteName: string;
|
|
53
|
+
defaultBranch: string;
|
|
54
|
+
stagingBranch: string | null;
|
|
55
|
+
pushed: boolean;
|
|
56
|
+
mode: string;
|
|
57
|
+
} | {
|
|
58
|
+
repository: any;
|
|
59
|
+
remoteName: string;
|
|
60
|
+
defaultBranch: string;
|
|
61
|
+
stagingBranch: string | null;
|
|
62
|
+
pushed: boolean;
|
|
63
|
+
mode?: undefined;
|
|
64
|
+
};
|
|
5
65
|
export declare function resolveGitRepositoryRoot(tenantRoot: any): any;
|
|
6
66
|
export declare function requiredGitHubEnvironment(tenantRoot: any, { scope, purpose }?: {
|
|
7
67
|
scope?: string | undefined;
|
|
@@ -190,3 +250,28 @@ export declare function ensureGitHubDeployAutomation(tenantRoot: any, { dryRun }
|
|
|
190
250
|
mode?: undefined;
|
|
191
251
|
};
|
|
192
252
|
};
|
|
253
|
+
export declare function waitForGitHubWorkflowCompletion(tenantRoot: any, { repository, workflow, headSha, branch, timeoutSeconds, pollSeconds, }?: {
|
|
254
|
+
workflow?: string | undefined;
|
|
255
|
+
timeoutSeconds?: number | undefined;
|
|
256
|
+
pollSeconds?: number | undefined;
|
|
257
|
+
}): {
|
|
258
|
+
status: string;
|
|
259
|
+
reason: string;
|
|
260
|
+
repository: any;
|
|
261
|
+
workflow: string;
|
|
262
|
+
headSha: any;
|
|
263
|
+
branch: any;
|
|
264
|
+
runId?: undefined;
|
|
265
|
+
conclusion?: undefined;
|
|
266
|
+
url?: undefined;
|
|
267
|
+
} | {
|
|
268
|
+
status: string;
|
|
269
|
+
repository: any;
|
|
270
|
+
workflow: string;
|
|
271
|
+
runId: any;
|
|
272
|
+
headSha: any;
|
|
273
|
+
conclusion: any;
|
|
274
|
+
url: any;
|
|
275
|
+
reason?: undefined;
|
|
276
|
+
branch?: undefined;
|
|
277
|
+
};
|
|
@@ -7,6 +7,9 @@ function envOrNull(key) {
|
|
|
7
7
|
const value = process.env[key];
|
|
8
8
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
9
9
|
}
|
|
10
|
+
function slugifySegment(value, fallback = "project") {
|
|
11
|
+
return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-").slice(0, 96) || fallback;
|
|
12
|
+
}
|
|
10
13
|
function getGitHubAutomationMode() {
|
|
11
14
|
return process.env.TREESEED_GITHUB_AUTOMATION_MODE === "stub" ? "stub" : "real";
|
|
12
15
|
}
|
|
@@ -53,6 +56,36 @@ function runGh(args, { cwd, allowFailure = false, capture = true, input } = {})
|
|
|
53
56
|
}
|
|
54
57
|
return result;
|
|
55
58
|
}
|
|
59
|
+
function sleepSeconds(seconds) {
|
|
60
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
spawnSync("sleep", [String(seconds)], {
|
|
64
|
+
stdio: "ignore"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function resolveGitHubRemoteUrls(owner, name) {
|
|
68
|
+
const normalizedOwner = slugifySegment(owner, "owner");
|
|
69
|
+
const normalizedName = slugifySegment(name, "repo");
|
|
70
|
+
return {
|
|
71
|
+
slug: `${normalizedOwner}/${normalizedName}`,
|
|
72
|
+
owner: normalizedOwner,
|
|
73
|
+
name: normalizedName,
|
|
74
|
+
sshUrl: `git@github.com:${normalizedOwner}/${normalizedName}.git`,
|
|
75
|
+
httpsUrl: `https://github.com/${normalizedOwner}/${normalizedName}.git`,
|
|
76
|
+
url: `https://github.com/${normalizedOwner}/${normalizedName}`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function ensureGitIdentity(cwd) {
|
|
80
|
+
const currentName = runGit(["config", "--get", "user.name"], { cwd, allowFailure: true }).stdout?.trim() ?? "";
|
|
81
|
+
const currentEmail = runGit(["config", "--get", "user.email"], { cwd, allowFailure: true }).stdout?.trim() ?? "";
|
|
82
|
+
if (!currentName) {
|
|
83
|
+
runGit(["config", "user.name", envOrNull("TREESEED_GITHUB_COMMITTER_NAME") ?? "Treeseed Launch"], { cwd });
|
|
84
|
+
}
|
|
85
|
+
if (!currentEmail) {
|
|
86
|
+
runGit(["config", "user.email", envOrNull("TREESEED_GITHUB_COMMITTER_EMAIL") ?? "launch@knowledge.coop"], { cwd });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
56
89
|
function resolveGitHubRepositorySlug(tenantRoot) {
|
|
57
90
|
const remoteResult = runGit(["remote", "get-url", "origin"], { cwd: tenantRoot });
|
|
58
91
|
const remoteUrl = remoteResult.stdout?.trim() ?? "";
|
|
@@ -69,6 +102,116 @@ function maybeResolveGitHubRepositorySlug(tenantRoot) {
|
|
|
69
102
|
return null;
|
|
70
103
|
}
|
|
71
104
|
}
|
|
105
|
+
function resolveDefaultGitHubOwner() {
|
|
106
|
+
const explicit = envOrNull("TREESEED_KNOWLEDGE_COOP_GITHUB_OWNER");
|
|
107
|
+
if (explicit) {
|
|
108
|
+
return explicit;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const repository = maybeResolveGitHubRepositorySlug(process.cwd());
|
|
112
|
+
if (repository?.includes("/")) {
|
|
113
|
+
return repository.split("/")[0];
|
|
114
|
+
}
|
|
115
|
+
} catch {
|
|
116
|
+
}
|
|
117
|
+
return "treeseed-ai";
|
|
118
|
+
}
|
|
119
|
+
function createGitHubRepository(input) {
|
|
120
|
+
const visibility = input.visibility ?? "private";
|
|
121
|
+
const remotes = resolveGitHubRemoteUrls(input.owner, input.name);
|
|
122
|
+
if (isGitHubAutomationStubbed()) {
|
|
123
|
+
return {
|
|
124
|
+
...remotes,
|
|
125
|
+
visibility,
|
|
126
|
+
defaultBranch: "main",
|
|
127
|
+
mode: "stub"
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const existing = runGh(["repo", "view", remotes.slug, "--json", "name,owner,url,isPrivate,defaultBranchRef,visibility"], {
|
|
131
|
+
allowFailure: true
|
|
132
|
+
});
|
|
133
|
+
if (existing.status !== 0) {
|
|
134
|
+
const args = ["repo", "create", remotes.slug, "--disable-wiki", "--confirm"];
|
|
135
|
+
if (visibility === "public") {
|
|
136
|
+
args.push("--public");
|
|
137
|
+
} else if (visibility === "internal") {
|
|
138
|
+
args.push("--internal");
|
|
139
|
+
} else {
|
|
140
|
+
args.push("--private");
|
|
141
|
+
}
|
|
142
|
+
if (input.description) {
|
|
143
|
+
args.push("--description", input.description);
|
|
144
|
+
}
|
|
145
|
+
if (input.homepageUrl) {
|
|
146
|
+
args.push("--homepage", input.homepageUrl);
|
|
147
|
+
}
|
|
148
|
+
runGh(args, { capture: false });
|
|
149
|
+
}
|
|
150
|
+
if (Array.isArray(input.topics) && input.topics.length > 0) {
|
|
151
|
+
runGh(
|
|
152
|
+
["repo", "edit", remotes.slug, ...input.topics.flatMap((topic) => ["--add-topic", slugifySegment(topic, "treeseed")])],
|
|
153
|
+
{ capture: false }
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
const viewed = runGh(["repo", "view", remotes.slug, "--json", "name,owner,url,isPrivate,defaultBranchRef,visibility"], {});
|
|
157
|
+
const payload = JSON.parse(viewed.stdout || "{}");
|
|
158
|
+
return {
|
|
159
|
+
...remotes,
|
|
160
|
+
owner: String(payload.owner?.login ?? remotes.owner),
|
|
161
|
+
name: String(payload.name ?? remotes.name),
|
|
162
|
+
url: String(payload.url ?? remotes.url),
|
|
163
|
+
visibility: String(payload.visibility ?? (payload.isPrivate === true ? "private" : visibility)),
|
|
164
|
+
defaultBranch: String(payload.defaultBranchRef?.name ?? "main")
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function initializeGitHubRepositoryWorkingTree(cwd, repository, {
|
|
168
|
+
defaultBranch = "main",
|
|
169
|
+
createStaging = true,
|
|
170
|
+
commitMessage = "Initialize Knowledge Coop hub",
|
|
171
|
+
remoteName = "origin",
|
|
172
|
+
push = true
|
|
173
|
+
} = {}) {
|
|
174
|
+
if (isGitHubAutomationStubbed()) {
|
|
175
|
+
return {
|
|
176
|
+
repository,
|
|
177
|
+
remoteName,
|
|
178
|
+
defaultBranch,
|
|
179
|
+
stagingBranch: createStaging ? "staging" : null,
|
|
180
|
+
pushed: false,
|
|
181
|
+
mode: "stub"
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
runGit(["init", "-b", defaultBranch], { cwd, allowFailure: true });
|
|
185
|
+
ensureGitIdentity(cwd);
|
|
186
|
+
const currentRemote = runGit(["remote", "get-url", remoteName], { cwd, allowFailure: true }).stdout?.trim() ?? "";
|
|
187
|
+
if (!currentRemote) {
|
|
188
|
+
runGit(["remote", "add", remoteName, repository.sshUrl], { cwd });
|
|
189
|
+
} else if (currentRemote !== repository.sshUrl && currentRemote !== repository.httpsUrl) {
|
|
190
|
+
runGit(["remote", "set-url", remoteName, repository.sshUrl], { cwd });
|
|
191
|
+
}
|
|
192
|
+
runGit(["add", "-A"], { cwd });
|
|
193
|
+
const hasChanges = runGit(["status", "--porcelain"], { cwd }).stdout?.trim().length > 0;
|
|
194
|
+
if (hasChanges) {
|
|
195
|
+
runGit(["commit", "-m", commitMessage], { cwd });
|
|
196
|
+
}
|
|
197
|
+
if (push) {
|
|
198
|
+
runGit(["push", "-u", remoteName, defaultBranch], { cwd, capture: false });
|
|
199
|
+
}
|
|
200
|
+
if (createStaging) {
|
|
201
|
+
runGit(["checkout", "-B", "staging"], { cwd });
|
|
202
|
+
if (push) {
|
|
203
|
+
runGit(["push", "-u", remoteName, "staging"], { cwd, capture: false });
|
|
204
|
+
}
|
|
205
|
+
runGit(["checkout", defaultBranch], { cwd });
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
repository,
|
|
209
|
+
remoteName,
|
|
210
|
+
defaultBranch,
|
|
211
|
+
stagingBranch: createStaging ? "staging" : null,
|
|
212
|
+
pushed: push
|
|
213
|
+
};
|
|
214
|
+
}
|
|
72
215
|
function resolveGitRepositoryRoot(tenantRoot) {
|
|
73
216
|
const result = runGit(["rev-parse", "--show-toplevel"], { cwd: tenantRoot, allowFailure: true });
|
|
74
217
|
return result.status === 0 ? result.stdout.trim() : tenantRoot;
|
|
@@ -291,7 +434,80 @@ function ensureGitHubDeployAutomation(tenantRoot, { dryRun = false } = {}) {
|
|
|
291
434
|
environment
|
|
292
435
|
};
|
|
293
436
|
}
|
|
437
|
+
function waitForGitHubWorkflowCompletion(tenantRoot, {
|
|
438
|
+
repository,
|
|
439
|
+
workflow = "publish.yml",
|
|
440
|
+
headSha,
|
|
441
|
+
branch,
|
|
442
|
+
timeoutSeconds = 600,
|
|
443
|
+
pollSeconds = 5
|
|
444
|
+
} = {}) {
|
|
445
|
+
if (isGitHubAutomationStubbed()) {
|
|
446
|
+
return {
|
|
447
|
+
status: "skipped",
|
|
448
|
+
reason: "stubbed",
|
|
449
|
+
repository: repository ?? maybeResolveGitHubRepositorySlug(tenantRoot),
|
|
450
|
+
workflow,
|
|
451
|
+
headSha: headSha ?? null,
|
|
452
|
+
branch: branch ?? null
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
const repo = repository ?? resolveGitHubRepositorySlug(tenantRoot);
|
|
456
|
+
const startedAt = Date.now();
|
|
457
|
+
while (Date.now() - startedAt < timeoutSeconds * 1e3) {
|
|
458
|
+
const result = runGh([
|
|
459
|
+
"run",
|
|
460
|
+
"list",
|
|
461
|
+
"--repo",
|
|
462
|
+
repo,
|
|
463
|
+
"--workflow",
|
|
464
|
+
workflow,
|
|
465
|
+
"--limit",
|
|
466
|
+
"20",
|
|
467
|
+
"--json",
|
|
468
|
+
"databaseId,headSha,headBranch,status,conclusion,event,displayTitle,url"
|
|
469
|
+
], { cwd: tenantRoot });
|
|
470
|
+
const runs = JSON.parse(result.stdout || "[]");
|
|
471
|
+
const match = runs.find((run) => {
|
|
472
|
+
if (headSha && run?.headSha !== headSha) {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
if (branch && run?.headBranch !== branch) {
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
return true;
|
|
479
|
+
});
|
|
480
|
+
if (match?.databaseId) {
|
|
481
|
+
runGh(["run", "watch", String(match.databaseId), "--repo", repo, "--exit-status"], {
|
|
482
|
+
cwd: tenantRoot,
|
|
483
|
+
capture: false
|
|
484
|
+
});
|
|
485
|
+
const finalResult = runGh([
|
|
486
|
+
"run",
|
|
487
|
+
"view",
|
|
488
|
+
String(match.databaseId),
|
|
489
|
+
"--repo",
|
|
490
|
+
repo,
|
|
491
|
+
"--json",
|
|
492
|
+
"status,conclusion,url,workflowName,headSha"
|
|
493
|
+
], { cwd: tenantRoot });
|
|
494
|
+
const finalRun = JSON.parse(finalResult.stdout || "{}");
|
|
495
|
+
return {
|
|
496
|
+
status: "completed",
|
|
497
|
+
repository: repo,
|
|
498
|
+
workflow,
|
|
499
|
+
runId: match.databaseId,
|
|
500
|
+
headSha: finalRun.headSha ?? match.headSha ?? null,
|
|
501
|
+
conclusion: finalRun.conclusion ?? match.conclusion ?? null,
|
|
502
|
+
url: finalRun.url ?? match.url ?? null
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
sleepSeconds(pollSeconds);
|
|
506
|
+
}
|
|
507
|
+
throw new Error(`Timed out waiting for GitHub workflow ${workflow} in ${repo}.`);
|
|
508
|
+
}
|
|
294
509
|
export {
|
|
510
|
+
createGitHubRepository,
|
|
295
511
|
ensureDeployWorkflow,
|
|
296
512
|
ensureGitHubDeployAutomation,
|
|
297
513
|
ensureGitHubEnvironment,
|
|
@@ -300,6 +516,7 @@ export {
|
|
|
300
516
|
ensureStandardizedGitHubWorkflows,
|
|
301
517
|
formatMissingSecretsReport,
|
|
302
518
|
getGitHubAutomationMode,
|
|
519
|
+
initializeGitHubRepositoryWorkingTree,
|
|
303
520
|
listGitHubSecretNames,
|
|
304
521
|
listGitHubVariableNames,
|
|
305
522
|
maybeResolveGitHubRepositorySlug,
|
|
@@ -308,6 +525,8 @@ export {
|
|
|
308
525
|
renderHostedProjectWorkflow,
|
|
309
526
|
requiredGitHubEnvironment,
|
|
310
527
|
requiredGitHubSecrets,
|
|
528
|
+
resolveDefaultGitHubOwner,
|
|
311
529
|
resolveGitHubRepositorySlug,
|
|
312
|
-
resolveGitRepositoryRoot
|
|
530
|
+
resolveGitRepositoryRoot,
|
|
531
|
+
waitForGitHubWorkflowCompletion
|
|
313
532
|
};
|