@wtfalch/foundry 0.41.2 → 0.43.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/bootstrap/versions.d.ts +2 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +4 -2
- package/dist/migrations/0054_org_signin_in_app.sql +6 -0
- package/dist/migrations/0055_release_requests.sql +20 -0
- package/dist/migrations/0056_platform_archon_blue_green.sql +7 -0
- package/dist/org.d.ts +30 -0
- package/dist/org.js +52 -1
- package/dist/plan/agora.d.ts +4 -1
- package/dist/plan/agora.js +16 -2
- package/dist/plan/archon-blue-green.d.ts +54 -0
- package/dist/plan/archon-blue-green.js +72 -0
- package/dist/plan/blue-green-apply.d.ts +82 -0
- package/dist/plan/blue-green-apply.js +360 -0
- package/dist/plan/blue-green.d.ts +223 -0
- package/dist/plan/blue-green.js +444 -0
- package/dist/plan/boule.d.ts +5 -2
- package/dist/plan/boule.js +14 -2
- package/dist/plan/cloudflared-connector.d.ts +26 -0
- package/dist/plan/cloudflared-connector.js +37 -0
- package/dist/plan/coolify-previews.d.ts +10 -0
- package/dist/plan/coolify-previews.js +14 -0
- package/dist/plan/diff.d.ts +6 -0
- package/dist/plan/diff.js +123 -11
- package/dist/plan/edge-ratelimits.d.ts +5 -0
- package/dist/plan/edge-ratelimits.js +16 -6
- package/dist/plan/executor.d.ts +79 -0
- package/dist/plan/executor.js +527 -31
- package/dist/plan/login-host.d.ts +23 -2
- package/dist/plan/login-host.js +30 -5
- package/dist/plan/own-diff.js +6 -0
- package/dist/plan/plan-apply.d.ts +51 -0
- package/dist/plan/plan-apply.js +222 -0
- package/dist/plan/platform-diff.d.ts +9 -0
- package/dist/plan/platform-diff.js +28 -1
- package/dist/plan/platform-org.d.ts +6 -0
- package/dist/plan/platform-org.js +5 -0
- package/dist/plan/platform-providers.d.ts +31 -2
- package/dist/plan/platform-providers.js +345 -13
- package/dist/plan/providers-readers.js +6 -2
- package/dist/plan/proxy-labels.d.ts +2 -2
- package/dist/plan/proxy-labels.js +12 -4
- package/dist/plan/release-host.d.ts +59 -0
- package/dist/plan/release-host.js +239 -0
- package/dist/plan/remote-database.d.ts +124 -0
- package/dist/plan/remote-database.js +373 -0
- package/dist/plan/sign-in-archon.d.ts +46 -0
- package/dist/plan/sign-in-archon.js +71 -0
- package/dist/plan/sign-in-bindings.d.ts +16 -0
- package/dist/plan/sign-in-bindings.js +44 -0
- package/dist/plan/sign-in.d.ts +135 -0
- package/dist/plan/sign-in.js +172 -0
- package/dist/platform.d.ts +11 -1
- package/dist/platform.js +4 -1
- package/dist/release/decide.d.ts +95 -0
- package/dist/release/decide.js +242 -0
- package/dist/release/health.d.ts +48 -0
- package/dist/release/health.js +61 -0
- package/dist/release/run.d.ts +40 -0
- package/dist/release/run.js +56 -0
- package/dist/release/state.d.ts +64 -0
- package/dist/release/state.js +126 -0
- package/dist/release/types.d.ts +54 -0
- package/dist/release/types.js +4 -0
- package/dist/store/postgres.d.ts +8 -0
- package/dist/store/postgres.js +62 -3
- package/dist/store/schema.d.ts +171 -0
- package/dist/store/schema.js +14 -0
- package/package.json +1 -1
- package/versions.digests.json +2 -1
- package/versions.json +2 -1
|
@@ -102,6 +102,8 @@ export interface OrgPlatformReadiness {
|
|
|
102
102
|
* platform's, not as strangers. Absent when none is recorded.
|
|
103
103
|
*/
|
|
104
104
|
platformZitadelIds?: readonly string[];
|
|
105
|
+
/** The second login app that serves `/sign-in` for companies with `signIn.inApp` is applied. Absent reads as false. */
|
|
106
|
+
signInLoginReady?: boolean;
|
|
105
107
|
/** The platform's own sign-in (#168), which every org's own ZITADEL org lives inside. */
|
|
106
108
|
authReady: boolean;
|
|
107
109
|
/**
|
|
@@ -310,6 +312,10 @@ export interface OwnerSignIn {
|
|
|
310
312
|
* is declared, absent while the owner step has recorded nothing.
|
|
311
313
|
*/
|
|
312
314
|
firstOwnerUserId?: string | null;
|
|
315
|
+
/** The company's in-app login app (`<slug>-auth-login-sign-in`), once it is applied. Absent before. */
|
|
316
|
+
signInLoginAppId?: string;
|
|
317
|
+
/** True when the company has `signIn.inApp` and that login app is applied: Archon signs in on its own address. */
|
|
318
|
+
signInInApp?: true;
|
|
313
319
|
}
|
|
314
320
|
/** The owner company's own files host, as Archon's `FILES_*` env reads it. */
|
|
315
321
|
export interface OwnerFiles {
|
|
@@ -7,6 +7,7 @@ import { oikosIngressApplied } from './oikos-ingress.js';
|
|
|
7
7
|
import { ownHostnames } from './own-hostnames.js';
|
|
8
8
|
import { OWN_SERVICES_APPLIED_SCOPE_KEY, orgTarget } from './own-services.js';
|
|
9
9
|
import { JOBS_INTERNAL_URL_SCOPE_KEY, JOBS_SCHEDULER_KEY, PLATFORM_ACCESS_ZITADEL_APP_SCOPE_KEY, PLATFORM_ACCESS_ZITADEL_PROJECT_SCOPE_KEY, PLATFORM_AI_KEY, PLATFORM_AI_TUNNEL_SCOPE_KEY, PLATFORM_ARCHON_APPLIED_BROKER_SCOPE_KEY, PLATFORM_ARCHON_ZITADEL_APP_SCOPE_KEY, PLATFORM_ARCHON_ZITADEL_PROJECT_SCOPE_KEY, PLATFORM_AUTH_BROKER_SCOPE_KEY, PLATFORM_AUTH_KEY, PLATFORM_EDGE_KEY, PLATFORM_FILES_APPLIED_HOSTNAME_SCOPE_KEY, PLATFORM_FILES_INTERNAL_URL_SCOPE_KEY, PLATFORM_FILES_KEY, PLATFORM_MAIL_INTERNAL_URL_SCOPE_KEY, PLATFORM_MAIL_KEY, PLATFORM_MAIL_ZITADEL_PROJECT_SCOPE_KEY, platformMailMxHost, } from './platform-diff.js';
|
|
10
|
+
import { SIGN_IN_LOGIN_APP_SCOPE_KEY, inAppSignIn } from './sign-in.js';
|
|
10
11
|
/**
|
|
11
12
|
* #443: the no-domain company mail apex -- `<slug>.oikos.host`, the same
|
|
12
13
|
* fixed suffix `agora.ts`'s `agoraHostnameFor`, `boule.ts`'s
|
|
@@ -159,6 +160,7 @@ edgePortPresent = false) {
|
|
|
159
160
|
...(coolifyAppApplied(platformRecordedIds, PLATFORM_AUTH_KEY)
|
|
160
161
|
? { platformAuthRecordedHost: platform.auth.hostname }
|
|
161
162
|
: {}),
|
|
163
|
+
...(platformRecordedIds[SIGN_IN_LOGIN_APP_SCOPE_KEY] ? { signInLoginReady: true } : {}),
|
|
162
164
|
authReady,
|
|
163
165
|
authIssuer: authReady ? `https://${platform.auth.hostname}` : null,
|
|
164
166
|
jobsReady: jobsApplied && jobsUrl !== undefined && missingKeys.jobs === null,
|
|
@@ -314,6 +316,7 @@ export function ownerSignInFrom(owner, recorded) {
|
|
|
314
316
|
if (!applied || applied !== ownHostnames(owner).auth)
|
|
315
317
|
return null;
|
|
316
318
|
const hostname = applied;
|
|
319
|
+
const signInLoginAppId = recorded[SIGN_IN_LOGIN_APP_SCOPE_KEY];
|
|
317
320
|
return {
|
|
318
321
|
issuerUrl: `https://${applied}`,
|
|
319
322
|
organisationId,
|
|
@@ -321,6 +324,8 @@ export function ownerSignInFrom(owner, recorded) {
|
|
|
321
324
|
bearerRef: orgTarget(owner).refs.instanceBearer,
|
|
322
325
|
hostname,
|
|
323
326
|
firstOwnerUserId: platformOwnerUserIdFrom(owner, recorded),
|
|
327
|
+
...(signInLoginAppId ? { signInLoginAppId } : {}),
|
|
328
|
+
...(signInLoginAppId && inAppSignIn(owner) ? { signInInApp: true } : {}),
|
|
324
329
|
};
|
|
325
330
|
}
|
|
326
331
|
/**
|
|
@@ -2,6 +2,7 @@ import type { CloudflareClient } from '@wtfalch/providers/cloudflare';
|
|
|
2
2
|
import { type DeclaredOrg } from '../org.js';
|
|
3
3
|
import type { DeclaredPlatform } from '../platform.js';
|
|
4
4
|
import type { DeclaredOrgStore, PlatformStore } from '../store.js';
|
|
5
|
+
import { type BlueGreenServer, type BlueGreenSubject } from './blue-green.js';
|
|
5
6
|
import { type DeployHealthRuntime } from './deploy-health.js';
|
|
6
7
|
import type { StepAction } from './diff.js';
|
|
7
8
|
import type { AccessPort } from './edge-access.js';
|
|
@@ -10,6 +11,7 @@ import type { RateLimitPort } from './edge-ratelimits.js';
|
|
|
10
11
|
import type { TunnelPort } from './edge-tunnels.js';
|
|
11
12
|
import type { ZonePort } from './edge-zones.js';
|
|
12
13
|
import type { CloudflarePort, CoolifyPort, FoundryStepExecutorPorts, ZitadelPort } from './executor.js';
|
|
14
|
+
import { type ReleaseContext, type ReleaseHost } from './release-host.js';
|
|
13
15
|
export { FILES_MANAGEMENT_KEY_REF, JOBS_ADMIN_TOKEN_REF, PLATFORM_AI_MANAGEMENT_KEY_REF, } from './held-key-refs.js';
|
|
14
16
|
import type { LiveResource, PlatformCloudflareReader, PlatformCoolifyReader } from './live.js';
|
|
15
17
|
import { type OikosIngressPorts } from './oikos-ingress.js';
|
|
@@ -349,6 +351,14 @@ export declare class FoundryPlatformStepExecutor implements PlatformStepExecutor
|
|
|
349
351
|
private onPlatform;
|
|
350
352
|
/** `deps` with its Coolify port placed on the platform destination, then limited by `profile`. */
|
|
351
353
|
private limitedOnPlatform;
|
|
354
|
+
/** Every Coolify server and why platform-archon's blue/green cannot run here, for the planner. */
|
|
355
|
+
archonBlueGreen(): Promise<{
|
|
356
|
+
servers?: BlueGreenServer[];
|
|
357
|
+
blocked?: string;
|
|
358
|
+
}>;
|
|
359
|
+
/** The release runner's outside calls for platform-archon (`plan/release-host.ts`). The token is only read. */
|
|
360
|
+
releaseHost(platform: DeclaredPlatform, subject: BlueGreenSubject, context: ReleaseContext, renew: () => Promise<void>): ReleaseHost | null;
|
|
361
|
+
private archonBlueGreenStep;
|
|
352
362
|
blockedSteps(platform: DeclaredPlatform, recordedIds?: Readonly<Record<string, string>>, owner?: PlatformOwnerInput): Promise<{
|
|
353
363
|
auth?: string;
|
|
354
364
|
authExecutorMissing?: boolean;
|
|
@@ -408,6 +418,14 @@ export declare class FoundryPlatformStepExecutor implements PlatformStepExecutor
|
|
|
408
418
|
* (or the runner was never applied).
|
|
409
419
|
*/
|
|
410
420
|
refreshFilesShare(_platform: DeclaredPlatform, recordedIds: Readonly<Record<string, string>>): Promise<Record<string, string> | null>;
|
|
421
|
+
/** True while a company signs in on its apps' own addresses through the platform's login. */
|
|
422
|
+
private signInLoginWanted;
|
|
423
|
+
/**
|
|
424
|
+
* In-app sign-in: the login app that serves `/sign-in` is wanted and either not recorded, gone from
|
|
425
|
+
* Coolify, or holding a host table other than the login's. The step then plans again and repairs it.
|
|
426
|
+
* A Coolify read that fails counts as not drifted, with one fixed log line (the error can carry values).
|
|
427
|
+
*/
|
|
428
|
+
private signInLoginDrifted;
|
|
411
429
|
execute(action: StepAction, context: PlatformStepExecutionContext): Promise<{
|
|
412
430
|
resourceId?: string;
|
|
413
431
|
} | undefined>;
|
|
@@ -510,6 +528,13 @@ export interface AuthStackInput {
|
|
|
510
528
|
defaultRedirectUri: string | null;
|
|
511
529
|
/** The company whose owner is invited into its own sign-in org; null for a company's own stack. */
|
|
512
530
|
ownerCompany: DeclaredOrg | null;
|
|
531
|
+
/**
|
|
532
|
+
* In-app sign-in: a second login app serves `/sign-in` next to the login app. Absent: none is made.
|
|
533
|
+
* `bindings` is its `LOGIN_HOST_BINDINGS` document; `null` copies the login app's live one.
|
|
534
|
+
*/
|
|
535
|
+
signInLogin?: {
|
|
536
|
+
bindings: string | null;
|
|
537
|
+
};
|
|
513
538
|
}
|
|
514
539
|
/**
|
|
515
540
|
* #168: makes `coolify:app` keyed {@link PLATFORM_AUTH_KEY} true -- a Coolify
|
|
@@ -881,7 +906,9 @@ export declare function ownerInviteBlockedReason(ownerCompany: DeclaredOrg | nul
|
|
|
881
906
|
* {@link PlatformStepExecutionContext}, bundled like {@link PlatformAuthDeps}.
|
|
882
907
|
*/
|
|
883
908
|
export interface PlatformArchonDeps {
|
|
884
|
-
coolify: Pick<CoolifyPort, 'findProjectByName' | 'listEnvironments' | 'createProject' | 'findOrCreateEnvironment' | 'listServers' | 'findApplicationByName' | 'getApplication' | 'requireGithubApp' | 'createGithubAppApplication' | 'createDockerfileApplication' | 'listDatabases' | 'createPostgresDatabase' | 'getDatabase' | 'raw' | 'bulkUpsertEnvs' | 'listEnvs' | 'deleteEnv' | 'updateApplication' | 'deploy' | 'deployAndWait' | 'getDeployment'
|
|
909
|
+
coolify: Pick<CoolifyPort, 'findProjectByName' | 'listEnvironments' | 'createProject' | 'findOrCreateEnvironment' | 'listServers' | 'findApplicationByName' | 'getApplication' | 'requireGithubApp' | 'createGithubAppApplication' | 'createDockerfileApplication' | 'listDatabases' | 'createPostgresDatabase' | 'getDatabase' | 'raw' | 'bulkUpsertEnvs' | 'listEnvs' | 'deleteEnv' | 'updateApplication' | 'deploy' | 'deployAndWait' | 'getDeployment' | 'listStorages' | 'createPersistentStorage' | 'createFileStorage' | 'updateFileStorage'> & {
|
|
910
|
+
listApplicationDeployments?: CoolifyPort['listApplicationDeployments'];
|
|
911
|
+
};
|
|
885
912
|
/** F4.dns: every DNS record call, through edge at its recorded address (see {@link PlatformDnsFactory}). */
|
|
886
913
|
dns: PlatformDnsFactory;
|
|
887
914
|
/** F4.tunnels: every tunnel call, through edge at its recorded address (see {@link PlatformTunnelsFactory}). */
|
|
@@ -890,7 +917,7 @@ export interface PlatformArchonDeps {
|
|
|
890
917
|
access: PlatformAccessFactory;
|
|
891
918
|
cloudflare: Pick<CloudflarePort, 'findZoneByApex'>;
|
|
892
919
|
/** Must target the platform's own ZITADEL instance, or `zitadelForInstance` must be set. */
|
|
893
|
-
zitadel: Pick<ZitadelPort, 'findOrCreateOrg' | 'findOrCreateProject' | 'createOidcApp' | 'listApps' | 'deleteApp' | 'updateOidcAppIdTokenUserinfoAssertion'
|
|
920
|
+
zitadel: Pick<ZitadelPort, 'findOrCreateOrg' | 'findOrCreateProject' | 'createOidcApp' | 'listApps' | 'deleteApp' | 'updateOidcAppIdTokenUserinfoAssertion'> & Partial<Pick<ZitadelPort, 'ensureTrustedDomain' | 'deleteTrustedDomain' | 'updateOidcAppLoginBaseUri' | 'allowPerAppLoginBaseUri'>>;
|
|
894
921
|
/**
|
|
895
922
|
* {@link PlatformAuthDeps.zitadelForInstance}, for Archon's sign-in client:
|
|
896
923
|
* the owner company's own ZITADEL, by its issuer and the held-key reference of
|
|
@@ -957,6 +984,8 @@ export interface PlatformArchonRuntime {
|
|
|
957
984
|
readyTimeoutMs?: number;
|
|
958
985
|
/** Pause between readiness polls (default 5 seconds). */
|
|
959
986
|
readyIntervalMs?: number;
|
|
987
|
+
/** Called with every secret the blue/green steps read or mint (the health token, copied env), so the host can redact it. */
|
|
988
|
+
onSecret?: (value: string) => void;
|
|
960
989
|
}
|
|
961
990
|
/**
|
|
962
991
|
* The name of foundry's own Cloudflare Access app in front of Archon. Same
|