@shipfox/api-runners-dto 12.2.0 → 13.0.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +13 -0
- package/dist/events.d.ts +0 -17
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +0 -9
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/inter-module.d.ts +0 -27
- package/dist/inter-module.d.ts.map +1 -1
- package/dist/inter-module.js +0 -27
- package/dist/inter-module.js.map +1 -1
- package/dist/schemas/assign-runner-instances.d.ts +2 -0
- package/dist/schemas/assign-runner-instances.d.ts.map +1 -1
- package/dist/schemas/assign-runner-instances.js +2 -0
- package/dist/schemas/assign-runner-instances.js.map +1 -1
- package/dist/schemas/index.d.ts +2 -2
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +2 -2
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/poll-demand.d.ts +1 -0
- package/dist/schemas/poll-demand.d.ts.map +1 -1
- package/dist/schemas/poll-demand.js +1 -0
- package/dist/schemas/poll-demand.js.map +1 -1
- package/dist/schemas/reconcile-runner-instances.d.ts +4 -0
- package/dist/schemas/reconcile-runner-instances.d.ts.map +1 -1
- package/dist/schemas/reconcile-runner-instances.js +3 -0
- package/dist/schemas/reconcile-runner-instances.js.map +1 -1
- package/dist/schemas/runner-enrollment.d.ts +2 -0
- package/dist/schemas/runner-enrollment.d.ts.map +1 -1
- package/dist/schemas/runner-enrollment.js +7 -2
- package/dist/schemas/runner-enrollment.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/events.ts +0 -12
- package/src/index.ts +4 -3
- package/src/inter-module.test.ts +0 -24
- package/src/inter-module.ts +0 -23
- package/src/schemas/assign-runner-instances.ts +3 -0
- package/src/schemas/index.ts +4 -0
- package/src/schemas/poll-demand.test.ts +1 -0
- package/src/schemas/poll-demand.ts +8 -0
- package/src/schemas/reconcile-runner-instances.test.ts +27 -3
- package/src/schemas/reconcile-runner-instances.ts +4 -0
- package/src/schemas/runner-enrollment.ts +9 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
package/src/events.ts
CHANGED
|
@@ -4,7 +4,6 @@ const nonEmptyStringSchema = z.string().nonempty();
|
|
|
4
4
|
const isoDateTimeSchema = z.string().datetime();
|
|
5
5
|
|
|
6
6
|
export const RUNNER_JOB_LEASE_EXPIRED = 'runners.job.lease_expired' as const;
|
|
7
|
-
export const RUNNER_JOB_QUEUED = 'runners.job.queued' as const;
|
|
8
7
|
export const RUNNER_JOB_CLAIMED = 'runners.job.claimed' as const;
|
|
9
8
|
|
|
10
9
|
export const runnerJobLeaseExpiredEventSchema = z.object({
|
|
@@ -15,15 +14,6 @@ export const runnerJobLeaseExpiredEventSchema = z.object({
|
|
|
15
14
|
});
|
|
16
15
|
export type RunnerJobLeaseExpiredEvent = z.infer<typeof runnerJobLeaseExpiredEventSchema>;
|
|
17
16
|
|
|
18
|
-
export const runnerJobQueuedEventSchema = z.object({
|
|
19
|
-
workflowRunId: nonEmptyStringSchema,
|
|
20
|
-
workflowRunAttemptId: nonEmptyStringSchema,
|
|
21
|
-
jobId: nonEmptyStringSchema,
|
|
22
|
-
jobExecutionId: nonEmptyStringSchema,
|
|
23
|
-
queuedAt: isoDateTimeSchema,
|
|
24
|
-
});
|
|
25
|
-
export type RunnerJobQueuedEvent = z.infer<typeof runnerJobQueuedEventSchema>;
|
|
26
|
-
|
|
27
17
|
export const runnerJobClaimedEventSchema = z.object({
|
|
28
18
|
workflowRunId: nonEmptyStringSchema,
|
|
29
19
|
workflowRunAttemptId: nonEmptyStringSchema,
|
|
@@ -35,12 +25,10 @@ export type RunnerJobClaimedEvent = z.infer<typeof runnerJobClaimedEventSchema>;
|
|
|
35
25
|
|
|
36
26
|
export interface RunnersEventMap {
|
|
37
27
|
[RUNNER_JOB_LEASE_EXPIRED]: RunnerJobLeaseExpiredEvent;
|
|
38
|
-
[RUNNER_JOB_QUEUED]: RunnerJobQueuedEvent;
|
|
39
28
|
[RUNNER_JOB_CLAIMED]: RunnerJobClaimedEvent;
|
|
40
29
|
}
|
|
41
30
|
|
|
42
31
|
export const runnersEventSchemas = {
|
|
43
32
|
[RUNNER_JOB_LEASE_EXPIRED]: runnerJobLeaseExpiredEventSchema,
|
|
44
|
-
[RUNNER_JOB_QUEUED]: runnerJobQueuedEventSchema,
|
|
45
33
|
[RUNNER_JOB_CLAIMED]: runnerJobClaimedEventSchema,
|
|
46
34
|
} satisfies Record<keyof RunnersEventMap, z.ZodType>;
|
package/src/index.ts
CHANGED
|
@@ -76,6 +76,9 @@ export {
|
|
|
76
76
|
providerRunnerStateSchema,
|
|
77
77
|
provisionerIdentityResponseSchema,
|
|
78
78
|
provisionerTokenDtoSchema,
|
|
79
|
+
RECONCILE_RUNNER_INSTANCES_INTENDED_RESERVATION_HEADER,
|
|
80
|
+
RECONCILE_RUNNER_INSTANCES_INTENDED_RESERVATION_HEADER_VALUE,
|
|
81
|
+
RESERVATION_EXPIRED_ERROR_CODE,
|
|
79
82
|
type ReconcileDesiredIntentDto,
|
|
80
83
|
type ReconciledBoundJobDto,
|
|
81
84
|
type ReconciledRunnerInstanceDto,
|
|
@@ -91,6 +94,7 @@ export {
|
|
|
91
94
|
type RevokeManualRegistrationTokenResponseDto,
|
|
92
95
|
type RevokeProvisionerTokenResponseDto,
|
|
93
96
|
RUNNER_ASSIGNMENT_POLL_DEFAULT_WAIT_SECONDS,
|
|
97
|
+
RUNNER_INSTANCE_NOT_ASSIGNABLE_ERROR_CODE,
|
|
94
98
|
RUNNER_SESSION_EXHAUSTED_CODE,
|
|
95
99
|
type RunnerAdministratorInstanceDto,
|
|
96
100
|
type RunnerAssignmentPollQueryDto,
|
|
@@ -134,13 +138,10 @@ export {
|
|
|
134
138
|
export {
|
|
135
139
|
RUNNER_JOB_CLAIMED,
|
|
136
140
|
RUNNER_JOB_LEASE_EXPIRED,
|
|
137
|
-
RUNNER_JOB_QUEUED,
|
|
138
141
|
type RunnerJobClaimedEvent,
|
|
139
142
|
type RunnerJobLeaseExpiredEvent,
|
|
140
|
-
type RunnerJobQueuedEvent,
|
|
141
143
|
type RunnersEventMap,
|
|
142
144
|
runnerJobClaimedEventSchema,
|
|
143
145
|
runnerJobLeaseExpiredEventSchema,
|
|
144
|
-
runnerJobQueuedEventSchema,
|
|
145
146
|
runnersEventSchemas,
|
|
146
147
|
} from './events.js';
|
package/src/inter-module.test.ts
CHANGED
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
import {runnersInterModuleContract} from './inter-module.js';
|
|
2
2
|
|
|
3
|
-
const id = '00000000-0000-4000-8000-000000000001';
|
|
4
|
-
|
|
5
3
|
describe('runnersInterModuleContract', () => {
|
|
6
|
-
test('accepts stable job-execution identities for idempotent commands', () => {
|
|
7
|
-
const input = runnersInterModuleContract.methods.enqueueJobExecution.input.parse({
|
|
8
|
-
workspaceId: id,
|
|
9
|
-
workflowRunId: id,
|
|
10
|
-
workflowRunAttemptId: id,
|
|
11
|
-
jobId: id,
|
|
12
|
-
jobExecutionId: id,
|
|
13
|
-
projectId: id,
|
|
14
|
-
requiredLabels: ['linux'],
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
expect(input.jobExecutionId).toBe(id);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
4
|
test('exposes bounded JSON capability results', () => {
|
|
21
5
|
const result =
|
|
22
6
|
runnersInterModuleContract.methods.getEffectiveRunnerToolCapabilities.output.parse({
|
|
@@ -29,12 +13,4 @@ describe('runnersInterModuleContract', () => {
|
|
|
29
13
|
reportFresh: true,
|
|
30
14
|
});
|
|
31
15
|
});
|
|
32
|
-
|
|
33
|
-
test('defines the scheduling validation failure', () => {
|
|
34
|
-
const details = runnersInterModuleContract.methods.enqueueJobExecution.errors[
|
|
35
|
-
'empty-required-labels'
|
|
36
|
-
].parse({});
|
|
37
|
-
|
|
38
|
-
expect(details).toEqual({});
|
|
39
|
-
});
|
|
40
16
|
});
|
package/src/inter-module.ts
CHANGED
|
@@ -7,29 +7,6 @@ const idSchema = z.string().uuid();
|
|
|
7
7
|
export const runnersInterModuleContract = defineInterModuleContract({
|
|
8
8
|
module: 'runners',
|
|
9
9
|
methods: {
|
|
10
|
-
enqueueJobExecution: {
|
|
11
|
-
input: z.object({
|
|
12
|
-
workspaceId: idSchema,
|
|
13
|
-
workflowRunId: idSchema,
|
|
14
|
-
workflowRunAttemptId: idSchema,
|
|
15
|
-
jobId: idSchema,
|
|
16
|
-
jobExecutionId: idSchema,
|
|
17
|
-
projectId: idSchema,
|
|
18
|
-
requiredLabels: z.array(z.string()),
|
|
19
|
-
}),
|
|
20
|
-
output: z.object({}),
|
|
21
|
-
errors: {
|
|
22
|
-
'empty-required-labels': z.object({}),
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
releaseJobExecution: {
|
|
26
|
-
input: z.object({jobExecutionId: idSchema}),
|
|
27
|
-
output: z.object({}),
|
|
28
|
-
},
|
|
29
|
-
cancelJobs: {
|
|
30
|
-
input: z.object({jobIds: z.array(idSchema)}),
|
|
31
|
-
output: z.object({}),
|
|
32
|
-
},
|
|
33
10
|
getLeaseState: {
|
|
34
11
|
input: z.object({
|
|
35
12
|
jobId: idSchema,
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import {z} from 'zod';
|
|
2
2
|
|
|
3
|
+
export const RESERVATION_EXPIRED_ERROR_CODE = 'reservation-expired';
|
|
4
|
+
export const RUNNER_INSTANCE_NOT_ASSIGNABLE_ERROR_CODE = 'runner-instance-not-assignable';
|
|
5
|
+
|
|
3
6
|
export const assignRunnerInstancesBodySchema = z
|
|
4
7
|
.object({
|
|
5
8
|
reservation_id: z.string().uuid(),
|
package/src/schemas/index.ts
CHANGED
|
@@ -33,6 +33,8 @@ export {
|
|
|
33
33
|
type AssignRunnerInstancesResponseDto,
|
|
34
34
|
assignRunnerInstancesBodySchema,
|
|
35
35
|
assignRunnerInstancesResponseSchema,
|
|
36
|
+
RESERVATION_EXPIRED_ERROR_CODE,
|
|
37
|
+
RUNNER_INSTANCE_NOT_ASSIGNABLE_ERROR_CODE,
|
|
36
38
|
} from './assign-runner-instances.js';
|
|
37
39
|
export {
|
|
38
40
|
type ClaimedJobResponseDto,
|
|
@@ -94,6 +96,8 @@ export {
|
|
|
94
96
|
export {
|
|
95
97
|
MAX_OBSERVED_PROVIDER_RUNNER_ID_LENGTH,
|
|
96
98
|
MAX_RECONCILE_OBSERVED_RUNNERS,
|
|
99
|
+
RECONCILE_RUNNER_INSTANCES_INTENDED_RESERVATION_HEADER,
|
|
100
|
+
RECONCILE_RUNNER_INSTANCES_INTENDED_RESERVATION_HEADER_VALUE,
|
|
97
101
|
type ReconcileDesiredIntentDto,
|
|
98
102
|
type ReconciledBoundJobDto,
|
|
99
103
|
type ReconciledRunnerInstanceDto,
|
|
@@ -42,6 +42,14 @@ export const reservationGrantSchema = z.object({
|
|
|
42
42
|
export const pollDemandResponseSchema = z.object({
|
|
43
43
|
stats: z.array(demandStatSchema),
|
|
44
44
|
reservations: z.array(reservationGrantSchema),
|
|
45
|
+
newly_reserved_count: z
|
|
46
|
+
.number()
|
|
47
|
+
.int()
|
|
48
|
+
.min(0)
|
|
49
|
+
.optional()
|
|
50
|
+
.describe(
|
|
51
|
+
'Reservation units created by this poll, including units satisfied by adopted runners.',
|
|
52
|
+
),
|
|
45
53
|
terminate_provider_runner_ids: z.array(z.string()),
|
|
46
54
|
});
|
|
47
55
|
|
|
@@ -60,12 +60,33 @@ describe('reconcileRunnerInstancesBodySchema', () => {
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
describe('reconcileRunnerInstancesResponseSchema', () => {
|
|
63
|
-
it('
|
|
64
|
-
const result = reconcileRunnerInstancesResponseSchema.
|
|
63
|
+
it('keeps the optional field absent for responses from older servers', () => {
|
|
64
|
+
const result = reconcileRunnerInstancesResponseSchema.parse({
|
|
65
65
|
runners: [
|
|
66
66
|
{
|
|
67
67
|
provider_runner_id: 'provisioned-runner-1',
|
|
68
68
|
state: 'running',
|
|
69
|
+
reservation_id: null,
|
|
70
|
+
runner_session_id: null,
|
|
71
|
+
bound_job: null,
|
|
72
|
+
desired_intent: 'keep',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
terminated_absent_provider_runner_ids: [],
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const runner = result.runners[0];
|
|
79
|
+
if (!runner) throw new Error('Expected one parsed runner');
|
|
80
|
+
expect(Object.hasOwn(runner, 'intended_reservation_id')).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('keeps an explicit null field present for current responses', () => {
|
|
84
|
+
const result = reconcileRunnerInstancesResponseSchema.parse({
|
|
85
|
+
runners: [
|
|
86
|
+
{
|
|
87
|
+
provider_runner_id: 'provisioned-runner-1',
|
|
88
|
+
state: 'running',
|
|
89
|
+
intended_reservation_id: null,
|
|
69
90
|
reservation_id: crypto.randomUUID(),
|
|
70
91
|
runner_session_id: crypto.randomUUID(),
|
|
71
92
|
bound_job: {
|
|
@@ -80,6 +101,9 @@ describe('reconcileRunnerInstancesResponseSchema', () => {
|
|
|
80
101
|
terminated_absent_provider_runner_ids: ['provisioned-runner-2'],
|
|
81
102
|
});
|
|
82
103
|
|
|
83
|
-
|
|
104
|
+
const runner = result.runners[0];
|
|
105
|
+
if (!runner) throw new Error('Expected one parsed runner');
|
|
106
|
+
expect(Object.hasOwn(runner, 'intended_reservation_id')).toBe(true);
|
|
107
|
+
expect(runner.intended_reservation_id).toBeNull();
|
|
84
108
|
});
|
|
85
109
|
});
|
|
@@ -3,6 +3,9 @@ import {providerRunnerStateSchema} from './report-runner-instances.js';
|
|
|
3
3
|
|
|
4
4
|
export const MAX_RECONCILE_OBSERVED_RUNNERS = 5000;
|
|
5
5
|
export const MAX_OBSERVED_PROVIDER_RUNNER_ID_LENGTH = 255;
|
|
6
|
+
export const RECONCILE_RUNNER_INSTANCES_INTENDED_RESERVATION_HEADER =
|
|
7
|
+
'x-shipfox-reconcile-intended-reservation';
|
|
8
|
+
export const RECONCILE_RUNNER_INSTANCES_INTENDED_RESERVATION_HEADER_VALUE = '1';
|
|
6
9
|
|
|
7
10
|
export const reconcileRunnerInstancesBodySchema = z
|
|
8
11
|
.object({
|
|
@@ -35,6 +38,7 @@ export const reconciledRunnerInstanceSchema = z
|
|
|
35
38
|
.object({
|
|
36
39
|
provider_runner_id: z.string(),
|
|
37
40
|
state: providerRunnerStateSchema.nullable(),
|
|
41
|
+
intended_reservation_id: z.string().uuid().nullable().optional(),
|
|
38
42
|
reservation_id: z.string().uuid().nullable(),
|
|
39
43
|
runner_session_id: z.string().uuid().nullable(),
|
|
40
44
|
bound_job: reconciledBoundJobSchema.nullable(),
|
|
@@ -24,8 +24,16 @@ export const createRunnerInstancesBodySchema = z
|
|
|
24
24
|
.strict();
|
|
25
25
|
export const createRunnerInstancesResponseSchema = z.object({
|
|
26
26
|
runner_instances: z.array(
|
|
27
|
-
z.object({
|
|
27
|
+
z.object({
|
|
28
|
+
runner_instance_id: z.string().uuid(),
|
|
29
|
+
bootstrap_token: z.string().min(1),
|
|
30
|
+
// Accepted instances retain their request position for short responses.
|
|
31
|
+
request_index: z.number().int().nonnegative().optional(),
|
|
32
|
+
}),
|
|
28
33
|
),
|
|
34
|
+
// A demand reservation can be consumed or stale between demand polling and launch.
|
|
35
|
+
// The field is omitted for the normal and warm-launch paths.
|
|
36
|
+
reservation_unavailable: z.literal(true).optional(),
|
|
29
37
|
});
|
|
30
38
|
export const runnerBootstrapExchangeResponseSchema = z.object({
|
|
31
39
|
runner_instance_id: z.string().uuid(),
|