@shipfox/api-workflows 12.7.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.
Files changed (97) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/CHANGELOG.md +9 -0
  3. package/dist/db/index.d.ts +1 -1
  4. package/dist/db/index.d.ts.map +1 -1
  5. package/dist/db/index.js +1 -1
  6. package/dist/db/index.js.map +1 -1
  7. package/dist/db/job-listeners.d.ts.map +1 -1
  8. package/dist/db/job-listeners.js +17 -1
  9. package/dist/db/job-listeners.js.map +1 -1
  10. package/dist/db/workflow-runs/job-executions.d.ts +2 -3
  11. package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
  12. package/dist/db/workflow-runs/job-executions.js +48 -20
  13. package/dist/db/workflow-runs/job-executions.js.map +1 -1
  14. package/dist/db/workflow-runs/outbox.d.ts +15 -0
  15. package/dist/db/workflow-runs/outbox.d.ts.map +1 -1
  16. package/dist/db/workflow-runs/outbox.js +35 -1
  17. package/dist/db/workflow-runs/outbox.js.map +1 -1
  18. package/dist/db/workflow-runs/run-graph.d.ts.map +1 -1
  19. package/dist/db/workflow-runs/run-graph.js +12 -0
  20. package/dist/db/workflow-runs/run-graph.js.map +1 -1
  21. package/dist/db/workflow-runs/run-status.d.ts.map +1 -1
  22. package/dist/db/workflow-runs/run-status.js +13 -1
  23. package/dist/db/workflow-runs/run-status.js.map +1 -1
  24. package/dist/db/workflow-runs.d.ts +2 -2
  25. package/dist/db/workflow-runs.d.ts.map +1 -1
  26. package/dist/db/workflow-runs.js +2 -2
  27. package/dist/db/workflow-runs.js.map +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +2 -4
  30. package/dist/index.js.map +1 -1
  31. package/dist/presentation/index.d.ts +1 -1
  32. package/dist/presentation/index.d.ts.map +1 -1
  33. package/dist/presentation/index.js +1 -1
  34. package/dist/presentation/index.js.map +1 -1
  35. package/dist/presentation/subscribers/index.d.ts +0 -1
  36. package/dist/presentation/subscribers/index.d.ts.map +1 -1
  37. package/dist/presentation/subscribers/index.js +0 -1
  38. package/dist/presentation/subscribers/index.js.map +1 -1
  39. package/dist/temporal/activities/index.d.ts +2 -18
  40. package/dist/temporal/activities/index.d.ts.map +1 -1
  41. package/dist/temporal/activities/index.js +3 -5
  42. package/dist/temporal/activities/index.js.map +1 -1
  43. package/dist/temporal/activities/orchestration-activities.d.ts +5 -14
  44. package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
  45. package/dist/temporal/activities/orchestration-activities.js +13 -34
  46. package/dist/temporal/activities/orchestration-activities.js.map +1 -1
  47. package/dist/temporal/workflows/index.bundle.js +20 -68
  48. package/dist/temporal/workflows/job-execution-orchestration.d.ts +0 -3
  49. package/dist/temporal/workflows/job-execution-orchestration.d.ts.map +1 -1
  50. package/dist/temporal/workflows/job-execution-orchestration.js +17 -41
  51. package/dist/temporal/workflows/job-execution-orchestration.js.map +1 -1
  52. package/dist/temporal/workflows/job-listener-orchestration.d.ts +0 -3
  53. package/dist/temporal/workflows/job-listener-orchestration.d.ts.map +1 -1
  54. package/dist/temporal/workflows/job-listener-orchestration.js +1 -9
  55. package/dist/temporal/workflows/job-listener-orchestration.js.map +1 -1
  56. package/dist/temporal/workflows/run-orchestration.d.ts.map +1 -1
  57. package/dist/temporal/workflows/run-orchestration.js +2 -18
  58. package/dist/temporal/workflows/run-orchestration.js.map +1 -1
  59. package/dist/temporal/workflows/test-env.d.ts +4 -6
  60. package/dist/temporal/workflows/test-env.d.ts.map +1 -1
  61. package/dist/temporal/workflows/test-env.js +13 -24
  62. package/dist/temporal/workflows/test-env.js.map +1 -1
  63. package/dist/tsconfig.test.tsbuildinfo +1 -1
  64. package/package.json +3 -3
  65. package/src/db/index.ts +1 -1
  66. package/src/db/job-listeners.test.ts +21 -0
  67. package/src/db/job-listeners.ts +18 -0
  68. package/src/db/workflow-runs/job-executions.test.ts +110 -12
  69. package/src/db/workflow-runs/job-executions.ts +54 -29
  70. package/src/db/workflow-runs/outbox.ts +63 -0
  71. package/src/db/workflow-runs/run-graph.ts +17 -0
  72. package/src/db/workflow-runs/run-status.test.ts +13 -0
  73. package/src/db/workflow-runs/run-status.ts +15 -1
  74. package/src/db/workflow-runs.ts +3 -1
  75. package/src/index.ts +1 -5
  76. package/src/presentation/index.ts +0 -1
  77. package/src/presentation/subscribers/index.ts +0 -1
  78. package/src/temporal/activities/index.ts +2 -8
  79. package/src/temporal/activities/orchestration-activities.test.ts +17 -1
  80. package/src/temporal/activities/orchestration-activities.ts +13 -46
  81. package/src/temporal/workflows/job-execution-orchestration.test.ts +6 -25
  82. package/src/temporal/workflows/job-execution-orchestration.ts +17 -43
  83. package/src/temporal/workflows/job-listener-orchestration-continuation.test.ts +0 -3
  84. package/src/temporal/workflows/job-listener-orchestration.test.ts +9 -12
  85. package/src/temporal/workflows/job-listener-orchestration.ts +0 -8
  86. package/src/temporal/workflows/run-orchestration.test.ts +22 -33
  87. package/src/temporal/workflows/run-orchestration.ts +4 -28
  88. package/src/temporal/workflows/test-env.ts +14 -34
  89. package/test/fixtures/runners-inter-module.ts +0 -3
  90. package/test/helpers/workflow-runs.ts +25 -0
  91. package/tsconfig.build.tsbuildinfo +1 -1
  92. package/dist/presentation/subscribers/on-runner-job-queued.d.ts +0 -3
  93. package/dist/presentation/subscribers/on-runner-job-queued.d.ts.map +0 -1
  94. package/dist/presentation/subscribers/on-runner-job-queued.js +0 -20
  95. package/dist/presentation/subscribers/on-runner-job-queued.js.map +0 -1
  96. package/src/presentation/subscribers/on-runner-job-queued.test.ts +0 -57
  97. package/src/presentation/subscribers/on-runner-job-queued.ts +0 -23
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/workflow-runs/job-executions.ts"],"sourcesContent":["import {readPersistedWorkflowModel} from '@shipfox/api-definitions-dto';\nimport type {SecretsInterModuleClient} from '@shipfox/api-secrets-dto/inter-module';\nimport {WORKFLOWS_JOB_EXECUTION_TIMED_OUT} from '@shipfox/api-workflows-dto';\nimport {and, asc, desc, eq, isNull, notInArray, sql} from 'drizzle-orm';\nimport type {JobStatusReason} from '#core/entities/job.js';\nimport type {JobExecution, JobExecutionStatus} from '#core/entities/job-execution.js';\nimport {\n InterpolationUnresolvableError,\n JobNotFoundError,\n JobOutputNotJsonSafeError,\n JobOutputTooLargeError,\n JobOutputTooManyEntriesError,\n} from '#core/errors.js';\nimport {deriveJobExecutionOutputs} from '#core/job-transition/index.js';\nimport {deriveCompletion, isTerminal} from '#core/step-transition/decide-step-transition.js';\nimport type {RuntimeCompletionStatus} from '#core/workflow-scheduling/runtime-dag.js';\nimport {\n recordWorkflowJobExecutionLeaseExpiryResolved,\n recordWorkflowJobExecutionQueued,\n recordWorkflowJobExecutionStarted,\n recordWorkflowJobExecutionStatusChanged,\n recordWorkflowJobExecutionTimedOut,\n} from '#metrics/instance.js';\nimport {db, type Tx} from '../db.js';\nimport {writeWorkflowsOutboxEvent} from '../outbox-writes.js';\nimport {jobExecutions, toJobExecution} from '../schema/job-executions.js';\nimport {jobs, toJob} from '../schema/jobs.js';\nimport {stepAttempts, toStepAttempt} from '../schema/step-attempts.js';\nimport {steps, toStep} from '../schema/steps.js';\nimport {workflowRunAttempts} from '../schema/workflow-run-attempts.js';\nimport {toWorkflowRun, workflowRuns} from '../schema/workflow-runs.js';\nimport {getDirectDependencyJobContexts} from './jobs.js';\nimport {loadReferencedVariables} from './runs.js';\nimport {\n getWorkflowContextForJob,\n optimisticLockRetry,\n TERMINAL_EXECUTION_STATUSES,\n} from './shared.js';\nimport {bulkUpdateStepStatuses, getStepsByJobExecutionIdForUpdate} from './steps.js';\n\nasync function getJobExecutionFallbackName(tx: Tx, jobExecutionId: string): Promise<string> {\n const [row] = await tx\n .select({job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.id, jobExecutionId))\n .limit(1);\n if (!row) throw new JobNotFoundError(jobExecutionId);\n return row.job.name ?? row.job.key;\n}\n\nexport async function getJobExecutionById(id: string, tx?: Tx): Promise<JobExecution | undefined> {\n const rows = await (tx ?? db())\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.id, id))\n .limit(1);\n const row = rows[0];\n return row ? toJobExecution(row.jobExecution, row.job.name ?? row.job.key) : undefined;\n}\n\nexport async function getJobExecutionsByWorkflowRunAttemptId(\n workflowRunAttemptId: string,\n): Promise<JobExecution[]> {\n const rows = await db()\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobs.workflowRunAttemptId, workflowRunAttemptId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id));\n return rows.map((row) => toJobExecution(row.jobExecution, row.job.name ?? row.job.key));\n}\n\nexport async function getJobExecutionsByJobId(jobId: string): Promise<JobExecution[]> {\n const rows = await db()\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id));\n return rows.map((row) => toJobExecution(row.jobExecution, row.job.name ?? row.job.key));\n}\n\nexport async function getFirstJobExecutionByJobId(\n jobId: string,\n tx?: Tx,\n): Promise<JobExecution | undefined> {\n const rows = await (tx ?? db())\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id))\n .limit(1);\n const row = rows[0];\n return row ? toJobExecution(row.jobExecution, row.job.name ?? row.job.key) : undefined;\n}\n\nexport async function getLatestJobExecutionByJobId(\n jobId: string,\n tx?: Tx,\n): Promise<JobExecution | undefined> {\n const rows = await (tx ?? db())\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(desc(jobExecutions.sequence), desc(jobExecutions.id))\n .limit(1);\n const row = rows[0];\n return row ? toJobExecution(row.jobExecution, row.job.name ?? row.job.key) : undefined;\n}\n\nexport interface UpdateJobExecutionStatusAtVersionParams {\n jobExecutionId: string;\n status: JobExecutionStatus;\n expectedVersion: number;\n statusReason?: JobStatusReason | null | undefined;\n statusReasonMessage?: string | null | undefined;\n markTimedOut?: boolean;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}\n\nconst MAX_STATUS_REASON_MESSAGE_LENGTH = 2048;\n\nexport type JobOutputFailure = {\n statusReason: Extract<JobStatusReason, 'output_invalid' | 'output_too_large'>;\n statusReasonMessage: string;\n};\n\nexport function classifyJobOutputFailure(error: unknown): JobOutputFailure | null {\n if (error instanceof JobOutputTooLargeError) {\n return {\n statusReason: 'output_too_large',\n statusReasonMessage: boundedStatusReasonMessage(error.message),\n };\n }\n\n if (\n (error instanceof InterpolationUnresolvableError && error.field === 'job.outputs') ||\n error instanceof JobOutputNotJsonSafeError ||\n error instanceof JobOutputTooManyEntriesError\n ) {\n return {\n statusReason: 'output_invalid',\n statusReasonMessage: boundedStatusReasonMessage(error.message),\n };\n }\n\n return null;\n}\n\nfunction boundedStatusReasonMessage(message: string): string {\n return message.length <= MAX_STATUS_REASON_MESSAGE_LENGTH\n ? message\n : `${message.slice(0, MAX_STATUS_REASON_MESSAGE_LENGTH - 1)}…`;\n}\n\nasync function resolveJobExecutionOutputs(\n tx: Tx,\n params: {\n jobExecutionId: string;\n status: JobExecutionStatus;\n statusReason: JobStatusReason | null;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n },\n): Promise<Record<string, unknown> | null> {\n const [target] = await tx\n .select({execution: jobExecutions, job: jobs, attempt: workflowRunAttempts, run: workflowRuns})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1);\n if (!target) throw new JobNotFoundError(params.jobExecutionId);\n const model =\n target.attempt.model === null ? null : readPersistedWorkflowModel(target.attempt.model);\n if (!model) return null;\n const modelJob = model.jobs.find((job) => job.key === target.job.key);\n if (!modelJob || modelJob.outputs === undefined) return null;\n\n const executionRows = await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.jobId, target.job.id))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id));\n const fallbackName = target.job.name ?? target.job.key;\n const executions = executionRows.map((row) =>\n row.id === target.execution.id\n ? toJobExecution(\n {...row, status: params.status, statusReason: params.statusReason},\n fallbackName,\n )\n : toJobExecution(row, fallbackName),\n );\n const jobExecution = executions.find((execution) => execution.id === target.execution.id);\n if (!jobExecution) throw new JobNotFoundError(params.jobExecutionId);\n\n const stepRows = await tx\n .select()\n .from(steps)\n .where(eq(steps.jobExecutionId, params.jobExecutionId))\n .orderBy(asc(steps.position), asc(steps.id));\n const attemptRows = await tx\n .select()\n .from(stepAttempts)\n .where(eq(stepAttempts.jobExecutionId, params.jobExecutionId))\n .orderBy(asc(stepAttempts.executionOrder), asc(stepAttempts.id));\n const dependencyJobs = await getDirectDependencyJobContexts(target.job.id, tx);\n\n return deriveJobExecutionOutputs({\n run: toWorkflowRun(target.run),\n modelJob,\n job: toJob(target.job),\n jobExecution,\n executions,\n steps: stepRows.map(toStep),\n attempts: attemptRows.map(toStepAttempt),\n jobs: dependencyJobs,\n vars: await loadReferencedVariables({\n model,\n jobs: [modelJob],\n workspaceId: target.run.workspaceId,\n projectId: target.run.projectId,\n definitionId: target.run.definitionId,\n secrets: params.secrets,\n }),\n });\n}\n\nasync function updateJobExecutionStatusAtVersion(\n tx: Tx,\n params: UpdateJobExecutionStatusAtVersionParams,\n): Promise<{execution: JobExecution; changed: boolean} | null> {\n let status = params.status;\n let statusReason = params.statusReason ?? null;\n let statusReasonMessage = params.statusReasonMessage ?? null;\n let outputs: Record<string, unknown> | null | undefined;\n if (TERMINAL_EXECUTION_STATUSES.includes(status)) {\n outputs = null;\n }\n if (status === 'succeeded') {\n try {\n outputs = await resolveJobExecutionOutputs(tx, {\n jobExecutionId: params.jobExecutionId,\n status,\n statusReason,\n secrets: params.secrets,\n });\n } catch (error) {\n const outputFailure = classifyJobOutputFailure(error);\n if (outputFailure === null) throw error;\n status = 'failed';\n statusReason = outputFailure.statusReason;\n statusReasonMessage = outputFailure.statusReasonMessage;\n outputs = null;\n }\n }\n\n const rows = await tx\n .update(jobExecutions)\n .set({\n status,\n statusReason,\n statusReasonMessage,\n ...(outputs === undefined ? {} : {outputs}),\n version: sql`${jobExecutions.version} + 1`,\n updatedAt: new Date(),\n ...(params.markTimedOut ? {timedOutAt: new Date()} : {}),\n ...(TERMINAL_EXECUTION_STATUSES.includes(status) ? {finishedAt: sql`now()`} : {}),\n })\n .where(\n and(\n eq(jobExecutions.id, params.jobExecutionId),\n eq(jobExecutions.version, params.expectedVersion),\n notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES),\n ),\n )\n .returning();\n\n const row = rows[0];\n if (!row) return null;\n return {\n execution: toJobExecution(row, await getJobExecutionFallbackName(tx, row.id)),\n changed: true,\n };\n}\n\nexport interface UpdateJobExecutionStatusParams {\n jobExecutionId: string;\n status: JobExecutionStatus;\n expectedVersion: number;\n statusReason?: JobStatusReason | null | undefined;\n statusReasonMessage?: string | null | undefined;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}\n\nexport async function updateJobExecutionStatus(\n params: UpdateJobExecutionStatusParams,\n): Promise<JobExecution> {\n const statusReason = params.statusReason ?? null;\n const result = await db().transaction(async (tx) => {\n return await optimisticLockRetry({\n updateFn: () =>\n updateJobExecutionStatusAtVersion(tx, {\n jobExecutionId: params.jobExecutionId,\n status: params.status,\n expectedVersion: params.expectedVersion,\n statusReason,\n statusReasonMessage: params.statusReasonMessage,\n secrets: params.secrets,\n }),\n fetchFn: async () => {\n const row = (\n await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1)\n )[0];\n return row ? toJobExecution(row, await getJobExecutionFallbackName(tx, row.id)) : undefined;\n },\n matchFn: (execution) =>\n (execution.status === params.status && execution.statusReason === statusReason) ||\n TERMINAL_EXECUTION_STATUSES.includes(execution.status)\n ? {execution, changed: false}\n : null,\n failureMessage: `Optimistic lock failure: job execution ${params.jobExecutionId} version ${params.expectedVersion}`,\n });\n });\n\n if (result.changed) recordWorkflowJobExecutionStatusChanged(result.execution.status);\n\n return result.execution;\n}\n\nexport async function recordJobExecutionQueuedAt(params: {\n jobExecutionId: string;\n queuedAt: Date;\n}): Promise<void> {\n const updated = await db()\n .update(jobExecutions)\n .set({queuedAt: params.queuedAt})\n .where(and(eq(jobExecutions.id, params.jobExecutionId), isNull(jobExecutions.queuedAt)))\n .returning({id: jobExecutions.id});\n\n if (updated.length > 0) recordWorkflowJobExecutionQueued();\n}\n\nexport async function recordJobExecutionStartedAt(params: {\n jobExecutionId: string;\n startedAt: Date;\n}): Promise<void> {\n const updated = await db()\n .update(jobExecutions)\n .set({startedAt: params.startedAt})\n .where(and(eq(jobExecutions.id, params.jobExecutionId), isNull(jobExecutions.startedAt)))\n .returning({id: jobExecutions.id});\n\n if (updated.length > 0) recordWorkflowJobExecutionStarted();\n}\n\nexport async function failJobExecutionAsTimedOut(params: {\n jobExecutionId: string;\n workflowRunAttemptId: string;\n expectedVersion: number;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}): Promise<JobExecution> {\n const result = await db().transaction(async (tx) => {\n const updated = await optimisticLockRetry({\n updateFn: () =>\n updateJobExecutionStatusAtVersion(tx, {\n jobExecutionId: params.jobExecutionId,\n status: 'failed',\n expectedVersion: params.expectedVersion,\n statusReason: 'timed_out',\n markTimedOut: true,\n secrets: params.secrets,\n }),\n fetchFn: async () => {\n const row = (\n await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1)\n )[0];\n return row ? toJobExecution(row, await getJobExecutionFallbackName(tx, row.id)) : undefined;\n },\n matchFn: (execution) => (execution.timedOutAt !== null ? {execution, changed: false} : null),\n failureMessage: `Optimistic lock failure: job execution ${params.jobExecutionId} version ${params.expectedVersion}`,\n });\n\n if (updated.changed) {\n const identity = await getWorkflowContextForJob(updated.execution.jobId, tx);\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_JOB_EXECUTION_TIMED_OUT,\n payload: {\n jobId: identity.jobId,\n jobExecutionId: params.jobExecutionId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n },\n });\n }\n\n return updated;\n });\n\n if (result.changed) {\n recordWorkflowJobExecutionStatusChanged(result.execution.status);\n recordWorkflowJobExecutionTimedOut();\n }\n\n return result.execution;\n}\n\nexport async function resolveJobExecutionAfterLeaseExpiry(params: {\n jobExecutionId: string;\n expectedVersion: number;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}): Promise<{status: RuntimeCompletionStatus; executionVersion: number}> {\n const result = await db().transaction(async (tx) => {\n const jobExecutionSteps = await getStepsByJobExecutionIdForUpdate(params.jobExecutionId, tx);\n let changedJobExecution: JobExecution | null = null;\n\n if (jobExecutionSteps.length === 0) {\n throw new JobNotFoundError(params.jobExecutionId);\n }\n\n if (jobExecutionSteps.every((step) => isTerminal(step.status))) {\n const status = deriveCompletion(jobExecutionSteps);\n const updated = await updateJobExecutionStatusAtVersion(tx, {\n jobExecutionId: params.jobExecutionId,\n status,\n expectedVersion: params.expectedVersion,\n statusReason: statusReasonForStepCompletion(status),\n secrets: params.secrets,\n });\n changedJobExecution = updated?.changed ? updated.execution : null;\n } else {\n const updated = await updateJobExecutionStatusAtVersion(tx, {\n jobExecutionId: params.jobExecutionId,\n status: 'failed',\n expectedVersion: params.expectedVersion,\n statusReason: 'runner_lost',\n secrets: params.secrets,\n });\n if (updated?.changed) {\n changedJobExecution = updated.execution;\n await bulkUpdateStepStatuses(\n {jobExecutionId: params.jobExecutionId, status: 'cancelled'},\n tx,\n );\n }\n }\n\n const jobExecutionRow = (\n await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1)\n )[0];\n if (!jobExecutionRow) {\n throw new Error(`Job execution not found resolving lease expiry: ${params.jobExecutionId}`);\n }\n const status: RuntimeCompletionStatus =\n jobExecutionRow.status === 'succeeded' ? 'succeeded' : 'failed';\n return {status, executionVersion: jobExecutionRow.version, changedJobExecution};\n });\n\n recordWorkflowJobExecutionLeaseExpiryResolved(result.status);\n if (result.changedJobExecution) {\n recordWorkflowJobExecutionStatusChanged(result.changedJobExecution.status);\n }\n\n return {status: result.status, executionVersion: result.executionVersion};\n}\n\nfunction statusReasonForStepCompletion(status: RuntimeCompletionStatus): JobStatusReason | null {\n return status === 'failed' ? 'step_failed' : null;\n}\n"],"names":["readPersistedWorkflowModel","WORKFLOWS_JOB_EXECUTION_TIMED_OUT","and","asc","desc","eq","isNull","notInArray","sql","InterpolationUnresolvableError","JobNotFoundError","JobOutputNotJsonSafeError","JobOutputTooLargeError","JobOutputTooManyEntriesError","deriveJobExecutionOutputs","deriveCompletion","isTerminal","recordWorkflowJobExecutionLeaseExpiryResolved","recordWorkflowJobExecutionQueued","recordWorkflowJobExecutionStarted","recordWorkflowJobExecutionStatusChanged","recordWorkflowJobExecutionTimedOut","db","writeWorkflowsOutboxEvent","jobExecutions","toJobExecution","jobs","toJob","stepAttempts","toStepAttempt","steps","toStep","workflowRunAttempts","toWorkflowRun","workflowRuns","getDirectDependencyJobContexts","loadReferencedVariables","getWorkflowContextForJob","optimisticLockRetry","TERMINAL_EXECUTION_STATUSES","bulkUpdateStepStatuses","getStepsByJobExecutionIdForUpdate","getJobExecutionFallbackName","tx","jobExecutionId","row","select","job","from","innerJoin","jobId","id","where","limit","name","key","getJobExecutionById","rows","jobExecution","undefined","getJobExecutionsByWorkflowRunAttemptId","workflowRunAttemptId","orderBy","sequence","map","getJobExecutionsByJobId","getFirstJobExecutionByJobId","getLatestJobExecutionByJobId","MAX_STATUS_REASON_MESSAGE_LENGTH","classifyJobOutputFailure","error","statusReason","statusReasonMessage","boundedStatusReasonMessage","message","field","length","slice","resolveJobExecutionOutputs","params","target","execution","attempt","run","workflowRunId","model","modelJob","find","outputs","executionRows","fallbackName","executions","status","stepRows","position","attemptRows","executionOrder","dependencyJobs","attempts","vars","workspaceId","projectId","definitionId","secrets","updateJobExecutionStatusAtVersion","includes","outputFailure","update","set","version","updatedAt","Date","markTimedOut","timedOutAt","finishedAt","expectedVersion","returning","changed","updateJobExecutionStatus","result","transaction","updateFn","fetchFn","matchFn","failureMessage","recordJobExecutionQueuedAt","updated","queuedAt","recordJobExecutionStartedAt","startedAt","failJobExecutionAsTimedOut","identity","type","payload","resolveJobExecutionAfterLeaseExpiry","jobExecutionSteps","changedJobExecution","every","step","statusReasonForStepCompletion","jobExecutionRow","Error","executionVersion"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/db/workflow-runs/job-executions.ts"],"sourcesContent":["import {readPersistedWorkflowModel} from '@shipfox/api-definitions-dto';\nimport type {SecretsInterModuleClient} from '@shipfox/api-secrets-dto/inter-module';\nimport {canonicalizeLabels} from '@shipfox/runner-labels';\nimport {and, asc, desc, eq, isNull, notInArray, sql} from 'drizzle-orm';\nimport type {JobStatusReason} from '#core/entities/job.js';\nimport type {JobExecution, JobExecutionStatus} from '#core/entities/job-execution.js';\nimport {\n InterpolationUnresolvableError,\n JobNotFoundError,\n JobOutputNotJsonSafeError,\n JobOutputTooLargeError,\n JobOutputTooManyEntriesError,\n} from '#core/errors.js';\nimport {deriveJobExecutionOutputs} from '#core/job-transition/index.js';\nimport {deriveCompletion, isTerminal} from '#core/step-transition/decide-step-transition.js';\nimport type {RuntimeCompletionStatus} from '#core/workflow-scheduling/runtime-dag.js';\nimport {\n recordWorkflowJobExecutionLeaseExpiryResolved,\n recordWorkflowJobExecutionQueued,\n recordWorkflowJobExecutionStarted,\n recordWorkflowJobExecutionStatusChanged,\n recordWorkflowJobExecutionTimedOut,\n} from '#metrics/instance.js';\nimport {db, type Tx} from '../db.js';\nimport {jobExecutions, toJobExecution} from '../schema/job-executions.js';\nimport {jobs, toJob} from '../schema/jobs.js';\nimport {stepAttempts, toStepAttempt} from '../schema/step-attempts.js';\nimport {steps, toStep} from '../schema/steps.js';\nimport {workflowRunAttempts} from '../schema/workflow-run-attempts.js';\nimport {toWorkflowRun, workflowRuns} from '../schema/workflow-runs.js';\nimport {getDirectDependencyJobContexts} from './jobs.js';\nimport {writeJobExecutionQueuedOutbox, writeJobExecutionTerminatedOutbox} from './outbox.js';\nimport {loadReferencedVariables} from './runs.js';\nimport {optimisticLockRetry, TERMINAL_EXECUTION_STATUSES} from './shared.js';\nimport {bulkUpdateStepStatuses, getStepsByJobExecutionIdForUpdate} from './steps.js';\n\nasync function getJobExecutionFallbackName(tx: Tx, jobExecutionId: string): Promise<string> {\n const [row] = await tx\n .select({job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.id, jobExecutionId))\n .limit(1);\n if (!row) throw new JobNotFoundError(jobExecutionId);\n return row.job.name ?? row.job.key;\n}\n\nexport async function getJobExecutionById(id: string, tx?: Tx): Promise<JobExecution | undefined> {\n const rows = await (tx ?? db())\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.id, id))\n .limit(1);\n const row = rows[0];\n return row ? toJobExecution(row.jobExecution, row.job.name ?? row.job.key) : undefined;\n}\n\nexport async function getJobExecutionsByWorkflowRunAttemptId(\n workflowRunAttemptId: string,\n): Promise<JobExecution[]> {\n const rows = await db()\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobs.workflowRunAttemptId, workflowRunAttemptId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id));\n return rows.map((row) => toJobExecution(row.jobExecution, row.job.name ?? row.job.key));\n}\n\nexport async function getJobExecutionsByJobId(jobId: string): Promise<JobExecution[]> {\n const rows = await db()\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id));\n return rows.map((row) => toJobExecution(row.jobExecution, row.job.name ?? row.job.key));\n}\n\nexport async function getFirstJobExecutionByJobId(\n jobId: string,\n tx?: Tx,\n): Promise<JobExecution | undefined> {\n const rows = await (tx ?? db())\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id))\n .limit(1);\n const row = rows[0];\n return row ? toJobExecution(row.jobExecution, row.job.name ?? row.job.key) : undefined;\n}\n\nexport async function getLatestJobExecutionByJobId(\n jobId: string,\n tx?: Tx,\n): Promise<JobExecution | undefined> {\n const rows = await (tx ?? db())\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.jobId, jobId))\n .orderBy(desc(jobExecutions.sequence), desc(jobExecutions.id))\n .limit(1);\n const row = rows[0];\n return row ? toJobExecution(row.jobExecution, row.job.name ?? row.job.key) : undefined;\n}\n\nexport interface UpdateJobExecutionStatusAtVersionParams {\n jobExecutionId: string;\n status: JobExecutionStatus;\n expectedVersion: number;\n statusReason?: JobStatusReason | null | undefined;\n statusReasonMessage?: string | null | undefined;\n markTimedOut?: boolean;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}\n\nconst MAX_STATUS_REASON_MESSAGE_LENGTH = 2048;\n\nexport type JobOutputFailure = {\n statusReason: Extract<JobStatusReason, 'output_invalid' | 'output_too_large'>;\n statusReasonMessage: string;\n};\n\nexport function classifyJobOutputFailure(error: unknown): JobOutputFailure | null {\n if (error instanceof JobOutputTooLargeError) {\n return {\n statusReason: 'output_too_large',\n statusReasonMessage: boundedStatusReasonMessage(error.message),\n };\n }\n\n if (\n (error instanceof InterpolationUnresolvableError && error.field === 'job.outputs') ||\n error instanceof JobOutputNotJsonSafeError ||\n error instanceof JobOutputTooManyEntriesError\n ) {\n return {\n statusReason: 'output_invalid',\n statusReasonMessage: boundedStatusReasonMessage(error.message),\n };\n }\n\n return null;\n}\n\nfunction boundedStatusReasonMessage(message: string): string {\n return message.length <= MAX_STATUS_REASON_MESSAGE_LENGTH\n ? message\n : `${message.slice(0, MAX_STATUS_REASON_MESSAGE_LENGTH - 1)}…`;\n}\n\nasync function resolveJobExecutionOutputs(\n tx: Tx,\n params: {\n jobExecutionId: string;\n status: JobExecutionStatus;\n statusReason: JobStatusReason | null;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n },\n): Promise<Record<string, unknown> | null> {\n const [target] = await tx\n .select({execution: jobExecutions, job: jobs, attempt: workflowRunAttempts, run: workflowRuns})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1);\n if (!target) throw new JobNotFoundError(params.jobExecutionId);\n const model =\n target.attempt.model === null ? null : readPersistedWorkflowModel(target.attempt.model);\n if (!model) return null;\n const modelJob = model.jobs.find((job) => job.key === target.job.key);\n if (!modelJob || modelJob.outputs === undefined) return null;\n\n const executionRows = await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.jobId, target.job.id))\n .orderBy(asc(jobExecutions.sequence), asc(jobExecutions.id));\n const fallbackName = target.job.name ?? target.job.key;\n const executions = executionRows.map((row) =>\n row.id === target.execution.id\n ? toJobExecution(\n {...row, status: params.status, statusReason: params.statusReason},\n fallbackName,\n )\n : toJobExecution(row, fallbackName),\n );\n const jobExecution = executions.find((execution) => execution.id === target.execution.id);\n if (!jobExecution) throw new JobNotFoundError(params.jobExecutionId);\n\n const stepRows = await tx\n .select()\n .from(steps)\n .where(eq(steps.jobExecutionId, params.jobExecutionId))\n .orderBy(asc(steps.position), asc(steps.id));\n const attemptRows = await tx\n .select()\n .from(stepAttempts)\n .where(eq(stepAttempts.jobExecutionId, params.jobExecutionId))\n .orderBy(asc(stepAttempts.executionOrder), asc(stepAttempts.id));\n const dependencyJobs = await getDirectDependencyJobContexts(target.job.id, tx);\n\n return deriveJobExecutionOutputs({\n run: toWorkflowRun(target.run),\n modelJob,\n job: toJob(target.job),\n jobExecution,\n executions,\n steps: stepRows.map(toStep),\n attempts: attemptRows.map(toStepAttempt),\n jobs: dependencyJobs,\n vars: await loadReferencedVariables({\n model,\n jobs: [modelJob],\n workspaceId: target.run.workspaceId,\n projectId: target.run.projectId,\n definitionId: target.run.definitionId,\n secrets: params.secrets,\n }),\n });\n}\n\nasync function updateJobExecutionStatusAtVersion(\n tx: Tx,\n params: UpdateJobExecutionStatusAtVersionParams,\n): Promise<{execution: JobExecution; changed: boolean} | null> {\n let status = params.status;\n let statusReason = params.statusReason ?? null;\n let statusReasonMessage = params.statusReasonMessage ?? null;\n let outputs: Record<string, unknown> | null | undefined;\n if (TERMINAL_EXECUTION_STATUSES.includes(status)) {\n outputs = null;\n }\n if (status === 'succeeded') {\n try {\n outputs = await resolveJobExecutionOutputs(tx, {\n jobExecutionId: params.jobExecutionId,\n status,\n statusReason,\n secrets: params.secrets,\n });\n } catch (error) {\n const outputFailure = classifyJobOutputFailure(error);\n if (outputFailure === null) throw error;\n status = 'failed';\n statusReason = outputFailure.statusReason;\n statusReasonMessage = outputFailure.statusReasonMessage;\n outputs = null;\n }\n }\n\n const rows = await tx\n .update(jobExecutions)\n .set({\n status,\n statusReason,\n statusReasonMessage,\n ...(outputs === undefined ? {} : {outputs}),\n version: sql`${jobExecutions.version} + 1`,\n updatedAt: new Date(),\n ...(params.markTimedOut ? {timedOutAt: new Date()} : {}),\n ...(TERMINAL_EXECUTION_STATUSES.includes(status) ? {finishedAt: sql`now()`} : {}),\n })\n .where(\n and(\n eq(jobExecutions.id, params.jobExecutionId),\n eq(jobExecutions.version, params.expectedVersion),\n notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES),\n ),\n )\n .returning();\n\n const row = rows[0];\n if (!row) return null;\n if (TERMINAL_EXECUTION_STATUSES.includes(row.status)) {\n await writeJobExecutionTerminatedOutbox(tx, {\n jobId: row.jobId,\n jobExecutionId: row.id,\n status: row.status,\n statusReason: row.statusReason,\n statusReasonMessage: row.statusReasonMessage,\n });\n }\n return {\n execution: toJobExecution(row, await getJobExecutionFallbackName(tx, row.id)),\n changed: true,\n };\n}\n\nexport interface UpdateJobExecutionStatusParams {\n jobExecutionId: string;\n status: JobExecutionStatus;\n expectedVersion: number;\n statusReason?: JobStatusReason | null | undefined;\n statusReasonMessage?: string | null | undefined;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}\n\nexport async function updateJobExecutionStatus(\n params: UpdateJobExecutionStatusParams,\n): Promise<JobExecution> {\n const statusReason = params.statusReason ?? null;\n const result = await db().transaction(async (tx) => {\n return await optimisticLockRetry({\n updateFn: () =>\n updateJobExecutionStatusAtVersion(tx, {\n jobExecutionId: params.jobExecutionId,\n status: params.status,\n expectedVersion: params.expectedVersion,\n statusReason,\n statusReasonMessage: params.statusReasonMessage,\n secrets: params.secrets,\n }),\n fetchFn: async () => {\n const row = (\n await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1)\n )[0];\n return row ? toJobExecution(row, await getJobExecutionFallbackName(tx, row.id)) : undefined;\n },\n matchFn: (execution) =>\n (execution.status === params.status && execution.statusReason === statusReason) ||\n TERMINAL_EXECUTION_STATUSES.includes(execution.status)\n ? {execution, changed: false}\n : null,\n failureMessage: `Optimistic lock failure: job execution ${params.jobExecutionId} version ${params.expectedVersion}`,\n });\n });\n\n if (result.changed) recordWorkflowJobExecutionStatusChanged(result.execution.status);\n\n return result.execution;\n}\n\nexport async function queueJobExecution(params: {jobExecutionId: string}): Promise<JobExecution> {\n const result = await db().transaction(async (tx) => {\n const [row] = await tx\n .select({jobExecution: jobExecutions, job: jobs})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1)\n .for('update');\n if (!row) throw new JobNotFoundError(params.jobExecutionId);\n\n const existing = toJobExecution(row.jobExecution, row.job.name ?? row.job.key);\n if (existing.queuedAt !== null || TERMINAL_EXECUTION_STATUSES.includes(existing.status)) {\n return {execution: existing, changed: false};\n }\n\n const requiredLabels = [...canonicalizeLabels(existing.runner ?? row.job.runner ?? [])];\n if (requiredLabels.length === 0) {\n throw new Error(`Job execution ${params.jobExecutionId} has no required runner labels`);\n }\n\n const [queued] = await tx\n .update(jobExecutions)\n .set({queuedAt: sql`now()`})\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .returning();\n if (!queued?.queuedAt) throw new Error(`Cannot queue job execution ${params.jobExecutionId}`);\n\n await writeJobExecutionQueuedOutbox(tx, {\n jobId: queued.jobId,\n jobExecutionId: queued.id,\n requiredLabels,\n queuedAt: queued.queuedAt,\n });\n\n return {\n execution: toJobExecution(queued, row.job.name ?? row.job.key),\n changed: true,\n };\n });\n\n if (result.changed) recordWorkflowJobExecutionQueued();\n return result.execution;\n}\n\nexport async function recordJobExecutionStartedAt(params: {\n jobExecutionId: string;\n startedAt: Date;\n}): Promise<void> {\n const updated = await db()\n .update(jobExecutions)\n .set({startedAt: params.startedAt})\n .where(and(eq(jobExecutions.id, params.jobExecutionId), isNull(jobExecutions.startedAt)))\n .returning({id: jobExecutions.id});\n\n if (updated.length > 0) recordWorkflowJobExecutionStarted();\n}\n\nexport async function failJobExecutionAsTimedOut(params: {\n jobExecutionId: string;\n workflowRunAttemptId: string;\n expectedVersion: number;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}): Promise<JobExecution> {\n const result = await db().transaction(async (tx) => {\n const updated = await optimisticLockRetry({\n updateFn: () =>\n updateJobExecutionStatusAtVersion(tx, {\n jobExecutionId: params.jobExecutionId,\n status: 'failed',\n expectedVersion: params.expectedVersion,\n statusReason: 'timed_out',\n markTimedOut: true,\n secrets: params.secrets,\n }),\n fetchFn: async () => {\n const row = (\n await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1)\n )[0];\n return row ? toJobExecution(row, await getJobExecutionFallbackName(tx, row.id)) : undefined;\n },\n matchFn: (execution) => (execution.timedOutAt !== null ? {execution, changed: false} : null),\n failureMessage: `Optimistic lock failure: job execution ${params.jobExecutionId} version ${params.expectedVersion}`,\n });\n\n return updated;\n });\n\n if (result.changed) {\n recordWorkflowJobExecutionStatusChanged(result.execution.status);\n recordWorkflowJobExecutionTimedOut();\n }\n\n return result.execution;\n}\n\nexport async function resolveJobExecutionAfterLeaseExpiry(params: {\n jobExecutionId: string;\n expectedVersion: number;\n secrets?: Pick<SecretsInterModuleClient, 'getVariablesByNamespace'> | undefined;\n}): Promise<{status: RuntimeCompletionStatus; executionVersion: number}> {\n const result = await db().transaction(async (tx) => {\n const jobExecutionSteps = await getStepsByJobExecutionIdForUpdate(params.jobExecutionId, tx);\n let changedJobExecution: JobExecution | null = null;\n\n if (jobExecutionSteps.length === 0) {\n throw new JobNotFoundError(params.jobExecutionId);\n }\n\n if (jobExecutionSteps.every((step) => isTerminal(step.status))) {\n const status = deriveCompletion(jobExecutionSteps);\n const updated = await updateJobExecutionStatusAtVersion(tx, {\n jobExecutionId: params.jobExecutionId,\n status,\n expectedVersion: params.expectedVersion,\n statusReason: statusReasonForStepCompletion(status),\n secrets: params.secrets,\n });\n changedJobExecution = updated?.changed ? updated.execution : null;\n } else {\n const updated = await updateJobExecutionStatusAtVersion(tx, {\n jobExecutionId: params.jobExecutionId,\n status: 'failed',\n expectedVersion: params.expectedVersion,\n statusReason: 'runner_lost',\n secrets: params.secrets,\n });\n if (updated?.changed) {\n changedJobExecution = updated.execution;\n await bulkUpdateStepStatuses(\n {jobExecutionId: params.jobExecutionId, status: 'cancelled'},\n tx,\n );\n }\n }\n\n const jobExecutionRow = (\n await tx\n .select()\n .from(jobExecutions)\n .where(eq(jobExecutions.id, params.jobExecutionId))\n .limit(1)\n )[0];\n if (!jobExecutionRow) {\n throw new Error(`Job execution not found resolving lease expiry: ${params.jobExecutionId}`);\n }\n const status: RuntimeCompletionStatus =\n jobExecutionRow.status === 'succeeded' ? 'succeeded' : 'failed';\n return {status, executionVersion: jobExecutionRow.version, changedJobExecution};\n });\n\n recordWorkflowJobExecutionLeaseExpiryResolved(result.status);\n if (result.changedJobExecution) {\n recordWorkflowJobExecutionStatusChanged(result.changedJobExecution.status);\n }\n\n return {status: result.status, executionVersion: result.executionVersion};\n}\n\nfunction statusReasonForStepCompletion(status: RuntimeCompletionStatus): JobStatusReason | null {\n return status === 'failed' ? 'step_failed' : null;\n}\n"],"names":["readPersistedWorkflowModel","canonicalizeLabels","and","asc","desc","eq","isNull","notInArray","sql","InterpolationUnresolvableError","JobNotFoundError","JobOutputNotJsonSafeError","JobOutputTooLargeError","JobOutputTooManyEntriesError","deriveJobExecutionOutputs","deriveCompletion","isTerminal","recordWorkflowJobExecutionLeaseExpiryResolved","recordWorkflowJobExecutionQueued","recordWorkflowJobExecutionStarted","recordWorkflowJobExecutionStatusChanged","recordWorkflowJobExecutionTimedOut","db","jobExecutions","toJobExecution","jobs","toJob","stepAttempts","toStepAttempt","steps","toStep","workflowRunAttempts","toWorkflowRun","workflowRuns","getDirectDependencyJobContexts","writeJobExecutionQueuedOutbox","writeJobExecutionTerminatedOutbox","loadReferencedVariables","optimisticLockRetry","TERMINAL_EXECUTION_STATUSES","bulkUpdateStepStatuses","getStepsByJobExecutionIdForUpdate","getJobExecutionFallbackName","tx","jobExecutionId","row","select","job","from","innerJoin","jobId","id","where","limit","name","key","getJobExecutionById","rows","jobExecution","undefined","getJobExecutionsByWorkflowRunAttemptId","workflowRunAttemptId","orderBy","sequence","map","getJobExecutionsByJobId","getFirstJobExecutionByJobId","getLatestJobExecutionByJobId","MAX_STATUS_REASON_MESSAGE_LENGTH","classifyJobOutputFailure","error","statusReason","statusReasonMessage","boundedStatusReasonMessage","message","field","length","slice","resolveJobExecutionOutputs","params","target","execution","attempt","run","workflowRunId","model","modelJob","find","outputs","executionRows","fallbackName","executions","status","stepRows","position","attemptRows","executionOrder","dependencyJobs","attempts","vars","workspaceId","projectId","definitionId","secrets","updateJobExecutionStatusAtVersion","includes","outputFailure","update","set","version","updatedAt","Date","markTimedOut","timedOutAt","finishedAt","expectedVersion","returning","changed","updateJobExecutionStatus","result","transaction","updateFn","fetchFn","matchFn","failureMessage","queueJobExecution","for","existing","queuedAt","requiredLabels","runner","Error","queued","recordJobExecutionStartedAt","updated","startedAt","failJobExecutionAsTimedOut","resolveJobExecutionAfterLeaseExpiry","jobExecutionSteps","changedJobExecution","every","step","statusReasonForStepCompletion","jobExecutionRow","executionVersion"],"mappings":"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"}
@@ -1,5 +1,20 @@
1
1
  import { type LogOutcomeDto } from '@shipfox/api-workflows-dto';
2
+ import type { JobStatusReason } from '#core/entities/job.js';
3
+ import type { JobExecutionStatus } from '#core/entities/job-execution.js';
2
4
  import type { Tx } from '../db.js';
5
+ export declare function writeJobExecutionQueuedOutbox(tx: Tx, params: {
6
+ jobId: string;
7
+ jobExecutionId: string;
8
+ requiredLabels: string[];
9
+ queuedAt: Date;
10
+ }): Promise<void>;
11
+ export declare function writeJobExecutionTerminatedOutbox(tx: Tx, params: {
12
+ jobId: string;
13
+ jobExecutionId: string;
14
+ status: JobExecutionStatus;
15
+ statusReason: JobStatusReason | null;
16
+ statusReasonMessage?: string | null | undefined;
17
+ }): Promise<void>;
3
18
  export declare function writeJobStepsSettledOutbox(tx: Tx, params: {
4
19
  jobId: string;
5
20
  jobExecutionId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"outbox.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/outbox.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAInB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,UAAU,CAAC;AAUjC,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAA;CAAC,GAC9E,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,gCAAgC,CACpD,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC7C,UAAU,EAAE,aAAa,CAAC;CAC3B,GACA,OAAO,CAAC,IAAI,CAAC,CAiBf;AA8BD,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,IAAI,CAAC,CAef"}
1
+ {"version":3,"file":"outbox.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/outbox.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAMnB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,UAAU,CAAC;AAMjC,wBAAsB,6BAA6B,CACjD,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,IAAI,CAAC;CAChB,GACA,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,iCAAiC,CACrD,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACjD,GACA,OAAO,CAAC,IAAI,CAAC,CAsBf;AAMD,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAA;CAAC,GAC9E,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,gCAAgC,CACpD,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC7C,UAAU,EAAE,aAAa,CAAC;CAC3B,GACA,OAAO,CAAC,IAAI,CAAC,CAiBf;AA8BD,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -1,9 +1,43 @@
1
- import { WORKFLOWS_JOB_STEPS_SETTLED, WORKFLOWS_STEP_ATTEMPT_TERMINATED, WORKFLOWS_STEP_RESTART_ENQUEUED } from '@shipfox/api-workflows-dto';
1
+ import { WORKFLOWS_JOB_EXECUTION_QUEUED, WORKFLOWS_JOB_EXECUTION_TERMINATED, WORKFLOWS_JOB_STEPS_SETTLED, WORKFLOWS_STEP_ATTEMPT_TERMINATED, WORKFLOWS_STEP_RESTART_ENQUEUED } from '@shipfox/api-workflows-dto';
2
2
  import { eq } from 'drizzle-orm';
3
3
  import { writeWorkflowsOutboxEvent } from '../outbox-writes.js';
4
4
  import { jobExecutions } from '../schema/job-executions.js';
5
5
  import { steps } from '../schema/steps.js';
6
6
  import { getWorkflowContextForJob } from './shared.js';
7
+ export async function writeJobExecutionQueuedOutbox(tx, params) {
8
+ const identity = await getWorkflowContextForJob(params.jobId, tx);
9
+ await writeWorkflowsOutboxEvent(tx, {
10
+ type: WORKFLOWS_JOB_EXECUTION_QUEUED,
11
+ payload: {
12
+ jobId: params.jobId,
13
+ jobExecutionId: params.jobExecutionId,
14
+ workflowRunId: identity.workflowRunId,
15
+ workflowRunAttemptId: identity.workflowRunAttemptId,
16
+ workspaceId: identity.workspaceId,
17
+ projectId: identity.projectId,
18
+ requiredLabels: params.requiredLabels,
19
+ queuedAt: params.queuedAt.toISOString()
20
+ }
21
+ });
22
+ }
23
+ export async function writeJobExecutionTerminatedOutbox(tx, params) {
24
+ if (params.status !== 'succeeded' && params.status !== 'failed' && params.status !== 'cancelled') {
25
+ throw new Error(`Cannot enqueue terminal job execution event for status ${params.status}`);
26
+ }
27
+ const identity = await getWorkflowContextForJob(params.jobId, tx);
28
+ await writeWorkflowsOutboxEvent(tx, {
29
+ type: WORKFLOWS_JOB_EXECUTION_TERMINATED,
30
+ payload: {
31
+ jobId: params.jobId,
32
+ jobExecutionId: params.jobExecutionId,
33
+ workflowRunId: identity.workflowRunId,
34
+ workflowRunAttemptId: identity.workflowRunAttemptId,
35
+ status: params.status,
36
+ statusReason: params.statusReason,
37
+ statusReasonMessage: params.statusReasonMessage ?? null
38
+ }
39
+ });
40
+ }
7
41
  // Enqueue the steps-settled signal in the same transaction as the final per-step
8
42
  // result, so per-step execution observes it exactly once (the outbox is at-least-once;
9
43
  // the job workflow dedupes the signal). Drives the Temporal JOB_FINISHED_SIGNAL; the
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/workflow-runs/outbox.ts"],"sourcesContent":["import {\n type LogOutcomeDto,\n WORKFLOWS_JOB_STEPS_SETTLED,\n WORKFLOWS_STEP_ATTEMPT_TERMINATED,\n WORKFLOWS_STEP_RESTART_ENQUEUED,\n} from '@shipfox/api-workflows-dto';\nimport {eq} from 'drizzle-orm';\nimport type {Tx} from '../db.js';\nimport {writeWorkflowsOutboxEvent} from '../outbox-writes.js';\nimport {jobExecutions} from '../schema/job-executions.js';\nimport {steps} from '../schema/steps.js';\nimport {getWorkflowContextForJob} from './shared.js';\n\n// Enqueue the steps-settled signal in the same transaction as the final per-step\n// result, so per-step execution observes it exactly once (the outbox is at-least-once;\n// the job workflow dedupes the signal). Drives the Temporal JOB_FINISHED_SIGNAL; the\n// job's terminal fact is emitted separately by updateJobStatusAtVersion.\nexport async function writeJobStepsSettledOutbox(\n tx: Tx,\n params: {jobId: string; jobExecutionId: string; status: 'succeeded' | 'failed'},\n): Promise<void> {\n const identity = await getWorkflowContextForJob(params.jobId, tx);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_JOB_STEPS_SETTLED,\n payload: {\n jobId: params.jobId,\n jobExecutionId: params.jobExecutionId,\n workflowRunId: identity.workflowRunId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n status: params.status,\n },\n });\n}\n\nexport async function writeStepAttemptTerminatedOutbox(\n tx: Tx,\n params: {\n stepId: string;\n attempt: number;\n status: 'succeeded' | 'failed' | 'cancelled';\n logOutcome: LogOutcomeDto;\n },\n): Promise<void> {\n const identity = await getStepAttemptTerminatedOutboxIdentity(tx, params.stepId);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_STEP_ATTEMPT_TERMINATED,\n payload: {\n jobId: identity.jobId,\n workflowRunId: identity.workflowRunId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n workspaceId: identity.workspaceId,\n projectId: identity.projectId,\n stepId: params.stepId,\n attempt: params.attempt,\n status: params.status,\n logOutcome: params.logOutcome,\n },\n });\n}\n\nasync function getStepAttemptTerminatedOutboxIdentity(\n tx: Tx,\n stepId: string,\n): Promise<{\n jobId: string;\n workflowRunId: string;\n workflowRunAttemptId: string;\n workspaceId: string;\n projectId: string;\n}> {\n const rows = await tx\n .select({\n jobId: jobExecutions.jobId,\n })\n .from(steps)\n .innerJoin(jobExecutions, eq(steps.jobExecutionId, jobExecutions.id))\n .where(eq(steps.id, stepId))\n .limit(1);\n const step = rows[0];\n if (!step) {\n throw new Error(`Cannot enqueue step-attempt-terminated event: step ${stepId} not found`);\n }\n\n return getWorkflowContextForJob(step.jobId, tx);\n}\n\n// Enqueue the durable audit record of a restart, in the same transaction as the\n// rewind. Looks up the workflow run id like writeJobStepsSettledOutbox.\nexport async function writeStepRestartEnqueuedOutbox(\n tx: Tx,\n params: {\n jobId: string;\n failedStepId: string;\n failedStepAttempt: number;\n restartFromStepId: string;\n feedback: string;\n },\n): Promise<void> {\n const identity = await getWorkflowContextForJob(params.jobId, tx);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_STEP_RESTART_ENQUEUED,\n payload: {\n jobId: params.jobId,\n workflowRunId: identity.workflowRunId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n failedStepId: params.failedStepId,\n failedStepAttempt: params.failedStepAttempt,\n restartFromStepId: params.restartFromStepId,\n feedback: params.feedback,\n },\n });\n}\n"],"names":["WORKFLOWS_JOB_STEPS_SETTLED","WORKFLOWS_STEP_ATTEMPT_TERMINATED","WORKFLOWS_STEP_RESTART_ENQUEUED","eq","writeWorkflowsOutboxEvent","jobExecutions","steps","getWorkflowContextForJob","writeJobStepsSettledOutbox","tx","params","identity","jobId","type","payload","jobExecutionId","workflowRunId","workflowRunAttemptId","status","writeStepAttemptTerminatedOutbox","getStepAttemptTerminatedOutboxIdentity","stepId","workspaceId","projectId","attempt","logOutcome","rows","select","from","innerJoin","id","where","limit","step","Error","writeStepRestartEnqueuedOutbox","failedStepId","failedStepAttempt","restartFromStepId","feedback"],"mappings":"AAAA,SAEEA,2BAA2B,EAC3BC,iCAAiC,EACjCC,+BAA+B,QAC1B,6BAA6B;AACpC,SAAQC,EAAE,QAAO,cAAc;AAE/B,SAAQC,yBAAyB,QAAO,sBAAsB;AAC9D,SAAQC,aAAa,QAAO,8BAA8B;AAC1D,SAAQC,KAAK,QAAO,qBAAqB;AACzC,SAAQC,wBAAwB,QAAO,cAAc;AAErD,iFAAiF;AACjF,uFAAuF;AACvF,qFAAqF;AACrF,yEAAyE;AACzE,OAAO,eAAeC,2BACpBC,EAAM,EACNC,MAA+E;IAE/E,MAAMC,WAAW,MAAMJ,yBAAyBG,OAAOE,KAAK,EAAEH;IAE9D,MAAML,0BAA0BK,IAAI;QAClCI,MAAMb;QACNc,SAAS;YACPF,OAAOF,OAAOE,KAAK;YACnBG,gBAAgBL,OAAOK,cAAc;YACrCC,eAAeL,SAASK,aAAa;YACrCC,sBAAsBN,SAASM,oBAAoB;YACnDC,QAAQR,OAAOQ,MAAM;QACvB;IACF;AACF;AAEA,OAAO,eAAeC,iCACpBV,EAAM,EACNC,MAKC;IAED,MAAMC,WAAW,MAAMS,uCAAuCX,IAAIC,OAAOW,MAAM;IAE/E,MAAMjB,0BAA0BK,IAAI;QAClCI,MAAMZ;QACNa,SAAS;YACPF,OAAOD,SAASC,KAAK;YACrBI,eAAeL,SAASK,aAAa;YACrCC,sBAAsBN,SAASM,oBAAoB;YACnDK,aAAaX,SAASW,WAAW;YACjCC,WAAWZ,SAASY,SAAS;YAC7BF,QAAQX,OAAOW,MAAM;YACrBG,SAASd,OAAOc,OAAO;YACvBN,QAAQR,OAAOQ,MAAM;YACrBO,YAAYf,OAAOe,UAAU;QAC/B;IACF;AACF;AAEA,eAAeL,uCACbX,EAAM,EACNY,MAAc;IAQd,MAAMK,OAAO,MAAMjB,GAChBkB,MAAM,CAAC;QACNf,OAAOP,cAAcO,KAAK;IAC5B,GACCgB,IAAI,CAACtB,OACLuB,SAAS,CAACxB,eAAeF,GAAGG,MAAMS,cAAc,EAAEV,cAAcyB,EAAE,GAClEC,KAAK,CAAC5B,GAAGG,MAAMwB,EAAE,EAAET,SACnBW,KAAK,CAAC;IACT,MAAMC,OAAOP,IAAI,CAAC,EAAE;IACpB,IAAI,CAACO,MAAM;QACT,MAAM,IAAIC,MAAM,CAAC,mDAAmD,EAAEb,OAAO,UAAU,CAAC;IAC1F;IAEA,OAAOd,yBAAyB0B,KAAKrB,KAAK,EAAEH;AAC9C;AAEA,gFAAgF;AAChF,wEAAwE;AACxE,OAAO,eAAe0B,+BACpB1B,EAAM,EACNC,MAMC;IAED,MAAMC,WAAW,MAAMJ,yBAAyBG,OAAOE,KAAK,EAAEH;IAE9D,MAAML,0BAA0BK,IAAI;QAClCI,MAAMX;QACNY,SAAS;YACPF,OAAOF,OAAOE,KAAK;YACnBI,eAAeL,SAASK,aAAa;YACrCC,sBAAsBN,SAASM,oBAAoB;YACnDmB,cAAc1B,OAAO0B,YAAY;YACjCC,mBAAmB3B,OAAO2B,iBAAiB;YAC3CC,mBAAmB5B,OAAO4B,iBAAiB;YAC3CC,UAAU7B,OAAO6B,QAAQ;QAC3B;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/db/workflow-runs/outbox.ts"],"sourcesContent":["import {\n type LogOutcomeDto,\n WORKFLOWS_JOB_EXECUTION_QUEUED,\n WORKFLOWS_JOB_EXECUTION_TERMINATED,\n WORKFLOWS_JOB_STEPS_SETTLED,\n WORKFLOWS_STEP_ATTEMPT_TERMINATED,\n WORKFLOWS_STEP_RESTART_ENQUEUED,\n} from '@shipfox/api-workflows-dto';\nimport {eq} from 'drizzle-orm';\nimport type {JobStatusReason} from '#core/entities/job.js';\nimport type {JobExecutionStatus} from '#core/entities/job-execution.js';\nimport type {Tx} from '../db.js';\nimport {writeWorkflowsOutboxEvent} from '../outbox-writes.js';\nimport {jobExecutions} from '../schema/job-executions.js';\nimport {steps} from '../schema/steps.js';\nimport {getWorkflowContextForJob} from './shared.js';\n\nexport async function writeJobExecutionQueuedOutbox(\n tx: Tx,\n params: {\n jobId: string;\n jobExecutionId: string;\n requiredLabels: string[];\n queuedAt: Date;\n },\n): Promise<void> {\n const identity = await getWorkflowContextForJob(params.jobId, tx);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_JOB_EXECUTION_QUEUED,\n payload: {\n jobId: params.jobId,\n jobExecutionId: params.jobExecutionId,\n workflowRunId: identity.workflowRunId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n workspaceId: identity.workspaceId,\n projectId: identity.projectId,\n requiredLabels: params.requiredLabels,\n queuedAt: params.queuedAt.toISOString(),\n },\n });\n}\n\nexport async function writeJobExecutionTerminatedOutbox(\n tx: Tx,\n params: {\n jobId: string;\n jobExecutionId: string;\n status: JobExecutionStatus;\n statusReason: JobStatusReason | null;\n statusReasonMessage?: string | null | undefined;\n },\n): Promise<void> {\n if (\n params.status !== 'succeeded' &&\n params.status !== 'failed' &&\n params.status !== 'cancelled'\n ) {\n throw new Error(`Cannot enqueue terminal job execution event for status ${params.status}`);\n }\n const identity = await getWorkflowContextForJob(params.jobId, tx);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_JOB_EXECUTION_TERMINATED,\n payload: {\n jobId: params.jobId,\n jobExecutionId: params.jobExecutionId,\n workflowRunId: identity.workflowRunId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n status: params.status,\n statusReason: params.statusReason,\n statusReasonMessage: params.statusReasonMessage ?? null,\n },\n });\n}\n\n// Enqueue the steps-settled signal in the same transaction as the final per-step\n// result, so per-step execution observes it exactly once (the outbox is at-least-once;\n// the job workflow dedupes the signal). Drives the Temporal JOB_FINISHED_SIGNAL; the\n// job's terminal fact is emitted separately by updateJobStatusAtVersion.\nexport async function writeJobStepsSettledOutbox(\n tx: Tx,\n params: {jobId: string; jobExecutionId: string; status: 'succeeded' | 'failed'},\n): Promise<void> {\n const identity = await getWorkflowContextForJob(params.jobId, tx);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_JOB_STEPS_SETTLED,\n payload: {\n jobId: params.jobId,\n jobExecutionId: params.jobExecutionId,\n workflowRunId: identity.workflowRunId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n status: params.status,\n },\n });\n}\n\nexport async function writeStepAttemptTerminatedOutbox(\n tx: Tx,\n params: {\n stepId: string;\n attempt: number;\n status: 'succeeded' | 'failed' | 'cancelled';\n logOutcome: LogOutcomeDto;\n },\n): Promise<void> {\n const identity = await getStepAttemptTerminatedOutboxIdentity(tx, params.stepId);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_STEP_ATTEMPT_TERMINATED,\n payload: {\n jobId: identity.jobId,\n workflowRunId: identity.workflowRunId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n workspaceId: identity.workspaceId,\n projectId: identity.projectId,\n stepId: params.stepId,\n attempt: params.attempt,\n status: params.status,\n logOutcome: params.logOutcome,\n },\n });\n}\n\nasync function getStepAttemptTerminatedOutboxIdentity(\n tx: Tx,\n stepId: string,\n): Promise<{\n jobId: string;\n workflowRunId: string;\n workflowRunAttemptId: string;\n workspaceId: string;\n projectId: string;\n}> {\n const rows = await tx\n .select({\n jobId: jobExecutions.jobId,\n })\n .from(steps)\n .innerJoin(jobExecutions, eq(steps.jobExecutionId, jobExecutions.id))\n .where(eq(steps.id, stepId))\n .limit(1);\n const step = rows[0];\n if (!step) {\n throw new Error(`Cannot enqueue step-attempt-terminated event: step ${stepId} not found`);\n }\n\n return getWorkflowContextForJob(step.jobId, tx);\n}\n\n// Enqueue the durable audit record of a restart, in the same transaction as the\n// rewind. Looks up the workflow run id like writeJobStepsSettledOutbox.\nexport async function writeStepRestartEnqueuedOutbox(\n tx: Tx,\n params: {\n jobId: string;\n failedStepId: string;\n failedStepAttempt: number;\n restartFromStepId: string;\n feedback: string;\n },\n): Promise<void> {\n const identity = await getWorkflowContextForJob(params.jobId, tx);\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_STEP_RESTART_ENQUEUED,\n payload: {\n jobId: params.jobId,\n workflowRunId: identity.workflowRunId,\n workflowRunAttemptId: identity.workflowRunAttemptId,\n failedStepId: params.failedStepId,\n failedStepAttempt: params.failedStepAttempt,\n restartFromStepId: params.restartFromStepId,\n feedback: params.feedback,\n },\n });\n}\n"],"names":["WORKFLOWS_JOB_EXECUTION_QUEUED","WORKFLOWS_JOB_EXECUTION_TERMINATED","WORKFLOWS_JOB_STEPS_SETTLED","WORKFLOWS_STEP_ATTEMPT_TERMINATED","WORKFLOWS_STEP_RESTART_ENQUEUED","eq","writeWorkflowsOutboxEvent","jobExecutions","steps","getWorkflowContextForJob","writeJobExecutionQueuedOutbox","tx","params","identity","jobId","type","payload","jobExecutionId","workflowRunId","workflowRunAttemptId","workspaceId","projectId","requiredLabels","queuedAt","toISOString","writeJobExecutionTerminatedOutbox","status","Error","statusReason","statusReasonMessage","writeJobStepsSettledOutbox","writeStepAttemptTerminatedOutbox","getStepAttemptTerminatedOutboxIdentity","stepId","attempt","logOutcome","rows","select","from","innerJoin","id","where","limit","step","writeStepRestartEnqueuedOutbox","failedStepId","failedStepAttempt","restartFromStepId","feedback"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-graph.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/run-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAChE,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,UAAU,CAAC;AAEjC,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EAEpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAC,KAAK,WAAW,EAAE,KAAK,KAAK,EAAO,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAC,KAAK,YAAY,EAAQ,MAAM,oBAAoB,CAAC;AAE5D,KAAK,gCAAgC,GAAG,IAAI,CAAC,oBAAoB,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG;IAC3F,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC;CAC5E,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAC;IACxD,QAAQ,CAAC,eAAe,CAAC,EACrB,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,gCAAgC,GAAG,SAAS,CAAC,GAC9D,SAAS,CAAC;IACd,QAAQ,CAAC,WAAW,CAAC,EACjB,CAAC,CAAC,MAAM,EAAE;QACR,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;QACpB,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;KACvC,KAAK,SAAS,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAC,EAAE,CAAC,GACtD,SAAS,CAAC;CACf;AAED,wBAAsB,2BAA2B,CAC/C,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,aAAa,GAAG,WAAW,GAAG,cAAc,CAAC,CAAC;IACrF,QAAQ,CAAC,kBAAkB,EAAE;QAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;IAC7E,QAAQ,CAAC,gBAAgB,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC/D,GACA,OAAO,CAAC,IAAI,CAAC,CAyDf"}
1
+ {"version":3,"file":"run-graph.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/run-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAChE,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,UAAU,CAAC;AAEjC,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EAEpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAC,KAAK,WAAW,EAAE,KAAK,KAAK,EAAO,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAC,KAAK,YAAY,EAAQ,MAAM,oBAAoB,CAAC;AAG5D,KAAK,gCAAgC,GAAG,IAAI,CAAC,oBAAoB,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG;IAC3F,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC;CAC5E,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAC;IACxD,QAAQ,CAAC,eAAe,CAAC,EACrB,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,gCAAgC,GAAG,SAAS,CAAC,GAC9D,SAAS,CAAC;IACd,QAAQ,CAAC,WAAW,CAAC,EACjB,CAAC,CAAC,MAAM,EAAE;QACR,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;QACpB,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;KACvC,KAAK,SAAS,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAC,EAAE,CAAC,GACtD,SAAS,CAAC;CACf;AAED,wBAAsB,2BAA2B,CAC/C,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,aAAa,GAAG,WAAW,GAAG,cAAc,CAAC,CAAC;IACrF,QAAQ,CAAC,kBAAkB,EAAE;QAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;IAC7E,QAAQ,CAAC,gBAAgB,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC/D,GACA,OAAO,CAAC,IAAI,CAAC,CAyEf"}
@@ -3,6 +3,7 @@ import { writeWorkflowsOutboxEvent } from '../outbox-writes.js';
3
3
  import { jobExecutions } from '../schema/job-executions.js';
4
4
  import { jobs } from '../schema/jobs.js';
5
5
  import { steps } from '../schema/steps.js';
6
+ import { writeJobExecutionTerminatedOutbox } from './outbox.js';
6
7
  export async function persistMaterializedRunGraph(tx, params) {
7
8
  const jobRows = params.materializedJobs.length === 0 ? [] : await tx.insert(jobs).values(params.materializedJobs.map((materializedJob)=>({
8
9
  ...materializedJob.job,
@@ -19,6 +20,17 @@ export async function persistMaterializedRunGraph(tx, params) {
19
20
  ];
20
21
  });
21
22
  const jobExecutionRows = jobExecutionValues.length === 0 ? [] : await tx.insert(jobExecutions).values(jobExecutionValues).returning();
23
+ for (const jobExecution of jobExecutionRows){
24
+ if (jobExecution.status === 'succeeded' || jobExecution.status === 'failed' || jobExecution.status === 'cancelled') {
25
+ await writeJobExecutionTerminatedOutbox(tx, {
26
+ jobId: jobExecution.jobId,
27
+ jobExecutionId: jobExecution.id,
28
+ status: jobExecution.status,
29
+ statusReason: jobExecution.statusReason,
30
+ statusReasonMessage: jobExecution.statusReasonMessage
31
+ });
32
+ }
33
+ }
22
34
  const jobById = new Map(jobRows.map((job)=>[
23
35
  job.id,
24
36
  job
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/workflow-runs/run-graph.ts"],"sourcesContent":["import {WORKFLOWS_WORKFLOW_RUN_ATTEMPT_CREATED} from '@shipfox/api-workflows-dto';\nimport type {SQL} from 'drizzle-orm';\nimport type {WorkflowRun} from '#core/entities/workflow-run.js';\nimport type {Tx} from '../db.js';\nimport {writeWorkflowsOutboxEvent} from '../outbox-writes.js';\nimport {\n type JobExecutionCreateDb,\n type JobExecutionDb,\n jobExecutions,\n} from '../schema/job-executions.js';\nimport {type JobCreateDb, type JobDb, jobs} from '../schema/jobs.js';\nimport {type StepCreateDb, steps} from '../schema/steps.js';\n\ntype MaterializedRunGraphJobExecution = Omit<JobExecutionCreateDb, 'finishedAt' | 'jobId'> & {\n readonly finishedAt?: JobExecutionCreateDb['finishedAt'] | SQL | undefined;\n};\n\nexport interface MaterializedRunGraphJob {\n readonly job: Omit<JobCreateDb, 'workflowRunAttemptId'>;\n readonly createExecution?:\n | ((job: JobDb) => MaterializedRunGraphJobExecution | undefined)\n | undefined;\n readonly createSteps?:\n | ((params: {\n readonly job: JobDb;\n readonly jobExecution: JobExecutionDb;\n }) => readonly Omit<StepCreateDb, 'jobExecutionId'>[])\n | undefined;\n}\n\nexport async function persistMaterializedRunGraph(\n tx: Tx,\n params: {\n readonly run: Pick<WorkflowRun, 'id' | 'workspaceId' | 'projectId' | 'definitionId'>;\n readonly workflowRunAttempt: {readonly id: string; readonly attempt: number};\n readonly materializedJobs: readonly MaterializedRunGraphJob[];\n },\n): Promise<void> {\n const jobRows =\n params.materializedJobs.length === 0\n ? []\n : await tx\n .insert(jobs)\n .values(\n params.materializedJobs.map((materializedJob) => ({\n ...materializedJob.job,\n workflowRunAttemptId: params.workflowRunAttempt.id,\n })),\n )\n .returning();\n\n const jobExecutionValues = jobRows.flatMap((jobRow, jobIndex) => {\n const materializedJob = params.materializedJobs[jobIndex];\n const jobExecution = materializedJob?.createExecution?.(jobRow);\n return jobExecution === undefined ? [] : [{...jobExecution, jobId: jobRow.id}];\n });\n const jobExecutionRows =\n jobExecutionValues.length === 0\n ? []\n : await tx.insert(jobExecutions).values(jobExecutionValues).returning();\n\n const jobById = new Map(jobRows.map((job) => [job.id, job]));\n const materializedJobByJobId = new Map(\n jobRows.flatMap((jobRow, index) => {\n const materializedJob = params.materializedJobs[index];\n return materializedJob === undefined ? [] : [[jobRow.id, materializedJob] as const];\n }),\n );\n const stepValues = jobExecutionRows.flatMap((jobExecution) => {\n const job = jobById.get(jobExecution.jobId);\n const materializedJob = materializedJobByJobId.get(jobExecution.jobId);\n if (!job || !materializedJob) return [];\n\n return (materializedJob.createSteps?.({job, jobExecution}) ?? []).map((step) => ({\n ...step,\n jobExecutionId: jobExecution.id,\n }));\n });\n\n if (stepValues.length > 0) {\n await tx.insert(steps).values(stepValues);\n }\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_WORKFLOW_RUN_ATTEMPT_CREATED,\n payload: {\n workflowRunId: params.run.id,\n workflowRunAttemptId: params.workflowRunAttempt.id,\n attempt: params.workflowRunAttempt.attempt,\n workspaceId: params.run.workspaceId,\n projectId: params.run.projectId,\n definitionId: params.run.definitionId,\n },\n });\n}\n"],"names":["WORKFLOWS_WORKFLOW_RUN_ATTEMPT_CREATED","writeWorkflowsOutboxEvent","jobExecutions","jobs","steps","persistMaterializedRunGraph","tx","params","jobRows","materializedJobs","length","insert","values","map","materializedJob","job","workflowRunAttemptId","workflowRunAttempt","id","returning","jobExecutionValues","flatMap","jobRow","jobIndex","jobExecution","createExecution","undefined","jobId","jobExecutionRows","jobById","Map","materializedJobByJobId","index","stepValues","get","createSteps","step","jobExecutionId","type","payload","workflowRunId","run","attempt","workspaceId","projectId","definitionId"],"mappings":"AAAA,SAAQA,sCAAsC,QAAO,6BAA6B;AAIlF,SAAQC,yBAAyB,QAAO,sBAAsB;AAC9D,SAGEC,aAAa,QACR,8BAA8B;AACrC,SAAsCC,IAAI,QAAO,oBAAoB;AACrE,SAA2BC,KAAK,QAAO,qBAAqB;AAmB5D,OAAO,eAAeC,4BACpBC,EAAM,EACNC,MAIC;IAED,MAAMC,UACJD,OAAOE,gBAAgB,CAACC,MAAM,KAAK,IAC/B,EAAE,GACF,MAAMJ,GACHK,MAAM,CAACR,MACPS,MAAM,CACLL,OAAOE,gBAAgB,CAACI,GAAG,CAAC,CAACC,kBAAqB,CAAA;YAChD,GAAGA,gBAAgBC,GAAG;YACtBC,sBAAsBT,OAAOU,kBAAkB,CAACC,EAAE;QACpD,CAAA,IAEDC,SAAS;IAElB,MAAMC,qBAAqBZ,QAAQa,OAAO,CAAC,CAACC,QAAQC;QAClD,MAAMT,kBAAkBP,OAAOE,gBAAgB,CAACc,SAAS;QACzD,MAAMC,eAAeV,iBAAiBW,kBAAkBH;QACxD,OAAOE,iBAAiBE,YAAY,EAAE,GAAG;YAAC;gBAAC,GAAGF,YAAY;gBAAEG,OAAOL,OAAOJ,EAAE;YAAA;SAAE;IAChF;IACA,MAAMU,mBACJR,mBAAmBV,MAAM,KAAK,IAC1B,EAAE,GACF,MAAMJ,GAAGK,MAAM,CAACT,eAAeU,MAAM,CAACQ,oBAAoBD,SAAS;IAEzE,MAAMU,UAAU,IAAIC,IAAItB,QAAQK,GAAG,CAAC,CAACE,MAAQ;YAACA,IAAIG,EAAE;YAAEH;SAAI;IAC1D,MAAMgB,yBAAyB,IAAID,IACjCtB,QAAQa,OAAO,CAAC,CAACC,QAAQU;QACvB,MAAMlB,kBAAkBP,OAAOE,gBAAgB,CAACuB,MAAM;QACtD,OAAOlB,oBAAoBY,YAAY,EAAE,GAAG;YAAC;gBAACJ,OAAOJ,EAAE;gBAAEJ;aAAgB;SAAU;IACrF;IAEF,MAAMmB,aAAaL,iBAAiBP,OAAO,CAAC,CAACG;QAC3C,MAAMT,MAAMc,QAAQK,GAAG,CAACV,aAAaG,KAAK;QAC1C,MAAMb,kBAAkBiB,uBAAuBG,GAAG,CAACV,aAAaG,KAAK;QACrE,IAAI,CAACZ,OAAO,CAACD,iBAAiB,OAAO,EAAE;QAEvC,OAAO,AAACA,CAAAA,gBAAgBqB,WAAW,GAAG;YAACpB;YAAKS;QAAY,MAAM,EAAE,AAAD,EAAGX,GAAG,CAAC,CAACuB,OAAU,CAAA;gBAC/E,GAAGA,IAAI;gBACPC,gBAAgBb,aAAaN,EAAE;YACjC,CAAA;IACF;IAEA,IAAIe,WAAWvB,MAAM,GAAG,GAAG;QACzB,MAAMJ,GAAGK,MAAM,CAACP,OAAOQ,MAAM,CAACqB;IAChC;IAEA,MAAMhC,0BAA0BK,IAAI;QAClCgC,MAAMtC;QACNuC,SAAS;YACPC,eAAejC,OAAOkC,GAAG,CAACvB,EAAE;YAC5BF,sBAAsBT,OAAOU,kBAAkB,CAACC,EAAE;YAClDwB,SAASnC,OAAOU,kBAAkB,CAACyB,OAAO;YAC1CC,aAAapC,OAAOkC,GAAG,CAACE,WAAW;YACnCC,WAAWrC,OAAOkC,GAAG,CAACG,SAAS;YAC/BC,cAActC,OAAOkC,GAAG,CAACI,YAAY;QACvC;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/db/workflow-runs/run-graph.ts"],"sourcesContent":["import {WORKFLOWS_WORKFLOW_RUN_ATTEMPT_CREATED} from '@shipfox/api-workflows-dto';\nimport type {SQL} from 'drizzle-orm';\nimport type {WorkflowRun} from '#core/entities/workflow-run.js';\nimport type {Tx} from '../db.js';\nimport {writeWorkflowsOutboxEvent} from '../outbox-writes.js';\nimport {\n type JobExecutionCreateDb,\n type JobExecutionDb,\n jobExecutions,\n} from '../schema/job-executions.js';\nimport {type JobCreateDb, type JobDb, jobs} from '../schema/jobs.js';\nimport {type StepCreateDb, steps} from '../schema/steps.js';\nimport {writeJobExecutionTerminatedOutbox} from './outbox.js';\n\ntype MaterializedRunGraphJobExecution = Omit<JobExecutionCreateDb, 'finishedAt' | 'jobId'> & {\n readonly finishedAt?: JobExecutionCreateDb['finishedAt'] | SQL | undefined;\n};\n\nexport interface MaterializedRunGraphJob {\n readonly job: Omit<JobCreateDb, 'workflowRunAttemptId'>;\n readonly createExecution?:\n | ((job: JobDb) => MaterializedRunGraphJobExecution | undefined)\n | undefined;\n readonly createSteps?:\n | ((params: {\n readonly job: JobDb;\n readonly jobExecution: JobExecutionDb;\n }) => readonly Omit<StepCreateDb, 'jobExecutionId'>[])\n | undefined;\n}\n\nexport async function persistMaterializedRunGraph(\n tx: Tx,\n params: {\n readonly run: Pick<WorkflowRun, 'id' | 'workspaceId' | 'projectId' | 'definitionId'>;\n readonly workflowRunAttempt: {readonly id: string; readonly attempt: number};\n readonly materializedJobs: readonly MaterializedRunGraphJob[];\n },\n): Promise<void> {\n const jobRows =\n params.materializedJobs.length === 0\n ? []\n : await tx\n .insert(jobs)\n .values(\n params.materializedJobs.map((materializedJob) => ({\n ...materializedJob.job,\n workflowRunAttemptId: params.workflowRunAttempt.id,\n })),\n )\n .returning();\n\n const jobExecutionValues = jobRows.flatMap((jobRow, jobIndex) => {\n const materializedJob = params.materializedJobs[jobIndex];\n const jobExecution = materializedJob?.createExecution?.(jobRow);\n return jobExecution === undefined ? [] : [{...jobExecution, jobId: jobRow.id}];\n });\n const jobExecutionRows =\n jobExecutionValues.length === 0\n ? []\n : await tx.insert(jobExecutions).values(jobExecutionValues).returning();\n\n for (const jobExecution of jobExecutionRows) {\n if (\n jobExecution.status === 'succeeded' ||\n jobExecution.status === 'failed' ||\n jobExecution.status === 'cancelled'\n ) {\n await writeJobExecutionTerminatedOutbox(tx, {\n jobId: jobExecution.jobId,\n jobExecutionId: jobExecution.id,\n status: jobExecution.status,\n statusReason: jobExecution.statusReason,\n statusReasonMessage: jobExecution.statusReasonMessage,\n });\n }\n }\n\n const jobById = new Map(jobRows.map((job) => [job.id, job]));\n const materializedJobByJobId = new Map(\n jobRows.flatMap((jobRow, index) => {\n const materializedJob = params.materializedJobs[index];\n return materializedJob === undefined ? [] : [[jobRow.id, materializedJob] as const];\n }),\n );\n const stepValues = jobExecutionRows.flatMap((jobExecution) => {\n const job = jobById.get(jobExecution.jobId);\n const materializedJob = materializedJobByJobId.get(jobExecution.jobId);\n if (!job || !materializedJob) return [];\n\n return (materializedJob.createSteps?.({job, jobExecution}) ?? []).map((step) => ({\n ...step,\n jobExecutionId: jobExecution.id,\n }));\n });\n\n if (stepValues.length > 0) {\n await tx.insert(steps).values(stepValues);\n }\n\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_WORKFLOW_RUN_ATTEMPT_CREATED,\n payload: {\n workflowRunId: params.run.id,\n workflowRunAttemptId: params.workflowRunAttempt.id,\n attempt: params.workflowRunAttempt.attempt,\n workspaceId: params.run.workspaceId,\n projectId: params.run.projectId,\n definitionId: params.run.definitionId,\n },\n });\n}\n"],"names":["WORKFLOWS_WORKFLOW_RUN_ATTEMPT_CREATED","writeWorkflowsOutboxEvent","jobExecutions","jobs","steps","writeJobExecutionTerminatedOutbox","persistMaterializedRunGraph","tx","params","jobRows","materializedJobs","length","insert","values","map","materializedJob","job","workflowRunAttemptId","workflowRunAttempt","id","returning","jobExecutionValues","flatMap","jobRow","jobIndex","jobExecution","createExecution","undefined","jobId","jobExecutionRows","status","jobExecutionId","statusReason","statusReasonMessage","jobById","Map","materializedJobByJobId","index","stepValues","get","createSteps","step","type","payload","workflowRunId","run","attempt","workspaceId","projectId","definitionId"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-status.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/run-status.ts"],"names":[],"mappings":"AAKA,OAAO,EAA0B,KAAK,eAAe,EAAC,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACvB,MAAM,gCAAgC,CAAC;AAkBxC,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,+BAA+B;IAC9C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,OAAO,CAAC,iBAAiB,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC;IACnE,YAAY,EAAE,OAAO,CAAC,eAAe,EAAE,WAAW,GAAG,eAAe,CAAC,CAAC;IACtE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AA2ID,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CA4C7F;AAED,MAAM,WAAW,6BAA6B;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,WAAW,CAAC,CAuHtB"}
1
+ {"version":3,"file":"run-status.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/run-status.ts"],"names":[],"mappings":"AAKA,OAAO,EAA0B,KAAK,eAAe,EAAC,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACvB,MAAM,gCAAgC,CAAC;AAmBxC,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,+BAA+B;IAC9C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,OAAO,CAAC,iBAAiB,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC;IACnE,YAAY,EAAE,OAAO,CAAC,eAAe,EAAE,WAAW,GAAG,eAAe,CAAC,CAAC;IACtE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAwJD,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CA4C7F;AAED,MAAM,WAAW,6BAA6B;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,WAAW,CAAC,CAuHtB"}
@@ -12,6 +12,7 @@ import { steps } from '../schema/steps.js';
12
12
  import { workflowRunAttempts } from '../schema/workflow-run-attempts.js';
13
13
  import { toWorkflowRun, workflowRuns } from '../schema/workflow-runs.js';
14
14
  import { updateJobStatusAtVersion } from './jobs.js';
15
+ import { writeJobExecutionTerminatedOutbox } from './outbox.js';
15
16
  import { lockWorkflowRun, TERMINAL_EXECUTION_STATUSES, TERMINAL_WORKFLOW_RUN_STATUSES } from './shared.js';
16
17
  import { bulkUpdateStepStatuses } from './steps.js';
17
18
  /**
@@ -57,9 +58,20 @@ import { bulkUpdateStepStatuses } from './steps.js';
57
58
  timedOutAt: sql`now()`
58
59
  } : {}
59
60
  }).where(and(eq(jobExecutions.jobId, jobRow.id), notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES))).returning({
60
- id: jobExecutions.id
61
+ id: jobExecutions.id,
62
+ jobId: jobExecutions.jobId,
63
+ status: jobExecutions.status,
64
+ statusReason: jobExecutions.statusReason,
65
+ statusReasonMessage: jobExecutions.statusReasonMessage
61
66
  });
62
67
  for (const jobExecution of terminatedExecutions){
68
+ await writeJobExecutionTerminatedOutbox(tx, {
69
+ jobId: jobExecution.jobId,
70
+ jobExecutionId: jobExecution.id,
71
+ status: jobExecution.status,
72
+ statusReason: jobExecution.statusReason,
73
+ statusReasonMessage: jobExecution.statusReasonMessage
74
+ });
63
75
  await bulkUpdateStepStatuses({
64
76
  jobExecutionId: jobExecution.id,
65
77
  status: spec.terminalStatus
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/workflow-runs/run-status.ts"],"sourcesContent":["import {\n WORKFLOWS_WORKFLOW_RUN_CANCELLED,\n WORKFLOWS_WORKFLOW_RUN_TERMINATED,\n} from '@shipfox/api-workflows-dto';\nimport {and, asc, eq, inArray, notInArray, sql} from 'drizzle-orm';\nimport {isJobTerminal, type Job, type JobStatusReason} from '#core/entities/job.js';\nimport {\n isWorkflowRunTerminal,\n type WorkflowRun,\n type WorkflowRunStatus,\n} from '#core/entities/workflow-run.js';\nimport {WorkflowRunNotCancellableError, WorkflowRunNotFoundError} from '#core/errors.js';\nimport {recordWorkflowJobStatusChanged, recordWorkflowRunStatusChanged} from '#metrics/instance.js';\nimport {db, type Tx} from '../db.js';\nimport {writeWorkflowsOutboxEvent} from '../outbox-writes.js';\nimport {jobExecutions} from '../schema/job-executions.js';\nimport {jobs} from '../schema/jobs.js';\nimport {steps} from '../schema/steps.js';\nimport {workflowRunAttempts} from '../schema/workflow-run-attempts.js';\nimport {toWorkflowRun, workflowRuns} from '../schema/workflow-runs.js';\nimport {updateJobStatusAtVersion} from './jobs.js';\nimport {\n lockWorkflowRun,\n TERMINAL_EXECUTION_STATUSES,\n TERMINAL_WORKFLOW_RUN_STATUSES,\n} from './shared.js';\nimport {bulkUpdateStepStatuses} from './steps.js';\n\nexport interface CancelWorkflowRunParams {\n workflowRunId: string;\n}\n\nexport interface FailWorkflowRunAsTimedOutParams {\n runAttemptId: string;\n}\n\nexport interface RunTerminationSpec {\n terminalStatus: Extract<WorkflowRunStatus, 'failed' | 'cancelled'>;\n statusReason: Extract<JobStatusReason, 'timed_out' | 'run_cancelled'>;\n markExecutionTimedOut: boolean;\n emitCancelledEvent: boolean;\n}\n\n/**\n * Shared terminal transition for a run attempt. The caller locks the run and the\n * attempt (and decides how an already-terminal run is handled: timeout returns\n * idempotently, cancellation rejects), then this drives every non-terminal job,\n * execution, and step to `spec.terminalStatus`, resolves still-listening jobs,\n * flips the attempt and run, and writes the outbox. Callers record metrics after\n * the transaction commits.\n */\nasync function terminateRunAttempt(\n tx: Tx,\n params: {\n lockedRun: typeof workflowRuns.$inferSelect;\n lockedAttempt: typeof workflowRunAttempts.$inferSelect;\n spec: RunTerminationSpec;\n },\n): Promise<{run: WorkflowRun; changedJobs: Job[]}> {\n const {lockedRun, lockedAttempt, spec} = params;\n\n const runJobExecutionIds = tx\n .select({id: jobExecutions.id})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobs.workflowRunAttemptId, lockedAttempt.id));\n\n await tx\n .select({id: steps.id})\n .from(steps)\n .where(inArray(steps.jobExecutionId, runJobExecutionIds))\n .orderBy(asc(steps.jobExecutionId), asc(steps.position))\n .for('update');\n\n const jobRows = await tx\n .select()\n .from(jobs)\n .where(eq(jobs.workflowRunAttemptId, lockedAttempt.id))\n .orderBy(asc(jobs.position), asc(jobs.id))\n .for('update');\n\n const changedJobs: Job[] = [];\n for (const jobRow of jobRows) {\n if (isJobTerminal(jobRow.status)) continue;\n\n const updated = await updateJobStatusAtVersion(tx, {\n jobId: jobRow.id,\n status: spec.terminalStatus,\n expectedVersion: jobRow.version,\n statusReason: spec.statusReason,\n });\n if (updated?.changed) changedJobs.push(updated.job);\n\n if (jobRow.mode === 'listening') {\n await tx\n .update(jobs)\n .set({listenerStatus: 'resolved', resolutionReason: 'cancelled', updatedAt: new Date()})\n .where(eq(jobs.id, jobRow.id));\n }\n\n const terminatedExecutions = await tx\n .update(jobExecutions)\n .set({\n status: spec.terminalStatus,\n statusReason: spec.statusReason,\n version: sql`${jobExecutions.version} + 1`,\n updatedAt: new Date(),\n finishedAt: sql`now()`,\n ...(spec.markExecutionTimedOut ? {timedOutAt: sql`now()`} : {}),\n })\n .where(\n and(\n eq(jobExecutions.jobId, jobRow.id),\n notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES),\n ),\n )\n .returning({id: jobExecutions.id});\n for (const jobExecution of terminatedExecutions) {\n await bulkUpdateStepStatuses(\n {jobExecutionId: jobExecution.id, status: spec.terminalStatus},\n tx,\n );\n }\n }\n\n await tx\n .update(workflowRunAttempts)\n .set({\n status: spec.terminalStatus,\n version: sql`${workflowRunAttempts.version} + 1`,\n updatedAt: new Date(),\n finishedAt: sql`now()`,\n })\n .where(\n and(\n eq(workflowRunAttempts.id, lockedAttempt.id),\n notInArray(workflowRunAttempts.status, TERMINAL_WORKFLOW_RUN_STATUSES),\n ),\n );\n\n const [terminatedRunRow] = await tx\n .update(workflowRuns)\n .set({\n status: spec.terminalStatus,\n version: sql`${workflowRuns.version} + 1`,\n updatedAt: new Date(),\n finishedAt: sql`now()`,\n })\n .where(\n and(\n eq(workflowRuns.id, lockedRun.id),\n notInArray(workflowRuns.status, TERMINAL_WORKFLOW_RUN_STATUSES),\n ),\n )\n .returning();\n\n const run = toWorkflowRun(terminatedRunRow ?? lockedRun);\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_WORKFLOW_RUN_TERMINATED,\n payload: {\n workflowRunId: run.id,\n workflowRunAttemptId: lockedAttempt.id,\n projectId: run.projectId,\n status: spec.terminalStatus,\n },\n });\n if (spec.emitCancelledEvent) {\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_WORKFLOW_RUN_CANCELLED,\n payload: {\n workflowRunId: run.id,\n workflowRunAttemptId: lockedAttempt.id,\n projectId: run.projectId,\n },\n });\n }\n\n return {run, changedJobs};\n}\n\nexport async function failWorkflowRunAsTimedOut(\n params: FailWorkflowRunAsTimedOutParams,\n): Promise<WorkflowRun> {\n const result = await db().transaction(async (tx) => {\n const [lockedAttempt] = await tx\n .select()\n .from(workflowRunAttempts)\n .where(eq(workflowRunAttempts.id, params.runAttemptId))\n .limit(1)\n .for('update');\n if (!lockedAttempt) throw new WorkflowRunNotFoundError(params.runAttemptId);\n\n const lockedRun = await lockWorkflowRun(lockedAttempt.workflowRunId, tx);\n if (!lockedRun) throw new WorkflowRunNotFoundError(lockedAttempt.workflowRunId);\n if (isWorkflowRunTerminal(lockedRun.status)) {\n return {run: toWorkflowRun(lockedRun), changedJobs: [], changed: false};\n }\n\n const result = await terminateRunAttempt(tx, {\n lockedRun,\n lockedAttempt,\n spec: {\n terminalStatus: 'failed',\n statusReason: 'timed_out',\n markExecutionTimedOut: true,\n emitCancelledEvent: false,\n },\n });\n return {...result, changed: true};\n });\n\n if (result.changed) recordWorkflowRunStatusChanged(result.run.status);\n for (const job of result.changedJobs) recordWorkflowJobStatusChanged(job.status);\n return result.run;\n}\n\nexport async function cancelWorkflowRun(params: CancelWorkflowRunParams): Promise<WorkflowRun> {\n const result = await db().transaction(async (tx) => {\n const lockedRun = await lockWorkflowRun(params.workflowRunId, tx);\n\n if (!lockedRun) {\n throw new WorkflowRunNotFoundError(params.workflowRunId);\n }\n if (isWorkflowRunTerminal(lockedRun.status)) {\n throw new WorkflowRunNotCancellableError(lockedRun.id, lockedRun.status);\n }\n\n const [lockedAttempt] = await tx\n .select()\n .from(workflowRunAttempts)\n .where(\n and(\n eq(workflowRunAttempts.workflowRunId, lockedRun.id),\n eq(workflowRunAttempts.attempt, lockedRun.currentAttempt),\n ),\n )\n .limit(1)\n .for('update');\n if (!lockedAttempt) {\n throw new Error(\n `Current attempt ${lockedRun.currentAttempt} missing for run ${lockedRun.id}`,\n );\n }\n\n return terminateRunAttempt(tx, {\n lockedRun,\n lockedAttempt,\n spec: {\n terminalStatus: 'cancelled',\n statusReason: 'run_cancelled',\n markExecutionTimedOut: false,\n emitCancelledEvent: true,\n },\n });\n });\n\n recordWorkflowRunStatusChanged(result.run.status);\n for (const job of result.changedJobs) recordWorkflowJobStatusChanged(job.status);\n\n return result.run;\n}\n\nexport interface UpdateWorkflowRunStatusParams {\n workflowRunId?: string;\n workflowRunAttemptId?: string;\n status: WorkflowRunStatus;\n expectedVersion: number;\n}\n\nexport async function updateWorkflowRunStatus(\n params: UpdateWorkflowRunStatusParams,\n): Promise<WorkflowRun> {\n const result = await db().transaction(async (tx) => {\n const [attemptRef] = params.workflowRunAttemptId\n ? await tx\n .select({\n id: workflowRunAttempts.id,\n workflowRunId: workflowRunAttempts.workflowRunId,\n })\n .from(workflowRunAttempts)\n .where(eq(workflowRunAttempts.id, params.workflowRunAttemptId))\n .limit(1)\n : [];\n\n const workflowRunId = attemptRef?.workflowRunId ?? params.workflowRunId ?? '';\n const lockedRun = await lockWorkflowRun(workflowRunId, tx);\n\n if (!lockedRun) {\n throw new WorkflowRunNotFoundError(params.workflowRunId ?? params.workflowRunAttemptId ?? '');\n }\n\n const [lockedAttempt] = await tx\n .select()\n .from(workflowRunAttempts)\n .where(\n params.workflowRunAttemptId\n ? eq(workflowRunAttempts.id, params.workflowRunAttemptId)\n : and(\n eq(workflowRunAttempts.workflowRunId, lockedRun.id),\n eq(workflowRunAttempts.attempt, lockedRun.currentAttempt),\n ),\n )\n .limit(1)\n .for('update');\n\n if (!lockedAttempt) {\n throw new WorkflowRunNotFoundError(params.workflowRunId ?? params.workflowRunAttemptId ?? '');\n }\n\n const target = {run: lockedRun, attempt: lockedAttempt};\n\n const rows = await tx\n .update(workflowRunAttempts)\n .set({\n status: params.status,\n version: sql`${workflowRunAttempts.version} + 1`,\n updatedAt: new Date(),\n ...(params.status === 'running'\n ? {startedAt: sql`coalesce(${workflowRunAttempts.startedAt}, now())`}\n : {}),\n ...(isWorkflowRunTerminal(params.status) ? {finishedAt: sql`now()`} : {}),\n })\n .where(\n and(\n eq(workflowRunAttempts.id, target.attempt.id),\n eq(workflowRunAttempts.version, params.expectedVersion),\n notInArray(workflowRunAttempts.status, TERMINAL_WORKFLOW_RUN_STATUSES),\n ),\n )\n .returning();\n\n const attemptRow = rows[0];\n if (!attemptRow) {\n const existing = await tx\n .select()\n .from(workflowRunAttempts)\n .where(eq(workflowRunAttempts.id, target.attempt.id))\n .limit(1);\n const existingRow = existing[0];\n if (\n existingRow &&\n (existingRow.status === params.status || isWorkflowRunTerminal(existingRow.status))\n ) {\n return {\n run: {...toWorkflowRun(target.run), version: existingRow.version},\n changed: false,\n };\n }\n throw new Error(\n `Optimistic lock failure: run attempt ${target.attempt.id} version ${params.expectedVersion}`,\n );\n }\n\n const shouldMirror = target.run.currentAttempt === attemptRow.attempt;\n const [runRow] = shouldMirror\n ? await tx\n .update(workflowRuns)\n .set({\n status: params.status,\n version: sql`${workflowRuns.version} + 1`,\n updatedAt: new Date(),\n ...(params.status === 'running'\n ? {startedAt: sql`coalesce(${workflowRuns.startedAt}, now())`}\n : {}),\n ...(isWorkflowRunTerminal(params.status) ? {finishedAt: sql`now()`} : {}),\n })\n .where(eq(workflowRuns.id, target.run.id))\n .returning()\n : [target.run];\n\n const run = {...toWorkflowRun(runRow ?? target.run), version: attemptRow.version};\n\n if (shouldMirror && isWorkflowRunTerminal(run.status)) {\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_WORKFLOW_RUN_TERMINATED,\n payload: {\n workflowRunId: run.id,\n workflowRunAttemptId: attemptRow.id,\n projectId: run.projectId,\n status: run.status,\n },\n });\n }\n\n return {run, changed: true};\n });\n\n if (result.changed) recordWorkflowRunStatusChanged(result.run.status);\n\n return result.run;\n}\n"],"names":["WORKFLOWS_WORKFLOW_RUN_CANCELLED","WORKFLOWS_WORKFLOW_RUN_TERMINATED","and","asc","eq","inArray","notInArray","sql","isJobTerminal","isWorkflowRunTerminal","WorkflowRunNotCancellableError","WorkflowRunNotFoundError","recordWorkflowJobStatusChanged","recordWorkflowRunStatusChanged","db","writeWorkflowsOutboxEvent","jobExecutions","jobs","steps","workflowRunAttempts","toWorkflowRun","workflowRuns","updateJobStatusAtVersion","lockWorkflowRun","TERMINAL_EXECUTION_STATUSES","TERMINAL_WORKFLOW_RUN_STATUSES","bulkUpdateStepStatuses","terminateRunAttempt","tx","params","lockedRun","lockedAttempt","spec","runJobExecutionIds","select","id","from","innerJoin","jobId","where","workflowRunAttemptId","jobExecutionId","orderBy","position","for","jobRows","changedJobs","jobRow","status","updated","terminalStatus","expectedVersion","version","statusReason","changed","push","job","mode","update","set","listenerStatus","resolutionReason","updatedAt","Date","terminatedExecutions","finishedAt","markExecutionTimedOut","timedOutAt","returning","jobExecution","terminatedRunRow","run","type","payload","workflowRunId","projectId","emitCancelledEvent","failWorkflowRunAsTimedOut","result","transaction","runAttemptId","limit","cancelWorkflowRun","attempt","currentAttempt","Error","updateWorkflowRunStatus","attemptRef","target","rows","startedAt","attemptRow","existing","existingRow","shouldMirror","runRow"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/db/workflow-runs/run-status.ts"],"sourcesContent":["import {\n WORKFLOWS_WORKFLOW_RUN_CANCELLED,\n WORKFLOWS_WORKFLOW_RUN_TERMINATED,\n} from '@shipfox/api-workflows-dto';\nimport {and, asc, eq, inArray, notInArray, sql} from 'drizzle-orm';\nimport {isJobTerminal, type Job, type JobStatusReason} from '#core/entities/job.js';\nimport {\n isWorkflowRunTerminal,\n type WorkflowRun,\n type WorkflowRunStatus,\n} from '#core/entities/workflow-run.js';\nimport {WorkflowRunNotCancellableError, WorkflowRunNotFoundError} from '#core/errors.js';\nimport {recordWorkflowJobStatusChanged, recordWorkflowRunStatusChanged} from '#metrics/instance.js';\nimport {db, type Tx} from '../db.js';\nimport {writeWorkflowsOutboxEvent} from '../outbox-writes.js';\nimport {jobExecutions} from '../schema/job-executions.js';\nimport {jobs} from '../schema/jobs.js';\nimport {steps} from '../schema/steps.js';\nimport {workflowRunAttempts} from '../schema/workflow-run-attempts.js';\nimport {toWorkflowRun, workflowRuns} from '../schema/workflow-runs.js';\nimport {updateJobStatusAtVersion} from './jobs.js';\nimport {writeJobExecutionTerminatedOutbox} from './outbox.js';\nimport {\n lockWorkflowRun,\n TERMINAL_EXECUTION_STATUSES,\n TERMINAL_WORKFLOW_RUN_STATUSES,\n} from './shared.js';\nimport {bulkUpdateStepStatuses} from './steps.js';\n\nexport interface CancelWorkflowRunParams {\n workflowRunId: string;\n}\n\nexport interface FailWorkflowRunAsTimedOutParams {\n runAttemptId: string;\n}\n\nexport interface RunTerminationSpec {\n terminalStatus: Extract<WorkflowRunStatus, 'failed' | 'cancelled'>;\n statusReason: Extract<JobStatusReason, 'timed_out' | 'run_cancelled'>;\n markExecutionTimedOut: boolean;\n emitCancelledEvent: boolean;\n}\n\n/**\n * Shared terminal transition for a run attempt. The caller locks the run and the\n * attempt (and decides how an already-terminal run is handled: timeout returns\n * idempotently, cancellation rejects), then this drives every non-terminal job,\n * execution, and step to `spec.terminalStatus`, resolves still-listening jobs,\n * flips the attempt and run, and writes the outbox. Callers record metrics after\n * the transaction commits.\n */\nasync function terminateRunAttempt(\n tx: Tx,\n params: {\n lockedRun: typeof workflowRuns.$inferSelect;\n lockedAttempt: typeof workflowRunAttempts.$inferSelect;\n spec: RunTerminationSpec;\n },\n): Promise<{run: WorkflowRun; changedJobs: Job[]}> {\n const {lockedRun, lockedAttempt, spec} = params;\n\n const runJobExecutionIds = tx\n .select({id: jobExecutions.id})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .where(eq(jobs.workflowRunAttemptId, lockedAttempt.id));\n\n await tx\n .select({id: steps.id})\n .from(steps)\n .where(inArray(steps.jobExecutionId, runJobExecutionIds))\n .orderBy(asc(steps.jobExecutionId), asc(steps.position))\n .for('update');\n\n const jobRows = await tx\n .select()\n .from(jobs)\n .where(eq(jobs.workflowRunAttemptId, lockedAttempt.id))\n .orderBy(asc(jobs.position), asc(jobs.id))\n .for('update');\n\n const changedJobs: Job[] = [];\n for (const jobRow of jobRows) {\n if (isJobTerminal(jobRow.status)) continue;\n\n const updated = await updateJobStatusAtVersion(tx, {\n jobId: jobRow.id,\n status: spec.terminalStatus,\n expectedVersion: jobRow.version,\n statusReason: spec.statusReason,\n });\n if (updated?.changed) changedJobs.push(updated.job);\n\n if (jobRow.mode === 'listening') {\n await tx\n .update(jobs)\n .set({listenerStatus: 'resolved', resolutionReason: 'cancelled', updatedAt: new Date()})\n .where(eq(jobs.id, jobRow.id));\n }\n\n const terminatedExecutions = await tx\n .update(jobExecutions)\n .set({\n status: spec.terminalStatus,\n statusReason: spec.statusReason,\n version: sql`${jobExecutions.version} + 1`,\n updatedAt: new Date(),\n finishedAt: sql`now()`,\n ...(spec.markExecutionTimedOut ? {timedOutAt: sql`now()`} : {}),\n })\n .where(\n and(\n eq(jobExecutions.jobId, jobRow.id),\n notInArray(jobExecutions.status, TERMINAL_EXECUTION_STATUSES),\n ),\n )\n .returning({\n id: jobExecutions.id,\n jobId: jobExecutions.jobId,\n status: jobExecutions.status,\n statusReason: jobExecutions.statusReason,\n statusReasonMessage: jobExecutions.statusReasonMessage,\n });\n for (const jobExecution of terminatedExecutions) {\n await writeJobExecutionTerminatedOutbox(tx, {\n jobId: jobExecution.jobId,\n jobExecutionId: jobExecution.id,\n status: jobExecution.status,\n statusReason: jobExecution.statusReason,\n statusReasonMessage: jobExecution.statusReasonMessage,\n });\n await bulkUpdateStepStatuses(\n {jobExecutionId: jobExecution.id, status: spec.terminalStatus},\n tx,\n );\n }\n }\n\n await tx\n .update(workflowRunAttempts)\n .set({\n status: spec.terminalStatus,\n version: sql`${workflowRunAttempts.version} + 1`,\n updatedAt: new Date(),\n finishedAt: sql`now()`,\n })\n .where(\n and(\n eq(workflowRunAttempts.id, lockedAttempt.id),\n notInArray(workflowRunAttempts.status, TERMINAL_WORKFLOW_RUN_STATUSES),\n ),\n );\n\n const [terminatedRunRow] = await tx\n .update(workflowRuns)\n .set({\n status: spec.terminalStatus,\n version: sql`${workflowRuns.version} + 1`,\n updatedAt: new Date(),\n finishedAt: sql`now()`,\n })\n .where(\n and(\n eq(workflowRuns.id, lockedRun.id),\n notInArray(workflowRuns.status, TERMINAL_WORKFLOW_RUN_STATUSES),\n ),\n )\n .returning();\n\n const run = toWorkflowRun(terminatedRunRow ?? lockedRun);\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_WORKFLOW_RUN_TERMINATED,\n payload: {\n workflowRunId: run.id,\n workflowRunAttemptId: lockedAttempt.id,\n projectId: run.projectId,\n status: spec.terminalStatus,\n },\n });\n if (spec.emitCancelledEvent) {\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_WORKFLOW_RUN_CANCELLED,\n payload: {\n workflowRunId: run.id,\n workflowRunAttemptId: lockedAttempt.id,\n projectId: run.projectId,\n },\n });\n }\n\n return {run, changedJobs};\n}\n\nexport async function failWorkflowRunAsTimedOut(\n params: FailWorkflowRunAsTimedOutParams,\n): Promise<WorkflowRun> {\n const result = await db().transaction(async (tx) => {\n const [lockedAttempt] = await tx\n .select()\n .from(workflowRunAttempts)\n .where(eq(workflowRunAttempts.id, params.runAttemptId))\n .limit(1)\n .for('update');\n if (!lockedAttempt) throw new WorkflowRunNotFoundError(params.runAttemptId);\n\n const lockedRun = await lockWorkflowRun(lockedAttempt.workflowRunId, tx);\n if (!lockedRun) throw new WorkflowRunNotFoundError(lockedAttempt.workflowRunId);\n if (isWorkflowRunTerminal(lockedRun.status)) {\n return {run: toWorkflowRun(lockedRun), changedJobs: [], changed: false};\n }\n\n const result = await terminateRunAttempt(tx, {\n lockedRun,\n lockedAttempt,\n spec: {\n terminalStatus: 'failed',\n statusReason: 'timed_out',\n markExecutionTimedOut: true,\n emitCancelledEvent: false,\n },\n });\n return {...result, changed: true};\n });\n\n if (result.changed) recordWorkflowRunStatusChanged(result.run.status);\n for (const job of result.changedJobs) recordWorkflowJobStatusChanged(job.status);\n return result.run;\n}\n\nexport async function cancelWorkflowRun(params: CancelWorkflowRunParams): Promise<WorkflowRun> {\n const result = await db().transaction(async (tx) => {\n const lockedRun = await lockWorkflowRun(params.workflowRunId, tx);\n\n if (!lockedRun) {\n throw new WorkflowRunNotFoundError(params.workflowRunId);\n }\n if (isWorkflowRunTerminal(lockedRun.status)) {\n throw new WorkflowRunNotCancellableError(lockedRun.id, lockedRun.status);\n }\n\n const [lockedAttempt] = await tx\n .select()\n .from(workflowRunAttempts)\n .where(\n and(\n eq(workflowRunAttempts.workflowRunId, lockedRun.id),\n eq(workflowRunAttempts.attempt, lockedRun.currentAttempt),\n ),\n )\n .limit(1)\n .for('update');\n if (!lockedAttempt) {\n throw new Error(\n `Current attempt ${lockedRun.currentAttempt} missing for run ${lockedRun.id}`,\n );\n }\n\n return terminateRunAttempt(tx, {\n lockedRun,\n lockedAttempt,\n spec: {\n terminalStatus: 'cancelled',\n statusReason: 'run_cancelled',\n markExecutionTimedOut: false,\n emitCancelledEvent: true,\n },\n });\n });\n\n recordWorkflowRunStatusChanged(result.run.status);\n for (const job of result.changedJobs) recordWorkflowJobStatusChanged(job.status);\n\n return result.run;\n}\n\nexport interface UpdateWorkflowRunStatusParams {\n workflowRunId?: string;\n workflowRunAttemptId?: string;\n status: WorkflowRunStatus;\n expectedVersion: number;\n}\n\nexport async function updateWorkflowRunStatus(\n params: UpdateWorkflowRunStatusParams,\n): Promise<WorkflowRun> {\n const result = await db().transaction(async (tx) => {\n const [attemptRef] = params.workflowRunAttemptId\n ? await tx\n .select({\n id: workflowRunAttempts.id,\n workflowRunId: workflowRunAttempts.workflowRunId,\n })\n .from(workflowRunAttempts)\n .where(eq(workflowRunAttempts.id, params.workflowRunAttemptId))\n .limit(1)\n : [];\n\n const workflowRunId = attemptRef?.workflowRunId ?? params.workflowRunId ?? '';\n const lockedRun = await lockWorkflowRun(workflowRunId, tx);\n\n if (!lockedRun) {\n throw new WorkflowRunNotFoundError(params.workflowRunId ?? params.workflowRunAttemptId ?? '');\n }\n\n const [lockedAttempt] = await tx\n .select()\n .from(workflowRunAttempts)\n .where(\n params.workflowRunAttemptId\n ? eq(workflowRunAttempts.id, params.workflowRunAttemptId)\n : and(\n eq(workflowRunAttempts.workflowRunId, lockedRun.id),\n eq(workflowRunAttempts.attempt, lockedRun.currentAttempt),\n ),\n )\n .limit(1)\n .for('update');\n\n if (!lockedAttempt) {\n throw new WorkflowRunNotFoundError(params.workflowRunId ?? params.workflowRunAttemptId ?? '');\n }\n\n const target = {run: lockedRun, attempt: lockedAttempt};\n\n const rows = await tx\n .update(workflowRunAttempts)\n .set({\n status: params.status,\n version: sql`${workflowRunAttempts.version} + 1`,\n updatedAt: new Date(),\n ...(params.status === 'running'\n ? {startedAt: sql`coalesce(${workflowRunAttempts.startedAt}, now())`}\n : {}),\n ...(isWorkflowRunTerminal(params.status) ? {finishedAt: sql`now()`} : {}),\n })\n .where(\n and(\n eq(workflowRunAttempts.id, target.attempt.id),\n eq(workflowRunAttempts.version, params.expectedVersion),\n notInArray(workflowRunAttempts.status, TERMINAL_WORKFLOW_RUN_STATUSES),\n ),\n )\n .returning();\n\n const attemptRow = rows[0];\n if (!attemptRow) {\n const existing = await tx\n .select()\n .from(workflowRunAttempts)\n .where(eq(workflowRunAttempts.id, target.attempt.id))\n .limit(1);\n const existingRow = existing[0];\n if (\n existingRow &&\n (existingRow.status === params.status || isWorkflowRunTerminal(existingRow.status))\n ) {\n return {\n run: {...toWorkflowRun(target.run), version: existingRow.version},\n changed: false,\n };\n }\n throw new Error(\n `Optimistic lock failure: run attempt ${target.attempt.id} version ${params.expectedVersion}`,\n );\n }\n\n const shouldMirror = target.run.currentAttempt === attemptRow.attempt;\n const [runRow] = shouldMirror\n ? await tx\n .update(workflowRuns)\n .set({\n status: params.status,\n version: sql`${workflowRuns.version} + 1`,\n updatedAt: new Date(),\n ...(params.status === 'running'\n ? {startedAt: sql`coalesce(${workflowRuns.startedAt}, now())`}\n : {}),\n ...(isWorkflowRunTerminal(params.status) ? {finishedAt: sql`now()`} : {}),\n })\n .where(eq(workflowRuns.id, target.run.id))\n .returning()\n : [target.run];\n\n const run = {...toWorkflowRun(runRow ?? target.run), version: attemptRow.version};\n\n if (shouldMirror && isWorkflowRunTerminal(run.status)) {\n await writeWorkflowsOutboxEvent(tx, {\n type: WORKFLOWS_WORKFLOW_RUN_TERMINATED,\n payload: {\n workflowRunId: run.id,\n workflowRunAttemptId: attemptRow.id,\n projectId: run.projectId,\n status: run.status,\n },\n });\n }\n\n return {run, changed: true};\n });\n\n if (result.changed) recordWorkflowRunStatusChanged(result.run.status);\n\n return result.run;\n}\n"],"names":["WORKFLOWS_WORKFLOW_RUN_CANCELLED","WORKFLOWS_WORKFLOW_RUN_TERMINATED","and","asc","eq","inArray","notInArray","sql","isJobTerminal","isWorkflowRunTerminal","WorkflowRunNotCancellableError","WorkflowRunNotFoundError","recordWorkflowJobStatusChanged","recordWorkflowRunStatusChanged","db","writeWorkflowsOutboxEvent","jobExecutions","jobs","steps","workflowRunAttempts","toWorkflowRun","workflowRuns","updateJobStatusAtVersion","writeJobExecutionTerminatedOutbox","lockWorkflowRun","TERMINAL_EXECUTION_STATUSES","TERMINAL_WORKFLOW_RUN_STATUSES","bulkUpdateStepStatuses","terminateRunAttempt","tx","params","lockedRun","lockedAttempt","spec","runJobExecutionIds","select","id","from","innerJoin","jobId","where","workflowRunAttemptId","jobExecutionId","orderBy","position","for","jobRows","changedJobs","jobRow","status","updated","terminalStatus","expectedVersion","version","statusReason","changed","push","job","mode","update","set","listenerStatus","resolutionReason","updatedAt","Date","terminatedExecutions","finishedAt","markExecutionTimedOut","timedOutAt","returning","statusReasonMessage","jobExecution","terminatedRunRow","run","type","payload","workflowRunId","projectId","emitCancelledEvent","failWorkflowRunAsTimedOut","result","transaction","runAttemptId","limit","cancelWorkflowRun","attempt","currentAttempt","Error","updateWorkflowRunStatus","attemptRef","target","rows","startedAt","attemptRow","existing","existingRow","shouldMirror","runRow"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  export type { UpdateJobExecutionStatusAtVersionParams, UpdateJobExecutionStatusParams, } from './workflow-runs/job-executions.js';
2
- export { failJobExecutionAsTimedOut, getFirstJobExecutionByJobId, getJobExecutionById, getJobExecutionsByJobId, getJobExecutionsByWorkflowRunAttemptId, getLatestJobExecutionByJobId, recordJobExecutionQueuedAt, recordJobExecutionStartedAt, resolveJobExecutionAfterLeaseExpiry, updateJobExecutionStatus, } from './workflow-runs/job-executions.js';
2
+ export { failJobExecutionAsTimedOut, getFirstJobExecutionByJobId, getJobExecutionById, getJobExecutionsByJobId, getJobExecutionsByWorkflowRunAttemptId, getLatestJobExecutionByJobId, queueJobExecution, recordJobExecutionStartedAt, resolveJobExecutionAfterLeaseExpiry, updateJobExecutionStatus, } from './workflow-runs/job-executions.js';
3
3
  export type { EvaluateJobActivationsParams, EvaluateJobSuccessResult, JobActivationDecision, JobScope, UpdateJobStatusAtVersionParams, UpdateJobStatusParams, } from './workflow-runs/jobs.js';
4
4
  export { evaluateJobActivations, evaluateJobSuccess, getDirectDependencyJobContexts, getJobById, getJobScope, getJobsByWorkflowRunAttemptId, getJobsByWorkflowRunId, resolveJobStatusFromJobExecutions, updateJobStatus, updateJobStatusAtVersion, } from './workflow-runs/jobs.js';
5
- export { writeJobStepsSettledOutbox, writeStepAttemptTerminatedOutbox, writeStepRestartEnqueuedOutbox, } from './workflow-runs/outbox.js';
5
+ export { writeJobExecutionQueuedOutbox, writeJobExecutionTerminatedOutbox, writeJobStepsSettledOutbox, writeStepAttemptTerminatedOutbox, writeStepRestartEnqueuedOutbox, } from './workflow-runs/outbox.js';
6
6
  export type { ListWorkflowRunsParams, ListWorkflowRunsResult, WorkflowJobExecutionDepth, WorkflowJobExecutionDepthParams, WorkflowRunAggregates, WorkflowRunCursor, WorkflowRunFilters, WorkflowRunJobRawStatusCount, WorkflowRunJobStatusCount, WorkflowRunJobSummary, WorkflowRunJobSummaryTarget, WorkflowRunJobsSummary, } from './workflow-runs/queries.js';
7
7
  export { buildWorkflowRunListConditions, getJobExecutionDetail, getLatestAttempt, getWorkflowJobExecutionDepth, getWorkflowRunAggregates, getWorkflowRunAttemptById, getWorkflowRunByAttemptId, getWorkflowRunById, getWorkflowRunDetail, listRunAttempts, listWorkflowRunJobSummaries, listWorkflowRuns, listWorkflowRunsByProject, } from './workflow-runs/queries.js';
8
8
  export type { CancelWorkflowRunParams, CreateRerunWorkflowRunParams, CreateWorkflowRunParams, FailWorkflowRunAsTimedOutParams, UpdateWorkflowRunStatusParams, } from './workflow-runs/runs.js';
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-runs.d.ts","sourceRoot":"","sources":["../../src/db/workflow-runs.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,uCAAuC,EACvC,8BAA8B,GAC/B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,uBAAuB,EACvB,sCAAsC,EACtC,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,EAC3B,mCAAmC,EACnC,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,4BAA4B,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,QAAQ,EACR,8BAA8B,EAC9B,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,8BAA8B,EAC9B,UAAU,EACV,WAAW,EACX,6BAA6B,EAC7B,sBAAsB,EACtB,iCAAiC,EACjC,eAAe,EACf,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EAChC,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,+BAA+B,EAC/B,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,EAC9B,qBAAqB,EACrB,gBAAgB,EAChB,4BAA4B,EAC5B,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,2BAA2B,EAC3B,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,uBAAuB,EACvB,4BAA4B,EAC5B,uBAAuB,EACvB,+BAA+B,EAC/B,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,wBAAwB,EAAC,MAAM,2BAA2B,CAAC;AACnE,YAAY,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,0BAA0B,EAC1B,qCAAqC,EACrC,uBAAuB,EACvB,8BAA8B,EAC9B,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,+BAA+B,EAC/B,iBAAiB,EACjB,4BAA4B,EAC5B,oBAAoB,EACpB,eAAe,EACf,+BAA+B,EAC/B,uBAAuB,EACvB,WAAW,EACX,0BAA0B,EAC1B,wBAAwB,EACxB,iCAAiC,EACjC,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,eAAe,GAChB,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"workflow-runs.d.ts","sourceRoot":"","sources":["../../src/db/workflow-runs.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,uCAAuC,EACvC,8BAA8B,GAC/B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,uBAAuB,EACvB,sCAAsC,EACtC,4BAA4B,EAC5B,iBAAiB,EACjB,2BAA2B,EAC3B,mCAAmC,EACnC,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,4BAA4B,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,QAAQ,EACR,8BAA8B,EAC9B,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,8BAA8B,EAC9B,UAAU,EACV,WAAW,EACX,6BAA6B,EAC7B,sBAAsB,EACtB,iCAAiC,EACjC,eAAe,EACf,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,6BAA6B,EAC7B,iCAAiC,EACjC,0BAA0B,EAC1B,gCAAgC,EAChC,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,+BAA+B,EAC/B,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,EAC9B,qBAAqB,EACrB,gBAAgB,EAChB,4BAA4B,EAC5B,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,2BAA2B,EAC3B,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,uBAAuB,EACvB,4BAA4B,EAC5B,uBAAuB,EACvB,+BAA+B,EAC/B,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,wBAAwB,EAAC,MAAM,2BAA2B,CAAC;AACnE,YAAY,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,0BAA0B,EAC1B,qCAAqC,EACrC,uBAAuB,EACvB,8BAA8B,EAC9B,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,+BAA+B,EAC/B,iBAAiB,EACjB,4BAA4B,EAC5B,oBAAoB,EACpB,eAAe,EACf,+BAA+B,EAC/B,uBAAuB,EACvB,WAAW,EACX,0BAA0B,EAC1B,wBAAwB,EACxB,iCAAiC,EACjC,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,eAAe,GAChB,MAAM,0BAA0B,CAAC"}
@@ -1,6 +1,6 @@
1
- export { failJobExecutionAsTimedOut, getFirstJobExecutionByJobId, getJobExecutionById, getJobExecutionsByJobId, getJobExecutionsByWorkflowRunAttemptId, getLatestJobExecutionByJobId, recordJobExecutionQueuedAt, recordJobExecutionStartedAt, resolveJobExecutionAfterLeaseExpiry, updateJobExecutionStatus } from './workflow-runs/job-executions.js';
1
+ export { failJobExecutionAsTimedOut, getFirstJobExecutionByJobId, getJobExecutionById, getJobExecutionsByJobId, getJobExecutionsByWorkflowRunAttemptId, getLatestJobExecutionByJobId, queueJobExecution, recordJobExecutionStartedAt, resolveJobExecutionAfterLeaseExpiry, updateJobExecutionStatus } from './workflow-runs/job-executions.js';
2
2
  export { evaluateJobActivations, evaluateJobSuccess, getDirectDependencyJobContexts, getJobById, getJobScope, getJobsByWorkflowRunAttemptId, getJobsByWorkflowRunId, resolveJobStatusFromJobExecutions, updateJobStatus, updateJobStatusAtVersion } from './workflow-runs/jobs.js';
3
- export { writeJobStepsSettledOutbox, writeStepAttemptTerminatedOutbox, writeStepRestartEnqueuedOutbox } from './workflow-runs/outbox.js';
3
+ export { writeJobExecutionQueuedOutbox, writeJobExecutionTerminatedOutbox, writeJobStepsSettledOutbox, writeStepAttemptTerminatedOutbox, writeStepRestartEnqueuedOutbox } from './workflow-runs/outbox.js';
4
4
  export { buildWorkflowRunListConditions, getJobExecutionDetail, getLatestAttempt, getWorkflowJobExecutionDepth, getWorkflowRunAggregates, getWorkflowRunAttemptById, getWorkflowRunByAttemptId, getWorkflowRunById, getWorkflowRunDetail, listRunAttempts, listWorkflowRunJobSummaries, listWorkflowRuns, listWorkflowRunsByProject } from './workflow-runs/queries.js';
5
5
  export { cancelWorkflowRun, createRerunWorkflowRun, createWorkflowRun, failWorkflowRunAsTimedOut, loadReferencedVariables, updateWorkflowRunStatus } from './workflow-runs/runs.js';
6
6
  export { getWorkflowContextForJob } from './workflow-runs/shared.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/workflow-runs.ts"],"sourcesContent":["export type {\n UpdateJobExecutionStatusAtVersionParams,\n UpdateJobExecutionStatusParams,\n} from './workflow-runs/job-executions.js';\nexport {\n failJobExecutionAsTimedOut,\n getFirstJobExecutionByJobId,\n getJobExecutionById,\n getJobExecutionsByJobId,\n getJobExecutionsByWorkflowRunAttemptId,\n getLatestJobExecutionByJobId,\n recordJobExecutionQueuedAt,\n recordJobExecutionStartedAt,\n resolveJobExecutionAfterLeaseExpiry,\n updateJobExecutionStatus,\n} from './workflow-runs/job-executions.js';\nexport type {\n EvaluateJobActivationsParams,\n EvaluateJobSuccessResult,\n JobActivationDecision,\n JobScope,\n UpdateJobStatusAtVersionParams,\n UpdateJobStatusParams,\n} from './workflow-runs/jobs.js';\nexport {\n evaluateJobActivations,\n evaluateJobSuccess,\n getDirectDependencyJobContexts,\n getJobById,\n getJobScope,\n getJobsByWorkflowRunAttemptId,\n getJobsByWorkflowRunId,\n resolveJobStatusFromJobExecutions,\n updateJobStatus,\n updateJobStatusAtVersion,\n} from './workflow-runs/jobs.js';\nexport {\n writeJobStepsSettledOutbox,\n writeStepAttemptTerminatedOutbox,\n writeStepRestartEnqueuedOutbox,\n} from './workflow-runs/outbox.js';\nexport type {\n ListWorkflowRunsParams,\n ListWorkflowRunsResult,\n WorkflowJobExecutionDepth,\n WorkflowJobExecutionDepthParams,\n WorkflowRunAggregates,\n WorkflowRunCursor,\n WorkflowRunFilters,\n WorkflowRunJobRawStatusCount,\n WorkflowRunJobStatusCount,\n WorkflowRunJobSummary,\n WorkflowRunJobSummaryTarget,\n WorkflowRunJobsSummary,\n} from './workflow-runs/queries.js';\nexport {\n buildWorkflowRunListConditions,\n getJobExecutionDetail,\n getLatestAttempt,\n getWorkflowJobExecutionDepth,\n getWorkflowRunAggregates,\n getWorkflowRunAttemptById,\n getWorkflowRunByAttemptId,\n getWorkflowRunById,\n getWorkflowRunDetail,\n listRunAttempts,\n listWorkflowRunJobSummaries,\n listWorkflowRuns,\n listWorkflowRunsByProject,\n} from './workflow-runs/queries.js';\nexport type {\n CancelWorkflowRunParams,\n CreateRerunWorkflowRunParams,\n CreateWorkflowRunParams,\n FailWorkflowRunAsTimedOutParams,\n UpdateWorkflowRunStatusParams,\n} from './workflow-runs/runs.js';\nexport {\n cancelWorkflowRun,\n createRerunWorkflowRun,\n createWorkflowRun,\n failWorkflowRunAsTimedOut,\n loadReferencedVariables,\n updateWorkflowRunStatus,\n} from './workflow-runs/runs.js';\nexport {getWorkflowContextForJob} from './workflow-runs/shared.js';\nexport type {\n ApplyStepResultParams,\n BulkUpdateStepStatusesParams,\n CancelRemainingStepsParams,\n DispatchStepWithCompletedConfigParams,\n FinishStepAttemptParams,\n InsertRunningStepAttemptParams,\n JobExecutionFailureOrigin,\n MarkStepRunningParams,\n MarkStepSkippedParams,\n RewindStepsToPendingParams,\n StepAttemptDetail,\n} from './workflow-runs/steps.js';\nexport {\n applyStepResult,\n bulkUpdateStepStatuses,\n cancelRemainingSteps,\n countStepAttempts,\n dispatchStepWithCompletedConfig,\n finishStepAttempt,\n getJobExecutionFailureOrigin,\n getStepAttemptDetail,\n getStepAttempts,\n getStepAttemptsByJobExecutionId,\n getStepAttemptsByJobIds,\n getStepById,\n getStepByIdForJobExecution,\n getStepsByJobExecutionId,\n getStepsByJobExecutionIdForUpdate,\n getStepsByJobId,\n insertRunningStepAttempt,\n markStepRunning,\n markStepSkipped,\n rewindStepsToPending,\n settleJobFailed,\n} from './workflow-runs/steps.js';\n"],"names":["failJobExecutionAsTimedOut","getFirstJobExecutionByJobId","getJobExecutionById","getJobExecutionsByJobId","getJobExecutionsByWorkflowRunAttemptId","getLatestJobExecutionByJobId","recordJobExecutionQueuedAt","recordJobExecutionStartedAt","resolveJobExecutionAfterLeaseExpiry","updateJobExecutionStatus","evaluateJobActivations","evaluateJobSuccess","getDirectDependencyJobContexts","getJobById","getJobScope","getJobsByWorkflowRunAttemptId","getJobsByWorkflowRunId","resolveJobStatusFromJobExecutions","updateJobStatus","updateJobStatusAtVersion","writeJobStepsSettledOutbox","writeStepAttemptTerminatedOutbox","writeStepRestartEnqueuedOutbox","buildWorkflowRunListConditions","getJobExecutionDetail","getLatestAttempt","getWorkflowJobExecutionDepth","getWorkflowRunAggregates","getWorkflowRunAttemptById","getWorkflowRunByAttemptId","getWorkflowRunById","getWorkflowRunDetail","listRunAttempts","listWorkflowRunJobSummaries","listWorkflowRuns","listWorkflowRunsByProject","cancelWorkflowRun","createRerunWorkflowRun","createWorkflowRun","failWorkflowRunAsTimedOut","loadReferencedVariables","updateWorkflowRunStatus","getWorkflowContextForJob","applyStepResult","bulkUpdateStepStatuses","cancelRemainingSteps","countStepAttempts","dispatchStepWithCompletedConfig","finishStepAttempt","getJobExecutionFailureOrigin","getStepAttemptDetail","getStepAttempts","getStepAttemptsByJobExecutionId","getStepAttemptsByJobIds","getStepById","getStepByIdForJobExecution","getStepsByJobExecutionId","getStepsByJobExecutionIdForUpdate","getStepsByJobId","insertRunningStepAttempt","markStepRunning","markStepSkipped","rewindStepsToPending","settleJobFailed"],"mappings":"AAIA,SACEA,0BAA0B,EAC1BC,2BAA2B,EAC3BC,mBAAmB,EACnBC,uBAAuB,EACvBC,sCAAsC,EACtCC,4BAA4B,EAC5BC,0BAA0B,EAC1BC,2BAA2B,EAC3BC,mCAAmC,EACnCC,wBAAwB,QACnB,oCAAoC;AAS3C,SACEC,sBAAsB,EACtBC,kBAAkB,EAClBC,8BAA8B,EAC9BC,UAAU,EACVC,WAAW,EACXC,6BAA6B,EAC7BC,sBAAsB,EACtBC,iCAAiC,EACjCC,eAAe,EACfC,wBAAwB,QACnB,0BAA0B;AACjC,SACEC,0BAA0B,EAC1BC,gCAAgC,EAChCC,8BAA8B,QACzB,4BAA4B;AAenC,SACEC,8BAA8B,EAC9BC,qBAAqB,EACrBC,gBAAgB,EAChBC,4BAA4B,EAC5BC,wBAAwB,EACxBC,yBAAyB,EACzBC,yBAAyB,EACzBC,kBAAkB,EAClBC,oBAAoB,EACpBC,eAAe,EACfC,2BAA2B,EAC3BC,gBAAgB,EAChBC,yBAAyB,QACpB,6BAA6B;AAQpC,SACEC,iBAAiB,EACjBC,sBAAsB,EACtBC,iBAAiB,EACjBC,yBAAyB,EACzBC,uBAAuB,EACvBC,uBAAuB,QAClB,0BAA0B;AACjC,SAAQC,wBAAwB,QAAO,4BAA4B;AAcnE,SACEC,eAAe,EACfC,sBAAsB,EACtBC,oBAAoB,EACpBC,iBAAiB,EACjBC,+BAA+B,EAC/BC,iBAAiB,EACjBC,4BAA4B,EAC5BC,oBAAoB,EACpBC,eAAe,EACfC,+BAA+B,EAC/BC,uBAAuB,EACvBC,WAAW,EACXC,0BAA0B,EAC1BC,wBAAwB,EACxBC,iCAAiC,EACjCC,eAAe,EACfC,wBAAwB,EACxBC,eAAe,EACfC,eAAe,EACfC,oBAAoB,EACpBC,eAAe,QACV,2BAA2B"}
1
+ {"version":3,"sources":["../../src/db/workflow-runs.ts"],"sourcesContent":["export type {\n UpdateJobExecutionStatusAtVersionParams,\n UpdateJobExecutionStatusParams,\n} from './workflow-runs/job-executions.js';\nexport {\n failJobExecutionAsTimedOut,\n getFirstJobExecutionByJobId,\n getJobExecutionById,\n getJobExecutionsByJobId,\n getJobExecutionsByWorkflowRunAttemptId,\n getLatestJobExecutionByJobId,\n queueJobExecution,\n recordJobExecutionStartedAt,\n resolveJobExecutionAfterLeaseExpiry,\n updateJobExecutionStatus,\n} from './workflow-runs/job-executions.js';\nexport type {\n EvaluateJobActivationsParams,\n EvaluateJobSuccessResult,\n JobActivationDecision,\n JobScope,\n UpdateJobStatusAtVersionParams,\n UpdateJobStatusParams,\n} from './workflow-runs/jobs.js';\nexport {\n evaluateJobActivations,\n evaluateJobSuccess,\n getDirectDependencyJobContexts,\n getJobById,\n getJobScope,\n getJobsByWorkflowRunAttemptId,\n getJobsByWorkflowRunId,\n resolveJobStatusFromJobExecutions,\n updateJobStatus,\n updateJobStatusAtVersion,\n} from './workflow-runs/jobs.js';\nexport {\n writeJobExecutionQueuedOutbox,\n writeJobExecutionTerminatedOutbox,\n writeJobStepsSettledOutbox,\n writeStepAttemptTerminatedOutbox,\n writeStepRestartEnqueuedOutbox,\n} from './workflow-runs/outbox.js';\nexport type {\n ListWorkflowRunsParams,\n ListWorkflowRunsResult,\n WorkflowJobExecutionDepth,\n WorkflowJobExecutionDepthParams,\n WorkflowRunAggregates,\n WorkflowRunCursor,\n WorkflowRunFilters,\n WorkflowRunJobRawStatusCount,\n WorkflowRunJobStatusCount,\n WorkflowRunJobSummary,\n WorkflowRunJobSummaryTarget,\n WorkflowRunJobsSummary,\n} from './workflow-runs/queries.js';\nexport {\n buildWorkflowRunListConditions,\n getJobExecutionDetail,\n getLatestAttempt,\n getWorkflowJobExecutionDepth,\n getWorkflowRunAggregates,\n getWorkflowRunAttemptById,\n getWorkflowRunByAttemptId,\n getWorkflowRunById,\n getWorkflowRunDetail,\n listRunAttempts,\n listWorkflowRunJobSummaries,\n listWorkflowRuns,\n listWorkflowRunsByProject,\n} from './workflow-runs/queries.js';\nexport type {\n CancelWorkflowRunParams,\n CreateRerunWorkflowRunParams,\n CreateWorkflowRunParams,\n FailWorkflowRunAsTimedOutParams,\n UpdateWorkflowRunStatusParams,\n} from './workflow-runs/runs.js';\nexport {\n cancelWorkflowRun,\n createRerunWorkflowRun,\n createWorkflowRun,\n failWorkflowRunAsTimedOut,\n loadReferencedVariables,\n updateWorkflowRunStatus,\n} from './workflow-runs/runs.js';\nexport {getWorkflowContextForJob} from './workflow-runs/shared.js';\nexport type {\n ApplyStepResultParams,\n BulkUpdateStepStatusesParams,\n CancelRemainingStepsParams,\n DispatchStepWithCompletedConfigParams,\n FinishStepAttemptParams,\n InsertRunningStepAttemptParams,\n JobExecutionFailureOrigin,\n MarkStepRunningParams,\n MarkStepSkippedParams,\n RewindStepsToPendingParams,\n StepAttemptDetail,\n} from './workflow-runs/steps.js';\nexport {\n applyStepResult,\n bulkUpdateStepStatuses,\n cancelRemainingSteps,\n countStepAttempts,\n dispatchStepWithCompletedConfig,\n finishStepAttempt,\n getJobExecutionFailureOrigin,\n getStepAttemptDetail,\n getStepAttempts,\n getStepAttemptsByJobExecutionId,\n getStepAttemptsByJobIds,\n getStepById,\n getStepByIdForJobExecution,\n getStepsByJobExecutionId,\n getStepsByJobExecutionIdForUpdate,\n getStepsByJobId,\n insertRunningStepAttempt,\n markStepRunning,\n markStepSkipped,\n rewindStepsToPending,\n settleJobFailed,\n} from './workflow-runs/steps.js';\n"],"names":["failJobExecutionAsTimedOut","getFirstJobExecutionByJobId","getJobExecutionById","getJobExecutionsByJobId","getJobExecutionsByWorkflowRunAttemptId","getLatestJobExecutionByJobId","queueJobExecution","recordJobExecutionStartedAt","resolveJobExecutionAfterLeaseExpiry","updateJobExecutionStatus","evaluateJobActivations","evaluateJobSuccess","getDirectDependencyJobContexts","getJobById","getJobScope","getJobsByWorkflowRunAttemptId","getJobsByWorkflowRunId","resolveJobStatusFromJobExecutions","updateJobStatus","updateJobStatusAtVersion","writeJobExecutionQueuedOutbox","writeJobExecutionTerminatedOutbox","writeJobStepsSettledOutbox","writeStepAttemptTerminatedOutbox","writeStepRestartEnqueuedOutbox","buildWorkflowRunListConditions","getJobExecutionDetail","getLatestAttempt","getWorkflowJobExecutionDepth","getWorkflowRunAggregates","getWorkflowRunAttemptById","getWorkflowRunByAttemptId","getWorkflowRunById","getWorkflowRunDetail","listRunAttempts","listWorkflowRunJobSummaries","listWorkflowRuns","listWorkflowRunsByProject","cancelWorkflowRun","createRerunWorkflowRun","createWorkflowRun","failWorkflowRunAsTimedOut","loadReferencedVariables","updateWorkflowRunStatus","getWorkflowContextForJob","applyStepResult","bulkUpdateStepStatuses","cancelRemainingSteps","countStepAttempts","dispatchStepWithCompletedConfig","finishStepAttempt","getJobExecutionFailureOrigin","getStepAttemptDetail","getStepAttempts","getStepAttemptsByJobExecutionId","getStepAttemptsByJobIds","getStepById","getStepByIdForJobExecution","getStepsByJobExecutionId","getStepsByJobExecutionIdForUpdate","getStepsByJobId","insertRunningStepAttempt","markStepRunning","markStepSkipped","rewindStepsToPending","settleJobFailed"],"mappings":"AAIA,SACEA,0BAA0B,EAC1BC,2BAA2B,EAC3BC,mBAAmB,EACnBC,uBAAuB,EACvBC,sCAAsC,EACtCC,4BAA4B,EAC5BC,iBAAiB,EACjBC,2BAA2B,EAC3BC,mCAAmC,EACnCC,wBAAwB,QACnB,oCAAoC;AAS3C,SACEC,sBAAsB,EACtBC,kBAAkB,EAClBC,8BAA8B,EAC9BC,UAAU,EACVC,WAAW,EACXC,6BAA6B,EAC7BC,sBAAsB,EACtBC,iCAAiC,EACjCC,eAAe,EACfC,wBAAwB,QACnB,0BAA0B;AACjC,SACEC,6BAA6B,EAC7BC,iCAAiC,EACjCC,0BAA0B,EAC1BC,gCAAgC,EAChCC,8BAA8B,QACzB,4BAA4B;AAenC,SACEC,8BAA8B,EAC9BC,qBAAqB,EACrBC,gBAAgB,EAChBC,4BAA4B,EAC5BC,wBAAwB,EACxBC,yBAAyB,EACzBC,yBAAyB,EACzBC,kBAAkB,EAClBC,oBAAoB,EACpBC,eAAe,EACfC,2BAA2B,EAC3BC,gBAAgB,EAChBC,yBAAyB,QACpB,6BAA6B;AAQpC,SACEC,iBAAiB,EACjBC,sBAAsB,EACtBC,iBAAiB,EACjBC,yBAAyB,EACzBC,uBAAuB,EACvBC,uBAAuB,QAClB,0BAA0B;AACjC,SAAQC,wBAAwB,QAAO,4BAA4B;AAcnE,SACEC,eAAe,EACfC,sBAAsB,EACtBC,oBAAoB,EACpBC,iBAAiB,EACjBC,+BAA+B,EAC/BC,iBAAiB,EACjBC,4BAA4B,EAC5BC,oBAAoB,EACpBC,eAAe,EACfC,+BAA+B,EAC/BC,uBAAuB,EACvBC,WAAW,EACXC,0BAA0B,EAC1BC,wBAAwB,EACxBC,iCAAiC,EACjCC,eAAe,EACfC,wBAAwB,EACxBC,eAAe,EACfC,eAAe,EACfC,oBAAoB,EACpBC,eAAe,QACV,2BAA2B"}