@shipfox/api-workflows 11.0.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +100 -0
- package/README.md +75 -0
- package/dist/core/agent-defaults.d.ts +2 -1
- package/dist/core/agent-defaults.d.ts.map +1 -1
- package/dist/core/agent-defaults.js.map +1 -1
- package/dist/core/checkout.d.ts +7 -21
- package/dist/core/checkout.d.ts.map +1 -1
- package/dist/core/checkout.js +122 -41
- package/dist/core/checkout.js.map +1 -1
- package/dist/core/entities/job-execution.d.ts +8 -0
- package/dist/core/entities/job-execution.d.ts.map +1 -1
- package/dist/core/entities/job-execution.js +13 -1
- package/dist/core/entities/job-execution.js.map +1 -1
- package/dist/core/entities/job-listener-event.d.ts +2 -0
- package/dist/core/entities/job-listener-event.d.ts.map +1 -1
- package/dist/core/entities/job-listener-event.js.map +1 -1
- package/dist/core/entities/step.d.ts +13 -3
- package/dist/core/entities/step.d.ts.map +1 -1
- package/dist/core/entities/step.js +6 -0
- package/dist/core/entities/step.js.map +1 -1
- package/dist/core/entities/workflow-run-attempt.d.ts +1 -0
- package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -1
- package/dist/core/entities/workflow-run-attempt.js.map +1 -1
- package/dist/core/entities/workflow-run.d.ts +17 -0
- package/dist/core/entities/workflow-run.d.ts.map +1 -1
- package/dist/core/entities/workflow-run.js.map +1 -1
- package/dist/core/errors.d.ts +9 -2
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +10 -5
- package/dist/core/errors.js.map +1 -1
- package/dist/core/job-execution.d.ts.map +1 -1
- package/dist/core/job-execution.js +14 -8
- package/dist/core/job-execution.js.map +1 -1
- package/dist/core/job-transition/decide-job-activation.d.ts +1 -0
- package/dist/core/job-transition/decide-job-activation.d.ts.map +1 -1
- package/dist/core/job-transition/decide-job-activation.js +1 -0
- package/dist/core/job-transition/decide-job-activation.js.map +1 -1
- package/dist/core/job-transition/derive-job-success.d.ts +1 -0
- package/dist/core/job-transition/derive-job-success.d.ts.map +1 -1
- package/dist/core/job-transition/derive-job-success.js +5 -8
- package/dist/core/job-transition/derive-job-success.js.map +1 -1
- package/dist/core/listener-execution-materialization.d.ts +6 -3
- package/dist/core/listener-execution-materialization.d.ts.map +1 -1
- package/dist/core/listener-execution-materialization.js +44 -6
- package/dist/core/listener-execution-materialization.js.map +1 -1
- package/dist/core/resolve-trigger-reference.d.ts +11 -0
- package/dist/core/resolve-trigger-reference.d.ts.map +1 -0
- package/dist/core/resolve-trigger-reference.js +39 -0
- package/dist/core/resolve-trigger-reference.js.map +1 -0
- package/dist/core/run-workflow.d.ts +1 -0
- package/dist/core/run-workflow.d.ts.map +1 -1
- package/dist/core/run-workflow.js +1 -0
- package/dist/core/run-workflow.js.map +1 -1
- package/dist/core/step-config/agent.d.ts +1 -2
- package/dist/core/step-config/agent.d.ts.map +1 -1
- package/dist/core/step-config/agent.js +22 -7
- package/dist/core/step-config/agent.js.map +1 -1
- package/dist/core/step-config/assemble-run-context.d.ts +19 -8
- package/dist/core/step-config/assemble-run-context.d.ts.map +1 -1
- package/dist/core/step-config/assemble-run-context.js +51 -19
- package/dist/core/step-config/assemble-run-context.js.map +1 -1
- package/dist/core/step-config/complete-step-dispatch-config.d.ts.map +1 -1
- package/dist/core/step-config/complete-step-dispatch-config.js +72 -4
- package/dist/core/step-config/complete-step-dispatch-config.js.map +1 -1
- package/dist/core/step-config/index.d.ts +1 -0
- package/dist/core/step-config/index.d.ts.map +1 -1
- package/dist/core/step-config/index.js +1 -0
- package/dist/core/step-config/index.js.map +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.d.ts +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.d.ts.map +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.js +49 -8
- package/dist/core/step-config/materialize-job-execution-steps.js.map +1 -1
- package/dist/core/step-config/materialize-workflow-model.d.ts +3 -3
- package/dist/core/step-config/materialize-workflow-model.d.ts.map +1 -1
- package/dist/core/step-config/materialize-workflow-model.js +9 -5
- package/dist/core/step-config/materialize-workflow-model.js.map +1 -1
- package/dist/core/step-config/resolve-job-execution-name.d.ts +3 -3
- package/dist/core/step-config/resolve-job-execution-name.d.ts.map +1 -1
- package/dist/core/step-config/resolve-job-execution-name.js +24 -13
- package/dist/core/step-config/resolve-job-execution-name.js.map +1 -1
- package/dist/core/step-config/resolve-step-config.d.ts.map +1 -1
- package/dist/core/step-config/resolve-step-config.js +174 -9
- package/dist/core/step-config/resolve-step-config.js.map +1 -1
- package/dist/core/step-config/resolve-workflow-run-name.d.ts +19 -0
- package/dist/core/step-config/resolve-workflow-run-name.d.ts.map +1 -0
- package/dist/core/step-config/resolve-workflow-run-name.js +73 -0
- package/dist/core/step-config/resolve-workflow-run-name.js.map +1 -0
- package/dist/core/step-transition/decide-step-transition.js.map +1 -1
- package/dist/core/step-transition/evaluate-gate.d.ts +2 -1
- package/dist/core/step-transition/evaluate-gate.d.ts.map +1 -1
- package/dist/core/step-transition/evaluate-gate.js +5 -3
- package/dist/core/step-transition/evaluate-gate.js.map +1 -1
- package/dist/core/workflow-run-creation.d.ts +3 -0
- package/dist/core/workflow-run-creation.d.ts.map +1 -1
- package/dist/core/workflow-run-creation.js +22 -7
- package/dist/core/workflow-run-creation.js.map +1 -1
- package/dist/db/db.d.ts +278 -10
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +2 -0
- package/dist/db/db.js.map +1 -1
- package/dist/db/index.d.ts +3 -2
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +2 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/job-listener-events.d.ts +2 -0
- package/dist/db/job-listener-events.d.ts.map +1 -1
- package/dist/db/job-listener-events.js +1 -0
- package/dist/db/job-listener-events.js.map +1 -1
- package/dist/db/job-listeners.d.ts +2 -0
- package/dist/db/job-listeners.d.ts.map +1 -1
- package/dist/db/job-listeners.js +81 -21
- package/dist/db/job-listeners.js.map +1 -1
- package/dist/db/schema/job-executions.d.ts +3 -3
- package/dist/db/schema/job-executions.d.ts.map +1 -1
- package/dist/db/schema/job-executions.js +8 -4
- package/dist/db/schema/job-executions.js.map +1 -1
- package/dist/db/schema/job-listener-events.d.ts +20 -0
- package/dist/db/schema/job-listener-events.d.ts.map +1 -1
- package/dist/db/schema/job-listener-events.js +2 -0
- package/dist/db/schema/job-listener-events.js.map +1 -1
- package/dist/db/schema/step-attempts.js +2 -2
- package/dist/db/schema/step-attempts.js.map +1 -1
- package/dist/db/schema/steps.d.ts +4 -2
- package/dist/db/schema/steps.d.ts.map +1 -1
- package/dist/db/schema/steps.js +1 -1
- package/dist/db/schema/steps.js.map +1 -1
- package/dist/db/schema/workflow-run-attempts.d.ts +21 -2
- package/dist/db/schema/workflow-run-attempts.d.ts.map +1 -1
- package/dist/db/schema/workflow-run-attempts.js +2 -0
- package/dist/db/schema/workflow-run-attempts.js.map +1 -1
- package/dist/db/schema/workflow-run-counters.d.ts +43 -0
- package/dist/db/schema/workflow-run-counters.d.ts.map +1 -0
- package/dist/db/schema/workflow-run-counters.js +10 -0
- package/dist/db/schema/workflow-run-counters.js.map +1 -0
- package/dist/db/schema/workflow-runs.d.ts +54 -1
- package/dist/db/schema/workflow-runs.d.ts.map +1 -1
- package/dist/db/schema/workflow-runs.js +10 -2
- package/dist/db/schema/workflow-runs.js.map +1 -1
- package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
- package/dist/db/workflow-runs/job-executions.js +35 -14
- package/dist/db/workflow-runs/job-executions.js.map +1 -1
- package/dist/db/workflow-runs/jobs.d.ts +2 -0
- package/dist/db/workflow-runs/jobs.d.ts.map +1 -1
- package/dist/db/workflow-runs/jobs.js +9 -5
- package/dist/db/workflow-runs/jobs.js.map +1 -1
- package/dist/db/workflow-runs/queries.d.ts +51 -0
- package/dist/db/workflow-runs/queries.d.ts.map +1 -1
- package/dist/db/workflow-runs/queries.js +82 -2
- package/dist/db/workflow-runs/queries.js.map +1 -1
- package/dist/db/workflow-runs/run-create.d.ts +1 -0
- package/dist/db/workflow-runs/run-create.d.ts.map +1 -1
- package/dist/db/workflow-runs/run-create.js +159 -32
- package/dist/db/workflow-runs/run-create.js.map +1 -1
- package/dist/db/workflow-runs/run-rerun.d.ts.map +1 -1
- package/dist/db/workflow-runs/run-rerun.js +13 -5
- package/dist/db/workflow-runs/run-rerun.js.map +1 -1
- package/dist/db/workflow-runs/shared.d.ts +1 -0
- package/dist/db/workflow-runs/shared.d.ts.map +1 -1
- package/dist/db/workflow-runs/shared.js +2 -1
- package/dist/db/workflow-runs/shared.js.map +1 -1
- package/dist/db/workflow-runs/steps.js +3 -3
- package/dist/db/workflow-runs/steps.js.map +1 -1
- package/dist/db/workflow-runs.d.ts +4 -3
- package/dist/db/workflow-runs.d.ts.map +1 -1
- package/dist/db/workflow-runs.js +3 -2
- package/dist/db/workflow-runs.js.map +1 -1
- package/dist/metrics/instance.d.ts +1 -0
- package/dist/metrics/instance.d.ts.map +1 -1
- package/dist/metrics/instance.js +9 -0
- package/dist/metrics/instance.js.map +1 -1
- package/dist/presentation/dto/checkout-token.d.ts +1 -0
- package/dist/presentation/dto/checkout-token.d.ts.map +1 -1
- package/dist/presentation/dto/checkout-token.js +1 -0
- package/dist/presentation/dto/checkout-token.js.map +1 -1
- package/dist/presentation/dto/index.d.ts +1 -1
- package/dist/presentation/dto/index.d.ts.map +1 -1
- package/dist/presentation/dto/index.js +1 -1
- package/dist/presentation/dto/index.js.map +1 -1
- package/dist/presentation/dto/step.d.ts.map +1 -1
- package/dist/presentation/dto/step.js +2 -2
- package/dist/presentation/dto/step.js.map +1 -1
- package/dist/presentation/dto/workflow-run.d.ts +3 -1
- package/dist/presentation/dto/workflow-run.d.ts.map +1 -1
- package/dist/presentation/dto/workflow-run.js +34 -0
- package/dist/presentation/dto/workflow-run.js.map +1 -1
- package/dist/presentation/inter-module.d.ts.map +1 -1
- package/dist/presentation/inter-module.js +31 -3
- package/dist/presentation/inter-module.js.map +1 -1
- package/dist/presentation/routes/checkout-token.d.ts +1 -1
- package/dist/presentation/routes/checkout-token.d.ts.map +1 -1
- package/dist/presentation/routes/checkout-token.js +32 -20
- package/dist/presentation/routes/checkout-token.js.map +1 -1
- package/dist/presentation/routes/leased-step.d.ts +2 -0
- package/dist/presentation/routes/leased-step.d.ts.map +1 -1
- package/dist/presentation/routes/leased-step.js +2 -1
- package/dist/presentation/routes/leased-step.js.map +1 -1
- package/dist/presentation/routes/list-runs.d.ts.map +1 -1
- package/dist/presentation/routes/list-runs.js +9 -3
- package/dist/presentation/routes/list-runs.js.map +1 -1
- package/dist/presentation/routes/project-access.d.ts +1 -0
- package/dist/presentation/routes/project-access.d.ts.map +1 -1
- package/dist/presentation/routes/report-step.d.ts.map +1 -1
- package/dist/presentation/routes/report-step.js +9 -2
- package/dist/presentation/routes/report-step.js.map +1 -1
- package/dist/presentation/subscribers/on-job-steps-settled.js +1 -1
- package/dist/presentation/subscribers/on-job-steps-settled.js.map +1 -1
- package/dist/presentation/subscribers/on-runner-job-claimed.d.ts.map +1 -1
- package/dist/presentation/subscribers/on-runner-job-claimed.js +21 -0
- package/dist/presentation/subscribers/on-runner-job-claimed.js.map +1 -1
- package/dist/temporal/activities/index.d.ts.map +1 -1
- package/dist/temporal/activities/index.js +2 -1
- package/dist/temporal/activities/index.js.map +1 -1
- package/dist/temporal/activities/orchestration-activities.d.ts +1 -0
- package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
- package/dist/temporal/activities/orchestration-activities.js.map +1 -1
- package/dist/temporal/constants.d.ts +1 -0
- package/dist/temporal/constants.d.ts.map +1 -1
- package/dist/temporal/constants.js +1 -0
- package/dist/temporal/constants.js.map +1 -1
- package/dist/temporal/index.d.ts +1 -1
- package/dist/temporal/index.d.ts.map +1 -1
- package/dist/temporal/index.js +1 -1
- package/dist/temporal/index.js.map +1 -1
- package/dist/temporal/workflows/index.bundle.js +82 -43
- package/dist/temporal/workflows/index.d.ts +1 -1
- package/dist/temporal/workflows/index.d.ts.map +1 -1
- package/dist/temporal/workflows/index.js +1 -1
- package/dist/temporal/workflows/index.js.map +1 -1
- package/dist/temporal/workflows/job-execution-orchestration.d.ts +5 -0
- package/dist/temporal/workflows/job-execution-orchestration.d.ts.map +1 -1
- package/dist/temporal/workflows/job-execution-orchestration.js +77 -43
- package/dist/temporal/workflows/job-execution-orchestration.js.map +1 -1
- package/dist/temporal/workflows/test-env.d.ts +5 -1
- package/dist/temporal/workflows/test-env.d.ts.map +1 -1
- package/dist/temporal/workflows/test-env.js +32 -11
- package/dist/temporal/workflows/test-env.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0000_initial.sql +14 -2
- package/drizzle/0001_windy_sunfire.sql +1 -0
- package/drizzle/meta/0000_snapshot.json +93 -1
- package/drizzle/meta/0001_snapshot.json +1711 -0
- package/drizzle/meta/_journal.json +2 -2
- package/package.json +21 -21
- package/src/core/agent-defaults.ts +2 -1
- package/src/core/checkout.test.ts +378 -67
- package/src/core/checkout.ts +142 -59
- package/src/core/entities/job-execution.test.ts +21 -0
- package/src/core/entities/job-execution.ts +24 -0
- package/src/core/entities/job-listener-event.ts +3 -0
- package/src/core/entities/step.ts +15 -3
- package/src/core/entities/workflow-run-attempt.ts +1 -0
- package/src/core/entities/workflow-run.ts +16 -0
- package/src/core/errors.ts +21 -7
- package/src/core/job-execution.ts +27 -4
- package/src/core/job-transition/decide-job-activation.test.ts +4 -0
- package/src/core/job-transition/decide-job-activation.ts +2 -0
- package/src/core/job-transition/derive-job-success.test.ts +12 -0
- package/src/core/job-transition/derive-job-success.ts +6 -9
- package/src/core/listener-execution-materialization.test.ts +2 -0
- package/src/core/listener-execution-materialization.ts +57 -11
- package/src/core/resolve-trigger-reference.test.ts +160 -0
- package/src/core/resolve-trigger-reference.ts +53 -0
- package/src/core/run-workflow.ts +2 -0
- package/src/core/step-config/agent.ts +29 -12
- package/src/core/step-config/assemble-run-context.test.ts +149 -6
- package/src/core/step-config/assemble-run-context.ts +87 -25
- package/src/core/step-config/complete-step-dispatch-config.test.ts +125 -2
- package/src/core/step-config/complete-step-dispatch-config.ts +83 -1
- package/src/core/step-config/index.ts +7 -0
- package/src/core/step-config/materialize-job-execution-steps.test.ts +250 -1
- package/src/core/step-config/materialize-job-execution-steps.ts +57 -10
- package/src/core/step-config/materialize-workflow-model.test.ts +212 -4
- package/src/core/step-config/materialize-workflow-model.ts +33 -28
- package/src/core/step-config/resolve-job-execution-name.test.ts +37 -15
- package/src/core/step-config/resolve-job-execution-name.ts +30 -15
- package/src/core/step-config/resolve-step-config.ts +175 -10
- package/src/core/step-config/resolve-workflow-run-name.test.ts +115 -0
- package/src/core/step-config/resolve-workflow-run-name.ts +108 -0
- package/src/core/step-transition/decide-step-transition.ts +2 -2
- package/src/core/step-transition/evaluate-gate.test.ts +8 -0
- package/src/core/step-transition/evaluate-gate.ts +8 -1
- package/src/core/workflow-run-creation.test.ts +7 -4
- package/src/core/workflow-run-creation.ts +13 -7
- package/src/db/db.ts +2 -0
- package/src/db/index.ts +6 -0
- package/src/db/job-listener-events.test.ts +19 -0
- package/src/db/job-listener-events.ts +3 -0
- package/src/db/job-listeners.test.ts +187 -5
- package/src/db/job-listeners.ts +122 -30
- package/src/db/schema/job-executions.ts +12 -5
- package/src/db/schema/job-listener-events.ts +3 -0
- package/src/db/schema/step-attempts.ts +2 -2
- package/src/db/schema/steps.ts +2 -1
- package/src/db/schema/workflow-run-attempts.ts +2 -0
- package/src/db/schema/workflow-run-counters.ts +13 -0
- package/src/db/schema/workflow-runs.ts +11 -2
- package/src/db/workflow-runs/job-executions.ts +37 -15
- package/src/db/workflow-runs/jobs.ts +17 -4
- package/src/db/workflow-runs/queries.test.ts +206 -0
- package/src/db/workflow-runs/queries.ts +146 -2
- package/src/db/workflow-runs/run-create.test.ts +606 -8
- package/src/db/workflow-runs/run-create.ts +185 -40
- package/src/db/workflow-runs/run-rerun.test.ts +61 -2
- package/src/db/workflow-runs/run-rerun.ts +15 -5
- package/src/db/workflow-runs/shared.ts +2 -0
- package/src/db/workflow-runs/steps.ts +3 -3
- package/src/db/workflow-runs.ts +7 -0
- package/src/metrics/instance.ts +14 -0
- package/src/presentation/dto/checkout-token.test.ts +19 -9
- package/src/presentation/dto/checkout-token.ts +2 -1
- package/src/presentation/dto/index.ts +1 -1
- package/src/presentation/dto/job.test.ts +9 -0
- package/src/presentation/dto/step.test.ts +12 -0
- package/src/presentation/dto/step.ts +5 -2
- package/src/presentation/dto/workflow-run.ts +44 -2
- package/src/presentation/inter-module.test.ts +165 -0
- package/src/presentation/inter-module.ts +38 -4
- package/src/presentation/routes/checkout-token.test.ts +357 -142
- package/src/presentation/routes/checkout-token.ts +56 -26
- package/src/presentation/routes/get-run.test.ts +2 -0
- package/src/presentation/routes/get-step-secrets.test.ts +7 -2
- package/src/presentation/routes/leased-step.ts +9 -1
- package/src/presentation/routes/list-runs.test.ts +57 -0
- package/src/presentation/routes/list-runs.ts +8 -3
- package/src/presentation/routes/report-step.test.ts +25 -0
- package/src/presentation/routes/report-step.ts +10 -2
- package/src/presentation/subscribers/on-job-steps-settled.ts +1 -1
- package/src/presentation/subscribers/on-runner-job-claimed.test.ts +49 -0
- package/src/presentation/subscribers/on-runner-job-claimed.ts +22 -0
- package/src/temporal/activities/index.ts +1 -0
- package/src/temporal/activities/orchestration-activities.ts +1 -0
- package/src/temporal/constants.ts +1 -0
- package/src/temporal/index.ts +1 -0
- package/src/temporal/workflows/index.ts +1 -0
- package/src/temporal/workflows/job-execution-orchestration.test.ts +142 -6
- package/src/temporal/workflows/job-execution-orchestration.ts +99 -50
- package/src/temporal/workflows/run-orchestration.test.ts +1 -1
- package/src/temporal/workflows/test-env.ts +50 -13
- package/test/factories/project.ts +2 -0
- package/test/factories/workflow-model.ts +80 -26
- package/test/factories/workflow-run.ts +4 -1
- package/test/fixtures/agent-inter-module.ts +2 -1
- package/test/fixtures/job-with-steps.ts +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/drizzle/0001_agent_tool_materialization.sql +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { WORKFLOW_MODEL_CHECKOUT_TARGET_FIELDS } from '@shipfox/api-definitions-dto';
|
|
1
2
|
import { capTraceEntries } from '@shipfox/expression';
|
|
2
3
|
import { resolveAgentStepConfig } from './agent.js';
|
|
3
|
-
import { freezeStepField } from './fields.js';
|
|
4
|
+
import { freezeStepField, resolveStepField } from './fields.js';
|
|
4
5
|
import { resolveRunStepConfig } from './run.js';
|
|
5
6
|
export async function resolveStepConfig(params) {
|
|
6
7
|
const context = evaluationContext(params);
|
|
@@ -35,6 +36,7 @@ export async function resolveStepConfig(params) {
|
|
|
35
36
|
async function buildStepConfig(params) {
|
|
36
37
|
const gate = gateConfigForStep(params.step);
|
|
37
38
|
const outputs = outputsConfigForStep(params.step);
|
|
39
|
+
const workingDirectory = resolveWorkingDirectoryConfig(params);
|
|
38
40
|
const runStep = runStepOrNull(params.step);
|
|
39
41
|
const isRunStep = runStep !== null;
|
|
40
42
|
if (isRunStep) {
|
|
@@ -44,14 +46,39 @@ async function buildStepConfig(params) {
|
|
|
44
46
|
});
|
|
45
47
|
return {
|
|
46
48
|
config: {
|
|
49
|
+
...workingDirectory.config,
|
|
47
50
|
...run.config,
|
|
48
51
|
...gate,
|
|
49
52
|
...outputs
|
|
50
53
|
},
|
|
51
|
-
configPlan: run.configPlan,
|
|
52
|
-
diagnostics:
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
configPlan: mergeConfigPlans(run.configPlan, workingDirectory.configPlan),
|
|
55
|
+
diagnostics: [
|
|
56
|
+
...workingDirectory.diagnostics,
|
|
57
|
+
...run.diagnostics
|
|
58
|
+
],
|
|
59
|
+
trace: [
|
|
60
|
+
...workingDirectory.trace,
|
|
61
|
+
...run.trace
|
|
62
|
+
],
|
|
63
|
+
hasTemplates: run.hasTemplates || workingDirectory.hasTemplates
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const checkoutStep = checkoutStepOrNull(params.step);
|
|
67
|
+
if (checkoutStep !== null) {
|
|
68
|
+
const checkout = resolveCheckoutStepConfig({
|
|
69
|
+
...params,
|
|
70
|
+
step: checkoutStep
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
config: {
|
|
74
|
+
...checkout.config,
|
|
75
|
+
...gate,
|
|
76
|
+
...outputs
|
|
77
|
+
},
|
|
78
|
+
configPlan: checkout.configPlan === undefined ? null : checkout.configPlan,
|
|
79
|
+
diagnostics: checkout.diagnostics,
|
|
80
|
+
trace: checkout.trace,
|
|
81
|
+
hasTemplates: checkout.hasTemplates
|
|
55
82
|
};
|
|
56
83
|
}
|
|
57
84
|
const agentStep = agentStepOrNull(params.step);
|
|
@@ -62,14 +89,89 @@ async function buildStepConfig(params) {
|
|
|
62
89
|
});
|
|
63
90
|
return {
|
|
64
91
|
config: {
|
|
92
|
+
...workingDirectory.config,
|
|
65
93
|
...agent.config,
|
|
66
94
|
...gate,
|
|
67
95
|
...outputs
|
|
68
96
|
},
|
|
69
|
-
configPlan: agent.configPlan,
|
|
70
|
-
diagnostics:
|
|
71
|
-
|
|
72
|
-
|
|
97
|
+
configPlan: mergeConfigPlans(agent.configPlan, workingDirectory.configPlan),
|
|
98
|
+
diagnostics: [
|
|
99
|
+
...workingDirectory.diagnostics,
|
|
100
|
+
...agent.diagnostics
|
|
101
|
+
],
|
|
102
|
+
trace: [
|
|
103
|
+
...workingDirectory.trace,
|
|
104
|
+
...agent.trace
|
|
105
|
+
],
|
|
106
|
+
hasTemplates: agent.hasTemplates || workingDirectory.hasTemplates
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function resolveWorkingDirectoryConfig(params) {
|
|
110
|
+
const value = params.step.workingDirectory;
|
|
111
|
+
const template = params.step.templates?.workingDirectory;
|
|
112
|
+
if (value === undefined) {
|
|
113
|
+
return {
|
|
114
|
+
config: {},
|
|
115
|
+
configPlan: undefined,
|
|
116
|
+
diagnostics: [],
|
|
117
|
+
trace: [],
|
|
118
|
+
hasTemplates: template !== undefined
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (template === undefined || params.mode === 'authored') {
|
|
122
|
+
return {
|
|
123
|
+
config: {
|
|
124
|
+
working_directory: value
|
|
125
|
+
},
|
|
126
|
+
configPlan: undefined,
|
|
127
|
+
diagnostics: [],
|
|
128
|
+
trace: [],
|
|
129
|
+
hasTemplates: template !== undefined
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const resolved = resolveStepField({
|
|
133
|
+
field: 'step.working_directory',
|
|
134
|
+
template: {
|
|
135
|
+
segments: template
|
|
136
|
+
},
|
|
137
|
+
context: params.context,
|
|
138
|
+
definitionId: params.definitionId,
|
|
139
|
+
errorField: 'step.working_directory'
|
|
140
|
+
});
|
|
141
|
+
const trace = resolved.trace.map((entry)=>({
|
|
142
|
+
...entry,
|
|
143
|
+
field: 'step.working_directory'
|
|
144
|
+
}));
|
|
145
|
+
const diagnostics = resolved.diagnostics.map((diagnostic)=>({
|
|
146
|
+
...diagnostic,
|
|
147
|
+
field: 'step.working_directory'
|
|
148
|
+
}));
|
|
149
|
+
if (resolved.kind === 'residual') {
|
|
150
|
+
return {
|
|
151
|
+
config: {},
|
|
152
|
+
configPlan: {
|
|
153
|
+
working_directory: resolved.field
|
|
154
|
+
},
|
|
155
|
+
diagnostics,
|
|
156
|
+
trace,
|
|
157
|
+
hasTemplates: true
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
config: {
|
|
162
|
+
working_directory: resolved.value
|
|
163
|
+
},
|
|
164
|
+
configPlan: undefined,
|
|
165
|
+
diagnostics,
|
|
166
|
+
trace,
|
|
167
|
+
hasTemplates: true
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function mergeConfigPlans(primary, secondary) {
|
|
171
|
+
if (secondary === undefined) return primary;
|
|
172
|
+
return {
|
|
173
|
+
...primary ?? {},
|
|
174
|
+
...secondary
|
|
73
175
|
};
|
|
74
176
|
}
|
|
75
177
|
function evaluationContext(params) {
|
|
@@ -86,6 +188,69 @@ function agentStepOrNull(step) {
|
|
|
86
188
|
const isAgentStep = step.kind === 'agent';
|
|
87
189
|
return isAgentStep ? step : null;
|
|
88
190
|
}
|
|
191
|
+
function checkoutStepOrNull(step) {
|
|
192
|
+
const isCheckoutStep = step.kind === 'checkout';
|
|
193
|
+
return isCheckoutStep ? step : null;
|
|
194
|
+
}
|
|
195
|
+
function resolveCheckoutStepConfig(params) {
|
|
196
|
+
const checkout = params.step.checkout;
|
|
197
|
+
const config = {
|
|
198
|
+
fetch_depth: checkout.fetchDepth,
|
|
199
|
+
permissions: checkout.permissions,
|
|
200
|
+
persist_credentials: checkout.persistCredentials,
|
|
201
|
+
...checkout.force === undefined ? {} : {
|
|
202
|
+
force: checkout.force
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
const checkoutConfig = config;
|
|
206
|
+
const checkoutPlan = {};
|
|
207
|
+
const diagnostics = [];
|
|
208
|
+
const trace = [];
|
|
209
|
+
let hasTemplates = false;
|
|
210
|
+
for (const [key, field] of WORKFLOW_MODEL_CHECKOUT_TARGET_FIELDS){
|
|
211
|
+
const template = checkout.templates?.[key];
|
|
212
|
+
if (template !== undefined) hasTemplates = true;
|
|
213
|
+
const value = checkout[key];
|
|
214
|
+
if (value === undefined) continue;
|
|
215
|
+
if (template === undefined || params.mode === 'authored') {
|
|
216
|
+
checkoutConfig[key] = value;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const resolved = resolveStepField({
|
|
220
|
+
field,
|
|
221
|
+
template: {
|
|
222
|
+
segments: template
|
|
223
|
+
},
|
|
224
|
+
context: params.context,
|
|
225
|
+
definitionId: params.definitionId,
|
|
226
|
+
errorField: field
|
|
227
|
+
});
|
|
228
|
+
trace.push(...resolved.trace.map((entry)=>({
|
|
229
|
+
...entry,
|
|
230
|
+
field
|
|
231
|
+
})));
|
|
232
|
+
diagnostics.push(...resolved.diagnostics.map((diagnostic)=>({
|
|
233
|
+
...diagnostic,
|
|
234
|
+
field
|
|
235
|
+
})));
|
|
236
|
+
if (resolved.kind === 'residual') {
|
|
237
|
+
checkoutPlan[key] = resolved.field;
|
|
238
|
+
} else {
|
|
239
|
+
checkoutConfig[key] = resolved.value;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
config: {
|
|
244
|
+
checkout: config
|
|
245
|
+
},
|
|
246
|
+
configPlan: Object.keys(checkoutPlan).length === 0 ? undefined : {
|
|
247
|
+
checkout: checkoutPlan
|
|
248
|
+
},
|
|
249
|
+
diagnostics,
|
|
250
|
+
trace,
|
|
251
|
+
hasTemplates
|
|
252
|
+
};
|
|
253
|
+
}
|
|
89
254
|
function gateConfigForStep(step) {
|
|
90
255
|
const hasGate = step.gate !== undefined;
|
|
91
256
|
return hasGate ? {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/step-config/resolve-step-config.ts"],"sourcesContent":["import type {WorkflowEnvTemplates, WorkflowModel} from '@shipfox/api-definitions-dto';\nimport {\n type AvailabilitySite,\n capTraceEntries,\n type EvaluationTraceLimitEntry,\n type WorkflowExpressionEvaluationContext,\n} from '@shipfox/expression';\nimport type {AgentDefaultsResolver} from '#core/agent-defaults.js';\nimport type {\n AgentToolMaterializationContext,\n AgentToolMaterializationSnapshot,\n} from '#core/agent-tools.js';\nimport type {StepConfigDispatchPlan} from '#core/entities/step.js';\nimport {resolveAgentStepConfig} from './agent.js';\nimport {\n freezeStepField,\n type StepConfigField,\n type WorkflowStepEvaluationTraceEntry,\n type WorkflowStepTemplateDiagnostic,\n} from './fields.js';\nimport {resolveRunStepConfig, type StepConfigMode} from './run.js';\nimport type {WorkflowEvaluationContext} from './workflow-evaluation-context.js';\n\ntype WorkflowModelJob = WorkflowModel['jobs'][number];\ntype WorkflowModelStep = WorkflowModelJob['steps'][number];\ntype WorkflowModelRunStep = Extract<WorkflowModelStep, {kind: 'run'}>;\ntype WorkflowModelAgentStep = Extract<WorkflowModelStep, {kind: 'agent'}>;\n\nexport type {StepConfigField, WorkflowStepTemplateDiagnostic};\n\nexport interface ResolvedStepConfig {\n readonly config: Record<string, unknown>;\n readonly configPlan: StepConfigDispatchPlan | null;\n readonly authoredConfig: Record<string, unknown> | null;\n readonly name?: string;\n readonly diagnostics: readonly WorkflowStepTemplateDiagnostic[];\n readonly trace: readonly (WorkflowStepEvaluationTraceEntry | EvaluationTraceLimitEntry)[];\n}\n\nexport interface ResolveStepConfigParams {\n readonly jobKey: string;\n readonly step: WorkflowModelStep;\n readonly workflowEnv: WorkflowModel['env'];\n readonly workflowEnvTemplates: WorkflowEnvTemplates | undefined;\n readonly jobEnv: WorkflowModelJob['env'];\n readonly jobEnvTemplates: WorkflowEnvTemplates | undefined;\n readonly context: WorkflowExpressionEvaluationContext;\n readonly site: AvailabilitySite;\n readonly resolveAgentDefaults?: AgentDefaultsResolver | undefined;\n readonly definitionId: string;\n readonly agentToolContext?: AgentToolMaterializationContext | undefined;\n readonly agentToolSnapshot?: AgentToolMaterializationSnapshot | null | undefined;\n}\n\ntype BuildStepConfigParams = ResolveStepConfigParams & {readonly mode: StepConfigMode};\n\ninterface BuiltStepConfig {\n readonly config: Record<string, unknown>;\n readonly configPlan: StepConfigDispatchPlan | null;\n readonly diagnostics: readonly WorkflowStepTemplateDiagnostic[];\n readonly trace: readonly WorkflowStepEvaluationTraceEntry[];\n readonly hasTemplates: boolean;\n}\n\nexport async function resolveStepConfig(\n params: ResolveStepConfigParams,\n): Promise<ResolvedStepConfig> {\n const context = evaluationContext(params);\n const effective = await buildStepConfig({...params, context, mode: 'effective'});\n const authoredConfig = effective.hasTemplates\n ? (await buildStepConfig({...params, context, mode: 'authored'})).config\n : null;\n const name = resolveStepName(params.step, context, params.definitionId);\n\n return {\n config: effective.config,\n configPlan: effective.configPlan,\n authoredConfig,\n ...(name.value === undefined || name.value === '' ? {} : {name: name.value}),\n diagnostics: [...effective.diagnostics, ...name.diagnostics],\n trace: capTraceEntries([...effective.trace, ...name.trace]),\n };\n}\n\nasync function buildStepConfig(\n params: Omit<BuildStepConfigParams, 'context'> & {readonly context: WorkflowEvaluationContext},\n): Promise<BuiltStepConfig> {\n const gate = gateConfigForStep(params.step);\n const outputs = outputsConfigForStep(params.step);\n const runStep = runStepOrNull(params.step);\n const isRunStep = runStep !== null;\n\n if (isRunStep) {\n const run = resolveRunStepConfig({...params, step: runStep});\n return {\n config: {...run.config, ...gate, ...outputs},\n configPlan: run.configPlan,\n diagnostics: run.diagnostics,\n trace: run.trace,\n hasTemplates: run.hasTemplates,\n };\n }\n\n const agentStep = agentStepOrNull(params.step);\n if (agentStep === null) throw new Error(`Unsupported workflow step kind: ${params.step.kind}`);\n\n const agent = await resolveAgentStepConfig({...params, step: agentStep});\n return {\n config: {...agent.config, ...gate, ...outputs},\n configPlan: agent.configPlan,\n diagnostics: agent.diagnostics,\n trace: agent.trace,\n hasTemplates: agent.hasTemplates,\n };\n}\n\nfunction evaluationContext(params: {\n readonly context: WorkflowExpressionEvaluationContext;\n readonly site: AvailabilitySite;\n}): WorkflowEvaluationContext {\n return {site: params.site, values: params.context};\n}\n\nfunction runStepOrNull(step: WorkflowModelStep): WorkflowModelRunStep | null {\n const isRunStep = step.kind === 'run';\n return isRunStep ? step : null;\n}\n\nfunction agentStepOrNull(step: WorkflowModelStep): WorkflowModelAgentStep | null {\n const isAgentStep = step.kind === 'agent';\n return isAgentStep ? step : null;\n}\n\nfunction gateConfigForStep(step: WorkflowModelStep): Record<string, unknown> {\n const hasGate = step.gate !== undefined;\n return hasGate ? {gate: stepGateConfig(step.gate)} : {};\n}\n\nfunction outputsConfigForStep(step: WorkflowModelStep): Record<string, unknown> {\n const hasOutputs = step.outputs !== undefined;\n return hasOutputs ? {outputs: step.outputs} : {};\n}\n\nfunction resolveStepName(\n step: WorkflowModelStep,\n context: WorkflowEvaluationContext,\n definitionId: string,\n): {\n readonly value: string | undefined;\n readonly diagnostics: readonly WorkflowStepTemplateDiagnostic[];\n readonly trace: readonly WorkflowStepEvaluationTraceEntry[];\n} {\n const hasName = step.name !== undefined;\n if (!hasName) return {value: undefined, diagnostics: [], trace: []};\n\n const hasNameTemplate = step.templates?.name !== undefined;\n if (!hasNameTemplate) return {value: step.name, diagnostics: [], trace: []};\n\n const resolved = freezeStepField({\n field: 'step.name',\n template: {segments: step.templates.name},\n context,\n definitionId,\n errorField: 'step.name',\n });\n return {\n value: resolved.value,\n diagnostics: resolved.diagnostics.map((diagnostic) => ({...diagnostic, field: 'step.name'})),\n trace: resolved.trace.map((entry) => ({...entry, field: 'step.name'})),\n };\n}\n\nfunction stepGateConfig(gate: NonNullable<WorkflowModelStep['gate']>): Record<string, unknown> {\n const hasSuccess = gate.success !== undefined;\n const hasOnFailure = gate.onFailure !== undefined;\n const hasOnFailureFeedback = gate.onFailure?.feedback !== undefined;\n const hasOnFailureFeedbackTemplate = gate.onFailure?.feedbackTemplate !== undefined;\n\n return {\n ...(hasSuccess\n ? {\n success: {\n language: gate.success.language,\n check: gate.success.check,\n source: gate.success.source,\n },\n }\n : {}),\n ...(hasOnFailure\n ? {\n on_failure: {\n restart_from: gate.onFailure.restartFrom,\n ...(hasOnFailureFeedback ? {feedback: gate.onFailure.feedback} : {}),\n ...(hasOnFailureFeedbackTemplate\n ? {feedback_template: {segments: gate.onFailure.feedbackTemplate}}\n : {}),\n },\n }\n : {}),\n };\n}\n"],"names":["capTraceEntries","resolveAgentStepConfig","freezeStepField","resolveRunStepConfig","resolveStepConfig","params","context","evaluationContext","effective","buildStepConfig","mode","authoredConfig","hasTemplates","config","name","resolveStepName","step","definitionId","configPlan","value","undefined","diagnostics","trace","gate","gateConfigForStep","outputs","outputsConfigForStep","runStep","runStepOrNull","isRunStep","run","agentStep","agentStepOrNull","Error","kind","agent","site","values","isAgentStep","hasGate","stepGateConfig","hasOutputs","hasName","hasNameTemplate","templates","resolved","field","template","segments","errorField","map","diagnostic","entry","hasSuccess","success","hasOnFailure","onFailure","hasOnFailureFeedback","feedback","hasOnFailureFeedbackTemplate","feedbackTemplate","language","check","source","on_failure","restart_from","restartFrom","feedback_template"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/step-config/resolve-step-config.ts"],"sourcesContent":["import type {WorkflowEnvTemplates, WorkflowModel} from '@shipfox/api-definitions-dto';\nimport {WORKFLOW_MODEL_CHECKOUT_TARGET_FIELDS} from '@shipfox/api-definitions-dto';\nimport {\n type AvailabilitySite,\n capTraceEntries,\n type EvaluationTraceLimitEntry,\n type WorkflowExpressionEvaluationContext,\n} from '@shipfox/expression';\nimport type {AgentDefaultsResolver} from '#core/agent-defaults.js';\nimport type {\n AgentToolMaterializationContext,\n AgentToolMaterializationSnapshot,\n} from '#core/agent-tools.js';\nimport type {StepConfigDispatchPlan} from '#core/entities/step.js';\nimport {resolveAgentStepConfig} from './agent.js';\nimport {\n freezeStepField,\n resolveStepField,\n type StepConfigField,\n type WorkflowStepEvaluationTraceEntry,\n type WorkflowStepTemplateDiagnostic,\n} from './fields.js';\nimport {resolveRunStepConfig, type StepConfigMode} from './run.js';\nimport type {WorkflowEvaluationContext} from './workflow-evaluation-context.js';\n\ntype WorkflowModelJob = WorkflowModel['jobs'][number];\ntype WorkflowModelStep = WorkflowModelJob['steps'][number];\ntype WorkflowModelRunStep = Extract<WorkflowModelStep, {kind: 'run'}>;\ntype WorkflowModelAgentStep = Extract<WorkflowModelStep, {kind: 'agent'}>;\ntype WorkflowModelCheckoutStep = Extract<WorkflowModelStep, {kind: 'checkout'}>;\n\nexport type {StepConfigField, WorkflowStepTemplateDiagnostic};\n\nexport interface ResolvedStepConfig {\n readonly config: Record<string, unknown>;\n readonly configPlan: StepConfigDispatchPlan | null;\n readonly authoredConfig: Record<string, unknown> | null;\n readonly name?: string;\n readonly diagnostics: readonly WorkflowStepTemplateDiagnostic[];\n readonly trace: readonly (WorkflowStepEvaluationTraceEntry | EvaluationTraceLimitEntry)[];\n}\n\nexport interface ResolveStepConfigParams {\n readonly jobKey: string;\n readonly step: WorkflowModelStep;\n readonly workflowEnv: WorkflowModel['env'];\n readonly workflowEnvTemplates: WorkflowEnvTemplates | undefined;\n readonly jobEnv: WorkflowModelJob['env'];\n readonly jobEnvTemplates: WorkflowEnvTemplates | undefined;\n readonly context: WorkflowExpressionEvaluationContext;\n readonly site: AvailabilitySite;\n readonly resolveAgentDefaults?: AgentDefaultsResolver | undefined;\n readonly definitionId: string;\n readonly agentToolContext?: AgentToolMaterializationContext | undefined;\n readonly agentToolSnapshot?: AgentToolMaterializationSnapshot | null | undefined;\n}\n\ntype BuildStepConfigParams = ResolveStepConfigParams & {readonly mode: StepConfigMode};\n\ninterface BuiltStepConfig {\n readonly config: Record<string, unknown>;\n readonly configPlan: StepConfigDispatchPlan | null;\n readonly diagnostics: readonly WorkflowStepTemplateDiagnostic[];\n readonly trace: readonly WorkflowStepEvaluationTraceEntry[];\n readonly hasTemplates: boolean;\n}\n\ninterface WorkingDirectoryConfig {\n readonly config: Record<string, unknown>;\n readonly configPlan: Pick<StepConfigDispatchPlan, 'working_directory'> | undefined;\n readonly diagnostics: readonly WorkflowStepTemplateDiagnostic[];\n readonly trace: readonly WorkflowStepEvaluationTraceEntry[];\n readonly hasTemplates: boolean;\n}\n\ninterface CheckoutConfig {\n readonly config: Record<string, unknown>;\n readonly configPlan: Pick<StepConfigDispatchPlan, 'checkout'> | undefined;\n readonly diagnostics: readonly WorkflowStepTemplateDiagnostic[];\n readonly trace: readonly WorkflowStepEvaluationTraceEntry[];\n readonly hasTemplates: boolean;\n}\n\nexport async function resolveStepConfig(\n params: ResolveStepConfigParams,\n): Promise<ResolvedStepConfig> {\n const context = evaluationContext(params);\n const effective = await buildStepConfig({...params, context, mode: 'effective'});\n const authoredConfig = effective.hasTemplates\n ? (await buildStepConfig({...params, context, mode: 'authored'})).config\n : null;\n const name = resolveStepName(params.step, context, params.definitionId);\n\n return {\n config: effective.config,\n configPlan: effective.configPlan,\n authoredConfig,\n ...(name.value === undefined || name.value === '' ? {} : {name: name.value}),\n diagnostics: [...effective.diagnostics, ...name.diagnostics],\n trace: capTraceEntries([...effective.trace, ...name.trace]),\n };\n}\n\nasync function buildStepConfig(\n params: Omit<BuildStepConfigParams, 'context'> & {readonly context: WorkflowEvaluationContext},\n): Promise<BuiltStepConfig> {\n const gate = gateConfigForStep(params.step);\n const outputs = outputsConfigForStep(params.step);\n const workingDirectory = resolveWorkingDirectoryConfig(params);\n const runStep = runStepOrNull(params.step);\n const isRunStep = runStep !== null;\n\n if (isRunStep) {\n const run = resolveRunStepConfig({...params, step: runStep});\n return {\n config: {...workingDirectory.config, ...run.config, ...gate, ...outputs},\n configPlan: mergeConfigPlans(run.configPlan, workingDirectory.configPlan),\n diagnostics: [...workingDirectory.diagnostics, ...run.diagnostics],\n trace: [...workingDirectory.trace, ...run.trace],\n hasTemplates: run.hasTemplates || workingDirectory.hasTemplates,\n };\n }\n\n const checkoutStep = checkoutStepOrNull(params.step);\n if (checkoutStep !== null) {\n const checkout = resolveCheckoutStepConfig({...params, step: checkoutStep});\n return {\n config: {\n ...checkout.config,\n ...gate,\n ...outputs,\n },\n configPlan: checkout.configPlan === undefined ? null : checkout.configPlan,\n diagnostics: checkout.diagnostics,\n trace: checkout.trace,\n hasTemplates: checkout.hasTemplates,\n };\n }\n\n const agentStep = agentStepOrNull(params.step);\n if (agentStep === null) throw new Error(`Unsupported workflow step kind: ${params.step.kind}`);\n\n const agent = await resolveAgentStepConfig({...params, step: agentStep});\n return {\n config: {...workingDirectory.config, ...agent.config, ...gate, ...outputs},\n configPlan: mergeConfigPlans(agent.configPlan, workingDirectory.configPlan),\n diagnostics: [...workingDirectory.diagnostics, ...agent.diagnostics],\n trace: [...workingDirectory.trace, ...agent.trace],\n hasTemplates: agent.hasTemplates || workingDirectory.hasTemplates,\n };\n}\n\nfunction resolveWorkingDirectoryConfig(\n params: Omit<BuildStepConfigParams, 'context'> & {readonly context: WorkflowEvaluationContext},\n): WorkingDirectoryConfig {\n const value = params.step.workingDirectory;\n const template = params.step.templates?.workingDirectory;\n if (value === undefined) {\n return {\n config: {},\n configPlan: undefined,\n diagnostics: [],\n trace: [],\n hasTemplates: template !== undefined,\n };\n }\n\n if (template === undefined || params.mode === 'authored') {\n return {\n config: {working_directory: value},\n configPlan: undefined,\n diagnostics: [],\n trace: [],\n hasTemplates: template !== undefined,\n };\n }\n\n const resolved = resolveStepField({\n field: 'step.working_directory',\n template: {segments: template},\n context: params.context,\n definitionId: params.definitionId,\n errorField: 'step.working_directory',\n });\n const trace = resolved.trace.map((entry) => ({\n ...entry,\n field: 'step.working_directory' as const,\n }));\n const diagnostics = resolved.diagnostics.map((diagnostic) => ({\n ...diagnostic,\n field: 'step.working_directory' as const,\n }));\n if (resolved.kind === 'residual') {\n return {\n config: {},\n configPlan: {working_directory: resolved.field},\n diagnostics,\n trace,\n hasTemplates: true,\n };\n }\n\n return {\n config: {working_directory: resolved.value},\n configPlan: undefined,\n diagnostics,\n trace,\n hasTemplates: true,\n };\n}\n\nfunction mergeConfigPlans(\n primary: StepConfigDispatchPlan | null,\n secondary: Pick<StepConfigDispatchPlan, 'working_directory'> | undefined,\n): StepConfigDispatchPlan | null {\n if (secondary === undefined) return primary;\n return {...(primary ?? {}), ...secondary};\n}\n\nfunction evaluationContext(params: {\n readonly context: WorkflowExpressionEvaluationContext;\n readonly site: AvailabilitySite;\n}): WorkflowEvaluationContext {\n return {site: params.site, values: params.context};\n}\n\nfunction runStepOrNull(step: WorkflowModelStep): WorkflowModelRunStep | null {\n const isRunStep = step.kind === 'run';\n return isRunStep ? step : null;\n}\n\nfunction agentStepOrNull(step: WorkflowModelStep): WorkflowModelAgentStep | null {\n const isAgentStep = step.kind === 'agent';\n return isAgentStep ? step : null;\n}\n\nfunction checkoutStepOrNull(step: WorkflowModelStep): WorkflowModelCheckoutStep | null {\n const isCheckoutStep = step.kind === 'checkout';\n return isCheckoutStep ? step : null;\n}\n\nfunction resolveCheckoutStepConfig(\n params: Omit<BuildStepConfigParams, 'context' | 'step'> & {\n readonly context: WorkflowEvaluationContext;\n readonly step: WorkflowModelCheckoutStep;\n },\n): CheckoutConfig {\n const checkout = params.step.checkout;\n const config: Record<string, unknown> = {\n fetch_depth: checkout.fetchDepth,\n permissions: checkout.permissions,\n persist_credentials: checkout.persistCredentials,\n ...(checkout.force === undefined ? {} : {force: checkout.force}),\n };\n const checkoutConfig: Record<string, unknown> = config;\n const checkoutPlan: NonNullable<StepConfigDispatchPlan['checkout']> = {};\n const diagnostics: WorkflowStepTemplateDiagnostic[] = [];\n const trace: WorkflowStepEvaluationTraceEntry[] = [];\n let hasTemplates = false;\n\n for (const [key, field] of WORKFLOW_MODEL_CHECKOUT_TARGET_FIELDS) {\n const template = checkout.templates?.[key];\n if (template !== undefined) hasTemplates = true;\n\n const value = checkout[key];\n if (value === undefined) continue;\n\n if (template === undefined || params.mode === 'authored') {\n checkoutConfig[key] = value;\n continue;\n }\n\n const resolved = resolveStepField({\n field,\n template: {segments: template},\n context: params.context,\n definitionId: params.definitionId,\n errorField: field,\n });\n trace.push(...resolved.trace.map((entry) => ({...entry, field})));\n diagnostics.push(...resolved.diagnostics.map((diagnostic) => ({...diagnostic, field})));\n\n if (resolved.kind === 'residual') {\n checkoutPlan[key] = resolved.field;\n } else {\n checkoutConfig[key] = resolved.value;\n }\n }\n\n return {\n config: {checkout: config},\n configPlan: Object.keys(checkoutPlan).length === 0 ? undefined : {checkout: checkoutPlan},\n diagnostics,\n trace,\n hasTemplates,\n };\n}\n\nfunction gateConfigForStep(step: WorkflowModelStep): Record<string, unknown> {\n const hasGate = step.gate !== undefined;\n return hasGate ? {gate: stepGateConfig(step.gate)} : {};\n}\n\nfunction outputsConfigForStep(step: WorkflowModelStep): Record<string, unknown> {\n const hasOutputs = step.outputs !== undefined;\n return hasOutputs ? {outputs: step.outputs} : {};\n}\n\nfunction resolveStepName(\n step: WorkflowModelStep,\n context: WorkflowEvaluationContext,\n definitionId: string,\n): {\n readonly value: string | undefined;\n readonly diagnostics: readonly WorkflowStepTemplateDiagnostic[];\n readonly trace: readonly WorkflowStepEvaluationTraceEntry[];\n} {\n const hasName = step.name !== undefined;\n if (!hasName) return {value: undefined, diagnostics: [], trace: []};\n\n const hasNameTemplate = step.templates?.name !== undefined;\n if (!hasNameTemplate) return {value: step.name, diagnostics: [], trace: []};\n\n const resolved = freezeStepField({\n field: 'step.name',\n template: {segments: step.templates.name},\n context,\n definitionId,\n errorField: 'step.name',\n });\n return {\n value: resolved.value,\n diagnostics: resolved.diagnostics.map((diagnostic) => ({...diagnostic, field: 'step.name'})),\n trace: resolved.trace.map((entry) => ({...entry, field: 'step.name'})),\n };\n}\n\nfunction stepGateConfig(gate: NonNullable<WorkflowModelStep['gate']>): Record<string, unknown> {\n const hasSuccess = gate.success !== undefined;\n const hasOnFailure = gate.onFailure !== undefined;\n const hasOnFailureFeedback = gate.onFailure?.feedback !== undefined;\n const hasOnFailureFeedbackTemplate = gate.onFailure?.feedbackTemplate !== undefined;\n\n return {\n ...(hasSuccess\n ? {\n success: {\n language: gate.success.language,\n check: gate.success.check,\n source: gate.success.source,\n },\n }\n : {}),\n ...(hasOnFailure\n ? {\n on_failure: {\n restart_from: gate.onFailure.restartFrom,\n ...(hasOnFailureFeedback ? {feedback: gate.onFailure.feedback} : {}),\n ...(hasOnFailureFeedbackTemplate\n ? {feedback_template: {segments: gate.onFailure.feedbackTemplate}}\n : {}),\n },\n }\n : {}),\n };\n}\n"],"names":["WORKFLOW_MODEL_CHECKOUT_TARGET_FIELDS","capTraceEntries","resolveAgentStepConfig","freezeStepField","resolveStepField","resolveRunStepConfig","resolveStepConfig","params","context","evaluationContext","effective","buildStepConfig","mode","authoredConfig","hasTemplates","config","name","resolveStepName","step","definitionId","configPlan","value","undefined","diagnostics","trace","gate","gateConfigForStep","outputs","outputsConfigForStep","workingDirectory","resolveWorkingDirectoryConfig","runStep","runStepOrNull","isRunStep","run","mergeConfigPlans","checkoutStep","checkoutStepOrNull","checkout","resolveCheckoutStepConfig","agentStep","agentStepOrNull","Error","kind","agent","template","templates","working_directory","resolved","field","segments","errorField","map","entry","diagnostic","primary","secondary","site","values","isAgentStep","isCheckoutStep","fetch_depth","fetchDepth","permissions","persist_credentials","persistCredentials","force","checkoutConfig","checkoutPlan","key","push","Object","keys","length","hasGate","stepGateConfig","hasOutputs","hasName","hasNameTemplate","hasSuccess","success","hasOnFailure","onFailure","hasOnFailureFeedback","feedback","hasOnFailureFeedbackTemplate","feedbackTemplate","language","check","source","on_failure","restart_from","restartFrom","feedback_template"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { WorkflowModel } from '@shipfox/api-definitions-dto';
|
|
2
|
+
import { type WorkflowExpressionEvaluationContext } from '@shipfox/expression';
|
|
3
|
+
import type { PersistedEvaluationTraceEntry } from '#core/entities/step.js';
|
|
4
|
+
export type WorkflowRunNameResolutionCause = 'missing_value' | 'evaluation_error' | 'empty_value' | 'sanitization';
|
|
5
|
+
export interface WorkflowRunNameDegradation {
|
|
6
|
+
readonly cause: WorkflowRunNameResolutionCause;
|
|
7
|
+
readonly expression?: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
export interface ResolveWorkflowRunNameResult {
|
|
10
|
+
readonly value: string | null;
|
|
11
|
+
readonly trace: readonly PersistedEvaluationTraceEntry[];
|
|
12
|
+
readonly degradation?: WorkflowRunNameDegradation | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function resolveWorkflowRunName(params: {
|
|
15
|
+
readonly runName: WorkflowModel['runName'];
|
|
16
|
+
readonly context: WorkflowExpressionEvaluationContext;
|
|
17
|
+
}): ResolveWorkflowRunNameResult;
|
|
18
|
+
export declare function sanitizeWorkflowDisplayText(value: string): string;
|
|
19
|
+
//# sourceMappingURL=resolve-workflow-run-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-workflow-run-name.d.ts","sourceRoot":"","sources":["../../../src/core/step-config/resolve-workflow-run-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAKL,KAAK,mCAAmC,EAEzC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,6BAA6B,EAAC,MAAM,wBAAwB,CAAC;AAK1E,MAAM,MAAM,8BAA8B,GACtC,eAAe,GACf,kBAAkB,GAClB,aAAa,GACb,cAAc,CAAC;AAEnB,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,KAAK,EAAE,8BAA8B,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,6BAA6B,EAAE,CAAC;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,0BAA0B,GAAG,SAAS,CAAC;CAC/D;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,mCAAmC,CAAC;CACvD,GAAG,4BAA4B,CAyD/B;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjE"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { capTraceEntries, getWorkflowInterpolationFieldFailurePolicy, resolveFieldAtSite, WorkflowTemplateResolutionError } from '@shipfox/expression';
|
|
2
|
+
const DISALLOWED_DISPLAY_CHARACTER_RE = /[\p{Cc}\p{Cf}]/gu;
|
|
3
|
+
const MAX_WORKFLOW_RUN_NAME_LENGTH = 255;
|
|
4
|
+
export function resolveWorkflowRunName(params) {
|
|
5
|
+
if (params.runName === undefined) return {
|
|
6
|
+
value: null,
|
|
7
|
+
trace: []
|
|
8
|
+
};
|
|
9
|
+
try {
|
|
10
|
+
const resolved = resolveFieldAtSite({
|
|
11
|
+
field: {
|
|
12
|
+
segments: params.runName
|
|
13
|
+
},
|
|
14
|
+
site: 'run-creation',
|
|
15
|
+
context: params.context,
|
|
16
|
+
failurePolicy: getWorkflowInterpolationFieldFailurePolicy('workflow.run_name')
|
|
17
|
+
});
|
|
18
|
+
const trace = capTraceEntries(resolved.trace.map((entry)=>({
|
|
19
|
+
...entry,
|
|
20
|
+
field: 'workflow.run_name'
|
|
21
|
+
})));
|
|
22
|
+
if (resolved.kind !== 'frozen' || resolved.diagnostics.length > 0) {
|
|
23
|
+
return degraded(trace, {
|
|
24
|
+
cause: 'missing_value',
|
|
25
|
+
expression: resolved.diagnostics[0]?.expression ?? firstExpressionSource(params.runName)
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (resolved.value === '') {
|
|
29
|
+
return degraded(trace, {
|
|
30
|
+
cause: 'empty_value',
|
|
31
|
+
expression: firstExpressionSource(params.runName)
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const sanitized = sanitizeWorkflowDisplayText(resolved.value);
|
|
35
|
+
if (sanitized === '') {
|
|
36
|
+
return degraded(trace, {
|
|
37
|
+
cause: 'sanitization',
|
|
38
|
+
expression: firstExpressionSource(params.runName)
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
value: sanitized,
|
|
43
|
+
trace,
|
|
44
|
+
...sanitized === resolved.value ? {} : {
|
|
45
|
+
degradation: {
|
|
46
|
+
cause: 'sanitization',
|
|
47
|
+
expression: firstExpressionSource(params.runName)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return degraded([], {
|
|
53
|
+
cause: 'evaluation_error',
|
|
54
|
+
expression: error instanceof WorkflowTemplateResolutionError ? error.source : firstExpressionSource(params.runName)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function sanitizeWorkflowDisplayText(value) {
|
|
59
|
+
const sanitized = value.replace(DISALLOWED_DISPLAY_CHARACTER_RE, ' ').trim();
|
|
60
|
+
return Array.from(sanitized).slice(0, MAX_WORKFLOW_RUN_NAME_LENGTH).join('');
|
|
61
|
+
}
|
|
62
|
+
function degraded(trace, degradation) {
|
|
63
|
+
return {
|
|
64
|
+
value: null,
|
|
65
|
+
trace,
|
|
66
|
+
degradation
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function firstExpressionSource(template) {
|
|
70
|
+
return template.find((segment)=>segment.kind === 'deferred')?.expression.source;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=resolve-workflow-run-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/step-config/resolve-workflow-run-name.ts"],"sourcesContent":["import type {WorkflowModel} from '@shipfox/api-definitions-dto';\nimport {\n capTraceEntries,\n getWorkflowInterpolationFieldFailurePolicy,\n type ResolvedFieldSegment,\n resolveFieldAtSite,\n type WorkflowExpressionEvaluationContext,\n WorkflowTemplateResolutionError,\n} from '@shipfox/expression';\nimport type {PersistedEvaluationTraceEntry} from '#core/entities/step.js';\n\nconst DISALLOWED_DISPLAY_CHARACTER_RE = /[\\p{Cc}\\p{Cf}]/gu;\nconst MAX_WORKFLOW_RUN_NAME_LENGTH = 255;\n\nexport type WorkflowRunNameResolutionCause =\n | 'missing_value'\n | 'evaluation_error'\n | 'empty_value'\n | 'sanitization';\n\nexport interface WorkflowRunNameDegradation {\n readonly cause: WorkflowRunNameResolutionCause;\n readonly expression?: string | undefined;\n}\n\nexport interface ResolveWorkflowRunNameResult {\n readonly value: string | null;\n readonly trace: readonly PersistedEvaluationTraceEntry[];\n readonly degradation?: WorkflowRunNameDegradation | undefined;\n}\n\nexport function resolveWorkflowRunName(params: {\n readonly runName: WorkflowModel['runName'];\n readonly context: WorkflowExpressionEvaluationContext;\n}): ResolveWorkflowRunNameResult {\n if (params.runName === undefined) return {value: null, trace: []};\n\n try {\n const resolved = resolveFieldAtSite({\n field: {segments: params.runName},\n site: 'run-creation',\n context: params.context,\n failurePolicy: getWorkflowInterpolationFieldFailurePolicy('workflow.run_name'),\n });\n const trace = capTraceEntries(\n resolved.trace.map((entry) => ({...entry, field: 'workflow.run_name'})),\n );\n\n if (resolved.kind !== 'frozen' || resolved.diagnostics.length > 0) {\n return degraded(trace, {\n cause: 'missing_value',\n expression: resolved.diagnostics[0]?.expression ?? firstExpressionSource(params.runName),\n });\n }\n\n if (resolved.value === '') {\n return degraded(trace, {\n cause: 'empty_value',\n expression: firstExpressionSource(params.runName),\n });\n }\n\n const sanitized = sanitizeWorkflowDisplayText(resolved.value);\n if (sanitized === '') {\n return degraded(trace, {\n cause: 'sanitization',\n expression: firstExpressionSource(params.runName),\n });\n }\n\n return {\n value: sanitized,\n trace,\n ...(sanitized === resolved.value\n ? {}\n : {\n degradation: {\n cause: 'sanitization' as const,\n expression: firstExpressionSource(params.runName),\n },\n }),\n };\n } catch (error) {\n return degraded([], {\n cause: 'evaluation_error',\n expression:\n error instanceof WorkflowTemplateResolutionError\n ? error.source\n : firstExpressionSource(params.runName),\n });\n }\n}\n\nexport function sanitizeWorkflowDisplayText(value: string): string {\n const sanitized = value.replace(DISALLOWED_DISPLAY_CHARACTER_RE, ' ').trim();\n return Array.from(sanitized).slice(0, MAX_WORKFLOW_RUN_NAME_LENGTH).join('');\n}\n\nfunction degraded(\n trace: readonly PersistedEvaluationTraceEntry[],\n degradation: WorkflowRunNameDegradation,\n): ResolveWorkflowRunNameResult {\n return {value: null, trace, degradation};\n}\n\nfunction firstExpressionSource(template: readonly ResolvedFieldSegment[]): string | undefined {\n return template.find((segment) => segment.kind === 'deferred')?.expression.source;\n}\n"],"names":["capTraceEntries","getWorkflowInterpolationFieldFailurePolicy","resolveFieldAtSite","WorkflowTemplateResolutionError","DISALLOWED_DISPLAY_CHARACTER_RE","MAX_WORKFLOW_RUN_NAME_LENGTH","resolveWorkflowRunName","params","runName","undefined","value","trace","resolved","field","segments","site","context","failurePolicy","map","entry","kind","diagnostics","length","degraded","cause","expression","firstExpressionSource","sanitized","sanitizeWorkflowDisplayText","degradation","error","source","replace","trim","Array","from","slice","join","template","find","segment"],"mappings":"AACA,SACEA,eAAe,EACfC,0CAA0C,EAE1CC,kBAAkB,EAElBC,+BAA+B,QAC1B,sBAAsB;AAG7B,MAAMC,kCAAkC;AACxC,MAAMC,+BAA+B;AAmBrC,OAAO,SAASC,uBAAuBC,MAGtC;IACC,IAAIA,OAAOC,OAAO,KAAKC,WAAW,OAAO;QAACC,OAAO;QAAMC,OAAO,EAAE;IAAA;IAEhE,IAAI;QACF,MAAMC,WAAWV,mBAAmB;YAClCW,OAAO;gBAACC,UAAUP,OAAOC,OAAO;YAAA;YAChCO,MAAM;YACNC,SAAST,OAAOS,OAAO;YACvBC,eAAehB,2CAA2C;QAC5D;QACA,MAAMU,QAAQX,gBACZY,SAASD,KAAK,CAACO,GAAG,CAAC,CAACC,QAAW,CAAA;gBAAC,GAAGA,KAAK;gBAAEN,OAAO;YAAmB,CAAA;QAGtE,IAAID,SAASQ,IAAI,KAAK,YAAYR,SAASS,WAAW,CAACC,MAAM,GAAG,GAAG;YACjE,OAAOC,SAASZ,OAAO;gBACrBa,OAAO;gBACPC,YAAYb,SAASS,WAAW,CAAC,EAAE,EAAEI,cAAcC,sBAAsBnB,OAAOC,OAAO;YACzF;QACF;QAEA,IAAII,SAASF,KAAK,KAAK,IAAI;YACzB,OAAOa,SAASZ,OAAO;gBACrBa,OAAO;gBACPC,YAAYC,sBAAsBnB,OAAOC,OAAO;YAClD;QACF;QAEA,MAAMmB,YAAYC,4BAA4BhB,SAASF,KAAK;QAC5D,IAAIiB,cAAc,IAAI;YACpB,OAAOJ,SAASZ,OAAO;gBACrBa,OAAO;gBACPC,YAAYC,sBAAsBnB,OAAOC,OAAO;YAClD;QACF;QAEA,OAAO;YACLE,OAAOiB;YACPhB;YACA,GAAIgB,cAAcf,SAASF,KAAK,GAC5B,CAAC,IACD;gBACEmB,aAAa;oBACXL,OAAO;oBACPC,YAAYC,sBAAsBnB,OAAOC,OAAO;gBAClD;YACF,CAAC;QACP;IACF,EAAE,OAAOsB,OAAO;QACd,OAAOP,SAAS,EAAE,EAAE;YAClBC,OAAO;YACPC,YACEK,iBAAiB3B,kCACb2B,MAAMC,MAAM,GACZL,sBAAsBnB,OAAOC,OAAO;QAC5C;IACF;AACF;AAEA,OAAO,SAASoB,4BAA4BlB,KAAa;IACvD,MAAMiB,YAAYjB,MAAMsB,OAAO,CAAC5B,iCAAiC,KAAK6B,IAAI;IAC1E,OAAOC,MAAMC,IAAI,CAACR,WAAWS,KAAK,CAAC,GAAG/B,8BAA8BgC,IAAI,CAAC;AAC3E;AAEA,SAASd,SACPZ,KAA+C,EAC/CkB,WAAuC;IAEvC,OAAO;QAACnB,OAAO;QAAMC;QAAOkB;IAAW;AACzC;AAEA,SAASH,sBAAsBY,QAAyC;IACtE,OAAOA,SAASC,IAAI,CAAC,CAACC,UAAYA,QAAQpB,IAAI,KAAK,aAAaK,WAAWM;AAC7E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/step-transition/decide-step-transition.ts"],"sourcesContent":["import type {PersistedEvaluationTraceEntry, Step, StepStatus} from '../entities/step.js';\n\nconst TERMINAL_STATUSES: ReadonlySet<StepStatus> = new Set([\n 'succeeded',\n 'failed',\n 'cancelled',\n 'skipped',\n]);\n\nexport function isTerminal(status: StepStatus): boolean {\n return TERMINAL_STATUSES.has(status);\n}\n\nexport function deriveCompletion(steps: Step[]): 'succeeded' | 'failed' {\n return steps.some((step) => step.status === 'failed') ? 'failed' : 'succeeded';\n}\n\n// The report the runner sent for the step being decided.\nexport interface StepReport {\n status: 'succeeded' | 'failed';\n exitCode?: number | null;\n error?: Record<string, unknown> | null;\n output?: Record<string, unknown> | null;\n response?: string | null;\n}\n\n// Precomputed gate evaluation (the CEL engine runs in evaluate-gate.ts, never\n// here). `passed`/`failed` are clean evaluations; `uncheckable` means the gate\n// could not be evaluated (no exit code, or an evaluation error) and is treated\n// as a plain command failure — never a restart.\nexport type GateOutcome =\n | {kind: 'no-gate'}\n | {kind: 'passed'; source: string; trace?: readonly PersistedEvaluationTraceEntry[]}\n | {kind: 'failed'; source: string; trace?: readonly PersistedEvaluationTraceEntry[]}\n | {\n kind: 'uncheckable';\n reason: string;\n source?: string;\n trace?: readonly PersistedEvaluationTraceEntry[];\n };\n\nexport interface DecideStepTransitionInput {\n // Full job projection, position-ordered (as returned by getStepsByJobIdForUpdate).\n steps: Step[];\n // The reporting step, already confirmed running at `reportedAttempt`.\n target: Step;\n reportedAttempt: number;\n result: StepReport;\n // Precomputed gate evaluation. Absent ⇒ no gate, so `result.status` is authoritative.\n gateOutcome?: GateOutcome;\n // The gate's on_failure policy, if any. Drives the restart branch.\n gateOnFailure?: {restartFrom: string; feedback?: string};\n restartFeedback?: string;\n // Max total attempts for the gating step before restart is exhausted; defaults\n // to DEFAULT_RESTART_ATTEMPT_CAP.\n maxAttempts?: number;\n // The gating step's own execution count (number of its attempts), used for the\n // cap. Defaults to `reportedAttempt` — correct for a single-gate job, where the\n // two are equal; the service passes the real count so a downstream gate in a\n // multi-gate job isn't penalized for upstream-induced rewinds.\n gatingAttemptCount?: number;\n}\n\n// Per-step restart cap: the gating step may run at most this many attempts before\n// a further restart is refused. Bounds runaway restart loops.\nexport const DEFAULT_RESTART_ATTEMPT_CAP = 3;\n\n// The semantic outcome of a step report, independent of persistence.\nexport type StepTransitionDecision =\n | {kind: 'complete-step'; stepId: string; attempt: number}\n // The step succeeds and is the last to finish; apply re-derives the job's\n // terminal status from the projection (it may be `failed` if a sibling was\n // cancelled), so the status is not carried on the decision.\n | {kind: 'complete-job'; stepId: string; attempt: number}\n | {\n kind: 'fail-job';\n failedStepId: string;\n attempt: number;\n // The error to record on the step/attempt (the reported error, or a\n // structured gate error).\n failureError: Record<string, unknown> | null;\n }\n | {\n kind: 'restart-job-from-step';\n failedStepId: string;\n restartFromStepId: string;\n restartFromPosition: number;\n attempt: number;\n feedback: string;\n // Recorded on the failed attempt before the rewind clears the projection.\n failureError: Record<string, unknown> | null;\n }\n | {\n kind: 'fail-job-restart-exhausted';\n failedStepId: string;\n attempt: number;\n maxAttempts: number;\n failureError: Record<string, unknown> | null;\n };\n\nfunction succeed(target: Step, attempt: number, steps: Step[]): StepTransitionDecision {\n // Completes the job when every other step is already terminal, otherwise just\n // advances this step.\n const everyOtherTerminal = steps\n .filter((step) => step.id !== target.id)\n .every((step) => isTerminal(step.status));\n return everyOtherTerminal\n ? {kind: 'complete-job', stepId: target.id, attempt}\n : {kind: 'complete-step', stepId: target.id, attempt};\n}\n\nfunction fail(\n target: Step,\n attempt: number,\n failureError: Record<string, unknown> | null,\n): StepTransitionDecision {\n return {\n kind: 'fail-job',\n failedStepId: target.id,\n attempt,\n failureError,\n };\n}\n\n// Pure: maps a step report (and its precomputed gate outcome) to a transition\n// decision. No DB, no expression engine. A passing gate succeeds; a checkable\n// failure with a resolvable `restart_from` rewinds (until the per-step attempt cap\n// is hit); everything else fails the job. An `uncheckable` failure (no exit code /\n// eval error) is always a plain failure, never a restart.\nexport function decideStepTransition(input: DecideStepTransitionInput): StepTransitionDecision {\n const {steps, target, reportedAttempt, result, gateOnFailure} = input;\n const gate = input.gateOutcome ?? {kind: 'no-gate'};\n const maxAttempts = input.maxAttempts ?? DEFAULT_RESTART_ATTEMPT_CAP;\n\n // 1. Did the step pass? The gate (when present and checkable) is authoritative\n // over the raw command status.\n if (gate.kind === 'no-gate' ? result.status === 'succeeded' : gate.kind === 'passed') {\n return succeed(target, reportedAttempt, steps);\n }\n\n // 2. It failed. Classify the failure error and whether it is restartable.\n // `uncheckable` (no exit code / eval error) is a plain command failure that\n // never restarts.\n const uncheckable = gate.kind === 'uncheckable';\n const failureError: Record<string, unknown> | null =\n gate.kind === 'failed'\n ? {kind: 'gate_failed', message: 'gate condition not met', source: gate.source}\n : gate.kind === 'uncheckable'\n ? (result.error ?? {kind: 'gate_uncheckable', message: gate.reason})\n : (result.error ?? null);\n\n // 3. Restart when a policy is configured and the failure is checkable.\n if (gateOnFailure?.restartFrom && !uncheckable) {\n // Exclude the synthetic setup step: a user step legitimately named \"Set up job\"\n // would otherwise resolve to position 0 and rewind setup (deleting the workspace\n // mid-job). Duplicate user-step names are already impossible (normalize rejects\n // them with duplicate-step-id), so this is the only collision to guard.\n const restartStep = steps.find(\n (step) =>\n step.type !== 'setup' &&\n step.position < target.position &&\n step.key === gateOnFailure.restartFrom,\n );\n if (!restartStep) {\n // The model validates restart_from to an earlier named step, but fail closed\n // if it can't be resolved at runtime rather than silently restarting wrong.\n return fail(target, reportedAttempt, {\n kind: 'restart_unresolved',\n message: `could not resolve restart_from \"${gateOnFailure.restartFrom}\"`,\n restart_from: gateOnFailure.restartFrom,\n });\n }\n const gatingAttemptCount = input.gatingAttemptCount ?? reportedAttempt;\n if (gatingAttemptCount >= maxAttempts) {\n return {\n kind: 'fail-job-restart-exhausted',\n failedStepId: target.id,\n attempt: reportedAttempt,\n maxAttempts,\n failureError: {\n kind: 'restart_exhausted',\n maxAttempts,\n restart_from: gateOnFailure.restartFrom,\n },\n };\n }\n return {\n kind: 'restart-job-from-step',\n failedStepId: target.id,\n restartFromStepId: restartStep.id,\n restartFromPosition: restartStep.position,\n attempt: reportedAttempt,\n feedback: input.restartFeedback ?? gateOnFailure.feedback ?? 'gate condition not met',\n failureError,\n };\n }\n\n // 4. No restart → plain fail-and-cancel.\n return fail(target, reportedAttempt, failureError);\n}\n"],"names":["TERMINAL_STATUSES","Set","isTerminal","status","has","deriveCompletion","steps","some","step","DEFAULT_RESTART_ATTEMPT_CAP","succeed","target","attempt","everyOtherTerminal","filter","id","every","kind","stepId","fail","failureError","failedStepId","decideStepTransition","input","reportedAttempt","result","gateOnFailure","gate","gateOutcome","maxAttempts","uncheckable","message","source","error","reason","restartFrom","restartStep","find","type","position","key","restart_from","gatingAttemptCount","restartFromStepId","restartFromPosition","feedback","restartFeedback"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/step-transition/decide-step-transition.ts"],"sourcesContent":["import type {PersistedEvaluationTraceEntry, Step, StepStatus} from '../entities/step.js';\n\nconst TERMINAL_STATUSES: ReadonlySet<StepStatus> = new Set([\n 'succeeded',\n 'failed',\n 'cancelled',\n 'skipped',\n]);\n\nexport function isTerminal(status: StepStatus): boolean {\n return TERMINAL_STATUSES.has(status);\n}\n\nexport function deriveCompletion(steps: Step[]): 'succeeded' | 'failed' {\n return steps.some((step) => step.status === 'failed') ? 'failed' : 'succeeded';\n}\n\n// The report the runner sent for the step being decided.\nexport interface StepReport {\n status: 'succeeded' | 'failed';\n exitCode?: number | null;\n error?: Record<string, unknown> | null;\n output?: Record<string, unknown> | null;\n response?: string | null;\n}\n\n// Precomputed gate evaluation (the CEL engine runs in evaluate-gate.ts, never\n// here). `passed`/`failed` are clean evaluations; `uncheckable` means the gate\n// could not be evaluated (no exit code, or an evaluation error) and is treated\n// as a plain command failure. It is never a restart.\nexport type GateOutcome =\n | {kind: 'no-gate'}\n | {kind: 'passed'; source: string; trace?: readonly PersistedEvaluationTraceEntry[]}\n | {kind: 'failed'; source: string; trace?: readonly PersistedEvaluationTraceEntry[]}\n | {\n kind: 'uncheckable';\n reason: string;\n source?: string;\n trace?: readonly PersistedEvaluationTraceEntry[];\n };\n\nexport interface DecideStepTransitionInput {\n // Full job projection, position-ordered (as returned by getStepsByJobIdForUpdate).\n steps: Step[];\n // The reporting step, already confirmed running at `reportedAttempt`.\n target: Step;\n reportedAttempt: number;\n result: StepReport;\n // Precomputed gate evaluation. Absent ⇒ no gate, so `result.status` is authoritative.\n gateOutcome?: GateOutcome;\n // The gate's on_failure policy, if any. Drives the restart branch.\n gateOnFailure?: {restartFrom: string; feedback?: string};\n restartFeedback?: string;\n // Max total attempts for the gating step before restart is exhausted; defaults\n // to DEFAULT_RESTART_ATTEMPT_CAP.\n maxAttempts?: number;\n // The gating step's own execution count (number of its attempts), used for the\n // cap. Defaults to `reportedAttempt`: correct for a single-gate job, where the\n // two are equal; the service passes the real count so a downstream gate in a\n // multi-gate job isn't penalized for upstream-induced rewinds.\n gatingAttemptCount?: number;\n}\n\n// Per-step restart cap: the gating step may run at most this many attempts before\n// a further restart is refused. Bounds runaway restart loops.\nexport const DEFAULT_RESTART_ATTEMPT_CAP = 3;\n\n// The semantic outcome of a step report, independent of persistence.\nexport type StepTransitionDecision =\n | {kind: 'complete-step'; stepId: string; attempt: number}\n // The step succeeds and is the last to finish; apply re-derives the job's\n // terminal status from the projection (it may be `failed` if a sibling was\n // cancelled), so the status is not carried on the decision.\n | {kind: 'complete-job'; stepId: string; attempt: number}\n | {\n kind: 'fail-job';\n failedStepId: string;\n attempt: number;\n // The error to record on the step/attempt (the reported error, or a\n // structured gate error).\n failureError: Record<string, unknown> | null;\n }\n | {\n kind: 'restart-job-from-step';\n failedStepId: string;\n restartFromStepId: string;\n restartFromPosition: number;\n attempt: number;\n feedback: string;\n // Recorded on the failed attempt before the rewind clears the projection.\n failureError: Record<string, unknown> | null;\n }\n | {\n kind: 'fail-job-restart-exhausted';\n failedStepId: string;\n attempt: number;\n maxAttempts: number;\n failureError: Record<string, unknown> | null;\n };\n\nfunction succeed(target: Step, attempt: number, steps: Step[]): StepTransitionDecision {\n // Completes the job when every other step is already terminal, otherwise just\n // advances this step.\n const everyOtherTerminal = steps\n .filter((step) => step.id !== target.id)\n .every((step) => isTerminal(step.status));\n return everyOtherTerminal\n ? {kind: 'complete-job', stepId: target.id, attempt}\n : {kind: 'complete-step', stepId: target.id, attempt};\n}\n\nfunction fail(\n target: Step,\n attempt: number,\n failureError: Record<string, unknown> | null,\n): StepTransitionDecision {\n return {\n kind: 'fail-job',\n failedStepId: target.id,\n attempt,\n failureError,\n };\n}\n\n// Pure: maps a step report (and its precomputed gate outcome) to a transition\n// decision. No DB, no expression engine. A passing gate succeeds; a checkable\n// failure with a resolvable `restart_from` rewinds (until the per-step attempt cap\n// is hit); everything else fails the job. An `uncheckable` failure (no exit code /\n// eval error) is always a plain failure, never a restart.\nexport function decideStepTransition(input: DecideStepTransitionInput): StepTransitionDecision {\n const {steps, target, reportedAttempt, result, gateOnFailure} = input;\n const gate = input.gateOutcome ?? {kind: 'no-gate'};\n const maxAttempts = input.maxAttempts ?? DEFAULT_RESTART_ATTEMPT_CAP;\n\n // 1. Did the step pass? The gate (when present and checkable) is authoritative\n // over the raw command status.\n if (gate.kind === 'no-gate' ? result.status === 'succeeded' : gate.kind === 'passed') {\n return succeed(target, reportedAttempt, steps);\n }\n\n // 2. It failed. Classify the failure error and whether it is restartable.\n // `uncheckable` (no exit code / eval error) is a plain command failure that\n // never restarts.\n const uncheckable = gate.kind === 'uncheckable';\n const failureError: Record<string, unknown> | null =\n gate.kind === 'failed'\n ? {kind: 'gate_failed', message: 'gate condition not met', source: gate.source}\n : gate.kind === 'uncheckable'\n ? (result.error ?? {kind: 'gate_uncheckable', message: gate.reason})\n : (result.error ?? null);\n\n // 3. Restart when a policy is configured and the failure is checkable.\n if (gateOnFailure?.restartFrom && !uncheckable) {\n // Exclude the synthetic setup step: a user step legitimately named \"Set up job\"\n // would otherwise resolve to position 0 and rewind setup (deleting the workspace\n // mid-job). Duplicate user-step names are already impossible (normalize rejects\n // them with duplicate-step-id), so this is the only collision to guard.\n const restartStep = steps.find(\n (step) =>\n step.type !== 'setup' &&\n step.position < target.position &&\n step.key === gateOnFailure.restartFrom,\n );\n if (!restartStep) {\n // The model validates restart_from to an earlier named step, but fail closed\n // if it can't be resolved at runtime rather than silently restarting wrong.\n return fail(target, reportedAttempt, {\n kind: 'restart_unresolved',\n message: `could not resolve restart_from \"${gateOnFailure.restartFrom}\"`,\n restart_from: gateOnFailure.restartFrom,\n });\n }\n const gatingAttemptCount = input.gatingAttemptCount ?? reportedAttempt;\n if (gatingAttemptCount >= maxAttempts) {\n return {\n kind: 'fail-job-restart-exhausted',\n failedStepId: target.id,\n attempt: reportedAttempt,\n maxAttempts,\n failureError: {\n kind: 'restart_exhausted',\n maxAttempts,\n restart_from: gateOnFailure.restartFrom,\n },\n };\n }\n return {\n kind: 'restart-job-from-step',\n failedStepId: target.id,\n restartFromStepId: restartStep.id,\n restartFromPosition: restartStep.position,\n attempt: reportedAttempt,\n feedback: input.restartFeedback ?? gateOnFailure.feedback ?? 'gate condition not met',\n failureError,\n };\n }\n\n // 4. No restart → plain fail-and-cancel.\n return fail(target, reportedAttempt, failureError);\n}\n"],"names":["TERMINAL_STATUSES","Set","isTerminal","status","has","deriveCompletion","steps","some","step","DEFAULT_RESTART_ATTEMPT_CAP","succeed","target","attempt","everyOtherTerminal","filter","id","every","kind","stepId","fail","failureError","failedStepId","decideStepTransition","input","reportedAttempt","result","gateOnFailure","gate","gateOutcome","maxAttempts","uncheckable","message","source","error","reason","restartFrom","restartStep","find","type","position","key","restart_from","gatingAttemptCount","restartFromStepId","restartFromPosition","feedback","restartFeedback"],"mappings":"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"}
|
|
@@ -18,11 +18,12 @@ export declare function readStepGate(config: Record<string, unknown>): StepGate
|
|
|
18
18
|
* unless evaluation gets a budget outside the lock. The materializer only
|
|
19
19
|
* persists CEL expressions, and this evaluator only needs the validated source.
|
|
20
20
|
*/
|
|
21
|
-
export declare function evaluateGate(gate: StepGate | undefined, result: StepReport): GateOutcome;
|
|
21
|
+
export declare function evaluateGate(gate: StepGate | undefined, result: StepReport, vars?: Record<string, string> | undefined): GateOutcome;
|
|
22
22
|
export declare function evaluateGateFeedback(params: {
|
|
23
23
|
readonly gate: StepGate;
|
|
24
24
|
readonly result: StepReport;
|
|
25
25
|
readonly definitionId: string;
|
|
26
|
+
readonly vars?: Record<string, string> | undefined;
|
|
26
27
|
}): string;
|
|
27
28
|
export declare function gateResultPayload(outcome: GateOutcome, exitCode: number | null | undefined): Record<string, unknown> | null;
|
|
28
29
|
//# sourceMappingURL=evaluate-gate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate-gate.d.ts","sourceRoot":"","sources":["../../../src/core/step-transition/evaluate-gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAC,WAAW,EAAE,UAAU,EAAC,MAAM,6BAA6B,CAAC;AAMzE,eAAO,MAAM,4BAA4B,sCAAsC,CAAC;AAGhF,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,SAAS,CAAC,EAAE;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,aAAa,CAAA;KAAC,CAAC;CACxF;AAID,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,GAAG,SAAS,CAoClF;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,
|
|
1
|
+
{"version":3,"file":"evaluate-gate.d.ts","sourceRoot":"","sources":["../../../src/core/step-transition/evaluate-gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAC,WAAW,EAAE,UAAU,EAAC,MAAM,6BAA6B,CAAC;AAMzE,eAAO,MAAM,4BAA4B,sCAAsC,CAAC;AAGhF,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,SAAS,CAAC,EAAE;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,aAAa,CAAA;KAAC,CAAC;CACxF;AAID,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,GAAG,SAAS,CAoClF;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,GAAG,SAAS,EAC1B,MAAM,EAAE,UAAU,EAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GACxC,WAAW,CAoCb;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CACpD,GAAG,MAAM,CAmBT;AAKD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA6BhC"}
|
|
@@ -44,7 +44,7 @@ export function readStepGate(config) {
|
|
|
44
44
|
* Callers hold step-row locks while this runs. Keep the CEL context bounded
|
|
45
45
|
* unless evaluation gets a budget outside the lock. The materializer only
|
|
46
46
|
* persists CEL expressions, and this evaluator only needs the validated source.
|
|
47
|
-
*/ export function evaluateGate(gate, result) {
|
|
47
|
+
*/ export function evaluateGate(gate, result, vars) {
|
|
48
48
|
if (!gate?.success) return {
|
|
49
49
|
kind: 'no-gate'
|
|
50
50
|
};
|
|
@@ -58,7 +58,8 @@ export function readStepGate(config) {
|
|
|
58
58
|
const context = assembleGateContext({
|
|
59
59
|
status: result.status,
|
|
60
60
|
exitCode: result.exitCode,
|
|
61
|
-
output: result.output
|
|
61
|
+
output: result.output,
|
|
62
|
+
vars
|
|
62
63
|
});
|
|
63
64
|
const outcome = evaluatePlannedPredicateAtSite({
|
|
64
65
|
expression: gate.success,
|
|
@@ -104,7 +105,8 @@ export function evaluateGateFeedback(params) {
|
|
|
104
105
|
const context = assembleGateContext({
|
|
105
106
|
status: params.result.status,
|
|
106
107
|
exitCode: params.result.exitCode ?? null,
|
|
107
|
-
output: params.result.output
|
|
108
|
+
output: params.result.output,
|
|
109
|
+
vars: params.vars
|
|
108
110
|
});
|
|
109
111
|
return completeStepField({
|
|
110
112
|
field: 'step.feedback',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/step-transition/evaluate-gate.ts"],"sourcesContent":["import {\n capTraceEntries,\n evaluatePlannedPredicateAtSite,\n predicateTraceEntry,\n type ResolvedField,\n type WorkflowExpression,\n} from '@shipfox/expression';\nimport {assembleGateContext} from '../step-config/assemble-run-context.js';\nimport {completeStepField} from '../step-config/fields.js';\nimport type {GateOutcome, StepReport} from './decide-step-transition.js';\n\n// The exact `uncheckable` reason recorded when the gate's CEL expression itself\n// throws (as opposed to a missing exit code). The DTO mapper keys on this string to\n// surface a distinct `evaluation_error` gate result, so the producer and the mapper\n// must share this constant rather than duplicating the literal.\nexport const GATE_EVALUATION_ERROR_REASON = 'gate expression evaluation failed';\n\n// The gate as parsed from a step's materialized `config.gate` (snake_case JSON).\nexport interface StepGate {\n success?: WorkflowExpression;\n onFailure?: {restartFrom: string; feedback?: string; feedbackTemplate?: ResolvedField};\n}\n\n// Read the gate persisted on a step's config by the materializer. Returns\n// undefined when the step has no gate of interest.\nexport function readStepGate(config: Record<string, unknown>): StepGate | undefined {\n const gate = config.gate;\n if (!gate || typeof gate !== 'object') return undefined;\n const raw = gate as Record<string, unknown>;\n\n const successRaw = raw.success as Record<string, unknown> | undefined;\n const success =\n successRaw && typeof successRaw.source === 'string'\n ? // The model validated this expression before materialization; the stored\n // JSON is structurally a WorkflowExpression.\n (successRaw as unknown as WorkflowExpression)\n : undefined;\n\n const onFailureRaw = raw.on_failure as Record<string, unknown> | undefined;\n const feedbackTemplateRaw = onFailureRaw?.feedback_template as\n | Record<string, unknown>\n | undefined;\n const feedbackTemplate =\n Array.isArray(feedbackTemplateRaw?.segments) &&\n feedbackTemplateRaw.segments.every((segment) => typeof segment === 'object' && segment !== null)\n ? (feedbackTemplateRaw as unknown as ResolvedField)\n : undefined;\n const onFailure =\n onFailureRaw && typeof onFailureRaw.restart_from === 'string'\n ? {\n restartFrom: onFailureRaw.restart_from,\n ...(typeof onFailureRaw.feedback === 'string' ? {feedback: onFailureRaw.feedback} : {}),\n ...(feedbackTemplate === undefined ? {} : {feedbackTemplate}),\n }\n : undefined;\n\n if (!success && !onFailure) return undefined;\n return {\n ...(success ? {success} : {}),\n ...(onFailure ? {onFailure} : {}),\n };\n}\n\n/**\n * Gate evaluation fails closed: a missing exit code or CEL evaluation error is\n * `uncheckable` (a plain command failure), never a gate failure that can restart.\n *\n * Callers hold step-row locks while this runs. Keep the CEL context bounded\n * unless evaluation gets a budget outside the lock. The materializer only\n * persists CEL expressions, and this evaluator only needs the validated source.\n */\nexport function evaluateGate(gate: StepGate | undefined, result: StepReport): GateOutcome {\n if (!gate?.success) return {kind: 'no-gate'};\n const source = gate.success.source;\n\n if (result.exitCode === null || result.exitCode === undefined) {\n return {kind: 'uncheckable', reason: 'step produced no exit code'};\n }\n\n const context = assembleGateContext({\n status: result.status,\n exitCode: result.exitCode,\n output: result.output,\n });\n const outcome = evaluatePlannedPredicateAtSite({\n expression: gate.success,\n field: 'step.success',\n site: context.site,\n context: context.values,\n });\n const trace = capTraceEntries([\n {\n ...predicateTraceEntry({\n expression: source,\n route: outcome.route,\n site: context.site,\n value: outcome.value,\n degraded: outcome.evaluationFailed,\n }),\n field: 'step.success',\n },\n ]);\n if (outcome.evaluationFailed) {\n return {kind: 'uncheckable', reason: GATE_EVALUATION_ERROR_REASON, source, trace};\n }\n return outcome.value ? {kind: 'passed', source, trace} : {kind: 'failed', source, trace};\n}\n\nexport function evaluateGateFeedback(params: {\n readonly gate: StepGate;\n readonly result: StepReport;\n readonly definitionId: string;\n}): string {\n const feedbackTemplate = params.gate.onFailure?.feedbackTemplate;\n if (feedbackTemplate === undefined) {\n return params.gate.onFailure?.feedback ?? 'gate condition not met';\n }\n\n const context = assembleGateContext({\n status: params.result.status,\n exitCode: params.result.exitCode ?? null,\n output: params.result.output,\n });\n return completeStepField({\n field: 'step.feedback',\n errorField: 'step.feedback',\n template: feedbackTemplate,\n context,\n definitionId: params.definitionId,\n });\n}\n\n// Build the audit payload recorded on the step attempt for a gate evaluation.\n// Includes the evaluated `exit_code` so the gate decision is reconstructable from\n// the attempt row alone, independent of the column shape.\nexport function gateResultPayload(\n outcome: GateOutcome,\n exitCode: number | null | undefined,\n): Record<string, unknown> | null {\n const exit_code = exitCode ?? null;\n switch (outcome.kind) {\n case 'no-gate':\n return null;\n case 'passed':\n return {\n passed: true,\n source: outcome.source,\n exit_code,\n ...(outcome.trace === undefined ? {} : {trace: outcome.trace}),\n };\n case 'failed':\n return {\n passed: false,\n source: outcome.source,\n exit_code,\n ...(outcome.trace === undefined ? {} : {trace: outcome.trace}),\n };\n case 'uncheckable':\n return {\n passed: false,\n uncheckable: true,\n reason: outcome.reason,\n exit_code,\n ...(outcome.source === undefined ? {} : {source: outcome.source}),\n ...(outcome.trace === undefined ? {} : {trace: outcome.trace}),\n };\n }\n}\n"],"names":["capTraceEntries","evaluatePlannedPredicateAtSite","predicateTraceEntry","assembleGateContext","completeStepField","GATE_EVALUATION_ERROR_REASON","readStepGate","config","gate","undefined","raw","successRaw","success","source","onFailureRaw","on_failure","feedbackTemplateRaw","feedback_template","feedbackTemplate","Array","isArray","segments","every","segment","onFailure","restart_from","restartFrom","feedback","evaluateGate","result","kind","exitCode","reason","context","status","output","outcome","expression","field","site","values","trace","route","value","degraded","evaluationFailed","evaluateGateFeedback","params","errorField","template","definitionId","gateResultPayload","exit_code","passed","uncheckable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/step-transition/evaluate-gate.ts"],"sourcesContent":["import {\n capTraceEntries,\n evaluatePlannedPredicateAtSite,\n predicateTraceEntry,\n type ResolvedField,\n type WorkflowExpression,\n} from '@shipfox/expression';\nimport {assembleGateContext} from '../step-config/assemble-run-context.js';\nimport {completeStepField} from '../step-config/fields.js';\nimport type {GateOutcome, StepReport} from './decide-step-transition.js';\n\n// The exact `uncheckable` reason recorded when the gate's CEL expression itself\n// throws (as opposed to a missing exit code). The DTO mapper keys on this string to\n// surface a distinct `evaluation_error` gate result, so the producer and the mapper\n// must share this constant rather than duplicating the literal.\nexport const GATE_EVALUATION_ERROR_REASON = 'gate expression evaluation failed';\n\n// The gate as parsed from a step's materialized `config.gate` (snake_case JSON).\nexport interface StepGate {\n success?: WorkflowExpression;\n onFailure?: {restartFrom: string; feedback?: string; feedbackTemplate?: ResolvedField};\n}\n\n// Read the gate persisted on a step's config by the materializer. Returns\n// undefined when the step has no gate of interest.\nexport function readStepGate(config: Record<string, unknown>): StepGate | undefined {\n const gate = config.gate;\n if (!gate || typeof gate !== 'object') return undefined;\n const raw = gate as Record<string, unknown>;\n\n const successRaw = raw.success as Record<string, unknown> | undefined;\n const success =\n successRaw && typeof successRaw.source === 'string'\n ? // The model validated this expression before materialization; the stored\n // JSON is structurally a WorkflowExpression.\n (successRaw as unknown as WorkflowExpression)\n : undefined;\n\n const onFailureRaw = raw.on_failure as Record<string, unknown> | undefined;\n const feedbackTemplateRaw = onFailureRaw?.feedback_template as\n | Record<string, unknown>\n | undefined;\n const feedbackTemplate =\n Array.isArray(feedbackTemplateRaw?.segments) &&\n feedbackTemplateRaw.segments.every((segment) => typeof segment === 'object' && segment !== null)\n ? (feedbackTemplateRaw as unknown as ResolvedField)\n : undefined;\n const onFailure =\n onFailureRaw && typeof onFailureRaw.restart_from === 'string'\n ? {\n restartFrom: onFailureRaw.restart_from,\n ...(typeof onFailureRaw.feedback === 'string' ? {feedback: onFailureRaw.feedback} : {}),\n ...(feedbackTemplate === undefined ? {} : {feedbackTemplate}),\n }\n : undefined;\n\n if (!success && !onFailure) return undefined;\n return {\n ...(success ? {success} : {}),\n ...(onFailure ? {onFailure} : {}),\n };\n}\n\n/**\n * Gate evaluation fails closed: a missing exit code or CEL evaluation error is\n * `uncheckable` (a plain command failure), never a gate failure that can restart.\n *\n * Callers hold step-row locks while this runs. Keep the CEL context bounded\n * unless evaluation gets a budget outside the lock. The materializer only\n * persists CEL expressions, and this evaluator only needs the validated source.\n */\nexport function evaluateGate(\n gate: StepGate | undefined,\n result: StepReport,\n vars?: Record<string, string> | undefined,\n): GateOutcome {\n if (!gate?.success) return {kind: 'no-gate'};\n const source = gate.success.source;\n\n if (result.exitCode === null || result.exitCode === undefined) {\n return {kind: 'uncheckable', reason: 'step produced no exit code'};\n }\n\n const context = assembleGateContext({\n status: result.status,\n exitCode: result.exitCode,\n output: result.output,\n vars,\n });\n const outcome = evaluatePlannedPredicateAtSite({\n expression: gate.success,\n field: 'step.success',\n site: context.site,\n context: context.values,\n });\n const trace = capTraceEntries([\n {\n ...predicateTraceEntry({\n expression: source,\n route: outcome.route,\n site: context.site,\n value: outcome.value,\n degraded: outcome.evaluationFailed,\n }),\n field: 'step.success',\n },\n ]);\n if (outcome.evaluationFailed) {\n return {kind: 'uncheckable', reason: GATE_EVALUATION_ERROR_REASON, source, trace};\n }\n return outcome.value ? {kind: 'passed', source, trace} : {kind: 'failed', source, trace};\n}\n\nexport function evaluateGateFeedback(params: {\n readonly gate: StepGate;\n readonly result: StepReport;\n readonly definitionId: string;\n readonly vars?: Record<string, string> | undefined;\n}): string {\n const feedbackTemplate = params.gate.onFailure?.feedbackTemplate;\n if (feedbackTemplate === undefined) {\n return params.gate.onFailure?.feedback ?? 'gate condition not met';\n }\n\n const context = assembleGateContext({\n status: params.result.status,\n exitCode: params.result.exitCode ?? null,\n output: params.result.output,\n vars: params.vars,\n });\n return completeStepField({\n field: 'step.feedback',\n errorField: 'step.feedback',\n template: feedbackTemplate,\n context,\n definitionId: params.definitionId,\n });\n}\n\n// Build the audit payload recorded on the step attempt for a gate evaluation.\n// Includes the evaluated `exit_code` so the gate decision is reconstructable from\n// the attempt row alone, independent of the column shape.\nexport function gateResultPayload(\n outcome: GateOutcome,\n exitCode: number | null | undefined,\n): Record<string, unknown> | null {\n const exit_code = exitCode ?? null;\n switch (outcome.kind) {\n case 'no-gate':\n return null;\n case 'passed':\n return {\n passed: true,\n source: outcome.source,\n exit_code,\n ...(outcome.trace === undefined ? {} : {trace: outcome.trace}),\n };\n case 'failed':\n return {\n passed: false,\n source: outcome.source,\n exit_code,\n ...(outcome.trace === undefined ? {} : {trace: outcome.trace}),\n };\n case 'uncheckable':\n return {\n passed: false,\n uncheckable: true,\n reason: outcome.reason,\n exit_code,\n ...(outcome.source === undefined ? {} : {source: outcome.source}),\n ...(outcome.trace === undefined ? {} : {trace: outcome.trace}),\n };\n }\n}\n"],"names":["capTraceEntries","evaluatePlannedPredicateAtSite","predicateTraceEntry","assembleGateContext","completeStepField","GATE_EVALUATION_ERROR_REASON","readStepGate","config","gate","undefined","raw","successRaw","success","source","onFailureRaw","on_failure","feedbackTemplateRaw","feedback_template","feedbackTemplate","Array","isArray","segments","every","segment","onFailure","restart_from","restartFrom","feedback","evaluateGate","result","vars","kind","exitCode","reason","context","status","output","outcome","expression","field","site","values","trace","route","value","degraded","evaluationFailed","evaluateGateFeedback","params","errorField","template","definitionId","gateResultPayload","exit_code","passed","uncheckable"],"mappings":"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"}
|
|
@@ -26,6 +26,7 @@ export declare function deriveInitialJobExecutionPlan(params: {
|
|
|
26
26
|
inputs?: Record<string, unknown> | null | undefined;
|
|
27
27
|
vars?: Record<string, string> | undefined;
|
|
28
28
|
}): {
|
|
29
|
+
nameOverride: string | null;
|
|
29
30
|
name: string;
|
|
30
31
|
runner: readonly string[];
|
|
31
32
|
evaluationTrace: JobExecution['evaluationTrace'];
|
|
@@ -35,7 +36,9 @@ export declare function deriveJobExecutionRunner(params: {
|
|
|
35
36
|
modelJob: WorkflowModel['jobs'][number];
|
|
36
37
|
jobId: string;
|
|
37
38
|
sequence: number;
|
|
39
|
+
nameOverride: string | null;
|
|
38
40
|
executionName: string;
|
|
41
|
+
jobName?: string | null | undefined;
|
|
39
42
|
status: JobExecution['status'];
|
|
40
43
|
triggerEvents?: readonly JobExecution['triggerEvents'][number][] | undefined;
|
|
41
44
|
priorExecutions?: readonly JobExecution[] | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-run-creation.d.ts","sourceRoot":"","sources":["../../src/core/workflow-run-creation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EACV,+BAA+B,EAC/B,gCAAgC,EACjC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAE,WAAW,EAAC,MAAM,4BAA4B,CAAC;AAK5E,OAAO,EACL,KAAK,uBAAuB,EAG7B,MAAM,6CAA6C,CAAC;AAGrD,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,GAAG,EAAE,WAAW,CAAC;IACjB,KAAK,EAAE,aAAa,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC1C,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,+BAA+B,GAAG,SAAS,CAAC;IAC/D,iBAAiB,CAAC,EAAE,gCAAgC,GAAG,IAAI,GAAG,SAAS,CAAC;CACzE,GAAG,OAAO,CAAC,SAAS,uBAAuB,EAAE,CAAC,CAe9C;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,GAAG,EAAE,WAAW,CAAC;IACjB,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;IACxC,GAAG,EAAE,uBAAuB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CAC3C,GAAG;IACF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,YAAY,CAAC,iBAAiB,CAAC,CAAC;CAClD,
|
|
1
|
+
{"version":3,"file":"workflow-run-creation.d.ts","sourceRoot":"","sources":["../../src/core/workflow-run-creation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EACV,+BAA+B,EAC/B,gCAAgC,EACjC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAE,WAAW,EAAC,MAAM,4BAA4B,CAAC;AAK5E,OAAO,EACL,KAAK,uBAAuB,EAG7B,MAAM,6CAA6C,CAAC;AAGrD,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,GAAG,EAAE,WAAW,CAAC;IACjB,KAAK,EAAE,aAAa,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC1C,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,+BAA+B,GAAG,SAAS,CAAC;IAC/D,iBAAiB,CAAC,EAAE,gCAAgC,GAAG,IAAI,GAAG,SAAS,CAAC;CACzE,GAAG,OAAO,CAAC,SAAS,uBAAuB,EAAE,CAAC,CAe9C;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,GAAG,EAAE,WAAW,CAAC;IACjB,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;IACxC,GAAG,EAAE,uBAAuB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CAC3C,GAAG;IACF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,YAAY,CAAC,iBAAiB,CAAC,CAAC;CAClD,CA0CA;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,GAAG,EAAE,WAAW,CAAC;IACjB,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,SAAS,YAAY,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC;IAC7E,eAAe,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;CACvD,GAAG,SAAS,MAAM,EAAE,CAiBpB"}
|