@shipfox/api-workflows 5.0.0 → 7.0.1
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/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +89 -0
- package/dist/core/agent-defaults.d.ts +17 -0
- package/dist/core/agent-defaults.d.ts.map +1 -0
- package/dist/core/agent-defaults.js +21 -0
- package/dist/core/agent-defaults.js.map +1 -0
- package/dist/core/agent-tool-capability-warning.d.ts +4 -0
- package/dist/core/agent-tool-capability-warning.d.ts.map +1 -1
- package/dist/core/agent-tool-capability-warning.js +15 -17
- package/dist/core/agent-tool-capability-warning.js.map +1 -1
- package/dist/core/agent-tools.d.ts +11 -9
- package/dist/core/agent-tools.d.ts.map +1 -1
- package/dist/core/agent-tools.js +23 -18
- package/dist/core/agent-tools.js.map +1 -1
- package/dist/core/checkout.d.ts +21 -7
- package/dist/core/checkout.d.ts.map +1 -1
- package/dist/core/checkout.js +23 -11
- package/dist/core/checkout.js.map +1 -1
- package/dist/core/entities/workflow-run-attempt.d.ts +1 -1
- package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -1
- package/dist/core/entities/workflow-run-attempt.js.map +1 -1
- package/dist/core/job-execution.d.ts +3 -1
- package/dist/core/job-execution.d.ts.map +1 -1
- package/dist/core/job-execution.js +14 -12
- package/dist/core/job-execution.js.map +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.d.ts +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.d.ts.map +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.js.map +1 -1
- package/dist/core/job-transition/derive-job-success.js +1 -1
- package/dist/core/job-transition/derive-job-success.js.map +1 -1
- package/dist/core/listener-execution-materialization.d.ts +3 -3
- package/dist/core/listener-execution-materialization.d.ts.map +1 -1
- package/dist/core/listener-execution-materialization.js +3 -4
- package/dist/core/listener-execution-materialization.js.map +1 -1
- package/dist/core/run-workflow.d.ts +12 -1
- package/dist/core/run-workflow.d.ts.map +1 -1
- package/dist/core/run-workflow.js +13 -8
- package/dist/core/run-workflow.js.map +1 -1
- package/dist/core/step-config/agent.d.ts +8 -8
- package/dist/core/step-config/agent.d.ts.map +1 -1
- package/dist/core/step-config/agent.js +12 -10
- package/dist/core/step-config/agent.js.map +1 -1
- package/dist/core/step-config/complete-step-dispatch-config.d.ts +4 -4
- package/dist/core/step-config/complete-step-dispatch-config.d.ts.map +1 -1
- package/dist/core/step-config/complete-step-dispatch-config.js +2 -2
- package/dist/core/step-config/complete-step-dispatch-config.js.map +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.d.ts +3 -3
- package/dist/core/step-config/materialize-job-execution-steps.d.ts.map +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.js +5 -6
- package/dist/core/step-config/materialize-job-execution-steps.js.map +1 -1
- package/dist/core/step-config/materialize-workflow-model.d.ts +3 -3
- package/dist/core/step-config/materialize-workflow-model.d.ts.map +1 -1
- package/dist/core/step-config/materialize-workflow-model.js +4 -4
- package/dist/core/step-config/materialize-workflow-model.js.map +1 -1
- package/dist/core/step-config/resolve-job-execution-name.d.ts +1 -1
- package/dist/core/step-config/resolve-job-execution-name.d.ts.map +1 -1
- package/dist/core/step-config/resolve-job-execution-name.js.map +1 -1
- package/dist/core/step-config/resolve-step-config.d.ts +4 -4
- package/dist/core/step-config/resolve-step-config.d.ts.map +1 -1
- package/dist/core/step-config/resolve-step-config.js +6 -6
- package/dist/core/step-config/resolve-step-config.js.map +1 -1
- package/dist/core/step-config/run.d.ts +1 -1
- package/dist/core/step-config/run.d.ts.map +1 -1
- package/dist/core/step-config/run.js.map +1 -1
- package/dist/core/workflow-run-creation.d.ts +3 -3
- package/dist/core/workflow-run-creation.d.ts.map +1 -1
- package/dist/core/workflow-run-creation.js +3 -4
- package/dist/core/workflow-run-creation.js.map +1 -1
- package/dist/db/db.d.ts +16 -4
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/job-listeners.d.ts +7 -1
- package/dist/db/job-listeners.d.ts.map +1 -1
- package/dist/db/job-listeners.js +10 -5
- package/dist/db/job-listeners.js.map +1 -1
- package/dist/db/runner-lease-table.d.ts +5 -5
- package/dist/db/runner-lease-table.d.ts.map +1 -1
- package/dist/db/runner-lease-table.js +3 -2
- package/dist/db/runner-lease-table.js.map +1 -1
- package/dist/db/schema/workflow-run-attempts.d.ts +9 -3
- package/dist/db/schema/workflow-run-attempts.d.ts.map +1 -1
- package/dist/db/schema/workflow-run-attempts.js +2 -1
- package/dist/db/schema/workflow-run-attempts.js.map +1 -1
- package/dist/db/schema/workflow-runs.js +1 -1
- package/dist/db/schema/workflow-runs.js.map +1 -1
- package/dist/db/workflow-runs/job-executions.d.ts +5 -0
- package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
- package/dist/db/workflow-runs/job-executions.js +14 -7
- package/dist/db/workflow-runs/job-executions.js.map +1 -1
- package/dist/db/workflow-runs/jobs.d.ts.map +1 -1
- package/dist/db/workflow-runs/jobs.js +3 -1
- package/dist/db/workflow-runs/jobs.js.map +1 -1
- package/dist/db/workflow-runs/run-create.d.ts +9 -2
- package/dist/db/workflow-runs/run-create.d.ts.map +1 -1
- package/dist/db/workflow-runs/run-create.js +12 -9
- package/dist/db/workflow-runs/run-create.js.map +1 -1
- package/dist/db/workflow-runs/run-rerun.d.ts.map +1 -1
- package/dist/db/workflow-runs/run-rerun.js +3 -1
- package/dist/db/workflow-runs/run-rerun.js.map +1 -1
- package/dist/index.d.ts +18 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -37
- package/dist/index.js.map +1 -1
- package/dist/presentation/dto/checkout-token.d.ts +14 -1
- package/dist/presentation/dto/checkout-token.d.ts.map +1 -1
- package/dist/presentation/dto/checkout-token.js.map +1 -1
- package/dist/presentation/index.d.ts +1 -1
- package/dist/presentation/index.d.ts.map +1 -1
- package/dist/presentation/index.js +1 -1
- package/dist/presentation/index.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +18 -0
- package/dist/presentation/inter-module.d.ts.map +1 -0
- package/dist/presentation/inter-module.js +113 -0
- package/dist/presentation/inter-module.js.map +1 -0
- package/dist/presentation/routes/agent-runtime-config.d.ts +6 -1
- package/dist/presentation/routes/agent-runtime-config.d.ts.map +1 -1
- package/dist/presentation/routes/agent-runtime-config.js +59 -57
- package/dist/presentation/routes/agent-runtime-config.js.map +1 -1
- package/dist/presentation/routes/cancel-run.d.ts +2 -1
- package/dist/presentation/routes/cancel-run.d.ts.map +1 -1
- package/dist/presentation/routes/cancel-run.js +37 -34
- package/dist/presentation/routes/cancel-run.js.map +1 -1
- package/dist/presentation/routes/checkout-token.d.ts +8 -1
- package/dist/presentation/routes/checkout-token.d.ts.map +1 -1
- package/dist/presentation/routes/checkout-token.js +65 -47
- package/dist/presentation/routes/checkout-token.js.map +1 -1
- package/dist/presentation/routes/get-run-aggregates.d.ts +2 -1
- package/dist/presentation/routes/get-run-aggregates.d.ts.map +1 -1
- package/dist/presentation/routes/get-run-aggregates.js +44 -53
- package/dist/presentation/routes/get-run-aggregates.js.map +1 -1
- package/dist/presentation/routes/get-run.d.ts +2 -1
- package/dist/presentation/routes/get-run.d.ts.map +1 -1
- package/dist/presentation/routes/get-run.js +53 -50
- package/dist/presentation/routes/get-run.js.map +1 -1
- package/dist/presentation/routes/get-step-secrets.d.ts +3 -1
- package/dist/presentation/routes/get-step-secrets.d.ts.map +1 -1
- package/dist/presentation/routes/get-step-secrets.js +72 -68
- package/dist/presentation/routes/get-step-secrets.js.map +1 -1
- package/dist/presentation/routes/index.d.ts +19 -2
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +38 -30
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/leased-step.d.ts +2 -0
- package/dist/presentation/routes/leased-step.d.ts.map +1 -1
- package/dist/presentation/routes/leased-step.js +1 -2
- package/dist/presentation/routes/leased-step.js.map +1 -1
- package/dist/presentation/routes/list-run-attempts.d.ts +2 -1
- package/dist/presentation/routes/list-run-attempts.d.ts.map +1 -1
- package/dist/presentation/routes/list-run-attempts.js +29 -26
- package/dist/presentation/routes/list-run-attempts.js.map +1 -1
- package/dist/presentation/routes/list-runs.d.ts +2 -1
- package/dist/presentation/routes/list-runs.d.ts.map +1 -1
- package/dist/presentation/routes/list-runs.js +51 -60
- package/dist/presentation/routes/list-runs.js.map +1 -1
- package/dist/presentation/routes/next-step.d.ts +10 -1
- package/dist/presentation/routes/next-step.d.ts.map +1 -1
- package/dist/presentation/routes/next-step.js +64 -50
- package/dist/presentation/routes/next-step.js.map +1 -1
- package/dist/presentation/routes/project-access.d.ts +10 -0
- package/dist/presentation/routes/project-access.d.ts.map +1 -0
- package/dist/presentation/routes/project-access.js +17 -0
- package/dist/presentation/routes/project-access.js.map +1 -0
- package/dist/presentation/routes/report-step.d.ts +2 -1
- package/dist/presentation/routes/report-step.d.ts.map +1 -1
- package/dist/presentation/routes/report-step.js +62 -61
- package/dist/presentation/routes/report-step.js.map +1 -1
- package/dist/presentation/routes/require-accessible-run.d.ts +3 -1
- package/dist/presentation/routes/require-accessible-run.d.ts.map +1 -1
- package/dist/presentation/routes/require-accessible-run.js +3 -6
- package/dist/presentation/routes/require-accessible-run.js.map +1 -1
- package/dist/presentation/routes/rerun-run.d.ts +2 -1
- package/dist/presentation/routes/rerun-run.d.ts.map +1 -1
- package/dist/presentation/routes/rerun-run.js +46 -43
- package/dist/presentation/routes/rerun-run.js.map +1 -1
- package/dist/temporal/activities/index.d.ts +44 -9
- package/dist/temporal/activities/index.d.ts.map +1 -1
- package/dist/temporal/activities/index.js +13 -9
- package/dist/temporal/activities/index.js.map +1 -1
- package/dist/temporal/activities/orchestration-activities.d.ts +20 -11
- package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
- package/dist/temporal/activities/orchestration-activities.js +48 -33
- package/dist/temporal/activities/orchestration-activities.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +28 -21
- package/src/core/agent-defaults.test.ts +28 -0
- package/src/core/agent-defaults.ts +36 -0
- package/src/core/agent-tool-capability-warning.test.ts +36 -11
- package/src/core/agent-tool-capability-warning.ts +27 -25
- package/src/core/agent-tools.ts +33 -36
- package/src/core/checkout.test.ts +38 -25
- package/src/core/checkout.ts +41 -14
- package/src/core/entities/workflow-run-attempt.ts +1 -1
- package/src/core/job-execution.ts +19 -9
- package/src/core/job-transition/derive-job-execution-outputs.ts +1 -1
- package/src/core/job-transition/derive-job-success.ts +1 -1
- package/src/core/listener-execution-materialization.test.ts +4 -2
- package/src/core/listener-execution-materialization.ts +6 -9
- package/src/core/run-workflow.test.ts +43 -38
- package/src/core/run-workflow.ts +26 -9
- package/src/core/step-config/agent.ts +24 -26
- package/src/core/step-config/complete-step-dispatch-config.test.ts +22 -23
- package/src/core/step-config/complete-step-dispatch-config.ts +6 -6
- package/src/core/step-config/materialize-job-execution-steps.test.ts +34 -23
- package/src/core/step-config/materialize-job-execution-steps.ts +38 -39
- package/src/core/step-config/materialize-workflow-model.test.ts +94 -82
- package/src/core/step-config/materialize-workflow-model.ts +31 -29
- package/src/core/step-config/resolve-job-execution-name.ts +1 -1
- package/src/core/step-config/resolve-step-config.ts +11 -9
- package/src/core/step-config/run.ts +1 -1
- package/src/core/workflow-run-creation.test.ts +14 -10
- package/src/core/workflow-run-creation.ts +6 -9
- package/src/db/job-listeners.ts +20 -5
- package/src/db/runner-lease-table.ts +2 -2
- package/src/db/schema/workflow-run-attempts.ts +7 -3
- package/src/db/schema/workflow-runs.ts +1 -1
- package/src/db/workflow-runs/job-executions.ts +15 -1
- package/src/db/workflow-runs/jobs.ts +4 -1
- package/src/db/workflow-runs/run-create.test.ts +7 -1
- package/src/db/workflow-runs/run-create.ts +25 -15
- package/src/db/workflow-runs/run-rerun.test.ts +1 -1
- package/src/db/workflow-runs/run-rerun.ts +6 -3
- package/src/index.ts +75 -33
- package/src/presentation/dto/checkout-token.ts +7 -1
- package/src/presentation/index.ts +1 -1
- package/src/presentation/inter-module.test.ts +149 -0
- package/src/presentation/inter-module.ts +132 -0
- package/src/presentation/routes/agent-runtime-config.test.ts +53 -10
- package/src/presentation/routes/agent-runtime-config.ts +89 -64
- package/src/presentation/routes/cancel-run.test.ts +10 -20
- package/src/presentation/routes/cancel-run.ts +30 -27
- package/src/presentation/routes/checkout-token.test.ts +52 -33
- package/src/presentation/routes/checkout-token.ts +109 -49
- package/src/presentation/routes/get-run-aggregates.test.ts +13 -7
- package/src/presentation/routes/get-run-aggregates.ts +54 -57
- package/src/presentation/routes/get-run.test.ts +10 -18
- package/src/presentation/routes/get-run.ts +51 -48
- package/src/presentation/routes/get-step-secrets.test.ts +29 -7
- package/src/presentation/routes/get-step-secrets.ts +72 -61
- package/src/presentation/routes/index.test.ts +16 -1
- package/src/presentation/routes/index.ts +54 -29
- package/src/presentation/routes/leased-step.ts +3 -2
- package/src/presentation/routes/list-run-attempts.test.ts +9 -19
- package/src/presentation/routes/list-run-attempts.ts +21 -18
- package/src/presentation/routes/list-runs.test.ts +13 -7
- package/src/presentation/routes/list-runs.ts +64 -67
- package/src/presentation/routes/next-step.test.ts +30 -11
- package/src/presentation/routes/next-step.ts +68 -48
- package/src/presentation/routes/project-access.ts +16 -0
- package/src/presentation/routes/report-step.test.ts +18 -2
- package/src/presentation/routes/report-step.ts +51 -49
- package/src/presentation/routes/require-accessible-run.ts +5 -2
- package/src/presentation/routes/rerun-run.test.ts +9 -19
- package/src/presentation/routes/rerun-run.ts +39 -36
- package/src/temporal/activities/index.ts +32 -12
- package/src/temporal/activities/orchestration-activities.test.ts +10 -8
- package/src/temporal/activities/orchestration-activities.ts +74 -50
- package/src/temporal/workflows/job-execution-orchestration.test.ts +47 -2
- package/test/env.ts +1 -3
- package/test/factories/project.ts +10 -5
- package/test/factories/workflow-model.test.ts +5 -1
- package/test/factories/workflow-model.ts +1 -1
- package/test/factories/workflow-run.ts +1 -1
- package/test/fixtures/agent-inter-module.ts +27 -0
- package/test/fixtures/annotations-inter-module.ts +5 -0
- package/test/fixtures/auth-inter-module.ts +22 -0
- package/test/fixtures/lease-token.ts +2 -1
- package/test/fixtures/projects-inter-module.ts +8 -0
- package/test/fixtures/runners-inter-module.ts +52 -0
- package/test/fixtures/secrets-inter-module.ts +61 -0
- package/test/globalSetup.ts +11 -11
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/core/source-control.d.ts +0 -5
- package/dist/core/source-control.d.ts.map +0 -1
- package/dist/core/source-control.js +0 -19
- package/dist/core/source-control.js.map +0 -1
- package/src/core/source-control.test.ts +0 -17
- package/src/core/source-control.ts +0 -22
- package/src/temporal/workflows/job-execution-orchestration-timeout.test.ts +0 -165
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
getJobsByWorkflowRunId,
|
|
6
6
|
updateJobExecutionStatus,
|
|
7
7
|
} from '#db/index.js';
|
|
8
|
+
import {createTestSecretsClient} from '#test/fixtures/secrets-inter-module.js';
|
|
8
9
|
import {stripSetupStep} from '#test/fixtures/strip-setup-step.js';
|
|
9
10
|
import {workflowModel} from '#test/index.js';
|
|
10
11
|
import {resolveLeaseExpiredJobExecutionActivity, setJobStatus} from './orchestration-activities.js';
|
|
@@ -12,6 +13,7 @@ import {resolveLeaseExpiredJobExecutionActivity, setJobStatus} from './orchestra
|
|
|
12
13
|
let workspaceId: string;
|
|
13
14
|
let projectId: string;
|
|
14
15
|
let definitionId: string;
|
|
16
|
+
const secrets = createTestSecretsClient();
|
|
15
17
|
|
|
16
18
|
beforeEach(() => {
|
|
17
19
|
workspaceId = crypto.randomUUID();
|
|
@@ -51,10 +53,10 @@ describe('resolveLeaseExpiredJobExecutionActivity', () => {
|
|
|
51
53
|
// reproduce a genuinely stepless (malformed) job.
|
|
52
54
|
await stripSetupStep(jobId);
|
|
53
55
|
|
|
54
|
-
const error = await resolveLeaseExpiredJobExecutionActivity(
|
|
55
|
-
jobExecutionId,
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
const error = await resolveLeaseExpiredJobExecutionActivity(
|
|
57
|
+
{jobExecutionId, expectedVersion: runningVersion},
|
|
58
|
+
secrets,
|
|
59
|
+
).catch((err: unknown) => err);
|
|
58
60
|
|
|
59
61
|
expect(error).toBeInstanceOf(ApplicationFailure);
|
|
60
62
|
expect((error as ApplicationFailure).nonRetryable).toBe(true);
|
|
@@ -63,10 +65,10 @@ describe('resolveLeaseExpiredJobExecutionActivity', () => {
|
|
|
63
65
|
test('a well-formed job resolves without raising', async () => {
|
|
64
66
|
const {jobExecutionId, runningVersion} = await seedRunningJob(2);
|
|
65
67
|
|
|
66
|
-
const result = await resolveLeaseExpiredJobExecutionActivity(
|
|
67
|
-
jobExecutionId,
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const result = await resolveLeaseExpiredJobExecutionActivity(
|
|
69
|
+
{jobExecutionId, expectedVersion: runningVersion},
|
|
70
|
+
secrets,
|
|
71
|
+
);
|
|
70
72
|
|
|
71
73
|
expect(result.status).toBe('failed');
|
|
72
74
|
});
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
2
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
3
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
4
|
+
import {
|
|
5
|
+
type RunnersInterModuleClient,
|
|
6
|
+
runnersInterModuleContract,
|
|
7
|
+
} from '@shipfox/api-runners-dto/inter-module';
|
|
8
|
+
import type {SecretsInterModuleClient} from '@shipfox/api-secrets-dto/inter-module';
|
|
9
|
+
import {isInterModuleKnownError} from '@shipfox/inter-module';
|
|
2
10
|
import {ApplicationFailure} from '@temporalio/common';
|
|
3
11
|
import {defaultJobConditionTrace} from '#core/condition-trace.js';
|
|
4
12
|
import type {JobStatus, JobStatusReason, ResolutionReason} from '#core/entities/job.js';
|
|
@@ -161,17 +169,21 @@ function jobStatusEvaluationTrace(params: {
|
|
|
161
169
|
: undefined;
|
|
162
170
|
}
|
|
163
171
|
|
|
164
|
-
export async function setJobExecutionStatus(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
172
|
+
export async function setJobExecutionStatus(
|
|
173
|
+
params: {
|
|
174
|
+
jobExecutionId: string;
|
|
175
|
+
status: Exclude<JobStatus, 'skipped'>;
|
|
176
|
+
version: number;
|
|
177
|
+
statusReason?: JobStatusReason | null | undefined;
|
|
178
|
+
},
|
|
179
|
+
secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'>,
|
|
180
|
+
): Promise<{newVersion: number; status: Exclude<JobStatus, 'skipped'>}> {
|
|
170
181
|
const updated = await updateJobExecutionStatus({
|
|
171
182
|
jobExecutionId: params.jobExecutionId,
|
|
172
183
|
status: params.status,
|
|
173
184
|
expectedVersion: params.version,
|
|
174
185
|
statusReason: params.statusReason,
|
|
186
|
+
secrets,
|
|
175
187
|
});
|
|
176
188
|
return {newVersion: updated.version, status: updated.status};
|
|
177
189
|
}
|
|
@@ -183,12 +195,12 @@ export async function bulkSetStepStatuses(params: {
|
|
|
183
195
|
await bulkUpdateStepStatuses(params);
|
|
184
196
|
}
|
|
185
197
|
|
|
186
|
-
export async function resolveLeaseExpiredJobExecutionActivity(
|
|
187
|
-
jobExecutionId: string;
|
|
188
|
-
|
|
189
|
-
|
|
198
|
+
export async function resolveLeaseExpiredJobExecutionActivity(
|
|
199
|
+
params: {jobExecutionId: string; expectedVersion: number},
|
|
200
|
+
secrets: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'>,
|
|
201
|
+
): Promise<{status: RuntimeCompletionStatus; executionVersion: number}> {
|
|
190
202
|
try {
|
|
191
|
-
return await resolveJobExecutionAfterLeaseExpiry(params);
|
|
203
|
+
return await resolveJobExecutionAfterLeaseExpiry({...params, secrets});
|
|
192
204
|
} catch (err) {
|
|
193
205
|
if (err instanceof JobNotFoundError) {
|
|
194
206
|
throw ApplicationFailure.nonRetryable(err.message, err.name);
|
|
@@ -200,50 +212,56 @@ export async function resolveLeaseExpiredJobExecutionActivity(params: {
|
|
|
200
212
|
// Best-effort lease cleanup on job finalization. Idempotent: deleting an
|
|
201
213
|
// already-released (or already-reaped) lease is a no-op. The workflow wraps the
|
|
202
214
|
// call so a persistent failure never blocks the DAG result.
|
|
203
|
-
export
|
|
204
|
-
|
|
215
|
+
export function createReleaseLeaseActivity(runners: RunnersInterModuleClient) {
|
|
216
|
+
return async function releaseLeaseActivity(params: {jobExecutionId: string}): Promise<void> {
|
|
217
|
+
await runners.releaseJobExecution({jobExecutionId: params.jobExecutionId});
|
|
218
|
+
};
|
|
205
219
|
}
|
|
206
220
|
|
|
207
|
-
export
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
221
|
+
export function createEnqueueJobExecutionForRunner(runners: RunnersInterModuleClient) {
|
|
222
|
+
return async function enqueueJobExecutionForRunner(params: {
|
|
223
|
+
workspaceId: string;
|
|
224
|
+
workflowRunId: string;
|
|
225
|
+
jobId: string;
|
|
226
|
+
jobExecutionId: string;
|
|
227
|
+
runAttemptId: string;
|
|
228
|
+
projectId: string;
|
|
229
|
+
requiredLabels: string[];
|
|
230
|
+
}): Promise<void> {
|
|
231
|
+
try {
|
|
232
|
+
await runners.enqueueJobExecution({
|
|
233
|
+
workspaceId: params.workspaceId,
|
|
234
|
+
workflowRunId: params.workflowRunId,
|
|
235
|
+
workflowRunAttemptId: params.runAttemptId,
|
|
236
|
+
jobId: params.jobId,
|
|
237
|
+
jobExecutionId: params.jobExecutionId,
|
|
238
|
+
projectId: params.projectId,
|
|
239
|
+
requiredLabels: params.requiredLabels,
|
|
240
|
+
});
|
|
241
|
+
} catch (err) {
|
|
242
|
+
if (isInterModuleKnownError(runnersInterModuleContract.methods.enqueueJobExecution, err)) {
|
|
243
|
+
throw ApplicationFailure.nonRetryable(err.message, err.name);
|
|
244
|
+
}
|
|
245
|
+
throw err;
|
|
229
246
|
}
|
|
230
|
-
|
|
231
|
-
}
|
|
247
|
+
};
|
|
232
248
|
}
|
|
233
249
|
|
|
234
|
-
export
|
|
235
|
-
|
|
250
|
+
export function createCancelRunnerJobsActivity(runners: RunnersInterModuleClient) {
|
|
251
|
+
return async function cancelRunnerJobsActivity(params: {jobIds: string[]}): Promise<void> {
|
|
252
|
+
await runners.cancelJobs(params);
|
|
253
|
+
};
|
|
236
254
|
}
|
|
237
255
|
|
|
238
|
-
export async function failJobExecutionAsTimedOutActivity(
|
|
239
|
-
jobExecutionId: string;
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}): Promise<{newVersion: number}> {
|
|
256
|
+
export async function failJobExecutionAsTimedOutActivity(
|
|
257
|
+
params: {jobExecutionId: string; runAttemptId: string; expectedVersion: number},
|
|
258
|
+
secrets: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'>,
|
|
259
|
+
): Promise<{newVersion: number}> {
|
|
243
260
|
const jobExecution = await failJobExecutionAsTimedOut({
|
|
244
261
|
jobExecutionId: params.jobExecutionId,
|
|
245
262
|
workflowRunAttemptId: params.runAttemptId,
|
|
246
263
|
expectedVersion: params.expectedVersion,
|
|
264
|
+
secrets,
|
|
247
265
|
});
|
|
248
266
|
return {newVersion: jobExecution.version};
|
|
249
267
|
}
|
|
@@ -265,12 +283,18 @@ export async function activateJobListenerActivity(params: {
|
|
|
265
283
|
return await activateJobListener(params);
|
|
266
284
|
}
|
|
267
285
|
|
|
268
|
-
export
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
286
|
+
export function createDrainListenerEventsActivity(clients: {
|
|
287
|
+
agent: AgentInterModuleClient;
|
|
288
|
+
integrations?: IntegrationsModuleClient | undefined;
|
|
289
|
+
projects?: ProjectsModuleClient | undefined;
|
|
272
290
|
}) {
|
|
273
|
-
return
|
|
291
|
+
return async function drainListenerEventsActivity(params: {
|
|
292
|
+
jobId: string;
|
|
293
|
+
expectedSequence: number;
|
|
294
|
+
maxSize?: number | undefined;
|
|
295
|
+
}) {
|
|
296
|
+
return await drainListenerEventsIntoExecution({...params, ...clients});
|
|
297
|
+
};
|
|
274
298
|
}
|
|
275
299
|
|
|
276
300
|
export async function peekListenerBufferActivity(params: {jobId: string}) {
|
|
@@ -22,7 +22,7 @@ const WORKFLOWS_PATH = resolve(import.meta.dirname, '../../../dist/temporal/work
|
|
|
22
22
|
|
|
23
23
|
beforeAll(async () => {
|
|
24
24
|
await setupEnv();
|
|
25
|
-
},
|
|
25
|
+
}, 15_000);
|
|
26
26
|
|
|
27
27
|
afterAll(async () => {
|
|
28
28
|
await teardownEnv();
|
|
@@ -43,7 +43,9 @@ const defaultJobInput = {
|
|
|
43
43
|
requiredLabels: ['ubuntu22'],
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
function executeJob(
|
|
46
|
+
function executeJob(
|
|
47
|
+
input: typeof defaultJobInput & {executionTimeoutMs?: number | undefined},
|
|
48
|
+
): Promise<{status: string; jobVersion: number}> {
|
|
47
49
|
const normalized = {
|
|
48
50
|
...input,
|
|
49
51
|
jobExecutionId:
|
|
@@ -297,6 +299,49 @@ describe('jobExecutionOrchestration', () => {
|
|
|
297
299
|
expect(callsNamed('releaseLeaseActivity').length).toBeGreaterThanOrEqual(1);
|
|
298
300
|
});
|
|
299
301
|
|
|
302
|
+
test('times out after the execution deadline and fails its steps without releasing the lease', async () => {
|
|
303
|
+
setCfg({
|
|
304
|
+
dag: makeDag([dagJob('job-timeout', 'build')]),
|
|
305
|
+
jobResults: new Map(),
|
|
306
|
+
skipSignal: true,
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const result = await executeJob({
|
|
310
|
+
...defaultJobInput,
|
|
311
|
+
jobId: 'job-timeout',
|
|
312
|
+
executionTimeoutMs: 250,
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
expect(result.status).toBe('failed');
|
|
316
|
+
expect(callsNamed('failJobExecutionAsTimedOutActivity')).toHaveLength(1);
|
|
317
|
+
expect(finalStatusesFor('job-timeout')).toEqual(['running']);
|
|
318
|
+
expect(callsNamed('bulkSetStepStatuses')).toContainEqual({
|
|
319
|
+
name: 'bulkSetStepStatuses',
|
|
320
|
+
params: {jobExecutionId: 'job-timeout', status: 'failed'},
|
|
321
|
+
});
|
|
322
|
+
expect(callsNamed('releaseLeaseActivity')).toHaveLength(0);
|
|
323
|
+
expect(callsNamed('resolveLeaseExpiredJobExecutionActivity')).toHaveLength(0);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
test('surfaces a timeout activity failure', async () => {
|
|
327
|
+
setCfg({
|
|
328
|
+
dag: makeDag([dagJob('job-timeout-error', 'build')]),
|
|
329
|
+
jobResults: new Map(),
|
|
330
|
+
skipSignal: true,
|
|
331
|
+
failJobExecutionAsTimedOutError: 'simulated DB outage',
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
await expect(
|
|
335
|
+
executeJob({
|
|
336
|
+
...defaultJobInput,
|
|
337
|
+
jobId: 'job-timeout-error',
|
|
338
|
+
executionTimeoutMs: 250,
|
|
339
|
+
}),
|
|
340
|
+
).rejects.toThrow();
|
|
341
|
+
|
|
342
|
+
expect(finalStatusesFor('job-timeout-error')).toEqual(['running']);
|
|
343
|
+
});
|
|
344
|
+
|
|
300
345
|
test('no signal — workflow stays blocked indefinitely', async () => {
|
|
301
346
|
setCfg({dag: makeDag([]), jobResults: new Map(), skipSignal: true});
|
|
302
347
|
|
package/test/env.ts
CHANGED
|
@@ -4,8 +4,6 @@ process.env.POSTGRES_USERNAME ??= 'shipfox';
|
|
|
4
4
|
process.env.POSTGRES_PASSWORD ??= 'password';
|
|
5
5
|
process.env.POSTGRES_DATABASE = 'api_test';
|
|
6
6
|
process.env.POSTGRES_MAX_CONNECTIONS ??= '5';
|
|
7
|
-
process.env.
|
|
8
|
-
process.env.AUTH_JOB_LEASE_TOKEN_SECRET = 'test-lease-secret';
|
|
9
|
-
process.env.AUTH_RUNNER_SESSION_TOKEN_SECRET = 'test-runner-session-secret';
|
|
7
|
+
process.env.AUTH_ROOT_KEY = 'MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=';
|
|
10
8
|
process.env.SECRETS_ENCRYPTION_KEK = 'ZmVkY2JhOTg3NjU0MzIxMGZlZGNiYTk4NzY1NDMyMTA=';
|
|
11
9
|
process.env.TZ = 'UTC';
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import type {Project} from '@shipfox/api-projects';
|
|
2
1
|
import {Factory} from 'fishery';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
interface Project {
|
|
4
|
+
id: string;
|
|
5
|
+
workspaceId: string;
|
|
6
|
+
sourceConnectionId: string;
|
|
7
|
+
sourceExternalRepositoryId: string;
|
|
8
|
+
name: string;
|
|
9
|
+
createdAt: Date;
|
|
10
|
+
updatedAt: Date;
|
|
11
|
+
}
|
|
12
|
+
|
|
8
13
|
export const projectFactory = Factory.define<Project>(({sequence}) => ({
|
|
9
14
|
id: crypto.randomUUID(),
|
|
10
15
|
workspaceId: crypto.randomUUID(),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {WorkflowModel} from '@shipfox/api-definitions-dto';
|
|
1
2
|
import {workflowModel} from './workflow-model.js';
|
|
2
3
|
|
|
3
4
|
describe('workflowModel', () => {
|
|
@@ -21,6 +22,9 @@ describe('workflowModel', () => {
|
|
|
21
22
|
},
|
|
22
23
|
});
|
|
23
24
|
|
|
24
|
-
expect(model.jobs.map((job) => job.runner)).toEqual([
|
|
25
|
+
expect(model.jobs.map((job: WorkflowModel['jobs'][number]) => job.runner)).toEqual([
|
|
26
|
+
['ubuntu-22'],
|
|
27
|
+
['ubuntu-22', 'node-22'],
|
|
28
|
+
]);
|
|
25
29
|
});
|
|
26
30
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {WorkflowModel} from '@shipfox/api-definitions';
|
|
1
|
+
import type {WorkflowModel} from '@shipfox/api-definitions-dto';
|
|
2
2
|
import {Factory} from 'fishery';
|
|
3
3
|
import type {WorkflowRun} from '#core/entities/workflow-run.js';
|
|
4
4
|
import {createWorkflowRun} from '#db/workflow-runs.js';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
2
|
+
import type {AgentDefaultsResolver} from '#core/agent-defaults.js';
|
|
3
|
+
|
|
4
|
+
export const agentTestClient: AgentInterModuleClient = {
|
|
5
|
+
resolveAgentConfig({config}) {
|
|
6
|
+
return Promise.resolve(resolveTestAgentDefaults(config));
|
|
7
|
+
},
|
|
8
|
+
resolveRuntimeCredentials({harness, provider, model, thinking}) {
|
|
9
|
+
return Promise.resolve({
|
|
10
|
+
harness,
|
|
11
|
+
provider_id: provider,
|
|
12
|
+
model,
|
|
13
|
+
thinking,
|
|
14
|
+
credentials: {api_key: 'test-agent-credential'},
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const resolveTestAgentDefaults: AgentDefaultsResolver = (config) => {
|
|
20
|
+
const provider = config.provider ?? 'anthropic';
|
|
21
|
+
return {
|
|
22
|
+
harness: config.harness ?? 'pi',
|
|
23
|
+
provider,
|
|
24
|
+
model: config.model ?? (provider === 'openai' ? 'gpt-5.5-pro' : 'claude-opus-4-8'),
|
|
25
|
+
thinking: config.thinking ?? 'xhigh',
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {JOB_LEASE_TOKEN_AUDIENCE} from '@shipfox/api-auth-dto';
|
|
2
|
+
import type {AuthInterModuleClient} from '@shipfox/api-auth-dto/inter-module';
|
|
3
|
+
import {jobLeaseTokenKey} from '@shipfox/node-auth-root-key';
|
|
4
|
+
import {signHs256} from '@shipfox/node-jwt';
|
|
5
|
+
|
|
6
|
+
const leaseSecret = jobLeaseTokenKey();
|
|
7
|
+
|
|
8
|
+
export const workflowsTestAuthClient: AuthInterModuleClient = {
|
|
9
|
+
mintRunnerSessionToken() {
|
|
10
|
+
throw new Error('Runner session token minting is not configured');
|
|
11
|
+
},
|
|
12
|
+
async mintJobLeaseToken(claims) {
|
|
13
|
+
return {
|
|
14
|
+
token: await signHs256({
|
|
15
|
+
payload: claims,
|
|
16
|
+
secret: leaseSecret,
|
|
17
|
+
expiresIn: '90m',
|
|
18
|
+
audience: JOB_LEASE_TOKEN_AUDIENCE,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {JOB_LEASE_TOKEN_AUDIENCE} from '@shipfox/api-auth-dto';
|
|
2
|
+
import {jobLeaseTokenKey} from '@shipfox/node-auth-root-key';
|
|
2
3
|
import {signHs256} from '@shipfox/node-jwt';
|
|
3
4
|
import {getFirstJobExecutionByJobId} from '#db/workflow-runs.js';
|
|
4
5
|
|
|
5
6
|
// Matches test/env.ts; the lease-token auth method reads this same value from config.
|
|
6
|
-
const SECRET =
|
|
7
|
+
const SECRET = jobLeaseTokenKey();
|
|
7
8
|
|
|
8
9
|
export interface MintLeaseTokenParams {
|
|
9
10
|
jobId: string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
2
|
+
|
|
3
|
+
export const projectsTestClient = {
|
|
4
|
+
getProjectById: async () => ({project: undefined}),
|
|
5
|
+
requireProjectForWorkspace: () => {
|
|
6
|
+
throw new Error('Project is not configured');
|
|
7
|
+
},
|
|
8
|
+
} as unknown as ProjectsModuleClient;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {runnerToolCapabilitiesSchema} from '@shipfox/api-runners-dto';
|
|
2
|
+
import type {RunnersInterModuleClient} from '@shipfox/api-runners-dto/inter-module';
|
|
3
|
+
import {sql} from 'drizzle-orm';
|
|
4
|
+
import {db} from '#db/db.js';
|
|
5
|
+
|
|
6
|
+
export const runnersTestClient: RunnersInterModuleClient = {
|
|
7
|
+
enqueueJobExecution() {
|
|
8
|
+
return Promise.resolve({});
|
|
9
|
+
},
|
|
10
|
+
releaseJobExecution() {
|
|
11
|
+
return Promise.resolve({});
|
|
12
|
+
},
|
|
13
|
+
cancelJobs() {
|
|
14
|
+
return Promise.resolve({});
|
|
15
|
+
},
|
|
16
|
+
async getLeaseState({jobId, jobExecutionId, runnerSessionId}) {
|
|
17
|
+
const result = await db().execute<{active: boolean}>(sql`
|
|
18
|
+
SELECT EXISTS(
|
|
19
|
+
SELECT 1
|
|
20
|
+
FROM runners_running_jobs
|
|
21
|
+
WHERE job_id = ${jobId}
|
|
22
|
+
AND job_execution_id = ${jobExecutionId}
|
|
23
|
+
AND runner_session_id = ${runnerSessionId}
|
|
24
|
+
) AS active
|
|
25
|
+
`);
|
|
26
|
+
return {active: result.rows[0]?.active ?? false};
|
|
27
|
+
},
|
|
28
|
+
async getEffectiveRunnerToolCapabilities({runnerSessionId}) {
|
|
29
|
+
const result = await db().execute<{
|
|
30
|
+
toolCapabilities: unknown;
|
|
31
|
+
toolCapabilitiesReportedAt: Date | string | null;
|
|
32
|
+
}>(sql`
|
|
33
|
+
SELECT
|
|
34
|
+
tool_capabilities AS "toolCapabilities",
|
|
35
|
+
tool_capabilities_reported_at AS "toolCapabilitiesReportedAt"
|
|
36
|
+
FROM runners_runner_sessions
|
|
37
|
+
WHERE id = ${runnerSessionId}
|
|
38
|
+
`);
|
|
39
|
+
const row = result.rows[0];
|
|
40
|
+
const reportedAt = row?.toolCapabilitiesReportedAt;
|
|
41
|
+
const reportFresh =
|
|
42
|
+
reportedAt !== null &&
|
|
43
|
+
reportedAt !== undefined &&
|
|
44
|
+
Date.now() - new Date(reportedAt).getTime() <= 60_000;
|
|
45
|
+
return {
|
|
46
|
+
capabilities: reportFresh
|
|
47
|
+
? runnerToolCapabilitiesSchema.parse(row?.toolCapabilities ?? {harnesses: {}})
|
|
48
|
+
: {harnesses: {}},
|
|
49
|
+
reportFresh,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type {SecretsInterModuleClient} from '@shipfox/api-secrets-dto/inter-module';
|
|
2
|
+
|
|
3
|
+
export function createTestSecretsClient(): SecretsInterModuleClient {
|
|
4
|
+
const values = new Map<string, string>();
|
|
5
|
+
const normalize = (params: {
|
|
6
|
+
workspaceId: string;
|
|
7
|
+
projectId?: string | null | undefined;
|
|
8
|
+
namespace?: string | undefined;
|
|
9
|
+
}) => ({
|
|
10
|
+
workspaceId: params.workspaceId,
|
|
11
|
+
projectId: params.projectId ?? null,
|
|
12
|
+
namespace: params.namespace ?? '',
|
|
13
|
+
});
|
|
14
|
+
const scopeId = (params: ReturnType<typeof normalize>) =>
|
|
15
|
+
`${params.workspaceId}\0${params.projectId ?? ''}\0${params.namespace}`;
|
|
16
|
+
const keyId = (params: ReturnType<typeof normalize>, key: string) => `${scopeId(params)}\0${key}`;
|
|
17
|
+
const entries = (input: {
|
|
18
|
+
workspaceId: string;
|
|
19
|
+
projectId?: string | null | undefined;
|
|
20
|
+
namespace?: string | undefined;
|
|
21
|
+
}) => {
|
|
22
|
+
const params = normalize(input);
|
|
23
|
+
const projectScope = `${scopeId(params)}\0`;
|
|
24
|
+
const workspaceScope = `${scopeId({...params, projectId: null})}\0`;
|
|
25
|
+
const selected = new Map<string, string>();
|
|
26
|
+
for (const [id, value] of values) {
|
|
27
|
+
if (id.startsWith(workspaceScope)) selected.set(id.slice(workspaceScope.length), value);
|
|
28
|
+
if (params.projectId && id.startsWith(projectScope))
|
|
29
|
+
selected.set(id.slice(projectScope.length), value);
|
|
30
|
+
}
|
|
31
|
+
return Object.fromEntries(selected);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
getSecret: async (params) => ({
|
|
36
|
+
value:
|
|
37
|
+
values.get(keyId(normalize(params), params.key)) ??
|
|
38
|
+
(params.projectId
|
|
39
|
+
? values.get(keyId(normalize({...params, projectId: null}), params.key))
|
|
40
|
+
: undefined) ??
|
|
41
|
+
null,
|
|
42
|
+
}),
|
|
43
|
+
getSecretsByNamespace: async (params) => ({values: entries(params)}),
|
|
44
|
+
getVariablesByNamespace: async (params) => ({values: entries(params)}),
|
|
45
|
+
setSecrets: async (params) => {
|
|
46
|
+
await Promise.resolve();
|
|
47
|
+
for (const [key, value] of Object.entries(params.values))
|
|
48
|
+
values.set(keyId(normalize(params), key), value);
|
|
49
|
+
return {};
|
|
50
|
+
},
|
|
51
|
+
deleteSecrets: async (params) => {
|
|
52
|
+
await Promise.resolve();
|
|
53
|
+
const keys = params.keys ?? Object.keys(entries(params));
|
|
54
|
+
let deleted = 0;
|
|
55
|
+
for (const key of keys) {
|
|
56
|
+
if (values.delete(keyId(normalize(params), key))) deleted += 1;
|
|
57
|
+
}
|
|
58
|
+
return {deleted};
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
package/test/globalSetup.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import './env.js';
|
|
2
2
|
import {annotationsModule} from '@shipfox/annotations';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import {createAgentModule} from '@shipfox/api-agent';
|
|
4
|
+
import type {AuthInterModuleClient} from '@shipfox/api-auth-dto/inter-module';
|
|
5
|
+
import {createRunnersModule} from '@shipfox/api-runners';
|
|
6
6
|
import {runMigrations} from '@shipfox/node-drizzle';
|
|
7
7
|
import {closePostgresClient, createPostgresClient} from '@shipfox/node-postgres';
|
|
8
8
|
import {sql} from 'drizzle-orm';
|
|
@@ -10,7 +10,15 @@ import {closeDb, db, migrationsPath} from '#db/index.js';
|
|
|
10
10
|
|
|
11
11
|
export async function setup() {
|
|
12
12
|
createPostgresClient();
|
|
13
|
+
const runnersModule = createRunnersModule({auth: {} as AuthInterModuleClient});
|
|
13
14
|
|
|
15
|
+
const agentModule = createAgentModule({
|
|
16
|
+
secrets: {
|
|
17
|
+
deleteSecrets: async () => ({deleted: 0}),
|
|
18
|
+
getSecretsByNamespace: async () => ({values: {}}),
|
|
19
|
+
setSecrets: async () => ({}),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
14
22
|
if (!agentModule.database || Array.isArray(agentModule.database)) {
|
|
15
23
|
throw new Error('Agent module database is not configured');
|
|
16
24
|
}
|
|
@@ -27,14 +35,6 @@ export async function setup() {
|
|
|
27
35
|
runnersModule.database.migrationsPath,
|
|
28
36
|
'__drizzle_migrations_runners',
|
|
29
37
|
);
|
|
30
|
-
if (!secretsModule.database || Array.isArray(secretsModule.database)) {
|
|
31
|
-
throw new Error('Secrets module database is not configured');
|
|
32
|
-
}
|
|
33
|
-
await runMigrations(
|
|
34
|
-
secretsModule.database.db(),
|
|
35
|
-
secretsModule.database.migrationsPath,
|
|
36
|
-
'__drizzle_migrations_secrets',
|
|
37
|
-
);
|
|
38
38
|
if (!annotationsModule.database || Array.isArray(annotationsModule.database)) {
|
|
39
39
|
throw new Error('Annotations module database is not configured');
|
|
40
40
|
}
|