@rizom/ops 0.2.0-alpha.140 → 0.2.0-alpha.142
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/brains-ops.js +145 -75
- package/dist/cert-bootstrap.d.ts +2 -0
- package/dist/content-repo-ref.d.ts +10 -0
- package/dist/deploy.js +7 -3
- package/dist/index.js +145 -75
- package/dist/load-registry.d.ts +8 -0
- package/dist/parse-args.d.ts +1 -0
- package/dist/schema.d.ts +60 -189
- package/dist/secrets-encrypt.d.ts +1 -11
- package/package.json +44 -44
- package/templates/rover-pilot/.github/workflows/build.yml +15 -11
- package/templates/rover-pilot/.github/workflows/deploy.yml +26 -8
- package/templates/rover-pilot/deploy/scripts/decrypt-user-secrets.ts +12 -0
- package/templates/rover-pilot/deploy/scripts/resolve-build-config.ts +53 -0
- package/templates/rover-pilot/deploy/scripts/resolve-deploy-handles.ts +1 -0
- package/templates/rover-pilot/deploy/scripts/resolve-user-config.ts +55 -8
- package/templates/rover-pilot/docs/user-onboarding.md +17 -17
package/dist/load-registry.d.ts
CHANGED
|
@@ -38,6 +38,11 @@ export interface ResolvedAtprotoConfig {
|
|
|
38
38
|
export interface ResolvedPlaybooksConfig {
|
|
39
39
|
onboarding?: boolean | undefined;
|
|
40
40
|
}
|
|
41
|
+
export interface ResolvedSiteOverride {
|
|
42
|
+
package: string;
|
|
43
|
+
version: string;
|
|
44
|
+
theme?: string | undefined;
|
|
45
|
+
}
|
|
41
46
|
export interface ResolvedUserIdentity {
|
|
42
47
|
handle: string;
|
|
43
48
|
cohort: string;
|
|
@@ -45,7 +50,10 @@ export interface ResolvedUserIdentity {
|
|
|
45
50
|
model: "rover";
|
|
46
51
|
preset: PilotPreset;
|
|
47
52
|
domain: string;
|
|
53
|
+
cloudflareZoneId?: string | undefined;
|
|
48
54
|
contentRepo: string;
|
|
55
|
+
addOverride?: string[];
|
|
56
|
+
siteOverride?: ResolvedSiteOverride;
|
|
49
57
|
discordEnabled: boolean;
|
|
50
58
|
discordAnchorUserId?: string;
|
|
51
59
|
effectiveAiApiKey: string;
|
package/dist/parse-args.d.ts
CHANGED
package/dist/schema.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { z } from "@brains/utils/zod";
|
|
2
|
-
export declare const presetSchema: z.ZodEnum<
|
|
2
|
+
export declare const presetSchema: z.ZodEnum<{
|
|
3
|
+
core: "core";
|
|
4
|
+
default: "default";
|
|
5
|
+
pro: "pro";
|
|
6
|
+
}>;
|
|
3
7
|
export declare const exactVersionSchema: z.ZodString;
|
|
4
8
|
export declare const handleSchema: z.ZodString;
|
|
5
9
|
export declare const secretNameSchema: z.ZodString;
|
|
@@ -11,209 +15,76 @@ export declare const pilotSchema: z.ZodObject<{
|
|
|
11
15
|
githubOrg: z.ZodString;
|
|
12
16
|
contentRepoPrefix: z.ZodString;
|
|
13
17
|
domainSuffix: z.ZodString;
|
|
14
|
-
preset:
|
|
18
|
+
preset: typeof presetSchema;
|
|
15
19
|
aiApiKey: z.ZodString;
|
|
16
20
|
gitSyncToken: z.ZodString;
|
|
17
21
|
contentRepoAdminToken: z.ZodString;
|
|
18
22
|
agePublicKey: z.ZodString;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
23
|
+
}>;
|
|
24
|
+
declare const anchorProfileSocialLinkSchema: z.ZodObject<{
|
|
25
|
+
platform: z.ZodEnum<{
|
|
26
|
+
github: "github";
|
|
27
|
+
instagram: "instagram";
|
|
28
|
+
linkedin: "linkedin";
|
|
29
|
+
email: "email";
|
|
30
|
+
website: "website";
|
|
31
|
+
}>;
|
|
32
|
+
url: z.ZodString;
|
|
33
|
+
label: z.ZodOptional<z.ZodString>;
|
|
34
|
+
}>;
|
|
35
|
+
declare const anchorProfileSchema: z.ZodObject<{
|
|
36
|
+
name: z.ZodOptional<z.ZodString>;
|
|
37
|
+
description: z.ZodOptional<z.ZodString>;
|
|
38
|
+
website: z.ZodOptional<z.ZodString>;
|
|
39
|
+
email: z.ZodOptional<z.ZodString>;
|
|
40
|
+
story: z.ZodOptional<z.ZodString>;
|
|
41
|
+
socialLinks: z.ZodOptional<z.ZodArray<typeof anchorProfileSocialLinkSchema>>;
|
|
42
|
+
}>;
|
|
43
|
+
declare const setupDeliverySchema: z.ZodObject<{
|
|
44
|
+
delivery: z.ZodLiteral<"email">;
|
|
45
|
+
email: z.ZodString;
|
|
46
|
+
}>;
|
|
47
|
+
declare const atprotoSchema: z.ZodObject<{
|
|
48
|
+
identifier: z.ZodString;
|
|
49
|
+
}>;
|
|
50
|
+
declare const siteOverrideSchema: z.ZodObject<{
|
|
51
|
+
package: z.ZodString;
|
|
52
|
+
version: typeof exactVersionSchema;
|
|
53
|
+
theme: z.ZodOptional<z.ZodString>;
|
|
54
|
+
}>;
|
|
55
|
+
declare const playbooksSchema: z.ZodObject<{
|
|
56
|
+
onboarding: z.ZodOptional<z.ZodBoolean>;
|
|
43
57
|
}>;
|
|
44
58
|
export declare const userSchema: z.ZodObject<{
|
|
45
59
|
handle: z.ZodString;
|
|
46
60
|
discord: z.ZodObject<{
|
|
47
61
|
enabled: z.ZodBoolean;
|
|
48
62
|
anchorUserId: z.ZodOptional<z.ZodString>;
|
|
49
|
-
}, "strict", z.ZodTypeAny, {
|
|
50
|
-
enabled: boolean;
|
|
51
|
-
anchorUserId?: string | undefined;
|
|
52
|
-
}, {
|
|
53
|
-
enabled: boolean;
|
|
54
|
-
anchorUserId?: string | undefined;
|
|
55
63
|
}>;
|
|
56
64
|
aiApiKeyOverride: z.ZodOptional<z.ZodString>;
|
|
57
65
|
gitSyncTokenOverride: z.ZodOptional<z.ZodString>;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}>>;
|
|
68
|
-
atproto: z.ZodOptional<z.ZodObject<{
|
|
69
|
-
identifier: z.ZodString;
|
|
70
|
-
}, "strict", z.ZodTypeAny, {
|
|
71
|
-
identifier: string;
|
|
72
|
-
}, {
|
|
73
|
-
identifier: string;
|
|
74
|
-
}>>;
|
|
75
|
-
playbooks: z.ZodOptional<z.ZodObject<{
|
|
76
|
-
onboarding: z.ZodOptional<z.ZodBoolean>;
|
|
77
|
-
}, "strict", z.ZodTypeAny, {
|
|
78
|
-
onboarding?: boolean | undefined;
|
|
79
|
-
}, {
|
|
80
|
-
onboarding?: boolean | undefined;
|
|
81
|
-
}>>;
|
|
82
|
-
anchorProfile: z.ZodOptional<z.ZodObject<{
|
|
83
|
-
name: z.ZodOptional<z.ZodString>;
|
|
84
|
-
description: z.ZodOptional<z.ZodString>;
|
|
85
|
-
website: z.ZodOptional<z.ZodString>;
|
|
86
|
-
email: z.ZodOptional<z.ZodString>;
|
|
87
|
-
story: z.ZodOptional<z.ZodString>;
|
|
88
|
-
socialLinks: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
89
|
-
platform: z.ZodEnum<["github", "instagram", "linkedin", "email", "website"]>;
|
|
90
|
-
url: z.ZodString;
|
|
91
|
-
label: z.ZodOptional<z.ZodString>;
|
|
92
|
-
}, "strict", z.ZodTypeAny, {
|
|
93
|
-
platform: "github" | "instagram" | "linkedin" | "email" | "website";
|
|
94
|
-
url: string;
|
|
95
|
-
label?: string | undefined;
|
|
96
|
-
}, {
|
|
97
|
-
platform: "github" | "instagram" | "linkedin" | "email" | "website";
|
|
98
|
-
url: string;
|
|
99
|
-
label?: string | undefined;
|
|
100
|
-
}>, "many">>;
|
|
101
|
-
}, "strict", z.ZodTypeAny, {
|
|
102
|
-
name?: string | undefined;
|
|
103
|
-
email?: string | undefined;
|
|
104
|
-
website?: string | undefined;
|
|
105
|
-
description?: string | undefined;
|
|
106
|
-
story?: string | undefined;
|
|
107
|
-
socialLinks?: {
|
|
108
|
-
platform: "github" | "instagram" | "linkedin" | "email" | "website";
|
|
109
|
-
url: string;
|
|
110
|
-
label?: string | undefined;
|
|
111
|
-
}[] | undefined;
|
|
112
|
-
}, {
|
|
113
|
-
name?: string | undefined;
|
|
114
|
-
email?: string | undefined;
|
|
115
|
-
website?: string | undefined;
|
|
116
|
-
description?: string | undefined;
|
|
117
|
-
story?: string | undefined;
|
|
118
|
-
socialLinks?: {
|
|
119
|
-
platform: "github" | "instagram" | "linkedin" | "email" | "website";
|
|
120
|
-
url: string;
|
|
121
|
-
label?: string | undefined;
|
|
122
|
-
}[] | undefined;
|
|
123
|
-
}>>;
|
|
124
|
-
}, "strict", z.ZodTypeAny, {
|
|
125
|
-
handle: string;
|
|
126
|
-
discord: {
|
|
127
|
-
enabled: boolean;
|
|
128
|
-
anchorUserId?: string | undefined;
|
|
129
|
-
};
|
|
130
|
-
aiApiKeyOverride?: string | undefined;
|
|
131
|
-
gitSyncTokenOverride?: string | undefined;
|
|
132
|
-
setup?: {
|
|
133
|
-
email: string;
|
|
134
|
-
delivery: "email";
|
|
135
|
-
} | undefined;
|
|
136
|
-
atproto?: {
|
|
137
|
-
identifier: string;
|
|
138
|
-
} | undefined;
|
|
139
|
-
playbooks?: {
|
|
140
|
-
onboarding?: boolean | undefined;
|
|
141
|
-
} | undefined;
|
|
142
|
-
anchorProfile?: {
|
|
143
|
-
name?: string | undefined;
|
|
144
|
-
email?: string | undefined;
|
|
145
|
-
website?: string | undefined;
|
|
146
|
-
description?: string | undefined;
|
|
147
|
-
story?: string | undefined;
|
|
148
|
-
socialLinks?: {
|
|
149
|
-
platform: "github" | "instagram" | "linkedin" | "email" | "website";
|
|
150
|
-
url: string;
|
|
151
|
-
label?: string | undefined;
|
|
152
|
-
}[] | undefined;
|
|
153
|
-
} | undefined;
|
|
154
|
-
}, {
|
|
155
|
-
handle: string;
|
|
156
|
-
discord: {
|
|
157
|
-
enabled: boolean;
|
|
158
|
-
anchorUserId?: string | undefined;
|
|
159
|
-
};
|
|
160
|
-
aiApiKeyOverride?: string | undefined;
|
|
161
|
-
gitSyncTokenOverride?: string | undefined;
|
|
162
|
-
setup?: {
|
|
163
|
-
email: string;
|
|
164
|
-
delivery: "email";
|
|
165
|
-
} | undefined;
|
|
166
|
-
atproto?: {
|
|
167
|
-
identifier: string;
|
|
168
|
-
} | undefined;
|
|
169
|
-
playbooks?: {
|
|
170
|
-
onboarding?: boolean | undefined;
|
|
171
|
-
} | undefined;
|
|
172
|
-
anchorProfile?: {
|
|
173
|
-
name?: string | undefined;
|
|
174
|
-
email?: string | undefined;
|
|
175
|
-
website?: string | undefined;
|
|
176
|
-
description?: string | undefined;
|
|
177
|
-
story?: string | undefined;
|
|
178
|
-
socialLinks?: {
|
|
179
|
-
platform: "github" | "instagram" | "linkedin" | "email" | "website";
|
|
180
|
-
url: string;
|
|
181
|
-
label?: string | undefined;
|
|
182
|
-
}[] | undefined;
|
|
183
|
-
} | undefined;
|
|
66
|
+
domainOverride: z.ZodOptional<z.ZodString>;
|
|
67
|
+
cloudflareZoneId: z.ZodOptional<z.ZodString>;
|
|
68
|
+
contentRepoOverride: z.ZodOptional<z.ZodString>;
|
|
69
|
+
addOverride: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
70
|
+
siteOverride: z.ZodOptional<typeof siteOverrideSchema>;
|
|
71
|
+
setup: z.ZodOptional<typeof setupDeliverySchema>;
|
|
72
|
+
atproto: z.ZodOptional<typeof atprotoSchema>;
|
|
73
|
+
playbooks: z.ZodOptional<typeof playbooksSchema>;
|
|
74
|
+
anchorProfile: z.ZodOptional<typeof anchorProfileSchema>;
|
|
184
75
|
}>;
|
|
185
|
-
export declare const cohortSchema: z.
|
|
186
|
-
members: z.ZodArray<z.ZodString
|
|
76
|
+
export declare const cohortSchema: z.ZodObject<{
|
|
77
|
+
members: z.ZodArray<z.ZodString>;
|
|
187
78
|
brainVersionOverride: z.ZodOptional<z.ZodString>;
|
|
188
|
-
presetOverride: z.ZodOptional<
|
|
79
|
+
presetOverride: z.ZodOptional<typeof presetSchema>;
|
|
189
80
|
aiApiKeyOverride: z.ZodOptional<z.ZodString>;
|
|
190
81
|
gitSyncTokenOverride: z.ZodOptional<z.ZodString>;
|
|
191
|
-
}, "strict", z.ZodTypeAny, {
|
|
192
|
-
members: string[];
|
|
193
|
-
aiApiKeyOverride?: string | undefined;
|
|
194
|
-
gitSyncTokenOverride?: string | undefined;
|
|
195
|
-
brainVersionOverride?: string | undefined;
|
|
196
|
-
presetOverride?: "default" | "core" | "pro" | undefined;
|
|
197
|
-
}, {
|
|
198
|
-
members: string[];
|
|
199
|
-
aiApiKeyOverride?: string | undefined;
|
|
200
|
-
gitSyncTokenOverride?: string | undefined;
|
|
201
|
-
brainVersionOverride?: string | undefined;
|
|
202
|
-
presetOverride?: "default" | "core" | "pro" | undefined;
|
|
203
|
-
}>, {
|
|
204
|
-
members: string[];
|
|
205
|
-
aiApiKeyOverride?: string | undefined;
|
|
206
|
-
gitSyncTokenOverride?: string | undefined;
|
|
207
|
-
brainVersionOverride?: string | undefined;
|
|
208
|
-
presetOverride?: "default" | "core" | "pro" | undefined;
|
|
209
|
-
}, {
|
|
210
|
-
members: string[];
|
|
211
|
-
aiApiKeyOverride?: string | undefined;
|
|
212
|
-
gitSyncTokenOverride?: string | undefined;
|
|
213
|
-
brainVersionOverride?: string | undefined;
|
|
214
|
-
presetOverride?: "default" | "core" | "pro" | undefined;
|
|
215
82
|
}>;
|
|
216
|
-
export type PilotConfig = z.
|
|
217
|
-
export type
|
|
218
|
-
export type
|
|
219
|
-
export type
|
|
83
|
+
export type PilotConfig = z.output<typeof pilotSchema>;
|
|
84
|
+
export type PilotConfigInput = z.input<typeof pilotSchema>;
|
|
85
|
+
export type UserConfig = z.output<typeof userSchema>;
|
|
86
|
+
export type UserConfigInput = z.input<typeof userSchema>;
|
|
87
|
+
export type CohortConfig = z.output<typeof cohortSchema>;
|
|
88
|
+
export type CohortConfigInput = z.input<typeof cohortSchema>;
|
|
89
|
+
export type PilotPreset = z.output<typeof presetSchema>;
|
|
90
|
+
export {};
|
|
@@ -4,18 +4,8 @@ declare const encryptedUserSecretsSchema: z.ZodObject<{
|
|
|
4
4
|
discordBotToken: z.ZodOptional<z.ZodString>;
|
|
5
5
|
aiApiKey: z.ZodOptional<z.ZodString>;
|
|
6
6
|
atprotoAppPassword: z.ZodOptional<z.ZodString>;
|
|
7
|
-
}, "strict", z.ZodTypeAny, {
|
|
8
|
-
aiApiKey?: string | undefined;
|
|
9
|
-
gitSyncToken?: string | undefined;
|
|
10
|
-
discordBotToken?: string | undefined;
|
|
11
|
-
atprotoAppPassword?: string | undefined;
|
|
12
|
-
}, {
|
|
13
|
-
aiApiKey?: string | undefined;
|
|
14
|
-
gitSyncToken?: string | undefined;
|
|
15
|
-
discordBotToken?: string | undefined;
|
|
16
|
-
atprotoAppPassword?: string | undefined;
|
|
17
7
|
}>;
|
|
18
|
-
export type EncryptedUserSecrets = z.
|
|
8
|
+
export type EncryptedUserSecrets = z.output<typeof encryptedUserSecretsSchema>;
|
|
19
9
|
export interface SecretsEncryptOptions {
|
|
20
10
|
env?: NodeJS.ProcessEnv | undefined;
|
|
21
11
|
logger?: ((message: string) => void) | undefined;
|
package/package.json
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rizom/ops",
|
|
3
|
+
"version": "0.2.0-alpha.142",
|
|
3
4
|
"description": "Operator CLI for managing private brain fleet registry repos",
|
|
4
|
-
"
|
|
5
|
-
"
|
|
5
|
+
"keywords": [
|
|
6
|
+
"brains",
|
|
7
|
+
"ops",
|
|
8
|
+
"cli",
|
|
9
|
+
"deploy",
|
|
10
|
+
"fleet",
|
|
11
|
+
"operator"
|
|
12
|
+
],
|
|
13
|
+
"license": "Apache-2.0",
|
|
14
|
+
"author": "Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",
|
|
15
|
+
"bin": {
|
|
16
|
+
"brains-ops": "./dist/brains-ops.js"
|
|
17
|
+
},
|
|
18
|
+
"bugs": "https://github.com/rizom-ai/brains/issues",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"age-encryption": "^0.3.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@brains/deploy-support": "workspace:*",
|
|
24
|
+
"@brains/eslint-config": "workspace:*",
|
|
25
|
+
"@brains/typescript-config": "workspace:*",
|
|
26
|
+
"@brains/utils": "workspace:*",
|
|
27
|
+
"@types/bun": "^1.3.14",
|
|
28
|
+
"typescript": "^6.0.3"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"bun": ">=1.3.3"
|
|
6
32
|
},
|
|
7
|
-
"version": "0.2.0-alpha.140",
|
|
8
|
-
"type": "module",
|
|
9
33
|
"exports": {
|
|
10
34
|
".": {
|
|
11
35
|
"types": "./dist/index.d.ts",
|
|
12
36
|
"import": "./dist/index.js"
|
|
13
37
|
},
|
|
14
38
|
"./deploy": {
|
|
15
|
-
"bun": "./dist/deploy.js",
|
|
16
39
|
"types": "./dist/deploy.d.ts",
|
|
17
|
-
"import": "./dist/deploy.js"
|
|
40
|
+
"import": "./dist/deploy.js",
|
|
41
|
+
"bun": "./dist/deploy.js"
|
|
18
42
|
}
|
|
19
43
|
},
|
|
20
|
-
"main": "./dist/index.js",
|
|
21
|
-
"types": "./dist/index.d.ts",
|
|
22
|
-
"bin": {
|
|
23
|
-
"brains-ops": "./dist/brains-ops.js"
|
|
24
|
-
},
|
|
25
44
|
"files": [
|
|
26
45
|
"dist",
|
|
27
46
|
"templates"
|
|
28
47
|
],
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
"lint": "eslint . --ext .ts,.tsx --max-warnings 0",
|
|
34
|
-
"lint:fix": "eslint . --ext .ts,.tsx --max-warnings 0 --fix",
|
|
35
|
-
"test": "bun run build && bun test --timeout 20000",
|
|
36
|
-
"test:smoke": "bun run build && RUN_SMOKE_TESTS=1 bun test --timeout 60000"
|
|
37
|
-
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"age-encryption": "^0.3.0"
|
|
40
|
-
},
|
|
41
|
-
"devDependencies": {
|
|
42
|
-
"@brains/deploy-support": "workspace:*",
|
|
43
|
-
"@brains/eslint-config": "workspace:*",
|
|
44
|
-
"@brains/typescript-config": "workspace:*",
|
|
45
|
-
"@brains/utils": "workspace:*",
|
|
46
|
-
"@types/bun": "latest",
|
|
47
|
-
"typescript": "^5.3.3"
|
|
48
|
+
"homepage": "https://github.com/rizom-ai/brains/tree/main/packages/brains-ops#readme",
|
|
49
|
+
"main": "./dist/index.js",
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
48
52
|
},
|
|
49
53
|
"repository": {
|
|
50
54
|
"type": "git",
|
|
51
55
|
"url": "https://github.com/rizom-ai/brains.git",
|
|
52
56
|
"directory": "packages/brains-ops"
|
|
53
57
|
},
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
58
|
+
"scripts": {
|
|
59
|
+
"build": "bun scripts/build.ts",
|
|
60
|
+
"lint": "eslint . --max-warnings 0",
|
|
61
|
+
"lint:fix": "eslint . --max-warnings 0 --fix",
|
|
62
|
+
"prepublishOnly": "bun scripts/build.ts",
|
|
63
|
+
"test": "bun run build && bun test --timeout 20000",
|
|
64
|
+
"test:smoke": "bun run build && RUN_SMOKE_TESTS=1 bun test --timeout 60000",
|
|
65
|
+
"typecheck": "tsc --noEmit"
|
|
60
66
|
},
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
"ops",
|
|
64
|
-
"cli",
|
|
65
|
-
"deploy",
|
|
66
|
-
"fleet",
|
|
67
|
-
"operator"
|
|
68
|
-
]
|
|
67
|
+
"type": "module",
|
|
68
|
+
"types": "./dist/index.d.ts"
|
|
69
69
|
}
|
|
@@ -11,6 +11,10 @@ on:
|
|
|
11
11
|
branches: ["main"]
|
|
12
12
|
paths:
|
|
13
13
|
- pilot.yaml
|
|
14
|
+
- cohorts/*.yaml
|
|
15
|
+
- users/*.yaml
|
|
16
|
+
- package.json
|
|
17
|
+
- bun.lock
|
|
14
18
|
- deploy/**
|
|
15
19
|
- .github/workflows/build.yml
|
|
16
20
|
|
|
@@ -26,17 +30,16 @@ jobs:
|
|
|
26
30
|
with:
|
|
27
31
|
ref: ${{ github.sha }}
|
|
28
32
|
|
|
29
|
-
-
|
|
33
|
+
- uses: oven-sh/setup-bun@v2
|
|
34
|
+
|
|
35
|
+
- name: Install operator tooling
|
|
36
|
+
run: bun install
|
|
37
|
+
|
|
38
|
+
- name: Resolve image metadata inputs
|
|
39
|
+
env:
|
|
40
|
+
BRAIN_VERSION_INPUT: ${{ inputs.brain_version || '' }}
|
|
30
41
|
run: |
|
|
31
|
-
|
|
32
|
-
if [ -z "$BRAIN_VERSION" ]; then
|
|
33
|
-
BRAIN_VERSION="$(grep '^brainVersion:' pilot.yaml | sed 's/^brainVersion:[[:space:]]*//' | tr -d '"' | tr -d "'")"
|
|
34
|
-
fi
|
|
35
|
-
if [ -z "$BRAIN_VERSION" ]; then
|
|
36
|
-
echo "Missing brainVersion in pilot.yaml" >&2
|
|
37
|
-
exit 1
|
|
38
|
-
fi
|
|
39
|
-
echo "BRAIN_VERSION=$BRAIN_VERSION" >> "$GITHUB_ENV"
|
|
42
|
+
bun deploy/scripts/resolve-build-config.ts
|
|
40
43
|
echo "IMAGE_REPOSITORY=ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}" >> "$GITHUB_ENV"
|
|
41
44
|
|
|
42
45
|
- name: Set up Docker Buildx
|
|
@@ -48,7 +51,7 @@ jobs:
|
|
|
48
51
|
with:
|
|
49
52
|
images: ${{ env.IMAGE_REPOSITORY }}
|
|
50
53
|
tags: |
|
|
51
|
-
type=raw,value
|
|
54
|
+
type=raw,value=${{ env.IMAGE_TAG }}
|
|
52
55
|
|
|
53
56
|
- name: Log in to GHCR
|
|
54
57
|
uses: docker/login-action@v4
|
|
@@ -66,6 +69,7 @@ jobs:
|
|
|
66
69
|
push: true
|
|
67
70
|
build-args: |
|
|
68
71
|
BRAIN_VERSION=${{ env.BRAIN_VERSION }}
|
|
72
|
+
SITE_PACKAGES=${{ env.SITE_PACKAGES }}
|
|
69
73
|
tags: ${{ steps.meta.outputs.tags }}
|
|
70
74
|
labels: |
|
|
71
75
|
${{ steps.meta.outputs.labels }}
|
|
@@ -10,6 +10,7 @@ on:
|
|
|
10
10
|
push:
|
|
11
11
|
branches: ["main"]
|
|
12
12
|
paths:
|
|
13
|
+
- users/*.yaml
|
|
13
14
|
- users/*/.env
|
|
14
15
|
- users/*/brain.yaml
|
|
15
16
|
- users/*/content/**
|
|
@@ -112,12 +113,16 @@ jobs:
|
|
|
112
113
|
KAMAL_SSH_PRIVATE_KEY: ${{ secrets.KAMAL_SSH_PRIVATE_KEY }}
|
|
113
114
|
KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }}
|
|
114
115
|
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
CONFIG_CF_ZONE_ID: ${{ steps.user_config.outputs.cloudflare_zone_id }}
|
|
117
|
+
SHARED_CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
|
|
118
|
+
SHARED_CERTIFICATE_PEM: ${{ secrets.CERTIFICATE_PEM }}
|
|
119
|
+
SHARED_PRIVATE_KEY_PEM: ${{ secrets.PRIVATE_KEY_PEM }}
|
|
118
120
|
run: |
|
|
119
121
|
export AI_API_KEY="${AI_API_KEY:-$SHARED_AI_API_KEY}"
|
|
120
122
|
export GIT_SYNC_TOKEN="${GIT_SYNC_TOKEN:-$SHARED_GIT_SYNC_TOKEN}"
|
|
123
|
+
export CF_ZONE_ID="${CONFIG_CF_ZONE_ID:-${CF_ZONE_ID:-$SHARED_CF_ZONE_ID}}"
|
|
124
|
+
export CERTIFICATE_PEM="${CERTIFICATE_PEM:-$SHARED_CERTIFICATE_PEM}"
|
|
125
|
+
export PRIVATE_KEY_PEM="${PRIVATE_KEY_PEM:-$SHARED_PRIVATE_KEY_PEM}"
|
|
121
126
|
bun deploy/scripts/validate-secrets.ts
|
|
122
127
|
|
|
123
128
|
- name: Seed content repo
|
|
@@ -137,7 +142,7 @@ jobs:
|
|
|
137
142
|
|
|
138
143
|
- name: Wait for shared image tag
|
|
139
144
|
run: |
|
|
140
|
-
IMAGE_TAG="${{ steps.user_config.outputs.image_repository }}
|
|
145
|
+
IMAGE_TAG="${{ steps.user_config.outputs.image_repository }}:${{ steps.user_config.outputs.image_tag }}"
|
|
141
146
|
for attempt in $(seq 1 24); do
|
|
142
147
|
if docker manifest inspect "$IMAGE_TAG" >/dev/null 2>&1; then
|
|
143
148
|
exit 0
|
|
@@ -178,11 +183,13 @@ jobs:
|
|
|
178
183
|
SETUP_EMAIL_API_KEY: ${{ secrets.SETUP_EMAIL_API_KEY }}
|
|
179
184
|
SETUP_EMAIL_FROM: ${{ secrets.SETUP_EMAIL_FROM }}
|
|
180
185
|
KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }}
|
|
181
|
-
|
|
182
|
-
|
|
186
|
+
SHARED_CERTIFICATE_PEM: ${{ secrets.CERTIFICATE_PEM }}
|
|
187
|
+
SHARED_PRIVATE_KEY_PEM: ${{ secrets.PRIVATE_KEY_PEM }}
|
|
183
188
|
run: |
|
|
184
189
|
export AI_API_KEY="${AI_API_KEY:-$SHARED_AI_API_KEY}"
|
|
185
190
|
export GIT_SYNC_TOKEN="${GIT_SYNC_TOKEN:-$SHARED_GIT_SYNC_TOKEN}"
|
|
191
|
+
export CERTIFICATE_PEM="${CERTIFICATE_PEM:-$SHARED_CERTIFICATE_PEM}"
|
|
192
|
+
export PRIVATE_KEY_PEM="${PRIVATE_KEY_PEM:-$SHARED_PRIVATE_KEY_PEM}"
|
|
186
193
|
bun deploy/scripts/write-kamal-secrets.ts
|
|
187
194
|
|
|
188
195
|
- name: Provision server
|
|
@@ -198,12 +205,18 @@ jobs:
|
|
|
198
205
|
- name: Update Cloudflare DNS
|
|
199
206
|
env:
|
|
200
207
|
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
|
|
201
|
-
|
|
208
|
+
CONFIG_CF_ZONE_ID: ${{ steps.user_config.outputs.cloudflare_zone_id }}
|
|
209
|
+
SHARED_CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
|
|
202
210
|
BRAIN_DOMAIN: ${{ steps.user_config.outputs.brain_domain }}
|
|
211
|
+
WWW_DOMAIN: ${{ steps.user_config.outputs.www_domain }}
|
|
203
212
|
PREVIEW_DOMAIN: ${{ steps.user_config.outputs.preview_domain }}
|
|
204
213
|
SERVER_IP: ${{ steps.provision.outputs.server_ip }}
|
|
205
214
|
run: |
|
|
215
|
+
export CF_ZONE_ID="${CONFIG_CF_ZONE_ID:-${CF_ZONE_ID:-$SHARED_CF_ZONE_ID}}"
|
|
206
216
|
bun deploy/scripts/update-dns.ts
|
|
217
|
+
if [ -n "$WWW_DOMAIN" ]; then
|
|
218
|
+
BRAIN_DOMAIN="$WWW_DOMAIN" bun deploy/scripts/update-dns.ts
|
|
219
|
+
fi
|
|
207
220
|
BRAIN_DOMAIN="$PREVIEW_DOMAIN" bun deploy/scripts/update-dns.ts
|
|
208
221
|
|
|
209
222
|
- name: Validate SSH key
|
|
@@ -227,10 +240,11 @@ jobs:
|
|
|
227
240
|
- name: Deploy
|
|
228
241
|
env:
|
|
229
242
|
SERVER_IP: ${{ steps.provision.outputs.server_ip }}
|
|
230
|
-
VERSION:
|
|
243
|
+
VERSION: ${{ steps.user_config.outputs.image_tag }}
|
|
231
244
|
IMAGE_REPOSITORY: ${{ steps.user_config.outputs.image_repository }}
|
|
232
245
|
REGISTRY_USERNAME: ${{ steps.user_config.outputs.registry_username }}
|
|
233
246
|
BRAIN_DOMAIN: ${{ steps.user_config.outputs.brain_domain }}
|
|
247
|
+
WWW_DOMAIN: ${{ steps.user_config.outputs.www_domain }}
|
|
234
248
|
PREVIEW_DOMAIN: ${{ steps.user_config.outputs.preview_domain }}
|
|
235
249
|
BRAIN_YAML_PATH: ${{ steps.user_config.outputs.brain_yaml_path }}
|
|
236
250
|
run: kamal setup --skip-push -c deploy/kamal/deploy.yml
|
|
@@ -239,9 +253,13 @@ jobs:
|
|
|
239
253
|
env:
|
|
240
254
|
SERVER_IP: ${{ steps.provision.outputs.server_ip }}
|
|
241
255
|
BRAIN_DOMAIN: ${{ steps.user_config.outputs.brain_domain }}
|
|
256
|
+
WWW_DOMAIN: ${{ steps.user_config.outputs.www_domain }}
|
|
242
257
|
PREVIEW_DOMAIN: ${{ steps.user_config.outputs.preview_domain }}
|
|
243
258
|
run: |
|
|
244
259
|
curl -I -k --max-time 20 --resolve "$BRAIN_DOMAIN:443:$SERVER_IP" "https://$BRAIN_DOMAIN/health"
|
|
260
|
+
if [ -n "$WWW_DOMAIN" ]; then
|
|
261
|
+
curl -I -k --max-time 20 --resolve "$WWW_DOMAIN:443:$SERVER_IP" "https://$WWW_DOMAIN/"
|
|
262
|
+
fi
|
|
245
263
|
curl -I -k --max-time 20 --resolve "$PREVIEW_DOMAIN:443:$SERVER_IP" "https://$PREVIEW_DOMAIN/"
|
|
246
264
|
|
|
247
265
|
- name: Upload generated config
|
|
@@ -22,6 +22,14 @@ writeGitHubEnv("AI_API_KEY", secrets["aiApiKey"] ?? "");
|
|
|
22
22
|
writeGitHubEnv("GIT_SYNC_TOKEN", secrets["gitSyncToken"] ?? "");
|
|
23
23
|
writeGitHubEnv("DISCORD_BOT_TOKEN", secrets["discordBotToken"] ?? "");
|
|
24
24
|
writeGitHubEnv("ATPROTO_APP_PASSWORD", secrets["atprotoAppPassword"] ?? "");
|
|
25
|
+
writeGitHubEnv(
|
|
26
|
+
"CERTIFICATE_PEM",
|
|
27
|
+
decodeEscapedSecret(secrets["certificatePem"]),
|
|
28
|
+
);
|
|
29
|
+
writeGitHubEnv(
|
|
30
|
+
"PRIVATE_KEY_PEM",
|
|
31
|
+
decodeEscapedSecret(secrets["privateKeyPem"]),
|
|
32
|
+
);
|
|
25
33
|
|
|
26
34
|
writeGitHubOutput(
|
|
27
35
|
"shared_ai_api_key_secret_name",
|
|
@@ -66,6 +74,10 @@ function parseFlatYaml(contents: string): Record<string, string> {
|
|
|
66
74
|
return result;
|
|
67
75
|
}
|
|
68
76
|
|
|
77
|
+
function decodeEscapedSecret(value: string | undefined): string {
|
|
78
|
+
return value?.replace(/\\n/g, "\n") ?? "";
|
|
79
|
+
}
|
|
80
|
+
|
|
69
81
|
function requireFlatValue(
|
|
70
82
|
values: Record<string, string>,
|
|
71
83
|
key: string,
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { loadPilotRegistry } from "@rizom/ops";
|
|
4
|
+
import { writeGitHubEnv, writeGitHubOutput } from "./helpers";
|
|
5
|
+
|
|
6
|
+
const requestedBrainVersion = process.env["BRAIN_VERSION_INPUT"]?.trim();
|
|
7
|
+
const registry = await loadPilotRegistry(process.cwd());
|
|
8
|
+
const brainVersion =
|
|
9
|
+
requestedBrainVersion && requestedBrainVersion.length > 0
|
|
10
|
+
? requestedBrainVersion
|
|
11
|
+
: registry.pilot.brainVersion;
|
|
12
|
+
|
|
13
|
+
const sitePackages = [
|
|
14
|
+
...new Set(
|
|
15
|
+
registry.users
|
|
16
|
+
.filter((user) => user.brainVersion === brainVersion)
|
|
17
|
+
.flatMap((user) =>
|
|
18
|
+
user.siteOverride
|
|
19
|
+
? [`${user.siteOverride.package}@${user.siteOverride.version}`]
|
|
20
|
+
: [],
|
|
21
|
+
),
|
|
22
|
+
),
|
|
23
|
+
].sort();
|
|
24
|
+
const sitePackagesValue = sitePackages.join(" ");
|
|
25
|
+
const imageTag = buildImageTag(brainVersion, sitePackages);
|
|
26
|
+
|
|
27
|
+
writeGitHubEnv("BRAIN_VERSION", brainVersion);
|
|
28
|
+
writeGitHubEnv("SITE_PACKAGES", sitePackagesValue);
|
|
29
|
+
writeGitHubEnv("IMAGE_TAG", imageTag);
|
|
30
|
+
writeGitHubOutput("brain_version", brainVersion);
|
|
31
|
+
writeGitHubOutput("site_packages", sitePackagesValue);
|
|
32
|
+
writeGitHubOutput("image_tag", imageTag);
|
|
33
|
+
|
|
34
|
+
console.log(`BRAIN_VERSION=${brainVersion}`);
|
|
35
|
+
console.log(`IMAGE_TAG=${imageTag}`);
|
|
36
|
+
console.log(
|
|
37
|
+
sitePackages.length > 0
|
|
38
|
+
? `SITE_PACKAGES=${sitePackagesValue}`
|
|
39
|
+
: "SITE_PACKAGES=(none)",
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
function buildImageTag(brainVersion: string, sitePackages: string[]): string {
|
|
43
|
+
if (sitePackages.length === 0) {
|
|
44
|
+
return `brain-${brainVersion}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const siteHash = createHash("sha256")
|
|
48
|
+
.update(sitePackages.join("\n"))
|
|
49
|
+
.digest("hex")
|
|
50
|
+
.slice(0, 12);
|
|
51
|
+
|
|
52
|
+
return `brain-${brainVersion}-sites-${siteHash}`;
|
|
53
|
+
}
|