@shipfox/api-definitions 2.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 +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +215 -0
- package/LICENSE +21 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +35 -0
- package/dist/config.js.map +1 -0
- package/dist/core/entities/index.d.ts +5 -0
- package/dist/core/entities/index.d.ts.map +1 -0
- package/dist/core/entities/index.js +6 -0
- package/dist/core/entities/index.js.map +1 -0
- package/dist/core/entities/integration-context.d.ts +11 -0
- package/dist/core/entities/integration-context.d.ts.map +1 -0
- package/dist/core/entities/integration-context.js +3 -0
- package/dist/core/entities/integration-context.js.map +1 -0
- package/dist/core/entities/sync-state.d.ts +19 -0
- package/dist/core/entities/sync-state.d.ts.map +1 -0
- package/dist/core/entities/sync-state.js +20 -0
- package/dist/core/entities/sync-state.js.map +1 -0
- package/dist/core/entities/workflow-definition.d.ts +35 -0
- package/dist/core/entities/workflow-definition.d.ts.map +1 -0
- package/dist/core/entities/workflow-definition.js +3 -0
- package/dist/core/entities/workflow-definition.js.map +1 -0
- package/dist/core/entities/workflow-model.d.ts +138 -0
- package/dist/core/entities/workflow-model.d.ts.map +1 -0
- package/dist/core/entities/workflow-model.js +3 -0
- package/dist/core/entities/workflow-model.js.map +1 -0
- package/dist/core/errors.d.ts +10 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +14 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/has-agent-step-integrations.d.ts +3 -0
- package/dist/core/has-agent-step-integrations.d.ts.map +1 -0
- package/dist/core/has-agent-step-integrations.js +5 -0
- package/dist/core/has-agent-step-integrations.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/parse-definition.d.ts +9 -0
- package/dist/core/parse-definition.d.ts.map +1 -0
- package/dist/core/parse-definition.js +17 -0
- package/dist/core/parse-definition.js.map +1 -0
- package/dist/core/sync-definitions.d.ts +44 -0
- package/dist/core/sync-definitions.d.ts.map +1 -0
- package/dist/core/sync-definitions.js +140 -0
- package/dist/core/sync-definitions.js.map +1 -0
- package/dist/core/validate-definition.d.ts +20 -0
- package/dist/core/validate-definition.d.ts.map +1 -0
- package/dist/core/validate-definition.js +61 -0
- package/dist/core/validate-definition.js.map +1 -0
- package/dist/core/workflow-model/constants.d.ts +2 -0
- package/dist/core/workflow-model/constants.d.ts.map +1 -0
- package/dist/core/workflow-model/constants.js +3 -0
- package/dist/core/workflow-model/constants.js.map +1 -0
- package/dist/core/workflow-model/cron-trigger.d.ts +16 -0
- package/dist/core/workflow-model/cron-trigger.d.ts.map +1 -0
- package/dist/core/workflow-model/cron-trigger.js +85 -0
- package/dist/core/workflow-model/cron-trigger.js.map +1 -0
- package/dist/core/workflow-model/index.d.ts +4 -0
- package/dist/core/workflow-model/index.d.ts.map +1 -0
- package/dist/core/workflow-model/index.js +5 -0
- package/dist/core/workflow-model/index.js.map +1 -0
- package/dist/core/workflow-model/invalid-workflow-model-error.d.ts +15 -0
- package/dist/core/workflow-model/invalid-workflow-model-error.d.ts.map +1 -0
- package/dist/core/workflow-model/invalid-workflow-model-error.js +9 -0
- package/dist/core/workflow-model/invalid-workflow-model-error.js.map +1 -0
- package/dist/core/workflow-model/map-job-ids.d.ts +4 -0
- package/dist/core/workflow-model/map-job-ids.d.ts.map +1 -0
- package/dist/core/workflow-model/map-job-ids.js +33 -0
- package/dist/core/workflow-model/map-job-ids.js.map +1 -0
- package/dist/core/workflow-model/normalize-agent-integrations.d.ts +12 -0
- package/dist/core/workflow-model/normalize-agent-integrations.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-agent-integrations.js +157 -0
- package/dist/core/workflow-model/normalize-agent-integrations.js.map +1 -0
- package/dist/core/workflow-model/normalize-dependencies.d.ts +6 -0
- package/dist/core/workflow-model/normalize-dependencies.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-dependencies.js +119 -0
- package/dist/core/workflow-model/normalize-dependencies.js.map +1 -0
- package/dist/core/workflow-model/normalize-env.d.ts +17 -0
- package/dist/core/workflow-model/normalize-env.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-env.js +40 -0
- package/dist/core/workflow-model/normalize-env.js.map +1 -0
- package/dist/core/workflow-model/normalize-if-condition.d.ts +14 -0
- package/dist/core/workflow-model/normalize-if-condition.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-if-condition.js +75 -0
- package/dist/core/workflow-model/normalize-if-condition.js.map +1 -0
- package/dist/core/workflow-model/normalize-job-checkout.d.ts +5 -0
- package/dist/core/workflow-model/normalize-job-checkout.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-job-checkout.js +16 -0
- package/dist/core/workflow-model/normalize-job-checkout.js.map +1 -0
- package/dist/core/workflow-model/normalize-job-listening.d.ts +10 -0
- package/dist/core/workflow-model/normalize-job-listening.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-job-listening.js +125 -0
- package/dist/core/workflow-model/normalize-job-listening.js.map +1 -0
- package/dist/core/workflow-model/normalize-job-success.d.ts +11 -0
- package/dist/core/workflow-model/normalize-job-success.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-job-success.js +23 -0
- package/dist/core/workflow-model/normalize-job-success.js.map +1 -0
- package/dist/core/workflow-model/normalize-jobs.d.ts +12 -0
- package/dist/core/workflow-model/normalize-jobs.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-jobs.js +935 -0
- package/dist/core/workflow-model/normalize-jobs.js.map +1 -0
- package/dist/core/workflow-model/normalize-needs.d.ts +2 -0
- package/dist/core/workflow-model/normalize-needs.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-needs.js +16 -0
- package/dist/core/workflow-model/normalize-needs.js.map +1 -0
- package/dist/core/workflow-model/normalize-step-gate.d.ts +15 -0
- package/dist/core/workflow-model/normalize-step-gate.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-step-gate.js +89 -0
- package/dist/core/workflow-model/normalize-step-gate.js.map +1 -0
- package/dist/core/workflow-model/normalize-step-outputs.d.ts +10 -0
- package/dist/core/workflow-model/normalize-step-outputs.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-step-outputs.js +32 -0
- package/dist/core/workflow-model/normalize-step-outputs.js.map +1 -0
- package/dist/core/workflow-model/normalize-triggers.d.ts +11 -0
- package/dist/core/workflow-model/normalize-triggers.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-triggers.js +128 -0
- package/dist/core/workflow-model/normalize-triggers.js.map +1 -0
- package/dist/core/workflow-model/normalize-workflow-document.d.ts +11 -0
- package/dist/core/workflow-model/normalize-workflow-document.d.ts.map +1 -0
- package/dist/core/workflow-model/normalize-workflow-document.js +43 -0
- package/dist/core/workflow-model/normalize-workflow-document.js.map +1 -0
- package/dist/core/workflow-model/parse-duration-ms.d.ts +11 -0
- package/dist/core/workflow-model/parse-duration-ms.d.ts.map +1 -0
- package/dist/core/workflow-model/parse-duration-ms.js +47 -0
- package/dist/core/workflow-model/parse-duration-ms.js.map +1 -0
- package/dist/core/workflow-model/parse-interpolation-field.d.ts +14 -0
- package/dist/core/workflow-model/parse-interpolation-field.d.ts.map +1 -0
- package/dist/core/workflow-model/parse-interpolation-field.js +377 -0
- package/dist/core/workflow-model/parse-interpolation-field.js.map +1 -0
- package/dist/core/workflow-model/stable-id.d.ts +2 -0
- package/dist/core/workflow-model/stable-id.d.ts.map +1 -0
- package/dist/core/workflow-model/stable-id.js +8 -0
- package/dist/core/workflow-model/stable-id.js.map +1 -0
- package/dist/core/workflow-model/validate-job-references.d.ts +10 -0
- package/dist/core/workflow-model/validate-job-references.d.ts.map +1 -0
- package/dist/core/workflow-model/validate-job-references.js +42 -0
- package/dist/core/workflow-model/validate-job-references.js.map +1 -0
- package/dist/core/workflow-model/validate-predicate-expression.d.ts +14 -0
- package/dist/core/workflow-model/validate-predicate-expression.d.ts.map +1 -0
- package/dist/core/workflow-model/validate-predicate-expression.js +273 -0
- package/dist/core/workflow-model/validate-predicate-expression.js.map +1 -0
- package/dist/core/workflow-model/validation-issue.d.ts +8 -0
- package/dist/core/workflow-model/validation-issue.d.ts.map +1 -0
- package/dist/core/workflow-model/validation-issue.js +17 -0
- package/dist/core/workflow-model/validation-issue.js.map +1 -0
- package/dist/core/workflow-model/workflow-field-label.d.ts +3 -0
- package/dist/core/workflow-model/workflow-field-label.d.ts.map +1 -0
- package/dist/core/workflow-model/workflow-field-label.js +47 -0
- package/dist/core/workflow-model/workflow-field-label.js.map +1 -0
- package/dist/core/workflow-yaml/index.d.ts +3 -0
- package/dist/core/workflow-yaml/index.d.ts.map +1 -0
- package/dist/core/workflow-yaml/index.js +4 -0
- package/dist/core/workflow-yaml/index.js.map +1 -0
- package/dist/core/workflow-yaml/invalid-workflow-yaml-error.d.ts +16 -0
- package/dist/core/workflow-yaml/invalid-workflow-yaml-error.d.ts.map +1 -0
- package/dist/core/workflow-yaml/invalid-workflow-yaml-error.js +12 -0
- package/dist/core/workflow-yaml/invalid-workflow-yaml-error.js.map +1 -0
- package/dist/core/workflow-yaml/parse-workflow-yaml.d.ts +9 -0
- package/dist/core/workflow-yaml/parse-workflow-yaml.d.ts.map +1 -0
- package/dist/core/workflow-yaml/parse-workflow-yaml.js +52 -0
- package/dist/core/workflow-yaml/parse-workflow-yaml.js.map +1 -0
- package/dist/core/workflow-yaml/source-locations.d.ts +3 -0
- package/dist/core/workflow-yaml/source-locations.d.ts.map +1 -0
- package/dist/core/workflow-yaml/source-locations.js +48 -0
- package/dist/core/workflow-yaml/source-locations.js.map +1 -0
- package/dist/db/db.d.ts +1277 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +22 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/definition-triggers.d.ts +4 -0
- package/dist/db/definition-triggers.d.ts.map +1 -0
- package/dist/db/definition-triggers.js +17 -0
- package/dist/db/definition-triggers.js.map +1 -0
- package/dist/db/definitions.d.ts +63 -0
- package/dist/db/definitions.d.ts.map +1 -0
- package/dist/db/definitions.js +208 -0
- package/dist/db/definitions.js.map +1 -0
- package/dist/db/index.d.ts +8 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +10 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/definitions.d.ts +237 -0
- package/dist/db/schema/definitions.d.ts.map +1 -0
- package/dist/db/schema/definitions.js +63 -0
- package/dist/db/schema/definitions.js.map +1 -0
- package/dist/db/schema/outbox.d.ts +195 -0
- package/dist/db/schema/outbox.d.ts.map +1 -0
- package/dist/db/schema/outbox.js +5 -0
- package/dist/db/schema/outbox.js.map +1 -0
- package/dist/db/schema/sync-states.d.ts +218 -0
- package/dist/db/schema/sync-states.d.ts.map +1 -0
- package/dist/db/schema/sync-states.js +68 -0
- package/dist/db/schema/sync-states.js.map +1 -0
- package/dist/db/sync-states.d.ts +21 -0
- package/dist/db/sync-states.d.ts.map +1 -0
- package/dist/db/sync-states.js +47 -0
- package/dist/db/sync-states.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/presentation/dto/definition.d.ts +6 -0
- package/dist/presentation/dto/definition.d.ts.map +1 -0
- package/dist/presentation/dto/definition.js +35 -0
- package/dist/presentation/dto/definition.js.map +1 -0
- package/dist/presentation/dto/index.d.ts +2 -0
- package/dist/presentation/dto/index.d.ts.map +1 -0
- package/dist/presentation/dto/index.js +3 -0
- package/dist/presentation/dto/index.js.map +1 -0
- package/dist/presentation/index.d.ts +2 -0
- package/dist/presentation/index.d.ts.map +1 -0
- package/dist/presentation/index.js +3 -0
- package/dist/presentation/index.js.map +1 -0
- package/dist/presentation/routes/create-definition.d.ts +9 -0
- package/dist/presentation/routes/create-definition.d.ts.map +1 -0
- package/dist/presentation/routes/create-definition.js +76 -0
- package/dist/presentation/routes/create-definition.js.map +1 -0
- package/dist/presentation/routes/get-definition.d.ts +2 -0
- package/dist/presentation/routes/get-definition.d.ts.map +1 -0
- package/dist/presentation/routes/get-definition.js +43 -0
- package/dist/presentation/routes/get-definition.js.map +1 -0
- package/dist/presentation/routes/index.d.ts +7 -0
- package/dist/presentation/routes/index.d.ts.map +1 -0
- package/dist/presentation/routes/index.js +22 -0
- package/dist/presentation/routes/index.js.map +1 -0
- package/dist/presentation/routes/list-definitions.d.ts +2 -0
- package/dist/presentation/routes/list-definitions.d.ts.map +1 -0
- package/dist/presentation/routes/list-definitions.js +56 -0
- package/dist/presentation/routes/list-definitions.js.map +1 -0
- package/dist/presentation/routes/validate-definition.d.ts +2 -0
- package/dist/presentation/routes/validate-definition.d.ts.map +1 -0
- package/dist/presentation/routes/validate-definition.js +43 -0
- package/dist/presentation/routes/validate-definition.js.map +1 -0
- package/dist/presentation/subscribers/index.d.ts +3 -0
- package/dist/presentation/subscribers/index.d.ts.map +1 -0
- package/dist/presentation/subscribers/index.js +4 -0
- package/dist/presentation/subscribers/index.js.map +1 -0
- package/dist/presentation/subscribers/on-project-source-bound.d.ts +3 -0
- package/dist/presentation/subscribers/on-project-source-bound.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-project-source-bound.js +11 -0
- package/dist/presentation/subscribers/on-project-source-bound.js.map +1 -0
- package/dist/presentation/subscribers/on-project-source-commit-observed.d.ts +3 -0
- package/dist/presentation/subscribers/on-project-source-commit-observed.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-project-source-commit-observed.js +13 -0
- package/dist/presentation/subscribers/on-project-source-commit-observed.js.map +1 -0
- package/dist/presentation/subscribers/start-definition-sync.d.ts +10 -0
- package/dist/presentation/subscribers/start-definition-sync.d.ts.map +1 -0
- package/dist/presentation/subscribers/start-definition-sync.js +26 -0
- package/dist/presentation/subscribers/start-definition-sync.js.map +1 -0
- package/dist/temporal/activities/index.d.ts +3 -0
- package/dist/temporal/activities/index.d.ts.map +1 -0
- package/dist/temporal/activities/index.js +3 -0
- package/dist/temporal/activities/index.js.map +1 -0
- package/dist/temporal/activities/sync-activities.d.ts +47 -0
- package/dist/temporal/activities/sync-activities.d.ts.map +1 -0
- package/dist/temporal/activities/sync-activities.js +128 -0
- package/dist/temporal/activities/sync-activities.js.map +1 -0
- package/dist/temporal/constants.d.ts +3 -0
- package/dist/temporal/constants.d.ts.map +1 -0
- package/dist/temporal/constants.js +4 -0
- package/dist/temporal/constants.js.map +1 -0
- package/dist/temporal/index.d.ts +3 -0
- package/dist/temporal/index.d.ts.map +1 -0
- package/dist/temporal/index.js +4 -0
- package/dist/temporal/index.js.map +1 -0
- package/dist/temporal/workflows/definition-sync.d.ts +20 -0
- package/dist/temporal/workflows/definition-sync.d.ts.map +1 -0
- package/dist/temporal/workflows/definition-sync.js +95 -0
- package/dist/temporal/workflows/definition-sync.js.map +1 -0
- package/dist/temporal/workflows/index.d.ts +2 -0
- package/dist/temporal/workflows/index.d.ts.map +1 -0
- package/dist/temporal/workflows/index.js +3 -0
- package/dist/temporal/workflows/index.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_initial.sql +64 -0
- package/drizzle/0001_definition_list_pagination.sql +1 -0
- package/drizzle/meta/0000_snapshot.json +527 -0
- package/drizzle/meta/_journal.json +20 -0
- package/drizzle.config.ts +11 -0
- package/package.json +89 -0
- package/src/config.test.ts +23 -0
- package/src/config.ts +50 -0
- package/src/core/entities/index.ts +4 -0
- package/src/core/entities/integration-context.ts +21 -0
- package/src/core/entities/sync-state.ts +40 -0
- package/src/core/entities/workflow-definition.ts +38 -0
- package/src/core/entities/workflow-model.ts +162 -0
- package/src/core/errors.ts +21 -0
- package/src/core/has-agent-step-integrations.ts +7 -0
- package/src/core/index.ts +23 -0
- package/src/core/parse-definition.test.ts +200 -0
- package/src/core/parse-definition.ts +28 -0
- package/src/core/sync-definitions.test.ts +390 -0
- package/src/core/sync-definitions.ts +216 -0
- package/src/core/validate-definition.test.ts +152 -0
- package/src/core/validate-definition.ts +72 -0
- package/src/core/workflow-model/README.md +129 -0
- package/src/core/workflow-model/constants.ts +1 -0
- package/src/core/workflow-model/cron-trigger.test.ts +29 -0
- package/src/core/workflow-model/cron-trigger.ts +83 -0
- package/src/core/workflow-model/index.ts +9 -0
- package/src/core/workflow-model/invalid-workflow-model-error.ts +71 -0
- package/src/core/workflow-model/map-job-ids.ts +33 -0
- package/src/core/workflow-model/normalize-agent-integrations.ts +208 -0
- package/src/core/workflow-model/normalize-dependencies.ts +139 -0
- package/src/core/workflow-model/normalize-env.ts +48 -0
- package/src/core/workflow-model/normalize-if-condition.ts +126 -0
- package/src/core/workflow-model/normalize-job-checkout.ts +19 -0
- package/src/core/workflow-model/normalize-job-listening.ts +121 -0
- package/src/core/workflow-model/normalize-job-success.ts +28 -0
- package/src/core/workflow-model/normalize-jobs.ts +1010 -0
- package/src/core/workflow-model/normalize-needs.ts +12 -0
- package/src/core/workflow-model/normalize-step-gate.ts +90 -0
- package/src/core/workflow-model/normalize-step-outputs.ts +36 -0
- package/src/core/workflow-model/normalize-triggers.ts +130 -0
- package/src/core/workflow-model/normalize-workflow-document.test.ts +4463 -0
- package/src/core/workflow-model/normalize-workflow-document.ts +63 -0
- package/src/core/workflow-model/parse-duration-ms.ts +58 -0
- package/src/core/workflow-model/parse-interpolation-field.ts +566 -0
- package/src/core/workflow-model/stable-id.ts +12 -0
- package/src/core/workflow-model/validate-job-references.ts +54 -0
- package/src/core/workflow-model/validate-predicate-expression.test.ts +161 -0
- package/src/core/workflow-model/validate-predicate-expression.ts +406 -0
- package/src/core/workflow-model/validation-issue.ts +27 -0
- package/src/core/workflow-model/workflow-field-label.ts +50 -0
- package/src/core/workflow-yaml/README.md +77 -0
- package/src/core/workflow-yaml/index.ts +11 -0
- package/src/core/workflow-yaml/invalid-workflow-yaml-error.ts +23 -0
- package/src/core/workflow-yaml/parse-workflow-yaml.test.ts +71 -0
- package/src/core/workflow-yaml/parse-workflow-yaml.ts +74 -0
- package/src/core/workflow-yaml/source-locations.ts +62 -0
- package/src/db/db.ts +18 -0
- package/src/db/definition-triggers.test.ts +95 -0
- package/src/db/definition-triggers.ts +17 -0
- package/src/db/definitions.test.ts +1309 -0
- package/src/db/definitions.ts +357 -0
- package/src/db/index.ts +31 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/definitions.test.ts +36 -0
- package/src/db/schema/definitions.ts +76 -0
- package/src/db/schema/outbox.ts +4 -0
- package/src/db/schema/sync-states.ts +79 -0
- package/src/db/sync-states.test.ts +90 -0
- package/src/db/sync-states.ts +86 -0
- package/src/index.ts +104 -0
- package/src/presentation/dto/definition.test.ts +59 -0
- package/src/presentation/dto/definition.ts +41 -0
- package/src/presentation/dto/index.ts +1 -0
- package/src/presentation/index.ts +1 -0
- package/src/presentation/routes/create-definition.test.ts +356 -0
- package/src/presentation/routes/create-definition.ts +101 -0
- package/src/presentation/routes/get-definition.test.ts +79 -0
- package/src/presentation/routes/get-definition.ts +37 -0
- package/src/presentation/routes/index.test.ts +41 -0
- package/src/presentation/routes/index.ts +28 -0
- package/src/presentation/routes/list-definitions.test.ts +195 -0
- package/src/presentation/routes/list-definitions.ts +49 -0
- package/src/presentation/routes/validate-definition.test.ts +63 -0
- package/src/presentation/routes/validate-definition.ts +46 -0
- package/src/presentation/subscribers/index.ts +2 -0
- package/src/presentation/subscribers/on-project-source-bound.test.ts +65 -0
- package/src/presentation/subscribers/on-project-source-bound.ts +11 -0
- package/src/presentation/subscribers/on-project-source-commit-observed.test.ts +56 -0
- package/src/presentation/subscribers/on-project-source-commit-observed.ts +15 -0
- package/src/presentation/subscribers/start-definition-sync.ts +38 -0
- package/src/temporal/activities/index.ts +10 -0
- package/src/temporal/activities/sync-activities.test.ts +337 -0
- package/src/temporal/activities/sync-activities.ts +206 -0
- package/src/temporal/constants.ts +2 -0
- package/src/temporal/index.ts +2 -0
- package/src/temporal/workflows/definition-sync.test.ts +59 -0
- package/src/temporal/workflows/definition-sync.ts +116 -0
- package/src/temporal/workflows/index.ts +1 -0
- package/test/env.ts +7 -0
- package/test/factories/definition.ts +66 -0
- package/test/fixtures/invalid-cycle.yml +13 -0
- package/test/fixtures/invalid-missing-name.yml +4 -0
- package/test/fixtures/invalid-yaml-syntax.yml +6 -0
- package/test/fixtures/valid-dag.yml +25 -0
- package/test/fixtures/valid-listening-job.yml +21 -0
- package/test/fixtures/valid-simple.yml +18 -0
- package/test/fixtures/workflow-yaml/invalid/invalid-yaml-syntax.yaml +6 -0
- package/test/fixtures/workflow-yaml/invalid/missing-step-run.yaml +5 -0
- package/test/fixtures/workflow-yaml/valid/simple-build.document.json +26 -0
- package/test/fixtures/workflow-yaml/valid/simple-build.yaml +14 -0
- package/test/globalSetup.ts +25 -0
- package/test/index.ts +1 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vitest.config.ts +11 -0
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shipfox/api-definitions",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"version": "2.0.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
8
|
+
"directory": "libs/api/definitions"
|
|
9
|
+
},
|
|
10
|
+
"private": false,
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"imports": {
|
|
15
|
+
"#test/*": "./test/*",
|
|
16
|
+
"#*": {
|
|
17
|
+
"workspace-source": "./src/*",
|
|
18
|
+
"development": "./src/*",
|
|
19
|
+
"default": "./dist/*"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"development": {
|
|
25
|
+
"types": "./src/index.ts",
|
|
26
|
+
"default": "./src/index.ts"
|
|
27
|
+
},
|
|
28
|
+
"default": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@temporalio/activity": "^1.16.1",
|
|
36
|
+
"@temporalio/common": "^1.16.1",
|
|
37
|
+
"@temporalio/workflow": "^1.16.1",
|
|
38
|
+
"cron-parser": "^5.6.1",
|
|
39
|
+
"drizzle-orm": "^0.45.2",
|
|
40
|
+
"js-yaml": "^4.1.0",
|
|
41
|
+
"yaml": "^2.8.3",
|
|
42
|
+
"zod": "^4.4.3",
|
|
43
|
+
"@shipfox/api-agent-dto": "2.0.0",
|
|
44
|
+
"@shipfox/api-auth-context": "2.0.0",
|
|
45
|
+
"@shipfox/api-definitions-dto": "2.0.0",
|
|
46
|
+
"@shipfox/api-integration-core": "2.0.0",
|
|
47
|
+
"@shipfox/api-integration-core-dto": "2.0.0",
|
|
48
|
+
"@shipfox/api-projects": "2.0.0",
|
|
49
|
+
"@shipfox/api-projects-dto": "2.0.0",
|
|
50
|
+
"@shipfox/config": "1.2.1",
|
|
51
|
+
"@shipfox/api-secrets-dto": "2.0.0",
|
|
52
|
+
"@shipfox/node-module": "0.2.0",
|
|
53
|
+
"@shipfox/expression": "1.1.1",
|
|
54
|
+
"@shipfox/node-fastify": "0.2.1",
|
|
55
|
+
"@shipfox/node-opentelemetry": "0.5.0",
|
|
56
|
+
"@shipfox/node-outbox": "0.2.1",
|
|
57
|
+
"@shipfox/node-postgres": "0.4.1",
|
|
58
|
+
"@shipfox/node-drizzle": "0.2.1",
|
|
59
|
+
"@shipfox/runner-labels": "0.1.0",
|
|
60
|
+
"@shipfox/workflow-document": "2.0.1",
|
|
61
|
+
"@shipfox/node-temporal": "0.2.0"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@temporalio/client": "^1.16.1",
|
|
65
|
+
"@temporalio/testing": "^1.16.1",
|
|
66
|
+
"@temporalio/worker": "^1.16.1",
|
|
67
|
+
"@types/js-yaml": "^4.0.9",
|
|
68
|
+
"@types/pg": "^8.15.5",
|
|
69
|
+
"drizzle-kit": "^0.31.10",
|
|
70
|
+
"fastify": "^5.3.3",
|
|
71
|
+
"fastify-type-provider-zod": "^6.0.0",
|
|
72
|
+
"fishery": "^2.2.2",
|
|
73
|
+
"@shipfox/regex": "0.2.1",
|
|
74
|
+
"@shipfox/swc": "1.2.5",
|
|
75
|
+
"@shipfox/biome": "1.8.1",
|
|
76
|
+
"@shipfox/typescript": "1.1.6",
|
|
77
|
+
"@shipfox/vitest": "1.2.2",
|
|
78
|
+
"@shipfox/ts-config": "1.3.8"
|
|
79
|
+
},
|
|
80
|
+
"scripts": {
|
|
81
|
+
"build": "shipfox-swc",
|
|
82
|
+
"check": "shipfox-biome-check",
|
|
83
|
+
"check:fix": "shipfox-biome-check --write",
|
|
84
|
+
"test": "shipfox-vitest-run",
|
|
85
|
+
"test:watch": "shipfox-vitest-watch",
|
|
86
|
+
"type": "shipfox-tsc-check",
|
|
87
|
+
"type:emit": "shipfox-tsc-emit"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {parseDefinitionDefaultRunnerLabels} from './config.js';
|
|
2
|
+
|
|
3
|
+
const defaultRunnerLabelEnvPattern = /DEFINITION_DEFAULT_RUNNER_LABEL/;
|
|
4
|
+
|
|
5
|
+
describe('parseDefinitionDefaultRunnerLabels', () => {
|
|
6
|
+
it('canonicalizes comma-delimited default runner labels', () => {
|
|
7
|
+
const labels = parseDefinitionDefaultRunnerLabels(' Ubuntu-Latest,node-22,ubuntu-latest ');
|
|
8
|
+
|
|
9
|
+
expect(labels).toEqual(['node-22', 'ubuntu-latest']);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('rejects invalid configured runner labels with the env var name', () => {
|
|
13
|
+
expect(() => parseDefinitionDefaultRunnerLabels('has space')).toThrow(
|
|
14
|
+
defaultRunnerLabelEnvPattern,
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('rejects too many configured runner labels with the env var name', () => {
|
|
19
|
+
const value = Array.from({length: 21}, (_, index) => `label-${index}`).join(',');
|
|
20
|
+
|
|
21
|
+
expect(() => parseDefinitionDefaultRunnerLabels(value)).toThrow(defaultRunnerLabelEnvPattern);
|
|
22
|
+
});
|
|
23
|
+
});
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildHarnessToolDeploymentConfig,
|
|
3
|
+
type HarnessToolDeploymentConfig,
|
|
4
|
+
} from '@shipfox/api-agent-dto';
|
|
5
|
+
import {bool, createConfig, str} from '@shipfox/config';
|
|
6
|
+
import {findInvalidLabels, MAX_RUNNER_LABELS, parseLabelList} from '@shipfox/runner-labels';
|
|
7
|
+
|
|
8
|
+
export const config = createConfig({
|
|
9
|
+
DEFINITION_DEFAULT_RUNNER_LABEL: str({
|
|
10
|
+
desc: 'Default runner label(s) applied to workflow jobs that do not declare a "runner" at the job or workflow level. Set it to a comma-separated list, for example ubuntu-latest or ubuntu-latest,node-22. Leave it empty to require every workflow job to declare runner labels explicitly; with no value set, a job without a runner fails definition validation.',
|
|
11
|
+
default: '',
|
|
12
|
+
}),
|
|
13
|
+
AGENT_PI_ENABLED_TOOL_PACKAGES: str({
|
|
14
|
+
desc: 'Comma-separated optional Pi tool packages enabled for this deployment. Defaults to pi-web-access so Pi web access is available. Set it to an empty value to enable only Pi built-in tools. Accepted values: pi-web-access.',
|
|
15
|
+
default: 'pi-web-access',
|
|
16
|
+
}),
|
|
17
|
+
AGENT_PI_WEB_SEARCH_ENABLED: bool({
|
|
18
|
+
desc: 'Enables Pi web search tools when pi-web-access is enabled. Set it to false to disable web_search and get_search_content while keeping fetch_content available.',
|
|
19
|
+
default: true,
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export function parseDefinitionDefaultRunnerLabels(value: string): readonly string[] {
|
|
24
|
+
const labels = parseLabelList(value);
|
|
25
|
+
const invalid = findInvalidLabels(labels);
|
|
26
|
+
|
|
27
|
+
if (invalid.length > 0) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`DEFINITION_DEFAULT_RUNNER_LABEL contains invalid runner label(s): ${invalid.join(', ')}`,
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (labels.length > MAX_RUNNER_LABELS) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`DEFINITION_DEFAULT_RUNNER_LABEL contains ${labels.length} runner labels; the maximum is ${MAX_RUNNER_LABELS}`,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return labels;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const definitionDefaultRunnerLabels = parseDefinitionDefaultRunnerLabels(
|
|
43
|
+
config.DEFINITION_DEFAULT_RUNNER_LABEL,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
export const definitionHarnessToolDeploymentConfig: HarnessToolDeploymentConfig =
|
|
47
|
+
buildHarnessToolDeploymentConfig({
|
|
48
|
+
piEnabledToolPackages: config.AGENT_PI_ENABLED_TOOL_PACKAGES,
|
|
49
|
+
piWebSearchEnabled: config.AGENT_PI_WEB_SEARCH_ENABLED,
|
|
50
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AgentToolSelectionCatalog,
|
|
3
|
+
IntegrationCapability,
|
|
4
|
+
IntegrationProviderKind,
|
|
5
|
+
} from '@shipfox/api-integration-core-dto';
|
|
6
|
+
|
|
7
|
+
export interface IntegrationValidationContext {
|
|
8
|
+
readonly agentToolSelectionCatalogs: ReadonlyMap<
|
|
9
|
+
IntegrationProviderKind,
|
|
10
|
+
AgentToolSelectionCatalog
|
|
11
|
+
>;
|
|
12
|
+
readonly workspaceConnectionSnapshot: ReadonlyMap<
|
|
13
|
+
string,
|
|
14
|
+
{
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly provider: IntegrationProviderKind;
|
|
17
|
+
readonly capabilities: readonly IntegrationCapability[];
|
|
18
|
+
}
|
|
19
|
+
>;
|
|
20
|
+
readonly defaultConnectionSlug?: string | undefined;
|
|
21
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type DefinitionSyncStatus = 'pending' | 'syncing' | 'succeeded' | 'failed';
|
|
2
|
+
|
|
3
|
+
export const DEFINITION_SYNC_ERROR_CODES = [
|
|
4
|
+
'no-workflow-files',
|
|
5
|
+
'invalid-definition',
|
|
6
|
+
'provider-repository-not-found',
|
|
7
|
+
'provider-file-not-found',
|
|
8
|
+
'provider-access-denied',
|
|
9
|
+
'provider-rate-limited',
|
|
10
|
+
'provider-timeout',
|
|
11
|
+
'provider-unavailable',
|
|
12
|
+
'provider-malformed-response',
|
|
13
|
+
'content-too-large',
|
|
14
|
+
'too-many-files',
|
|
15
|
+
'connection-unavailable',
|
|
16
|
+
'unknown',
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
export type DefinitionSyncErrorCode = (typeof DEFINITION_SYNC_ERROR_CODES)[number];
|
|
20
|
+
|
|
21
|
+
export function isDefinitionSyncErrorCode(value: unknown): value is DefinitionSyncErrorCode {
|
|
22
|
+
return (
|
|
23
|
+
typeof value === 'string' && (DEFINITION_SYNC_ERROR_CODES as readonly string[]).includes(value)
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface DefinitionSyncState {
|
|
28
|
+
id: string;
|
|
29
|
+
projectId: string;
|
|
30
|
+
sourceConnectionId: string;
|
|
31
|
+
sourceExternalRepositoryId: string;
|
|
32
|
+
ref: string;
|
|
33
|
+
status: DefinitionSyncStatus;
|
|
34
|
+
lastErrorCode: DefinitionSyncErrorCode | null;
|
|
35
|
+
lastErrorMessage: string | null;
|
|
36
|
+
startedAt: Date | null;
|
|
37
|
+
finishedAt: Date | null;
|
|
38
|
+
createdAt: Date;
|
|
39
|
+
updatedAt: Date;
|
|
40
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {WorkflowDocument} from '@shipfox/workflow-document';
|
|
2
|
+
import type {WorkflowModel} from './workflow-model.js';
|
|
3
|
+
|
|
4
|
+
export type WorkflowSpec = WorkflowDocument;
|
|
5
|
+
|
|
6
|
+
export interface WorkflowSourceSnapshot {
|
|
7
|
+
content: string;
|
|
8
|
+
format: 'yaml';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface WorkflowDefinitionPayload {
|
|
12
|
+
document: WorkflowDocument;
|
|
13
|
+
model: WorkflowModel;
|
|
14
|
+
sourceSnapshot?: WorkflowSourceSnapshot | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface WorkflowDefinition {
|
|
18
|
+
id: string;
|
|
19
|
+
projectId: string;
|
|
20
|
+
configPath: string | null;
|
|
21
|
+
source: 'manual' | 'vcs';
|
|
22
|
+
sha: string | null;
|
|
23
|
+
ref: string | null;
|
|
24
|
+
name: string;
|
|
25
|
+
/**
|
|
26
|
+
* Compatibility alias for packages that still consume the authoring document
|
|
27
|
+
* before they migrate to `document`/`model`.
|
|
28
|
+
*/
|
|
29
|
+
definition: WorkflowSpec;
|
|
30
|
+
document: WorkflowDocument;
|
|
31
|
+
model: WorkflowModel;
|
|
32
|
+
sourceSnapshot: WorkflowSourceSnapshot | null;
|
|
33
|
+
contentHash: string | null;
|
|
34
|
+
fetchedAt: Date;
|
|
35
|
+
createdAt: Date;
|
|
36
|
+
updatedAt: Date;
|
|
37
|
+
deletedAt: Date | null;
|
|
38
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ExpressionType,
|
|
3
|
+
OutputDeclarations,
|
|
4
|
+
ResolvedFieldSegment,
|
|
5
|
+
WorkflowExpression,
|
|
6
|
+
} from '@shipfox/expression';
|
|
7
|
+
import type {AgentThinking, Harness} from '@shipfox/workflow-document';
|
|
8
|
+
|
|
9
|
+
export type WorkflowFieldTemplate = readonly ResolvedFieldSegment[];
|
|
10
|
+
export type WorkflowEnvTemplates = Readonly<Record<string, WorkflowFieldTemplate>>;
|
|
11
|
+
export type WorkflowOutputTemplates = Readonly<Record<string, WorkflowFieldTemplate>>;
|
|
12
|
+
|
|
13
|
+
export interface WorkflowModel {
|
|
14
|
+
readonly kind: 'workflow';
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
17
|
+
readonly templates?: {
|
|
18
|
+
readonly env?: WorkflowEnvTemplates;
|
|
19
|
+
};
|
|
20
|
+
readonly triggers: readonly WorkflowModelTrigger[];
|
|
21
|
+
readonly jobs: readonly WorkflowModelJob[];
|
|
22
|
+
readonly dependencies: readonly WorkflowModelDependency[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface WorkflowModelTrigger {
|
|
26
|
+
readonly id: string;
|
|
27
|
+
readonly key: string;
|
|
28
|
+
readonly source: string;
|
|
29
|
+
readonly event: string;
|
|
30
|
+
readonly inputs?: Readonly<Record<string, unknown>>;
|
|
31
|
+
readonly filter?: string;
|
|
32
|
+
readonly config?: Readonly<Record<string, unknown>>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface WorkflowModelJob {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly key: string;
|
|
38
|
+
readonly mode: WorkflowModelJobMode;
|
|
39
|
+
readonly runner: readonly string[];
|
|
40
|
+
readonly runnerTemplates?: readonly WorkflowFieldTemplate[];
|
|
41
|
+
readonly checkout: WorkflowModelJobCheckout;
|
|
42
|
+
readonly if?: WorkflowExpression;
|
|
43
|
+
readonly success?: string;
|
|
44
|
+
readonly outputs?: WorkflowOutputTemplates;
|
|
45
|
+
readonly outputTypes?: Readonly<Record<string, ExpressionType>>;
|
|
46
|
+
readonly executionTimeoutMs?: number;
|
|
47
|
+
readonly listening?: WorkflowModelJobListening;
|
|
48
|
+
readonly name?: WorkflowFieldTemplate;
|
|
49
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
50
|
+
readonly templates?: {
|
|
51
|
+
readonly env?: WorkflowEnvTemplates;
|
|
52
|
+
};
|
|
53
|
+
readonly dependencies: readonly string[];
|
|
54
|
+
readonly steps: readonly WorkflowModelStep[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type WorkflowModelJobMode = 'one_shot' | 'listening';
|
|
58
|
+
|
|
59
|
+
export interface WorkflowModelJobListening {
|
|
60
|
+
readonly on: readonly WorkflowModelListeningTrigger[];
|
|
61
|
+
readonly until?: readonly WorkflowModelListeningTrigger[];
|
|
62
|
+
readonly timeoutMs?: number;
|
|
63
|
+
readonly maxExecutions?: number;
|
|
64
|
+
readonly batch?: WorkflowModelListeningBatch;
|
|
65
|
+
readonly onResolve: 'finish' | 'cancel';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface WorkflowModelListeningTrigger {
|
|
69
|
+
readonly source: string;
|
|
70
|
+
readonly event: string;
|
|
71
|
+
readonly inputs?: Readonly<Record<string, unknown>>;
|
|
72
|
+
readonly filter?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface WorkflowModelListeningBatch {
|
|
76
|
+
readonly debounceMs?: number;
|
|
77
|
+
readonly maxSize?: number;
|
|
78
|
+
readonly maxWaitMs?: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface WorkflowModelJobCheckout {
|
|
82
|
+
readonly permissions: {readonly contents: 'read' | 'write'};
|
|
83
|
+
readonly persistCredentials: boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type WorkflowModelStep = WorkflowModelRunStep | WorkflowModelAgentStep;
|
|
87
|
+
|
|
88
|
+
interface WorkflowModelStepBase {
|
|
89
|
+
readonly id: string;
|
|
90
|
+
readonly key?: string;
|
|
91
|
+
readonly if?: WorkflowExpression;
|
|
92
|
+
readonly name?: string;
|
|
93
|
+
readonly outputs?: OutputDeclarations;
|
|
94
|
+
readonly gate?: WorkflowModelStepGate;
|
|
95
|
+
readonly sourceLocation?: WorkflowSourceLocation;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface WorkflowModelRunStep extends WorkflowModelStepBase {
|
|
99
|
+
readonly kind: 'run';
|
|
100
|
+
readonly command: WorkflowModelRunCommand;
|
|
101
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
102
|
+
readonly templates?: {
|
|
103
|
+
readonly command?: WorkflowFieldTemplate;
|
|
104
|
+
readonly name?: WorkflowFieldTemplate;
|
|
105
|
+
readonly env?: WorkflowEnvTemplates;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface WorkflowModelAgentStep extends WorkflowModelStepBase {
|
|
110
|
+
readonly kind: 'agent';
|
|
111
|
+
readonly harness?: Harness;
|
|
112
|
+
readonly model?: string;
|
|
113
|
+
readonly provider?: string;
|
|
114
|
+
readonly thinking?: AgentThinking;
|
|
115
|
+
readonly tools?: readonly string[];
|
|
116
|
+
readonly integrations?: readonly WorkflowModelStepIntegration[];
|
|
117
|
+
readonly prompt: string;
|
|
118
|
+
readonly templates?: {
|
|
119
|
+
readonly prompt?: WorkflowFieldTemplate;
|
|
120
|
+
readonly model?: WorkflowFieldTemplate;
|
|
121
|
+
readonly provider?: WorkflowFieldTemplate;
|
|
122
|
+
readonly name?: WorkflowFieldTemplate;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface WorkflowModelStepIntegration {
|
|
127
|
+
readonly connection?: string;
|
|
128
|
+
readonly include: readonly string[];
|
|
129
|
+
readonly exclude?: readonly string[];
|
|
130
|
+
readonly allowWrite: boolean;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface WorkflowSourceLocation {
|
|
134
|
+
readonly startLine: number;
|
|
135
|
+
readonly endLine: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export type WorkflowStepSourceLocationMap = ReadonlyMap<
|
|
139
|
+
string,
|
|
140
|
+
ReadonlyMap<number, WorkflowSourceLocation>
|
|
141
|
+
>;
|
|
142
|
+
|
|
143
|
+
export interface WorkflowModelRunCommand {
|
|
144
|
+
readonly kind: 'shell';
|
|
145
|
+
readonly value: string;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface WorkflowModelStepGate {
|
|
149
|
+
readonly success?: WorkflowExpression;
|
|
150
|
+
readonly onFailure?: WorkflowModelStepFailureAction;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface WorkflowModelStepFailureAction {
|
|
154
|
+
readonly restartFrom: string;
|
|
155
|
+
readonly feedback?: string;
|
|
156
|
+
readonly feedbackTemplate?: WorkflowFieldTemplate;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface WorkflowModelDependency {
|
|
160
|
+
readonly from: string;
|
|
161
|
+
readonly to: string;
|
|
162
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type {DefinitionSyncErrorCode} from './entities/sync-state.js';
|
|
2
|
+
|
|
3
|
+
export class DefinitionParseError extends Error {
|
|
4
|
+
constructor(
|
|
5
|
+
message: string,
|
|
6
|
+
public details?: unknown,
|
|
7
|
+
) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'DefinitionParseError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class DefinitionSyncPermanentError extends Error {
|
|
14
|
+
constructor(
|
|
15
|
+
public readonly code: DefinitionSyncErrorCode,
|
|
16
|
+
message: string,
|
|
17
|
+
) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = 'DefinitionSyncPermanentError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type {WorkflowDocument} from '@shipfox/workflow-document';
|
|
2
|
+
|
|
3
|
+
export function hasAgentStepIntegrations(document: WorkflowDocument): boolean {
|
|
4
|
+
return Object.values(document.jobs).some((job) =>
|
|
5
|
+
job.steps.some((step) => step.integrations !== undefined),
|
|
6
|
+
);
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type * from './entities/index.js';
|
|
2
|
+
export {DefinitionParseError, DefinitionSyncPermanentError} from './errors.js';
|
|
3
|
+
export {parseDefinition} from './parse-definition.js';
|
|
4
|
+
export {
|
|
5
|
+
classifySyncFailure,
|
|
6
|
+
type DiscoverWorkflowFilesParams,
|
|
7
|
+
discoverWorkflowFiles,
|
|
8
|
+
type FetchAndParseWorkflowsParams,
|
|
9
|
+
FILE_FETCH_CONCURRENCY,
|
|
10
|
+
fetchAndParseWorkflows,
|
|
11
|
+
MAX_WORKFLOW_FILES,
|
|
12
|
+
type ParsedWorkflow,
|
|
13
|
+
type ResolvedSyncSource,
|
|
14
|
+
resolveSyncSource,
|
|
15
|
+
type SyncFailureClassification,
|
|
16
|
+
type SyncSourceContext,
|
|
17
|
+
UNRESOLVED_SYNC_REF,
|
|
18
|
+
WORKFLOW_PREFIX,
|
|
19
|
+
} from './sync-definitions.js';
|
|
20
|
+
export {DEFAULT_RUN_TIMEOUT_MS} from './workflow-model/constants.js';
|
|
21
|
+
export {normalizeWorkflowDocument} from './workflow-model/index.js';
|
|
22
|
+
export {DEFAULT_JOB_CHECKOUT} from './workflow-model/normalize-job-checkout.js';
|
|
23
|
+
export {DEFAULT_JOB_SUCCESS} from './workflow-model/normalize-job-success.js';
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import {readFileSync} from 'node:fs';
|
|
2
|
+
import {dirname, resolve} from 'node:path';
|
|
3
|
+
import {fileURLToPath} from 'node:url';
|
|
4
|
+
import {DefinitionParseError} from './errors.js';
|
|
5
|
+
import {parseDefinition} from './parse-definition.js';
|
|
6
|
+
|
|
7
|
+
const fixturesDir = resolve(dirname(fileURLToPath(import.meta.url)), '../../test/fixtures');
|
|
8
|
+
|
|
9
|
+
function readFixture(name: string): string {
|
|
10
|
+
return readFileSync(resolve(fixturesDir, name), 'utf-8');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
describe('parseDefinition', () => {
|
|
14
|
+
test('valid simple workflow returns document and model', () => {
|
|
15
|
+
const yaml = readFixture('valid-simple.yml');
|
|
16
|
+
|
|
17
|
+
const definition = parseDefinition(yaml);
|
|
18
|
+
|
|
19
|
+
expect(definition.document.name).toBe('Simple build');
|
|
20
|
+
expect(definition.document.triggers?.on_push?.source).toBe('github_acme');
|
|
21
|
+
expect(definition.document.triggers?.on_push?.event).toBe('push');
|
|
22
|
+
expect(definition.document.triggers?.on_demand?.source).toBe('manual');
|
|
23
|
+
expect(definition.document.triggers?.on_demand?.event).toBe('fire');
|
|
24
|
+
expect(definition.document.jobs.build?.steps).toHaveLength(2);
|
|
25
|
+
expect(definition.document.jobs.build?.steps?.[0]?.run).toBe('npm install');
|
|
26
|
+
const firstStep = definition.model.jobs.find((job) => job.id === 'build')?.steps[0];
|
|
27
|
+
expect(firstStep).toMatchObject({kind: 'run', command: {kind: 'shell', value: 'npm install'}});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('valid DAG workflow parses successfully', () => {
|
|
31
|
+
const yaml = readFixture('valid-dag.yml');
|
|
32
|
+
|
|
33
|
+
const definition = parseDefinition(yaml);
|
|
34
|
+
|
|
35
|
+
expect(definition.document.name).toBe('Multi-job pipeline');
|
|
36
|
+
expect(Object.keys(definition.document.jobs)).toHaveLength(4);
|
|
37
|
+
expect(definition.model.dependencies).toEqual([
|
|
38
|
+
{from: 'build', to: 'test-unit'},
|
|
39
|
+
{from: 'build', to: 'test-integration'},
|
|
40
|
+
{from: 'test-unit', to: 'deploy'},
|
|
41
|
+
{from: 'test-integration', to: 'deploy'},
|
|
42
|
+
]);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('valid listening job workflow parses successfully', () => {
|
|
46
|
+
const yaml = readFixture('valid-listening-job.yml');
|
|
47
|
+
|
|
48
|
+
const definition = parseDefinition(yaml);
|
|
49
|
+
|
|
50
|
+
expect(definition.model.jobs[0]).toMatchObject({
|
|
51
|
+
id: 'review',
|
|
52
|
+
key: 'review',
|
|
53
|
+
mode: 'listening',
|
|
54
|
+
listening: {
|
|
55
|
+
on: [{source: 'github', event: 'pull_request_review'}],
|
|
56
|
+
until: [{source: 'github', event: 'pull_request'}],
|
|
57
|
+
timeoutMs: 30 * 24 * 60 * 60 * 1000,
|
|
58
|
+
maxExecutions: 3,
|
|
59
|
+
batch: {debounceMs: 5000, maxSize: 10, maxWaitMs: 60 * 60 * 1000},
|
|
60
|
+
onResolve: 'cancel',
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
expect(definition.model.jobs[0]?.name).toBeDefined();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('attaches source line locations to workflow model steps', () => {
|
|
67
|
+
const yaml = `name: Source locations
|
|
68
|
+
runner: ubuntu-latest
|
|
69
|
+
jobs:
|
|
70
|
+
build:
|
|
71
|
+
steps:
|
|
72
|
+
- name: Install
|
|
73
|
+
run: pnpm install
|
|
74
|
+
# comments between authored steps are not part of either step range
|
|
75
|
+
- run: |
|
|
76
|
+
pnpm test
|
|
77
|
+
pnpm build
|
|
78
|
+
gate:
|
|
79
|
+
success: step.exit_code == 0
|
|
80
|
+
deploy:
|
|
81
|
+
needs: build
|
|
82
|
+
steps:
|
|
83
|
+
- name: Deploy
|
|
84
|
+
run: ./deploy.sh
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
const definition = parseDefinition(yaml);
|
|
88
|
+
|
|
89
|
+
const build = definition.model.jobs.find((job) => job.id === 'build');
|
|
90
|
+
const deploy = definition.model.jobs.find((job) => job.id === 'deploy');
|
|
91
|
+
expect(build?.steps.map((step) => step.sourceLocation)).toEqual([
|
|
92
|
+
{startLine: 6, endLine: 7},
|
|
93
|
+
{startLine: 9, endLine: 13},
|
|
94
|
+
]);
|
|
95
|
+
expect(deploy?.steps.map((step) => step.sourceLocation)).toEqual([
|
|
96
|
+
{startLine: 17, endLine: 18},
|
|
97
|
+
]);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('ends source line locations on the final content line of block scalar steps', () => {
|
|
101
|
+
const yaml = `name: Block scalar
|
|
102
|
+
runner: ubuntu-latest
|
|
103
|
+
jobs:
|
|
104
|
+
build:
|
|
105
|
+
steps:
|
|
106
|
+
- run: |
|
|
107
|
+
echo one
|
|
108
|
+
echo two
|
|
109
|
+
`;
|
|
110
|
+
|
|
111
|
+
const definition = parseDefinition(yaml);
|
|
112
|
+
|
|
113
|
+
expect(definition.model.jobs[0]?.steps[0]?.sourceLocation).toEqual({
|
|
114
|
+
startLine: 6,
|
|
115
|
+
endLine: 8,
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('accepts default runner labels through parse options', () => {
|
|
120
|
+
const yaml = `name: Default runner
|
|
121
|
+
jobs:
|
|
122
|
+
build:
|
|
123
|
+
steps:
|
|
124
|
+
- run: echo hello
|
|
125
|
+
`;
|
|
126
|
+
|
|
127
|
+
const definition = parseDefinition(yaml, {defaultRunnerLabels: ['ubuntu-latest']});
|
|
128
|
+
|
|
129
|
+
expect(definition.model.jobs[0]?.runner).toEqual(['ubuntu-latest']);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('invalid YAML syntax throws DefinitionParseError', () => {
|
|
133
|
+
const yaml = readFixture('invalid-yaml-syntax.yml');
|
|
134
|
+
|
|
135
|
+
expect(() => parseDefinition(yaml)).toThrow(DefinitionParseError);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('YAML that parses to a string throws DefinitionParseError', () => {
|
|
139
|
+
expect(() => parseDefinition('just a string')).toThrow(DefinitionParseError);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('YAML that parses to null throws DefinitionParseError', () => {
|
|
143
|
+
expect(() => parseDefinition('')).toThrow(DefinitionParseError);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test('YAML that parses to an array throws DefinitionParseError', () => {
|
|
147
|
+
expect(() => parseDefinition('- item1\n- item2')).toThrow(DefinitionParseError);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('valid YAML with invalid document throws DefinitionParseError with details', () => {
|
|
151
|
+
const yaml = readFixture('invalid-missing-name.yml');
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
parseDefinition(yaml);
|
|
155
|
+
expect.fail('Expected DefinitionParseError');
|
|
156
|
+
} catch (error) {
|
|
157
|
+
expect(error).toBeInstanceOf(DefinitionParseError);
|
|
158
|
+
expect((error as DefinitionParseError).details).toBeDefined();
|
|
159
|
+
expect(Array.isArray((error as DefinitionParseError).details)).toBe(true);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('valid document with cyclic job dependencies throws DefinitionParseError', () => {
|
|
164
|
+
const yaml = readFixture('invalid-cycle.yml');
|
|
165
|
+
|
|
166
|
+
expect(() => parseDefinition(yaml)).toThrow(DefinitionParseError);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('manual trigger requires an explicit event', () => {
|
|
170
|
+
const yaml = `name: Manual only
|
|
171
|
+
runner: ubuntu-latest
|
|
172
|
+
triggers:
|
|
173
|
+
on_demand:
|
|
174
|
+
source: manual
|
|
175
|
+
jobs:
|
|
176
|
+
run:
|
|
177
|
+
steps:
|
|
178
|
+
- run: echo hello
|
|
179
|
+
`;
|
|
180
|
+
|
|
181
|
+
expect(() => parseDefinition(yaml)).toThrow(DefinitionParseError);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('declaring more than one manual trigger throws DefinitionParseError', () => {
|
|
185
|
+
const yaml = `name: Multi manual
|
|
186
|
+
runner: ubuntu-latest
|
|
187
|
+
triggers:
|
|
188
|
+
deploy:
|
|
189
|
+
source: manual
|
|
190
|
+
rollback:
|
|
191
|
+
source: manual
|
|
192
|
+
jobs:
|
|
193
|
+
run:
|
|
194
|
+
steps:
|
|
195
|
+
- run: echo hello
|
|
196
|
+
`;
|
|
197
|
+
|
|
198
|
+
expect(() => parseDefinition(yaml)).toThrow(DefinitionParseError);
|
|
199
|
+
});
|
|
200
|
+
});
|