@shipfox/api-workflows 13.1.0 → 15.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 +4 -4
- package/CHANGELOG.md +61 -0
- package/README.md +12 -5
- package/dist/core/checkout.d.ts +4 -2
- package/dist/core/checkout.d.ts.map +1 -1
- package/dist/core/checkout.js +7 -2
- package/dist/core/checkout.js.map +1 -1
- package/dist/core/entities/job.d.ts +1 -1
- package/dist/core/entities/job.d.ts.map +1 -1
- package/dist/core/entities/job.js.map +1 -1
- package/dist/core/entities/workflow-run.d.ts +25 -6
- package/dist/core/entities/workflow-run.d.ts.map +1 -1
- package/dist/core/entities/workflow-run.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/run-workflow.d.ts +26 -1
- package/dist/core/run-workflow.d.ts.map +1 -1
- package/dist/core/run-workflow.js +27 -1
- package/dist/core/run-workflow.js.map +1 -1
- package/dist/db/db.d.ts +72 -0
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/schema/workflow-runs.d.ts +45 -1
- package/dist/db/schema/workflow-runs.d.ts.map +1 -1
- package/dist/db/schema/workflow-runs.js +42 -1
- package/dist/db/schema/workflow-runs.js.map +1 -1
- package/dist/db/workflow-runs/jobs.d.ts +3 -1
- package/dist/db/workflow-runs/jobs.d.ts.map +1 -1
- package/dist/db/workflow-runs/jobs.js +12 -3
- package/dist/db/workflow-runs/jobs.js.map +1 -1
- package/dist/db/workflow-runs/queries.d.ts +3 -2
- package/dist/db/workflow-runs/queries.d.ts.map +1 -1
- package/dist/db/workflow-runs/queries.js +3 -0
- package/dist/db/workflow-runs/queries.js.map +1 -1
- package/dist/db/workflow-runs/run-create.d.ts +4 -1
- package/dist/db/workflow-runs/run-create.d.ts.map +1 -1
- package/dist/db/workflow-runs/run-create.js +14 -1
- package/dist/db/workflow-runs/run-create.js.map +1 -1
- package/dist/presentation/dto/workflow-run.d.ts.map +1 -1
- package/dist/presentation/dto/workflow-run.js +14 -0
- package/dist/presentation/dto/workflow-run.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +1 -0
- package/dist/presentation/inter-module.d.ts.map +1 -1
- package/dist/presentation/inter-module.js +41 -4
- package/dist/presentation/inter-module.js.map +1 -1
- package/dist/presentation/routes/checkout-token.d.ts.map +1 -1
- package/dist/presentation/routes/checkout-token.js +2 -1
- package/dist/presentation/routes/checkout-token.js.map +1 -1
- package/dist/presentation/routes/get-run-aggregates.d.ts.map +1 -1
- package/dist/presentation/routes/get-run-aggregates.js +2 -1
- package/dist/presentation/routes/get-run-aggregates.js.map +1 -1
- package/dist/presentation/routes/leased-step.d.ts +3 -1
- package/dist/presentation/routes/leased-step.d.ts.map +1 -1
- package/dist/presentation/routes/leased-step.js +2 -1
- package/dist/presentation/routes/leased-step.js.map +1 -1
- package/dist/presentation/routes/list-runs.d.ts.map +1 -1
- package/dist/presentation/routes/list-runs.js +2 -1
- package/dist/presentation/routes/list-runs.js.map +1 -1
- package/dist/presentation/routes/project-access.d.ts +1 -0
- package/dist/presentation/routes/project-access.d.ts.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0004_dev_run_origin.sql +12 -0
- package/drizzle/meta/0004_snapshot.json +1773 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +16 -16
- package/src/core/checkout.test.ts +198 -1
- package/src/core/checkout.ts +18 -5
- package/src/core/entities/job.ts +1 -1
- package/src/core/entities/workflow-run.ts +26 -6
- package/src/core/index.ts +2 -2
- package/src/core/job-transition/decide-job-activation.test.ts +2 -0
- package/src/core/run-workflow.test.ts +151 -3
- package/src/core/run-workflow.ts +59 -3
- package/src/core/workflow-run-creation.test.ts +2 -0
- package/src/db/job-listeners.test.ts +17 -0
- package/src/db/schema/workflow-runs.ts +58 -0
- package/src/db/workflow-runs/jobs.ts +17 -3
- package/src/db/workflow-runs/queries.ts +6 -1
- package/src/db/workflow-runs/run-create.test.ts +87 -0
- package/src/db/workflow-runs/run-create.ts +23 -1
- package/src/presentation/dto/workflow-run.ts +23 -1
- package/src/presentation/inter-module.test.ts +131 -1
- package/src/presentation/inter-module.ts +48 -3
- package/src/presentation/routes/checkout-token.test.ts +45 -0
- package/src/presentation/routes/checkout-token.ts +2 -1
- package/src/presentation/routes/get-run-aggregates.test.ts +56 -0
- package/src/presentation/routes/get-run-aggregates.ts +2 -0
- package/src/presentation/routes/get-step-secrets.test.ts +1 -0
- package/src/presentation/routes/leased-step.ts +7 -1
- package/src/presentation/routes/list-runs.test.ts +152 -0
- package/src/presentation/routes/list-runs.ts +2 -0
- package/test/factories/workflow-run.ts +2 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipfox/api-workflows",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "15.0.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -23,30 +23,30 @@
|
|
|
23
23
|
"drizzle-orm": "^0.45.2",
|
|
24
24
|
"js-yaml": "^4.1.0",
|
|
25
25
|
"zod": "^4.4.3",
|
|
26
|
-
"@shipfox/api-auth-context": "
|
|
27
|
-
"@shipfox/api-auth-dto": "
|
|
28
|
-
"@shipfox/api-agent-dto": "
|
|
26
|
+
"@shipfox/api-auth-context": "15.0.0",
|
|
27
|
+
"@shipfox/api-auth-dto": "15.0.0",
|
|
28
|
+
"@shipfox/api-agent-dto": "15.0.0",
|
|
29
29
|
"@shipfox/annotations-dto": "12.3.0",
|
|
30
|
-
"@shipfox/api-definitions-dto": "
|
|
31
|
-
"@shipfox/api-projects-dto": "
|
|
32
|
-
"@shipfox/api-integration-core-dto": "
|
|
33
|
-
"@shipfox/api-runners-dto": "
|
|
30
|
+
"@shipfox/api-definitions-dto": "15.0.0",
|
|
31
|
+
"@shipfox/api-projects-dto": "15.0.0",
|
|
32
|
+
"@shipfox/api-integration-core-dto": "15.0.0",
|
|
33
|
+
"@shipfox/api-runners-dto": "14.0.0",
|
|
34
34
|
"@shipfox/api-secrets-dto": "12.0.0",
|
|
35
|
-
"@shipfox/api-workflows-dto": "
|
|
36
|
-
"@shipfox/api-workspaces-dto": "
|
|
35
|
+
"@shipfox/api-workflows-dto": "15.0.0",
|
|
36
|
+
"@shipfox/api-workspaces-dto": "15.0.0",
|
|
37
37
|
"@shipfox/config": "1.2.4",
|
|
38
38
|
"@shipfox/inter-module": "0.2.3",
|
|
39
|
-
"@shipfox/expression": "2.
|
|
39
|
+
"@shipfox/expression": "2.3.0",
|
|
40
40
|
"@shipfox/node-drizzle": "0.3.5",
|
|
41
41
|
"@shipfox/node-error-monitoring": "0.3.0",
|
|
42
|
-
"@shipfox/node-fastify": "0.4.
|
|
43
|
-
"@shipfox/node-module": "1.0.
|
|
44
|
-
"@shipfox/node-opentelemetry": "0.6.
|
|
42
|
+
"@shipfox/node-fastify": "0.4.3",
|
|
43
|
+
"@shipfox/node-module": "1.0.7",
|
|
44
|
+
"@shipfox/node-opentelemetry": "0.6.5",
|
|
45
45
|
"@shipfox/node-outbox": "0.2.6",
|
|
46
46
|
"@shipfox/node-postgres": "0.5.0",
|
|
47
|
-
"@shipfox/node-temporal": "0.4.
|
|
47
|
+
"@shipfox/node-temporal": "0.4.6",
|
|
48
48
|
"@shipfox/runner-labels": "0.2.0",
|
|
49
|
-
"@shipfox/workflow-document": "3.0
|
|
49
|
+
"@shipfox/workflow-document": "3.2.0"
|
|
50
50
|
},
|
|
51
51
|
"imports": {
|
|
52
52
|
"#*": "./dist/*"
|
|
@@ -3,9 +3,24 @@ import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module'
|
|
|
3
3
|
import {projectFactory} from '#test/factories/project.js';
|
|
4
4
|
import {createStepCheckoutSpec} from './checkout.js';
|
|
5
5
|
import type {Step} from './entities/step.js';
|
|
6
|
-
import type {WorkflowRunTriggerReference} from './entities/workflow-run.js';
|
|
6
|
+
import type {WorkflowRunDevSource, WorkflowRunTriggerReference} from './entities/workflow-run.js';
|
|
7
7
|
import {CheckoutConfigInvalidError, CheckoutIntentUnresolvedError} from './errors.js';
|
|
8
8
|
|
|
9
|
+
const syncedRun = {origin: 'synced', devSource: null} as const;
|
|
10
|
+
|
|
11
|
+
function devRun(commit: string): {origin: 'dev'; devSource: WorkflowRunDevSource} {
|
|
12
|
+
return {
|
|
13
|
+
origin: 'dev',
|
|
14
|
+
devSource: {
|
|
15
|
+
ref: 'fix-triage-prompt',
|
|
16
|
+
commit,
|
|
17
|
+
configPath: '.shipfox/workflows/triage-sentry.yml',
|
|
18
|
+
initiatedByUserId: crypto.randomUUID(),
|
|
19
|
+
replayOfEventId: null,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
9
24
|
const getProjectById = vi.fn();
|
|
10
25
|
const resolveCheckoutTarget = vi.fn();
|
|
11
26
|
const projects = {
|
|
@@ -46,6 +61,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
46
61
|
});
|
|
47
62
|
|
|
48
63
|
const result = await createStepCheckoutSpec({
|
|
64
|
+
run: syncedRun,
|
|
49
65
|
step,
|
|
50
66
|
workspaceId: project.workspaceId,
|
|
51
67
|
projectId: project.id,
|
|
@@ -96,6 +112,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
96
112
|
});
|
|
97
113
|
|
|
98
114
|
const result = await createStepCheckoutSpec({
|
|
115
|
+
run: syncedRun,
|
|
99
116
|
step,
|
|
100
117
|
workspaceId: project.workspaceId,
|
|
101
118
|
projectId: project.id,
|
|
@@ -134,6 +151,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
134
151
|
});
|
|
135
152
|
|
|
136
153
|
await createStepCheckoutSpec({
|
|
154
|
+
run: syncedRun,
|
|
137
155
|
step,
|
|
138
156
|
workspaceId: project.workspaceId,
|
|
139
157
|
projectId: project.id,
|
|
@@ -167,6 +185,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
167
185
|
});
|
|
168
186
|
|
|
169
187
|
await createStepCheckoutSpec({
|
|
188
|
+
run: syncedRun,
|
|
170
189
|
step,
|
|
171
190
|
workspaceId: project.workspaceId,
|
|
172
191
|
projectId: project.id,
|
|
@@ -200,6 +219,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
200
219
|
});
|
|
201
220
|
|
|
202
221
|
await createStepCheckoutSpec({
|
|
222
|
+
run: syncedRun,
|
|
203
223
|
step,
|
|
204
224
|
workspaceId: project.workspaceId,
|
|
205
225
|
projectId: project.id,
|
|
@@ -216,6 +236,41 @@ describe('createStepCheckoutSpec', () => {
|
|
|
216
236
|
});
|
|
217
237
|
});
|
|
218
238
|
|
|
239
|
+
it('falls through to the dev commit when a same-project trigger has no commit', async () => {
|
|
240
|
+
const project = projectFactory.build();
|
|
241
|
+
const devCommit = 'b'.repeat(40);
|
|
242
|
+
const triggerReference = {...triggerReferenceFor(project.id), commit: null};
|
|
243
|
+
const step = checkoutStep({permissions: {contents: 'read'}});
|
|
244
|
+
getProjectById.mockResolvedValue({project});
|
|
245
|
+
resolveCheckoutTarget.mockResolvedValue({
|
|
246
|
+
projectId: project.id,
|
|
247
|
+
connectionId: project.sourceConnectionId,
|
|
248
|
+
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
249
|
+
});
|
|
250
|
+
createCheckoutSpec.mockResolvedValue({
|
|
251
|
+
repositoryUrl: 'https://github.com/acme/repo.git',
|
|
252
|
+
ref: devCommit,
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
await createStepCheckoutSpec({
|
|
256
|
+
run: devRun(devCommit),
|
|
257
|
+
step,
|
|
258
|
+
workspaceId: project.workspaceId,
|
|
259
|
+
projectId: project.id,
|
|
260
|
+
triggerReference,
|
|
261
|
+
integrations: integrations as IntegrationsModuleClient,
|
|
262
|
+
projects: projects as ProjectsModuleClient,
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
expect(createCheckoutSpec).toHaveBeenCalledWith({
|
|
266
|
+
workspaceId: project.workspaceId,
|
|
267
|
+
connectionId: project.sourceConnectionId,
|
|
268
|
+
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
269
|
+
ref: devCommit,
|
|
270
|
+
permissions: {contents: 'read'},
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
219
274
|
it('keeps the provider default ref for a cross-repository target', async () => {
|
|
220
275
|
const project = projectFactory.build();
|
|
221
276
|
const targetProjectId = crypto.randomUUID();
|
|
@@ -232,6 +287,142 @@ describe('createStepCheckoutSpec', () => {
|
|
|
232
287
|
});
|
|
233
288
|
|
|
234
289
|
await createStepCheckoutSpec({
|
|
290
|
+
run: syncedRun,
|
|
291
|
+
step,
|
|
292
|
+
workspaceId: project.workspaceId,
|
|
293
|
+
projectId: project.id,
|
|
294
|
+
triggerReference: triggerReferenceFor(project.id),
|
|
295
|
+
integrations: integrations as IntegrationsModuleClient,
|
|
296
|
+
projects: projects as ProjectsModuleClient,
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
expect(createCheckoutSpec).toHaveBeenCalledWith({
|
|
300
|
+
workspaceId: project.workspaceId,
|
|
301
|
+
connectionId: expect.any(String),
|
|
302
|
+
externalRepositoryId: 'github:412',
|
|
303
|
+
permissions: {contents: 'read'},
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('checks out the dev commit for a dev run without a trigger reference', async () => {
|
|
308
|
+
const project = projectFactory.build();
|
|
309
|
+
const devCommit = 'b'.repeat(40);
|
|
310
|
+
const step = checkoutStep({permissions: {contents: 'read'}});
|
|
311
|
+
getProjectById.mockResolvedValue({project});
|
|
312
|
+
resolveCheckoutTarget.mockResolvedValue({
|
|
313
|
+
projectId: project.id,
|
|
314
|
+
connectionId: project.sourceConnectionId,
|
|
315
|
+
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
316
|
+
});
|
|
317
|
+
createCheckoutSpec.mockResolvedValue({
|
|
318
|
+
repositoryUrl: 'https://github.com/acme/repo.git',
|
|
319
|
+
ref: devCommit,
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
await createStepCheckoutSpec({
|
|
323
|
+
run: devRun(devCommit),
|
|
324
|
+
step,
|
|
325
|
+
workspaceId: project.workspaceId,
|
|
326
|
+
projectId: project.id,
|
|
327
|
+
integrations: integrations as IntegrationsModuleClient,
|
|
328
|
+
projects: projects as ProjectsModuleClient,
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
expect(createCheckoutSpec).toHaveBeenCalledWith({
|
|
332
|
+
workspaceId: project.workspaceId,
|
|
333
|
+
connectionId: project.sourceConnectionId,
|
|
334
|
+
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
335
|
+
ref: devCommit,
|
|
336
|
+
permissions: {contents: 'read'},
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('prefers the event commit over the dev commit on a dev replay of a same-project push', async () => {
|
|
341
|
+
const project = projectFactory.build();
|
|
342
|
+
const eventCommit = 'c'.repeat(40);
|
|
343
|
+
const triggerReference = {...triggerReferenceFor(project.id), commit: eventCommit};
|
|
344
|
+
const step = checkoutStep({permissions: {contents: 'read'}});
|
|
345
|
+
getProjectById.mockResolvedValue({project});
|
|
346
|
+
resolveCheckoutTarget.mockResolvedValue({
|
|
347
|
+
projectId: project.id,
|
|
348
|
+
connectionId: project.sourceConnectionId,
|
|
349
|
+
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
350
|
+
});
|
|
351
|
+
createCheckoutSpec.mockResolvedValue({
|
|
352
|
+
repositoryUrl: 'https://github.com/acme/repo.git',
|
|
353
|
+
ref: eventCommit,
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
await createStepCheckoutSpec({
|
|
357
|
+
run: devRun('b'.repeat(40)),
|
|
358
|
+
step,
|
|
359
|
+
workspaceId: project.workspaceId,
|
|
360
|
+
projectId: project.id,
|
|
361
|
+
triggerReference,
|
|
362
|
+
integrations: integrations as IntegrationsModuleClient,
|
|
363
|
+
projects: projects as ProjectsModuleClient,
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
expect(createCheckoutSpec).toHaveBeenCalledWith({
|
|
367
|
+
workspaceId: project.workspaceId,
|
|
368
|
+
connectionId: project.sourceConnectionId,
|
|
369
|
+
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
370
|
+
ref: eventCommit,
|
|
371
|
+
permissions: {contents: 'read'},
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
it('preserves an explicit ref on a dev run', async () => {
|
|
376
|
+
const project = projectFactory.build();
|
|
377
|
+
const explicitRef = 'refs/heads/feature/checkout';
|
|
378
|
+
const step = checkoutStep({ref: explicitRef, permissions: {contents: 'read'}});
|
|
379
|
+
getProjectById.mockResolvedValue({project});
|
|
380
|
+
resolveCheckoutTarget.mockResolvedValue({
|
|
381
|
+
projectId: project.id,
|
|
382
|
+
connectionId: project.sourceConnectionId,
|
|
383
|
+
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
384
|
+
});
|
|
385
|
+
createCheckoutSpec.mockResolvedValue({
|
|
386
|
+
repositoryUrl: 'https://github.com/acme/repo.git',
|
|
387
|
+
ref: explicitRef,
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
await createStepCheckoutSpec({
|
|
391
|
+
run: devRun('b'.repeat(40)),
|
|
392
|
+
step,
|
|
393
|
+
workspaceId: project.workspaceId,
|
|
394
|
+
projectId: project.id,
|
|
395
|
+
triggerReference: triggerReferenceFor(project.id),
|
|
396
|
+
integrations: integrations as IntegrationsModuleClient,
|
|
397
|
+
projects: projects as ProjectsModuleClient,
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
expect(createCheckoutSpec).toHaveBeenCalledWith({
|
|
401
|
+
workspaceId: project.workspaceId,
|
|
402
|
+
connectionId: project.sourceConnectionId,
|
|
403
|
+
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
404
|
+
ref: explicitRef,
|
|
405
|
+
permissions: {contents: 'read'},
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('keeps the provider default ref for a cross-project target in a dev run', async () => {
|
|
410
|
+
const project = projectFactory.build();
|
|
411
|
+
const targetProjectId = crypto.randomUUID();
|
|
412
|
+
const step = checkoutStep({project: targetProjectId});
|
|
413
|
+
getProjectById.mockResolvedValue({project});
|
|
414
|
+
resolveCheckoutTarget.mockResolvedValue({
|
|
415
|
+
projectId: targetProjectId,
|
|
416
|
+
connectionId: crypto.randomUUID(),
|
|
417
|
+
externalRepositoryId: 'github:412',
|
|
418
|
+
});
|
|
419
|
+
createCheckoutSpec.mockResolvedValue({
|
|
420
|
+
repositoryUrl: 'https://github.com/acme/target.git',
|
|
421
|
+
ref: 'main',
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
await createStepCheckoutSpec({
|
|
425
|
+
run: devRun('b'.repeat(40)),
|
|
235
426
|
step,
|
|
236
427
|
workspaceId: project.workspaceId,
|
|
237
428
|
projectId: project.id,
|
|
@@ -263,6 +454,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
263
454
|
});
|
|
264
455
|
|
|
265
456
|
await createStepCheckoutSpec({
|
|
457
|
+
run: syncedRun,
|
|
266
458
|
step,
|
|
267
459
|
workspaceId: project.workspaceId,
|
|
268
460
|
projectId: project.id,
|
|
@@ -294,6 +486,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
294
486
|
});
|
|
295
487
|
|
|
296
488
|
await createStepCheckoutSpec({
|
|
489
|
+
run: syncedRun,
|
|
297
490
|
step,
|
|
298
491
|
workspaceId: project.workspaceId,
|
|
299
492
|
projectId: project.id,
|
|
@@ -330,6 +523,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
330
523
|
});
|
|
331
524
|
|
|
332
525
|
await createStepCheckoutSpec({
|
|
526
|
+
run: syncedRun,
|
|
333
527
|
step,
|
|
334
528
|
workspaceId: project.workspaceId,
|
|
335
529
|
projectId: project.id,
|
|
@@ -350,6 +544,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
350
544
|
{connection: 'github'},
|
|
351
545
|
])('rejects invalid checkout target shape: %j', async (checkout) => {
|
|
352
546
|
const act = createStepCheckoutSpec({
|
|
547
|
+
run: syncedRun,
|
|
353
548
|
step: checkoutStep(checkout),
|
|
354
549
|
workspaceId: crypto.randomUUID(),
|
|
355
550
|
projectId: crypto.randomUUID(),
|
|
@@ -368,6 +563,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
368
563
|
getProjectById.mockResolvedValue({project: null});
|
|
369
564
|
|
|
370
565
|
const act = createStepCheckoutSpec({
|
|
566
|
+
run: syncedRun,
|
|
371
567
|
step: checkoutStep({}),
|
|
372
568
|
workspaceId: crypto.randomUUID(),
|
|
373
569
|
projectId,
|
|
@@ -387,6 +583,7 @@ describe('createStepCheckoutSpec', () => {
|
|
|
387
583
|
resolveConnection.mockResolvedValue(null);
|
|
388
584
|
|
|
389
585
|
const act = createStepCheckoutSpec({
|
|
586
|
+
run: syncedRun,
|
|
390
587
|
step,
|
|
391
588
|
workspaceId: project.workspaceId,
|
|
392
589
|
projectId: project.id,
|
package/src/core/checkout.ts
CHANGED
|
@@ -3,7 +3,10 @@ import type {ProjectsModuleClient} from '@shipfox/api-projects-dto/inter-module'
|
|
|
3
3
|
import {checkoutTargetValidationIssues} from '@shipfox/workflow-document';
|
|
4
4
|
import {z} from 'zod';
|
|
5
5
|
import type {Step} from '#core/entities/step.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
WorkflowRunOriginState,
|
|
8
|
+
WorkflowRunTriggerReference,
|
|
9
|
+
} from '#core/entities/workflow-run.js';
|
|
7
10
|
import {CheckoutConfigInvalidError, CheckoutIntentUnresolvedError} from './errors.js';
|
|
8
11
|
|
|
9
12
|
const checkoutConfigSchema = z
|
|
@@ -39,6 +42,7 @@ export async function createStepCheckoutSpec({
|
|
|
39
42
|
workspaceId,
|
|
40
43
|
projectId,
|
|
41
44
|
triggerReference,
|
|
45
|
+
run,
|
|
42
46
|
integrations,
|
|
43
47
|
projects,
|
|
44
48
|
}: {
|
|
@@ -46,6 +50,8 @@ export async function createStepCheckoutSpec({
|
|
|
46
50
|
workspaceId: string;
|
|
47
51
|
projectId: string;
|
|
48
52
|
triggerReference?: WorkflowRunTriggerReference | null | undefined;
|
|
53
|
+
/** The run's origin state; a dev run checks out its dev commit by default. */
|
|
54
|
+
run: WorkflowRunOriginState;
|
|
49
55
|
integrations: IntegrationsModuleClient;
|
|
50
56
|
projects: ProjectsModuleClient;
|
|
51
57
|
}): Promise<{
|
|
@@ -79,11 +85,18 @@ export async function createStepCheckoutSpec({
|
|
|
79
85
|
},
|
|
80
86
|
target,
|
|
81
87
|
});
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
// Explicit step refs win, followed by same-project event commits (including
|
|
89
|
+
// replays), then the pinned dev commit for the run's own project. Other targets
|
|
90
|
+
// intentionally use the provider default branch.
|
|
91
|
+
const triggerCommitRef =
|
|
92
|
+
triggerReference?.project?.id === resolvedTarget.projectId
|
|
85
93
|
? (triggerReference.commit ?? undefined)
|
|
86
|
-
: undefined
|
|
94
|
+
: undefined;
|
|
95
|
+
const devCommitRef =
|
|
96
|
+
run.origin === 'dev' && resolvedTarget.projectId === projectId
|
|
97
|
+
? run.devSource.commit
|
|
98
|
+
: undefined;
|
|
99
|
+
const ref = checkout.ref ?? triggerCommitRef ?? devCommitRef;
|
|
87
100
|
const response = await integrations.createCheckoutSpec({
|
|
88
101
|
workspaceId,
|
|
89
102
|
connectionId: resolvedTarget.connectionId,
|
package/src/core/entities/job.ts
CHANGED
|
@@ -5,6 +5,24 @@ import type {WorkflowRunAttempt} from './workflow-run-attempt.js';
|
|
|
5
5
|
|
|
6
6
|
export type WorkflowRunStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled';
|
|
7
7
|
|
|
8
|
+
export type WorkflowRunOrigin = 'synced' | 'dev';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Why a dev run was created: the ref and pinned commit the definition came from, the
|
|
12
|
+
* file that ran, the user who started it, and the journaled event it replays when any.
|
|
13
|
+
*/
|
|
14
|
+
export interface WorkflowRunDevSource {
|
|
15
|
+
ref: string;
|
|
16
|
+
commit: string;
|
|
17
|
+
configPath: string;
|
|
18
|
+
initiatedByUserId: string;
|
|
19
|
+
replayOfEventId: string | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type WorkflowRunOriginState =
|
|
23
|
+
| {origin: 'synced'; devSource: null}
|
|
24
|
+
| {origin: 'dev'; devSource: WorkflowRunDevSource};
|
|
25
|
+
|
|
8
26
|
export type TerminalWorkflowRunStatus = Extract<
|
|
9
27
|
WorkflowRunStatus,
|
|
10
28
|
'succeeded' | 'failed' | 'cancelled'
|
|
@@ -40,14 +58,16 @@ export type TriggerPayload =
|
|
|
40
58
|
source: 'manual';
|
|
41
59
|
provider?: 'manual' | undefined;
|
|
42
60
|
event: 'fire';
|
|
43
|
-
|
|
61
|
+
// A dev trigger has no subscription row, so the id is optional here.
|
|
62
|
+
subscriptionId?: string | undefined;
|
|
44
63
|
userId: string;
|
|
45
64
|
}
|
|
46
65
|
| {
|
|
47
66
|
source: 'cron';
|
|
48
67
|
provider?: 'cron' | undefined;
|
|
49
68
|
event: 'tick';
|
|
50
|
-
|
|
69
|
+
// A dev trigger has no schedule row, so the id is optional here.
|
|
70
|
+
scheduleId?: string | undefined;
|
|
51
71
|
}
|
|
52
72
|
// Integration sources (github, gitlab, sentry, …) flow through opaquely: the
|
|
53
73
|
// run records what fired it and carries the raw event payload, without the
|
|
@@ -60,7 +80,7 @@ export type TriggerPayload =
|
|
|
60
80
|
data: unknown;
|
|
61
81
|
};
|
|
62
82
|
|
|
63
|
-
export
|
|
83
|
+
export type WorkflowRun = WorkflowRunOriginState & {
|
|
64
84
|
id: string;
|
|
65
85
|
workspaceId: string;
|
|
66
86
|
projectId: string;
|
|
@@ -89,7 +109,7 @@ export interface WorkflowRun {
|
|
|
89
109
|
updatedAt: Date;
|
|
90
110
|
startedAt: Date | null;
|
|
91
111
|
finishedAt: Date | null;
|
|
92
|
-
}
|
|
112
|
+
};
|
|
93
113
|
|
|
94
114
|
export interface StepDetail extends Step {
|
|
95
115
|
attempts: StepAttempt[];
|
|
@@ -103,11 +123,11 @@ export interface WorkflowJobDetail extends Job {
|
|
|
103
123
|
jobExecutions: JobExecutionDetail[];
|
|
104
124
|
}
|
|
105
125
|
|
|
106
|
-
export
|
|
126
|
+
export type WorkflowRunDetail = WorkflowRun & {
|
|
107
127
|
runAttempt: WorkflowRunAttempt;
|
|
108
128
|
latestAttempt: number;
|
|
109
129
|
jobs: WorkflowJobDetail[];
|
|
110
130
|
/** Whether any job execution of this attempt reached its runner, decided here so the detail
|
|
111
131
|
* and the list cannot answer it differently. */
|
|
112
132
|
hasStartedJobExecution: boolean;
|
|
113
|
-
}
|
|
133
|
+
};
|
package/src/core/index.ts
CHANGED
|
@@ -35,8 +35,8 @@ export {
|
|
|
35
35
|
deriveJobSuccess,
|
|
36
36
|
type JobActivationDecision,
|
|
37
37
|
} from './job-transition/index.js';
|
|
38
|
-
export type {RunWorkflowParams} from './run-workflow.js';
|
|
39
|
-
export {runWorkflow} from './run-workflow.js';
|
|
38
|
+
export type {RunDevWorkflowParams, RunWorkflowParams} from './run-workflow.js';
|
|
39
|
+
export {runDevWorkflow, runWorkflow} from './run-workflow.js';
|
|
40
40
|
export {
|
|
41
41
|
type MaterializedWorkflowJob,
|
|
42
42
|
type MaterializedWorkflowStep,
|