@treeseed/sdk 0.6.41 → 0.6.43
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/operations/services/project-platform.js +5 -4
- package/dist/operations/services/railway-api.d.ts +8 -1
- package/dist/operations/services/railway-api.js +10 -1
- package/dist/operations/services/railway-deploy.d.ts +8 -8
- package/dist/operations/services/railway-deploy.js +53 -115
- package/package.json +1 -1
|
@@ -1120,9 +1120,10 @@ async function deployProjectPlatform(options) {
|
|
|
1120
1120
|
previousRailwayDeployNodeId = nodeId;
|
|
1121
1121
|
}
|
|
1122
1122
|
}
|
|
1123
|
+
const managesRailwaySchedules = options.scope === "staging" || options.scope === "prod";
|
|
1123
1124
|
let railwaySchedules = [];
|
|
1124
|
-
let railwayScheduleVerification = { ok: true, checks: [], skipped: true, reason: !selectedSystems.has("agents") ? "agents_not_selected" :
|
|
1125
|
-
if (
|
|
1125
|
+
let railwayScheduleVerification = { ok: true, checks: [], skipped: true, reason: !selectedSystems.has("agents") ? "agents_not_selected" : !managesRailwaySchedules ? "scope_not_scheduled" : "dry_run" };
|
|
1126
|
+
if (managesRailwaySchedules && selectedSystems.has("agents")) {
|
|
1126
1127
|
const agentDeployNodeIds = nodes.filter((node) => node.id.startsWith("agents:") && node.id.endsWith("-railway-deploy")).map((node) => node.id);
|
|
1127
1128
|
nodes.push({
|
|
1128
1129
|
id: "agents:schedules",
|
|
@@ -1156,9 +1157,9 @@ async function deployProjectPlatform(options) {
|
|
|
1156
1157
|
serviceResults
|
|
1157
1158
|
});
|
|
1158
1159
|
}
|
|
1159
|
-
if (
|
|
1160
|
+
if (!managesRailwaySchedules || !selectedSystems.has("agents")) {
|
|
1160
1161
|
railwaySchedules = [];
|
|
1161
|
-
railwayScheduleVerification = { ok: true, checks: railwaySchedules, skipped: true, reason: !selectedSystems.has("agents") ? "agents_not_selected" :
|
|
1162
|
+
railwayScheduleVerification = { ok: true, checks: railwaySchedules, skipped: true, reason: !selectedSystems.has("agents") ? "agents_not_selected" : !managesRailwaySchedules ? "scope_not_scheduled" : "dry_run" };
|
|
1162
1163
|
}
|
|
1163
1164
|
if (selectedSystems.has("agents")) {
|
|
1164
1165
|
serviceResults.push({
|
|
@@ -22,6 +22,7 @@ export type RailwayServiceInstanceSummary = {
|
|
|
22
22
|
id: string | null;
|
|
23
23
|
buildCommand: string | null;
|
|
24
24
|
startCommand: string | null;
|
|
25
|
+
cronSchedule: string | null;
|
|
25
26
|
rootDirectory: string | null;
|
|
26
27
|
healthcheckPath: string | null;
|
|
27
28
|
healthcheckTimeoutSeconds: number | null;
|
|
@@ -157,6 +158,7 @@ export declare function getRailwayServiceInstance({ serviceId, environmentId, en
|
|
|
157
158
|
id: string | null;
|
|
158
159
|
buildCommand: string | null;
|
|
159
160
|
startCommand: string | null;
|
|
161
|
+
cronSchedule: string | null;
|
|
160
162
|
rootDirectory: string | null;
|
|
161
163
|
healthcheckPath: string | null;
|
|
162
164
|
healthcheckTimeoutSeconds: number | null;
|
|
@@ -169,6 +171,7 @@ export declare function getRailwayServiceInstance({ serviceId, environmentId, en
|
|
|
169
171
|
id: string | null;
|
|
170
172
|
buildCommand: string | null;
|
|
171
173
|
startCommand: string | null;
|
|
174
|
+
cronSchedule: string | null;
|
|
172
175
|
rootDirectory: string | null;
|
|
173
176
|
healthcheckPath: null;
|
|
174
177
|
healthcheckTimeoutSeconds: null;
|
|
@@ -178,11 +181,12 @@ export declare function getRailwayServiceInstance({ serviceId, environmentId, en
|
|
|
178
181
|
sleepApplication: null;
|
|
179
182
|
runtimeConfigSupported: false;
|
|
180
183
|
}>;
|
|
181
|
-
export declare function ensureRailwayServiceInstanceConfiguration({ serviceId, environmentId, buildCommand, startCommand, rootDirectory, healthcheckPath, healthcheckTimeoutSeconds, healthcheckIntervalSeconds, restartPolicy, runtimeMode, env, fetchImpl, }: {
|
|
184
|
+
export declare function ensureRailwayServiceInstanceConfiguration({ serviceId, environmentId, buildCommand, startCommand, cronSchedule, rootDirectory, healthcheckPath, healthcheckTimeoutSeconds, healthcheckIntervalSeconds, restartPolicy, runtimeMode, env, fetchImpl, }: {
|
|
182
185
|
serviceId: string;
|
|
183
186
|
environmentId: string;
|
|
184
187
|
buildCommand?: string | null;
|
|
185
188
|
startCommand?: string | null;
|
|
189
|
+
cronSchedule?: string | null;
|
|
186
190
|
rootDirectory?: string | null;
|
|
187
191
|
healthcheckPath?: string | null;
|
|
188
192
|
healthcheckTimeoutSeconds?: number | null;
|
|
@@ -196,6 +200,7 @@ export declare function ensureRailwayServiceInstanceConfiguration({ serviceId, e
|
|
|
196
200
|
id: string | null;
|
|
197
201
|
buildCommand: string | null;
|
|
198
202
|
startCommand: string | null;
|
|
203
|
+
cronSchedule: string | null;
|
|
199
204
|
rootDirectory: string | null;
|
|
200
205
|
healthcheckPath: string | null;
|
|
201
206
|
healthcheckTimeoutSeconds: number | null;
|
|
@@ -208,6 +213,7 @@ export declare function ensureRailwayServiceInstanceConfiguration({ serviceId, e
|
|
|
208
213
|
id: string | null;
|
|
209
214
|
buildCommand: string | null;
|
|
210
215
|
startCommand: string | null;
|
|
216
|
+
cronSchedule: string | null;
|
|
211
217
|
rootDirectory: string | null;
|
|
212
218
|
healthcheckPath: null;
|
|
213
219
|
healthcheckTimeoutSeconds: null;
|
|
@@ -223,6 +229,7 @@ export declare function ensureRailwayServiceInstanceConfiguration({ serviceId, e
|
|
|
223
229
|
id: string;
|
|
224
230
|
buildCommand: string | null;
|
|
225
231
|
startCommand: string | null;
|
|
232
|
+
cronSchedule: string | null;
|
|
226
233
|
rootDirectory: string | null;
|
|
227
234
|
healthcheckPath: string | null;
|
|
228
235
|
healthcheckTimeoutSeconds: number | null;
|
|
@@ -659,6 +659,7 @@ async function getRailwayServiceInstance({
|
|
|
659
659
|
id: null,
|
|
660
660
|
buildCommand: null,
|
|
661
661
|
startCommand: null,
|
|
662
|
+
cronSchedule: null,
|
|
662
663
|
rootDirectory: null,
|
|
663
664
|
healthcheckPath: null,
|
|
664
665
|
healthcheckTimeoutSeconds: null,
|
|
@@ -676,6 +677,7 @@ query TreeseedRailwayServiceInstance($serviceId: String!, $environmentId: String
|
|
|
676
677
|
id
|
|
677
678
|
buildCommand
|
|
678
679
|
startCommand
|
|
680
|
+
cronSchedule
|
|
679
681
|
rootDirectory
|
|
680
682
|
healthcheckPath
|
|
681
683
|
healthcheckTimeout
|
|
@@ -692,6 +694,7 @@ query TreeseedRailwayServiceInstance($serviceId: String!, $environmentId: String
|
|
|
692
694
|
id: railwayConnectionLabel(instance?.id) || null,
|
|
693
695
|
buildCommand: railwayConnectionLabel(instance?.buildCommand) || null,
|
|
694
696
|
startCommand: railwayConnectionLabel(instance?.startCommand) || null,
|
|
697
|
+
cronSchedule: railwayConnectionLabel(instance?.cronSchedule) || null,
|
|
695
698
|
rootDirectory: railwayConnectionLabel(instance?.rootDirectory) || null,
|
|
696
699
|
healthcheckPath: railwayConnectionLabel(instance?.healthcheckPath) || null,
|
|
697
700
|
healthcheckTimeoutSeconds: normalizeRailwayNumber(instance?.healthcheckTimeout),
|
|
@@ -711,6 +714,7 @@ query TreeseedRailwayServiceInstanceLegacy($serviceId: String!, $environmentId:
|
|
|
711
714
|
id
|
|
712
715
|
buildCommand
|
|
713
716
|
startCommand
|
|
717
|
+
cronSchedule
|
|
714
718
|
rootDirectory
|
|
715
719
|
}
|
|
716
720
|
}
|
|
@@ -725,6 +729,7 @@ query TreeseedRailwayServiceInstanceLegacy($serviceId: String!, $environmentId:
|
|
|
725
729
|
id: railwayConnectionLabel(instance?.id) || null,
|
|
726
730
|
buildCommand: railwayConnectionLabel(instance?.buildCommand) || null,
|
|
727
731
|
startCommand: railwayConnectionLabel(instance?.startCommand) || null,
|
|
732
|
+
cronSchedule: railwayConnectionLabel(instance?.cronSchedule) || null,
|
|
728
733
|
rootDirectory: railwayConnectionLabel(instance?.rootDirectory) || null
|
|
729
734
|
};
|
|
730
735
|
}
|
|
@@ -739,6 +744,7 @@ async function ensureRailwayServiceInstanceConfiguration({
|
|
|
739
744
|
environmentId,
|
|
740
745
|
buildCommand,
|
|
741
746
|
startCommand,
|
|
747
|
+
cronSchedule,
|
|
742
748
|
rootDirectory,
|
|
743
749
|
healthcheckPath,
|
|
744
750
|
healthcheckTimeoutSeconds,
|
|
@@ -755,6 +761,7 @@ async function ensureRailwayServiceInstanceConfiguration({
|
|
|
755
761
|
const desired = {
|
|
756
762
|
buildCommand: railwayConnectionLabel(buildCommand) || null,
|
|
757
763
|
startCommand: railwayConnectionLabel(startCommand) || null,
|
|
764
|
+
cronSchedule: railwayConnectionLabel(cronSchedule) || null,
|
|
758
765
|
rootDirectory: railwayConnectionLabel(rootDirectory) || null,
|
|
759
766
|
healthcheckPath: railwayConnectionLabel(healthcheckPath) || null,
|
|
760
767
|
healthcheckTimeoutSeconds: normalizeRailwayNumber(healthcheckTimeoutSeconds),
|
|
@@ -773,7 +780,7 @@ async function ensureRailwayServiceInstanceConfiguration({
|
|
|
773
780
|
if (desired.restartPolicy !== null) {
|
|
774
781
|
throw new Error("Railway service instance restart policies are unsupported by the current Railway API schema.");
|
|
775
782
|
}
|
|
776
|
-
const drifted = desired.buildCommand !== null && desired.buildCommand !== current.buildCommand || desired.startCommand !== null && desired.startCommand !== current.startCommand || desired.rootDirectory !== null && desired.rootDirectory !== current.rootDirectory || desired.healthcheckPath !== null && desired.healthcheckPath !== current.healthcheckPath || desired.healthcheckTimeoutSeconds !== null && desired.healthcheckTimeoutSeconds !== current.healthcheckTimeoutSeconds || desired.runtimeMode !== null && desired.runtimeMode !== current.runtimeMode;
|
|
783
|
+
const drifted = desired.buildCommand !== null && desired.buildCommand !== current.buildCommand || desired.startCommand !== null && desired.startCommand !== current.startCommand || desired.cronSchedule !== null && desired.cronSchedule !== current.cronSchedule || desired.rootDirectory !== null && desired.rootDirectory !== current.rootDirectory || desired.healthcheckPath !== null && desired.healthcheckPath !== current.healthcheckPath || desired.healthcheckTimeoutSeconds !== null && desired.healthcheckTimeoutSeconds !== current.healthcheckTimeoutSeconds || desired.runtimeMode !== null && desired.runtimeMode !== current.runtimeMode;
|
|
777
784
|
if (!drifted) {
|
|
778
785
|
return { instance: current, updated: false };
|
|
779
786
|
}
|
|
@@ -795,6 +802,7 @@ mutation TreeseedRailwayServiceInstanceUpdateLegacy($serviceId: String!, $enviro
|
|
|
795
802
|
input: {
|
|
796
803
|
...desired.buildCommand !== null ? { buildCommand: desired.buildCommand } : {},
|
|
797
804
|
...desired.startCommand !== null ? { startCommand: desired.startCommand } : {},
|
|
805
|
+
...desired.cronSchedule !== null ? { cronSchedule: desired.cronSchedule } : {},
|
|
798
806
|
...desired.rootDirectory !== null ? { rootDirectory: desired.rootDirectory } : {},
|
|
799
807
|
...desired.healthcheckPath !== null ? { healthcheckPath: desired.healthcheckPath } : {},
|
|
800
808
|
...desired.healthcheckTimeoutSeconds !== null ? { healthcheckTimeout: desired.healthcheckTimeoutSeconds } : {},
|
|
@@ -822,6 +830,7 @@ mutation TreeseedRailwayServiceInstanceUpdateLegacy($serviceId: String!, $enviro
|
|
|
822
830
|
id: instance.id || current.id,
|
|
823
831
|
buildCommand: instance.buildCommand ?? desired.buildCommand,
|
|
824
832
|
startCommand: instance.startCommand ?? desired.startCommand,
|
|
833
|
+
cronSchedule: instance.cronSchedule ?? desired.cronSchedule,
|
|
825
834
|
rootDirectory: instance.rootDirectory ?? desired.rootDirectory,
|
|
826
835
|
healthcheckPath: instance.healthcheckPath ?? desired.healthcheckPath,
|
|
827
836
|
healthcheckTimeoutSeconds: instance.healthcheckTimeoutSeconds ?? desired.healthcheckTimeoutSeconds,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type TreeseedBootstrapTaskPrefix, type TreeseedBootstrapWriter } from './bootstrap-runner.ts';
|
|
2
2
|
export declare function deriveRailwayWorkerRunnerServiceName(projectSlug: any, index?: number): string;
|
|
3
|
-
export declare function deriveRailwayWorkerRunnerVolumeName(serviceName: any): string;
|
|
3
|
+
export declare function deriveRailwayWorkerRunnerVolumeName(serviceName: any, environmentName?: string): string;
|
|
4
4
|
export declare function railwayServiceRuntimeStartCommand(service: any): any;
|
|
5
5
|
export declare function isUsableRailwayToken(value: any): boolean;
|
|
6
6
|
export declare function resolveRailwayAuthToken(env?: NodeJS.ProcessEnv): string;
|
|
@@ -201,10 +201,10 @@ export declare function ensureRailwayScheduledJobs(tenantRoot: any, scope: any,
|
|
|
201
201
|
logicalName: string;
|
|
202
202
|
} | {
|
|
203
203
|
projectId: string;
|
|
204
|
-
id:
|
|
204
|
+
id: string | null;
|
|
205
205
|
status: string;
|
|
206
|
-
enabled:
|
|
207
|
-
command:
|
|
206
|
+
enabled: boolean;
|
|
207
|
+
command: string | null;
|
|
208
208
|
serviceId: string;
|
|
209
209
|
environmentId: string;
|
|
210
210
|
service: string;
|
|
@@ -257,16 +257,16 @@ export declare function verifyRailwayScheduledJobs(tenantRoot: any, scope: any,
|
|
|
257
257
|
enabled: boolean;
|
|
258
258
|
logicalName: string;
|
|
259
259
|
} | {
|
|
260
|
-
id:
|
|
260
|
+
id: string | null;
|
|
261
261
|
projectId: string;
|
|
262
262
|
serviceId: string;
|
|
263
263
|
environmentId: string;
|
|
264
264
|
ok: boolean;
|
|
265
265
|
status: string;
|
|
266
266
|
observed: {
|
|
267
|
-
expression:
|
|
268
|
-
command:
|
|
269
|
-
enabled:
|
|
267
|
+
expression: string | null;
|
|
268
|
+
command: string | null;
|
|
269
|
+
enabled: boolean;
|
|
270
270
|
} | null;
|
|
271
271
|
message: string | undefined;
|
|
272
272
|
service: string;
|
|
@@ -11,11 +11,11 @@ import {
|
|
|
11
11
|
ensureRailwayService,
|
|
12
12
|
ensureRailwayServiceInstanceConfiguration,
|
|
13
13
|
ensureRailwayServiceVolume,
|
|
14
|
+
getRailwayServiceInstance,
|
|
14
15
|
listRailwayEnvironments,
|
|
15
16
|
listRailwayProjects,
|
|
16
17
|
listRailwayServices,
|
|
17
18
|
normalizeRailwayEnvironmentName,
|
|
18
|
-
railwayGraphqlRequest,
|
|
19
19
|
resolveRailwayApiToken,
|
|
20
20
|
resolveRailwayApiUrl,
|
|
21
21
|
resolveRailwayWorkspace,
|
|
@@ -43,13 +43,12 @@ function deriveRailwayWorkerRunnerServiceName(projectSlug, index = WORKER_RUNNER
|
|
|
43
43
|
const normalizedIndex = Math.max(1, Number.parseInt(String(index), 10) || WORKER_RUNNER_BOOTSTRAP_INDEX);
|
|
44
44
|
return `${projectSlug}-worker-runner-${String(normalizedIndex).padStart(2, "0")}`;
|
|
45
45
|
}
|
|
46
|
-
function deriveRailwayWorkerRunnerVolumeName(serviceName) {
|
|
47
|
-
|
|
46
|
+
function deriveRailwayWorkerRunnerVolumeName(serviceName, environmentName = "") {
|
|
47
|
+
const environment = normalizeRailwayEnvironmentName(environmentName);
|
|
48
|
+
const environmentSuffix = environment && environment !== "production" ? `-${environment}` : "";
|
|
49
|
+
return `${serviceName}${environmentSuffix}-data`;
|
|
48
50
|
}
|
|
49
51
|
function railwayServiceRuntimeStartCommand(service) {
|
|
50
|
-
if (service.key === "workdayManager" && Array.isArray(service.schedule) && service.schedule.length > 0) {
|
|
51
|
-
return `node -e "console.log('workday-manager scheduled-only service idle')"`;
|
|
52
|
-
}
|
|
53
52
|
return service.startCommand;
|
|
54
53
|
}
|
|
55
54
|
function normalizeScheduleExpressions(value) {
|
|
@@ -691,7 +690,6 @@ async function ensureRailwayScheduledJobs(tenantRoot, scope, { dryRun = false, f
|
|
|
691
690
|
if (typeof effectiveApiToken !== "string" || effectiveApiToken.trim().length === 0) {
|
|
692
691
|
throw new Error("Configure RAILWAY_API_TOKEN before deploying Railway-managed services.");
|
|
693
692
|
}
|
|
694
|
-
const queries = defaultRailwayScheduleQueries();
|
|
695
693
|
const results = [];
|
|
696
694
|
try {
|
|
697
695
|
for (const schedule of schedules) {
|
|
@@ -713,21 +711,12 @@ async function ensureRailwayScheduledJobs(tenantRoot, scope, { dryRun = false, f
|
|
|
713
711
|
});
|
|
714
712
|
continue;
|
|
715
713
|
}
|
|
716
|
-
const
|
|
717
|
-
projectId: target.project.id,
|
|
714
|
+
const current = await getRailwayServiceInstance({
|
|
718
715
|
serviceId: target.service.id,
|
|
719
|
-
environmentId: target.environment.id
|
|
720
|
-
|
|
721
|
-
const listed = await railwayGraphqlRequest({
|
|
722
|
-
query: queries.listQuery,
|
|
723
|
-
variables,
|
|
724
|
-
apiToken: effectiveApiToken,
|
|
725
|
-
apiUrl: effectiveApiUrl,
|
|
716
|
+
environmentId: target.environment.id,
|
|
717
|
+
env: { ...env, RAILWAY_API_TOKEN: effectiveApiToken, TREESEED_RAILWAY_API_URL: effectiveApiUrl },
|
|
726
718
|
fetchImpl
|
|
727
719
|
});
|
|
728
|
-
const existing = collectRailwaySchedules(listed?.data).find(
|
|
729
|
-
(entry) => entry.id && entry.id === schedule.id || entry.name && entry.name === schedule.logicalName || entry.expression === schedule.expression && entry.serviceId === schedule.serviceId && (!schedule.environmentId || entry.environmentId === schedule.environmentId)
|
|
730
|
-
);
|
|
731
720
|
const desired = {
|
|
732
721
|
name: schedule.logicalName,
|
|
733
722
|
schedule: schedule.expression,
|
|
@@ -735,90 +724,38 @@ async function ensureRailwayScheduledJobs(tenantRoot, scope, { dryRun = false, f
|
|
|
735
724
|
enabled: schedule.enabled !== false
|
|
736
725
|
};
|
|
737
726
|
const drifted = Boolean(
|
|
738
|
-
|
|
727
|
+
current.id && (current.cronSchedule !== desired.schedule || (current.startCommand ?? null) !== (desired.command ?? null))
|
|
739
728
|
);
|
|
740
729
|
if (dryRun) {
|
|
741
730
|
results.push({
|
|
742
731
|
...schedule,
|
|
743
|
-
projectId:
|
|
744
|
-
id:
|
|
745
|
-
status:
|
|
732
|
+
projectId: target.project.id,
|
|
733
|
+
id: current.id,
|
|
734
|
+
status: current.id ? drifted ? "planned_update" : "planned_noop" : "planned_create",
|
|
746
735
|
enabled: desired.enabled,
|
|
747
736
|
command: desired.command,
|
|
748
|
-
serviceId:
|
|
749
|
-
environmentId:
|
|
750
|
-
});
|
|
751
|
-
continue;
|
|
752
|
-
}
|
|
753
|
-
if (!existing) {
|
|
754
|
-
const created = await railwayGraphqlRequest({
|
|
755
|
-
query: queries.createMutation,
|
|
756
|
-
variables: {
|
|
757
|
-
...variables,
|
|
758
|
-
name: desired.name,
|
|
759
|
-
schedule: desired.schedule,
|
|
760
|
-
command: desired.command,
|
|
761
|
-
enabled: desired.enabled
|
|
762
|
-
},
|
|
763
|
-
apiToken: effectiveApiToken,
|
|
764
|
-
apiUrl: effectiveApiUrl,
|
|
765
|
-
fetchImpl
|
|
766
|
-
});
|
|
767
|
-
const createdSchedule = collectRailwaySchedules(created?.data)[0];
|
|
768
|
-
if (!createdSchedule?.id) {
|
|
769
|
-
throw new Error(`Railway schedule create did not return an id for ${schedule.logicalName}.`);
|
|
770
|
-
}
|
|
771
|
-
results.push({
|
|
772
|
-
...schedule,
|
|
773
|
-
projectId: variables.projectId,
|
|
774
|
-
id: createdSchedule.id,
|
|
775
|
-
status: "created",
|
|
776
|
-
enabled: createdSchedule.enabled,
|
|
777
|
-
command: createdSchedule.command ?? desired.command,
|
|
778
|
-
serviceId: variables.serviceId,
|
|
779
|
-
environmentId: variables.environmentId
|
|
780
|
-
});
|
|
781
|
-
continue;
|
|
782
|
-
}
|
|
783
|
-
if (drifted) {
|
|
784
|
-
const updated = await railwayGraphqlRequest({
|
|
785
|
-
query: queries.updateMutation,
|
|
786
|
-
variables: {
|
|
787
|
-
id: existing.id,
|
|
788
|
-
name: desired.name,
|
|
789
|
-
schedule: desired.schedule,
|
|
790
|
-
command: desired.command,
|
|
791
|
-
enabled: desired.enabled
|
|
792
|
-
},
|
|
793
|
-
apiToken: effectiveApiToken,
|
|
794
|
-
apiUrl: effectiveApiUrl,
|
|
795
|
-
fetchImpl
|
|
796
|
-
});
|
|
797
|
-
const updatedSchedule = collectRailwaySchedules(updated?.data)[0];
|
|
798
|
-
if (!updatedSchedule?.id) {
|
|
799
|
-
throw new Error(`Railway schedule update did not return an id for ${schedule.logicalName}.`);
|
|
800
|
-
}
|
|
801
|
-
results.push({
|
|
802
|
-
...schedule,
|
|
803
|
-
projectId: variables.projectId,
|
|
804
|
-
id: updatedSchedule.id,
|
|
805
|
-
status: "updated",
|
|
806
|
-
enabled: updatedSchedule.enabled,
|
|
807
|
-
command: updatedSchedule.command ?? desired.command,
|
|
808
|
-
serviceId: variables.serviceId,
|
|
809
|
-
environmentId: variables.environmentId
|
|
737
|
+
serviceId: target.service.id,
|
|
738
|
+
environmentId: target.environment.id
|
|
810
739
|
});
|
|
811
740
|
continue;
|
|
812
741
|
}
|
|
742
|
+
const updated = await ensureRailwayServiceInstanceConfiguration({
|
|
743
|
+
serviceId: target.service.id,
|
|
744
|
+
environmentId: target.environment.id,
|
|
745
|
+
startCommand: desired.command,
|
|
746
|
+
cronSchedule: desired.schedule,
|
|
747
|
+
env: { ...env, RAILWAY_API_TOKEN: effectiveApiToken, TREESEED_RAILWAY_API_URL: effectiveApiUrl },
|
|
748
|
+
fetchImpl
|
|
749
|
+
});
|
|
813
750
|
results.push({
|
|
814
751
|
...schedule,
|
|
815
|
-
projectId:
|
|
816
|
-
id:
|
|
817
|
-
status: "noop",
|
|
818
|
-
enabled:
|
|
819
|
-
command:
|
|
820
|
-
serviceId:
|
|
821
|
-
environmentId:
|
|
752
|
+
projectId: target.project.id,
|
|
753
|
+
id: updated.instance.id,
|
|
754
|
+
status: updated.updated ? "updated" : "noop",
|
|
755
|
+
enabled: desired.enabled,
|
|
756
|
+
command: desired.command,
|
|
757
|
+
serviceId: target.service.id,
|
|
758
|
+
environmentId: target.environment.id
|
|
822
759
|
});
|
|
823
760
|
}
|
|
824
761
|
} catch (error) {
|
|
@@ -840,7 +777,6 @@ async function verifyRailwayScheduledJobs(tenantRoot, scope, { fetchImpl = fetch
|
|
|
840
777
|
const effectiveApiToken = apiToken || env?.RAILWAY_API_TOKEN;
|
|
841
778
|
const effectiveApiUrl = apiUrl || resolveRailwayApiUrl(env);
|
|
842
779
|
const configured = configuredRailwayScheduledJobs(tenantRoot, scope);
|
|
843
|
-
const queries = defaultRailwayScheduleQueries();
|
|
844
780
|
const checks = [];
|
|
845
781
|
try {
|
|
846
782
|
for (const schedule of configured) {
|
|
@@ -859,36 +795,28 @@ async function verifyRailwayScheduledJobs(tenantRoot, scope, { fetchImpl = fetch
|
|
|
859
795
|
});
|
|
860
796
|
continue;
|
|
861
797
|
}
|
|
862
|
-
const
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
serviceId: target.service.id,
|
|
867
|
-
environmentId: target.environment.id
|
|
868
|
-
},
|
|
869
|
-
apiToken: effectiveApiToken,
|
|
870
|
-
apiUrl: effectiveApiUrl,
|
|
798
|
+
const existing = await getRailwayServiceInstance({
|
|
799
|
+
serviceId: target.service.id,
|
|
800
|
+
environmentId: target.environment.id,
|
|
801
|
+
env: { ...env, RAILWAY_API_TOKEN: effectiveApiToken, TREESEED_RAILWAY_API_URL: effectiveApiUrl },
|
|
871
802
|
fetchImpl
|
|
872
803
|
});
|
|
873
|
-
const existing = collectRailwaySchedules(listed?.data).find(
|
|
874
|
-
(entry) => entry.name && entry.name === schedule.logicalName || entry.expression === schedule.expression && entry.serviceId === schedule.serviceId && (!schedule.environmentId || entry.environmentId === schedule.environmentId)
|
|
875
|
-
);
|
|
876
804
|
checks.push({
|
|
877
805
|
...schedule,
|
|
878
|
-
id: existing
|
|
806
|
+
id: existing.id,
|
|
879
807
|
projectId: target.project.id,
|
|
880
808
|
serviceId: target.service.id,
|
|
881
809
|
environmentId: target.environment.id,
|
|
882
810
|
ok: Boolean(
|
|
883
|
-
existing && existing.
|
|
811
|
+
existing.id && existing.cronSchedule === schedule.expression && (existing.startCommand ?? null) === (schedule.command ?? null)
|
|
884
812
|
),
|
|
885
|
-
status: existing ? "checked" : "missing",
|
|
886
|
-
observed: existing ? {
|
|
887
|
-
expression: existing.
|
|
888
|
-
command: existing.
|
|
889
|
-
enabled:
|
|
813
|
+
status: existing.id ? "checked" : "missing",
|
|
814
|
+
observed: existing.id ? {
|
|
815
|
+
expression: existing.cronSchedule,
|
|
816
|
+
command: existing.startCommand ?? null,
|
|
817
|
+
enabled: true
|
|
890
818
|
} : null,
|
|
891
|
-
message: existing ? void 0 : `Railway schedule ${schedule.logicalName} is missing for ${target.service.name} in ${target.environment.name}.`
|
|
819
|
+
message: existing.id ? void 0 : `Railway schedule ${schedule.logicalName} is missing for ${target.service.name} in ${target.environment.name}.`
|
|
892
820
|
});
|
|
893
821
|
}
|
|
894
822
|
} catch (error) {
|
|
@@ -1005,6 +933,7 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1005
933
|
environmentId: environment.id,
|
|
1006
934
|
buildCommand: service.buildCommand,
|
|
1007
935
|
startCommand: railwayServiceRuntimeStartCommand(service),
|
|
936
|
+
cronSchedule: service.schedule?.[0] ?? null,
|
|
1008
937
|
rootDirectory: relativeRailwayRootDir(tenantRoot, service.rootDir),
|
|
1009
938
|
healthcheckPath: service.healthcheckPath,
|
|
1010
939
|
healthcheckTimeoutSeconds: service.healthcheckTimeoutSeconds,
|
|
@@ -1013,6 +942,15 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1013
942
|
runtimeMode: service.runtimeMode,
|
|
1014
943
|
env
|
|
1015
944
|
}) : null;
|
|
945
|
+
await upsertRailwayVariables({
|
|
946
|
+
projectId: project.id,
|
|
947
|
+
environmentId: environment.id,
|
|
948
|
+
serviceId: railwayService.id,
|
|
949
|
+
variables: {
|
|
950
|
+
TREESEED_SKIP_PACKAGE_PREPARE: "1"
|
|
951
|
+
},
|
|
952
|
+
env
|
|
953
|
+
});
|
|
1016
954
|
const volumeMountPath = service.runnerPool?.volumeMountPath ?? WORKER_RUNNER_VOLUME_MOUNT_PATH;
|
|
1017
955
|
const volumeConfiguration = wantsRunnerVolume ? await ensureRailwayServiceVolumeWithCliFallback({
|
|
1018
956
|
tenantRoot,
|
|
@@ -1021,7 +959,7 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1021
959
|
environmentName: environment.name,
|
|
1022
960
|
serviceId: railwayService.id,
|
|
1023
961
|
serviceName: railwayService.name,
|
|
1024
|
-
name: deriveRailwayWorkerRunnerVolumeName(railwayService.name),
|
|
962
|
+
name: deriveRailwayWorkerRunnerVolumeName(railwayService.name, environment.name),
|
|
1025
963
|
mountPath: volumeMountPath,
|
|
1026
964
|
env
|
|
1027
965
|
}) : null;
|
|
@@ -1033,7 +971,7 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1033
971
|
variables: {
|
|
1034
972
|
TREESEED_RUNNER_SERVICE_NAME: railwayService.name,
|
|
1035
973
|
TREESEED_RUNNER_VOLUME_ROOT: volumeMountPath,
|
|
1036
|
-
TREESEED_RUNNER_VOLUME_NAME: volumeConfiguration?.volume.name ?? deriveRailwayWorkerRunnerVolumeName(railwayService.name),
|
|
974
|
+
TREESEED_RUNNER_VOLUME_NAME: volumeConfiguration?.volume.name ?? deriveRailwayWorkerRunnerVolumeName(railwayService.name, environment.name),
|
|
1037
975
|
TREESEED_WORKER_IDLE_EXIT_MS: configuredEnvValue(env, "TREESEED_WORKER_IDLE_EXIT_MS") || "60000",
|
|
1038
976
|
...volumeConfiguration?.volume.id ? { TREESEED_RUNNER_VOLUME_ID: volumeConfiguration.volume.id } : {}
|
|
1039
977
|
},
|