@treeseed/sdk 0.12.59 → 0.12.61
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/guarantees/index.js +59 -56
- package/dist/hosting/contracts.d.ts +0 -19
- package/dist/hosting/graph.d.ts +1 -86
- package/dist/hosting/graph.js +96 -247
- package/dist/local-dev/managed-dev.js +30 -8
- package/dist/managed-dependencies.d.ts +3 -0
- package/dist/managed-dependencies.js +294 -20
- package/dist/operations/services/deploy.js +6 -6
- package/dist/operations/services/deployment-readiness.js +5 -4
- package/dist/operations/services/git-runner.d.ts +2 -0
- package/dist/operations/services/git-runner.js +23 -2
- package/dist/operations/services/hosted-service-checks.js +28 -0
- package/dist/operations/services/live-hosted-service-checks.js +56 -14
- package/dist/operations/services/local-cleanup.d.ts +1 -0
- package/dist/operations/services/local-cleanup.js +28 -9
- package/dist/operations/services/package-adapters.js +3 -3
- package/dist/operations/services/railway-api.d.ts +72 -28
- package/dist/operations/services/railway-api.js +321 -876
- package/dist/operations/services/railway-cli.d.ts +47 -0
- package/dist/operations/services/railway-cli.js +142 -0
- package/dist/operations/services/railway-deploy.d.ts +5 -0
- package/dist/operations/services/railway-deploy.js +47 -75
- package/dist/operations/services/railway-source-policy.d.ts +6 -0
- package/dist/operations/services/railway-source-policy.js +52 -9
- package/dist/operations/services/repository-save-orchestrator.d.ts +2 -0
- package/dist/operations/services/repository-save-orchestrator.js +45 -14
- package/dist/operations-types.d.ts +3 -1
- package/dist/platform/contracts.d.ts +1 -0
- package/dist/platform/deploy-config.js +2 -1
- package/dist/reconcile/builtin-adapters.js +524 -680
- package/dist/reconcile/desired-state.js +5 -3
- package/dist/reconcile/engine.js +34 -28
- package/dist/reconcile/live-acceptance.js +2 -11
- package/dist/reconcile/providers/railway-iac.d.ts +148 -0
- package/dist/reconcile/providers/railway-iac.js +294 -18
- package/dist/scenes/runner.js +11 -11
- package/dist/scripts/build-dist.js +22 -0
- package/dist/workflow/operations.d.ts +12 -0
- package/dist/workflow/operations.js +265 -90
- package/dist/workflow/runs.d.ts +4 -0
- package/dist/workflow/runs.js +25 -0
- package/dist/workflow-support.d.ts +1 -1
- package/dist/workflow-support.js +3 -1
- package/package.json +1 -2
|
@@ -238,6 +238,7 @@ function deriveTreeseedDesiredUnits({
|
|
|
238
238
|
secrets: {},
|
|
239
239
|
metadata: {
|
|
240
240
|
serviceKey,
|
|
241
|
+
serviceInstanceKey: configuredService.instanceKey ?? desiredServiceName,
|
|
241
242
|
scheduleManaged: Array.isArray(configuredService.schedule) && configuredService.schedule.length > 0,
|
|
242
243
|
scheduleBootstrap: false,
|
|
243
244
|
scheduleDeployScopes: ["staging", "prod"],
|
|
@@ -293,13 +294,14 @@ function deriveTreeseedDesiredUnits({
|
|
|
293
294
|
return isPublicTreeDxNodeServiceKey(serviceKey) ? "api-runtime" : "api-runtime";
|
|
294
295
|
}
|
|
295
296
|
})();
|
|
297
|
+
const runtimeInstanceKey = serviceKey === "operationsRunner" ? configuredService.instanceKey ?? desiredServiceName : serviceKey;
|
|
296
298
|
add({
|
|
297
|
-
unitId: createTreeseedReconcileUnitId(runtimeUnitType,
|
|
299
|
+
unitId: createTreeseedReconcileUnitId(runtimeUnitType, runtimeInstanceKey),
|
|
298
300
|
unitType: runtimeUnitType,
|
|
299
301
|
provider: "treeseed",
|
|
300
302
|
identity,
|
|
301
303
|
target,
|
|
302
|
-
logicalName:
|
|
304
|
+
logicalName: runtimeInstanceKey,
|
|
303
305
|
dependencies: [
|
|
304
306
|
concreteId,
|
|
305
307
|
...apiCustomDomainId ? [apiCustomDomainId] : [],
|
|
@@ -310,7 +312,7 @@ function deriveTreeseedDesiredUnits({
|
|
|
310
312
|
publicBaseUrl: serviceState?.publicBaseUrl ?? null
|
|
311
313
|
},
|
|
312
314
|
secrets: {},
|
|
313
|
-
metadata: { bootstrapSystem: serviceBootstrapSystem }
|
|
315
|
+
metadata: { serviceKey, bootstrapSystem: serviceBootstrapSystem }
|
|
314
316
|
});
|
|
315
317
|
}
|
|
316
318
|
return { deployConfig, legacyState, units };
|
package/dist/reconcile/engine.js
CHANGED
|
@@ -309,7 +309,7 @@ async function reconcileTreeseedTarget({
|
|
|
309
309
|
};
|
|
310
310
|
const unitStartMs = performance.now();
|
|
311
311
|
timingEntries.push(unitTiming);
|
|
312
|
-
write?.(
|
|
312
|
+
write?.(`${planOnly ? "Planning" : "Applying"} ${plan.unit.provider}:${plan.unit.unitType} (${plan.unit.logicalName})...`);
|
|
313
313
|
const adapter = registry.get(plan.unit.unitType, plan.unit.provider);
|
|
314
314
|
const persisted = ensureTreeseedPersistedUnitState(planned.state, plan.unit);
|
|
315
315
|
try {
|
|
@@ -372,34 +372,40 @@ async function reconcileTreeseedTarget({
|
|
|
372
372
|
unitTiming.status = "failed";
|
|
373
373
|
wrapAdapterFailure("apply", plan.unit.provider, plan.unit.unitType, plan.unit.unitId, error);
|
|
374
374
|
}
|
|
375
|
+
if (planOnly) {
|
|
376
|
+
const plannedResult = { ...result, verification: null };
|
|
377
|
+
unitTiming.durationMs = elapsedMs(unitStartMs);
|
|
378
|
+
unitTiming.status = "success";
|
|
379
|
+
write?.(`Finished plan for ${plan.unit.provider}:${plan.unit.unitType} (${plan.unit.logicalName}) in ${formatDurationMs(unitTiming.durationMs)}.`);
|
|
380
|
+
results.push(plannedResult);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
375
383
|
let refreshedObserved = result.observed;
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
result
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
unitTiming.
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
unitTiming.
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
wrapAdapterFailure("refresh", plan.unit.provider, plan.unit.unitType, plan.unit.unitId, error);
|
|
402
|
-
}
|
|
384
|
+
try {
|
|
385
|
+
const stageStartMs = performance.now();
|
|
386
|
+
refreshedObserved = await Promise.resolve(adapter.refresh({
|
|
387
|
+
context,
|
|
388
|
+
unit: plan.unit,
|
|
389
|
+
persistedState: persisted
|
|
390
|
+
}));
|
|
391
|
+
result = {
|
|
392
|
+
...result,
|
|
393
|
+
observed: refreshedObserved
|
|
394
|
+
};
|
|
395
|
+
unitTiming.children?.push({
|
|
396
|
+
name: `${unitTiming.name}:refresh-after-apply`,
|
|
397
|
+
durationMs: elapsedMs(stageStartMs),
|
|
398
|
+
status: "success"
|
|
399
|
+
});
|
|
400
|
+
} catch (error) {
|
|
401
|
+
unitTiming.children?.push({
|
|
402
|
+
name: `${unitTiming.name}:refresh-after-apply`,
|
|
403
|
+
durationMs: elapsedMs(unitStartMs),
|
|
404
|
+
status: "failed"
|
|
405
|
+
});
|
|
406
|
+
unitTiming.durationMs = elapsedMs(unitStartMs);
|
|
407
|
+
unitTiming.status = "failed";
|
|
408
|
+
wrapAdapterFailure("refresh", plan.unit.provider, plan.unit.unitType, plan.unit.unitId, error);
|
|
403
409
|
}
|
|
404
410
|
write?.(`Verifying ${plan.unit.provider}:${plan.unit.unitType} (${plan.unit.logicalName})...`);
|
|
405
411
|
const postconditions = await Promise.resolve(adapter.requiredPostconditions?.({
|
|
@@ -11,6 +11,7 @@ import { runTreeseedGit } from "../operations/services/git-runner.js";
|
|
|
11
11
|
import {
|
|
12
12
|
deleteRailwayProject,
|
|
13
13
|
ensureRailwayEnvironment,
|
|
14
|
+
ensureRailwayCustomDomain,
|
|
14
15
|
ensureRailwayGeneratedServiceDomain,
|
|
15
16
|
ensureRailwayPostgresService,
|
|
16
17
|
ensureRailwayProject,
|
|
@@ -21,7 +22,6 @@ import {
|
|
|
21
22
|
listRailwayServices,
|
|
22
23
|
listRailwayVariables,
|
|
23
24
|
listRailwayVolumes,
|
|
24
|
-
railwayGraphqlRequest,
|
|
25
25
|
resolveRailwayWorkspaceContext,
|
|
26
26
|
upsertRailwayVariables
|
|
27
27
|
} from "../operations/services/railway-api.js";
|
|
@@ -1217,16 +1217,7 @@ async function runRailwayAcceptance(cwd, environment, runId, prefix, env, fetchI
|
|
|
1217
1217
|
const generatedDomain = await ensureRailwayGeneratedServiceDomain({ projectId, environmentId, serviceId, targetPort: 80, env, fetchImpl });
|
|
1218
1218
|
let customDomainCreated = false;
|
|
1219
1219
|
try {
|
|
1220
|
-
await
|
|
1221
|
-
query: `
|
|
1222
|
-
mutation TreeseedLiveRailwayCustomDomainCreate($input: CustomDomainCreateInput!) {
|
|
1223
|
-
customDomainCreate(input: $input) { id domain serviceId environmentId }
|
|
1224
|
-
}
|
|
1225
|
-
`.trim(),
|
|
1226
|
-
variables: { input: { projectId, environmentId, serviceId, domain: customDomain } },
|
|
1227
|
-
env,
|
|
1228
|
-
fetchImpl
|
|
1229
|
-
});
|
|
1220
|
+
await ensureRailwayCustomDomain({ projectId, environmentId, serviceId, domain: customDomain, env, fetchImpl });
|
|
1230
1221
|
customDomainCreated = true;
|
|
1231
1222
|
} catch {
|
|
1232
1223
|
customDomainCreated = false;
|
|
@@ -14,10 +14,51 @@ export type TreeseedRailwayIacService = {
|
|
|
14
14
|
healthcheckPath?: string | null;
|
|
15
15
|
healthcheckTimeoutSeconds?: number | null;
|
|
16
16
|
runtimeMode?: string | null;
|
|
17
|
+
numReplicas?: number | null;
|
|
17
18
|
volumeMountPath?: string | null;
|
|
19
|
+
volumeName?: string | null;
|
|
20
|
+
volumeAddress?: string | null;
|
|
18
21
|
variables?: Record<string, string>;
|
|
19
22
|
secrets?: Record<string, string>;
|
|
20
23
|
detachVolumeIds?: string[];
|
|
24
|
+
customDomains?: string[];
|
|
25
|
+
};
|
|
26
|
+
export type TreeseedRailwayObservedService = {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
};
|
|
30
|
+
export type TreeseedRailwayObservedVolumeInstance = {
|
|
31
|
+
id?: string | null;
|
|
32
|
+
environmentId?: string | null;
|
|
33
|
+
serviceId?: string | null;
|
|
34
|
+
mountPath?: string | null;
|
|
35
|
+
state?: string | null;
|
|
36
|
+
isPendingDeletion?: boolean | null;
|
|
37
|
+
deletedAt?: string | null;
|
|
38
|
+
};
|
|
39
|
+
export type TreeseedRailwayObservedVolume = {
|
|
40
|
+
id: string;
|
|
41
|
+
name?: string | null;
|
|
42
|
+
instances: TreeseedRailwayObservedVolumeInstance[];
|
|
43
|
+
};
|
|
44
|
+
export type TreeseedRailwayVolumeBinding = {
|
|
45
|
+
serviceName: string;
|
|
46
|
+
volumeId: string;
|
|
47
|
+
volumeName: string;
|
|
48
|
+
canonicalVolumeName: string;
|
|
49
|
+
mode: 'canonical' | 'environment-owned' | 'shared-legacy';
|
|
50
|
+
reason: string;
|
|
51
|
+
};
|
|
52
|
+
export type TreeseedRailwayVolumeBindingResult = {
|
|
53
|
+
bindings: TreeseedRailwayVolumeBinding[];
|
|
54
|
+
blockedReasons: string[];
|
|
55
|
+
};
|
|
56
|
+
export type TreeseedRailwayPendingVolumeCollision = {
|
|
57
|
+
serviceName: string;
|
|
58
|
+
volumeId: string;
|
|
59
|
+
canonicalVolumeName: string;
|
|
60
|
+
mountPath: string;
|
|
61
|
+
serviceId: string | null;
|
|
21
62
|
};
|
|
22
63
|
export type TreeseedRailwayIacDatabase = {
|
|
23
64
|
serviceName: string;
|
|
@@ -57,6 +98,111 @@ export type RailwayIacValidationResult = {
|
|
|
57
98
|
blockedReasons: string[];
|
|
58
99
|
allowedDrift: string[];
|
|
59
100
|
};
|
|
101
|
+
export declare function waitForRailwayVolumeAdoptionResources<TService, TVolume>({ load, serviceName, volumeId, attempts, intervalMs, sleep, }: {
|
|
102
|
+
load: () => Promise<{
|
|
103
|
+
services: Array<TService & {
|
|
104
|
+
name?: string | null;
|
|
105
|
+
}>;
|
|
106
|
+
volumes: Array<TVolume & {
|
|
107
|
+
id?: string | null;
|
|
108
|
+
}>;
|
|
109
|
+
}>;
|
|
110
|
+
serviceName: string;
|
|
111
|
+
volumeId: string;
|
|
112
|
+
attempts?: number;
|
|
113
|
+
intervalMs?: number;
|
|
114
|
+
sleep?: (milliseconds: number) => Promise<unknown>;
|
|
115
|
+
}): Promise<{
|
|
116
|
+
service: TService & {
|
|
117
|
+
name?: string | null;
|
|
118
|
+
};
|
|
119
|
+
volume: TVolume & {
|
|
120
|
+
id?: string | null;
|
|
121
|
+
};
|
|
122
|
+
services: (TService & {
|
|
123
|
+
name?: string | null;
|
|
124
|
+
})[];
|
|
125
|
+
volumes: (TVolume & {
|
|
126
|
+
id?: string | null;
|
|
127
|
+
})[];
|
|
128
|
+
attempt: number;
|
|
129
|
+
} | null>;
|
|
130
|
+
export declare function waitForRailwayServices<TService extends {
|
|
131
|
+
name?: string | null;
|
|
132
|
+
}>({ load, serviceNames, attempts, intervalMs, sleep, }: {
|
|
133
|
+
load: () => Promise<TService[]>;
|
|
134
|
+
serviceNames: Iterable<string>;
|
|
135
|
+
attempts?: number;
|
|
136
|
+
intervalMs?: number;
|
|
137
|
+
sleep?: (milliseconds: number) => Promise<unknown>;
|
|
138
|
+
}): Promise<{
|
|
139
|
+
services: TService[];
|
|
140
|
+
attempt: number;
|
|
141
|
+
} | null>;
|
|
142
|
+
export declare function waitForRailwayVolumeName<TVolume extends {
|
|
143
|
+
id?: string | null;
|
|
144
|
+
name?: string | null;
|
|
145
|
+
}>({ load, volumeId, expectedName, attempts, intervalMs, sleep, }: {
|
|
146
|
+
load: () => Promise<TVolume[]>;
|
|
147
|
+
volumeId: string;
|
|
148
|
+
expectedName: string;
|
|
149
|
+
attempts?: number;
|
|
150
|
+
intervalMs?: number;
|
|
151
|
+
sleep?: (milliseconds: number) => Promise<unknown>;
|
|
152
|
+
}): Promise<{
|
|
153
|
+
volume: TVolume;
|
|
154
|
+
attempt: number;
|
|
155
|
+
} | null>;
|
|
156
|
+
export declare function waitForRailwayVolumeDetachment<TVolume extends {
|
|
157
|
+
id?: string | null;
|
|
158
|
+
instances?: Array<{
|
|
159
|
+
environmentId?: string | null;
|
|
160
|
+
serviceId?: string | null;
|
|
161
|
+
}>;
|
|
162
|
+
}>({ load, volumeId, environmentId, serviceId, attempts, intervalMs, sleep, }: {
|
|
163
|
+
load: () => Promise<TVolume[]>;
|
|
164
|
+
volumeId: string;
|
|
165
|
+
environmentId: string;
|
|
166
|
+
serviceId: string;
|
|
167
|
+
attempts?: number;
|
|
168
|
+
intervalMs?: number;
|
|
169
|
+
sleep?: (milliseconds: number) => Promise<unknown>;
|
|
170
|
+
}): Promise<{
|
|
171
|
+
volume: TVolume | null;
|
|
172
|
+
attempt: number;
|
|
173
|
+
} | null>;
|
|
174
|
+
export declare function waitForRailwayServiceAbsence<TService extends {
|
|
175
|
+
id?: string | null;
|
|
176
|
+
}>({ load, serviceId, attempts, intervalMs, sleep, }: {
|
|
177
|
+
load: () => Promise<TService[]>;
|
|
178
|
+
serviceId: string;
|
|
179
|
+
attempts?: number;
|
|
180
|
+
intervalMs?: number;
|
|
181
|
+
sleep?: (milliseconds: number) => Promise<unknown>;
|
|
182
|
+
}): Promise<{
|
|
183
|
+
attempt: number;
|
|
184
|
+
} | null>;
|
|
185
|
+
export declare function cleanupStaleRailwayIacRenders(tenantRoot: string, now?: number): string[];
|
|
186
|
+
export declare function railwayIacApplyFailure(response: RailwayIacApplyResponse): string | null;
|
|
187
|
+
export declare function runRailwayIacWithRateLimitRetry<T>(run: () => Promise<T>, { delaysMs, sleep, onRetry, onWait, }?: {
|
|
188
|
+
delaysMs?: number[];
|
|
189
|
+
sleep?: (milliseconds: number) => Promise<unknown>;
|
|
190
|
+
onRetry?: (attempt: number, delayMs: number, error: unknown) => void;
|
|
191
|
+
onWait?: (attempt: number, remainingMs: number) => void;
|
|
192
|
+
}): Promise<T>;
|
|
193
|
+
export declare function findRailwayPendingVolumeNameCollisions(input: {
|
|
194
|
+
services: TreeseedRailwayIacService[];
|
|
195
|
+
liveServices?: TreeseedRailwayObservedService[];
|
|
196
|
+
volumes: TreeseedRailwayObservedVolume[];
|
|
197
|
+
}): TreeseedRailwayPendingVolumeCollision[];
|
|
198
|
+
export declare function resolveRailwayIacVolumeBindings(input: {
|
|
199
|
+
environmentId: string;
|
|
200
|
+
services: TreeseedRailwayIacService[];
|
|
201
|
+
liveServices: TreeseedRailwayObservedService[];
|
|
202
|
+
volumes: TreeseedRailwayObservedVolume[];
|
|
203
|
+
}): TreeseedRailwayVolumeBindingResult;
|
|
204
|
+
export declare function detachRetainedRailwayVolumeBindings(resources: ResourceNode[], bindings: TreeseedRailwayVolumeBinding[]): ResourceNode[];
|
|
205
|
+
export declare function detachRetainedRailwayCustomDomains(resources: ResourceNode[], domains: string[]): ResourceNode[];
|
|
60
206
|
export declare function renderRailwayIacProject(input: TreeseedRailwayIacProjectInput): TreeseedRailwayIacRenderResult;
|
|
61
207
|
export declare function selectRailwayIacRetainedResources(plan: Pick<RailwayIacPlanResponse, 'changeSet' | 'currentGraph'>, allowedNames: Iterable<string>): ResourceNode[];
|
|
62
208
|
export declare function validateRailwayIacChangeSet(changeSet: RailwayChangeSet | undefined, desiredNames: {
|
|
@@ -66,6 +212,8 @@ export declare function validateRailwayIacChangeSet(changeSet: RailwayChangeSet
|
|
|
66
212
|
scope: string;
|
|
67
213
|
serviceSourceModes?: Record<string, string | null | undefined>;
|
|
68
214
|
serviceSourceRefs?: Record<string, string | null | undefined>;
|
|
215
|
+
allowedResourceDeletions?: string[];
|
|
216
|
+
protectedResourceNames?: string[];
|
|
69
217
|
}): RailwayIacValidationResult;
|
|
70
218
|
export declare function planRailwayIacProject(input: TreeseedRailwayIacProjectInput, rendered?: TreeseedRailwayIacRenderResult): Promise<RailwayIacPlanResponse>;
|
|
71
219
|
export declare function applyRailwayIacProject(input: TreeseedRailwayIacProjectInput, rendered?: TreeseedRailwayIacRenderResult): Promise<RailwayIacApplyResponse>;
|