@shipfox/api-workflows 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +72 -0
- package/dist/core/agent-defaults.d.ts +17 -0
- package/dist/core/agent-defaults.d.ts.map +1 -0
- package/dist/core/agent-defaults.js +21 -0
- package/dist/core/agent-defaults.js.map +1 -0
- package/dist/core/agent-tool-capability-warning.d.ts +4 -0
- package/dist/core/agent-tool-capability-warning.d.ts.map +1 -1
- package/dist/core/agent-tool-capability-warning.js +15 -17
- package/dist/core/agent-tool-capability-warning.js.map +1 -1
- package/dist/core/agent-tools.d.ts +11 -9
- package/dist/core/agent-tools.d.ts.map +1 -1
- package/dist/core/agent-tools.js +23 -18
- package/dist/core/agent-tools.js.map +1 -1
- package/dist/core/checkout.d.ts +21 -7
- package/dist/core/checkout.d.ts.map +1 -1
- package/dist/core/checkout.js +23 -11
- package/dist/core/checkout.js.map +1 -1
- package/dist/core/entities/workflow-run-attempt.d.ts +1 -1
- 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/job-execution.d.ts +3 -1
- package/dist/core/job-execution.d.ts.map +1 -1
- package/dist/core/job-execution.js +14 -12
- package/dist/core/job-execution.js.map +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.d.ts +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.d.ts.map +1 -1
- package/dist/core/job-transition/derive-job-execution-outputs.js.map +1 -1
- package/dist/core/job-transition/derive-job-success.js +1 -1
- package/dist/core/job-transition/derive-job-success.js.map +1 -1
- package/dist/core/listener-execution-materialization.d.ts +3 -3
- package/dist/core/listener-execution-materialization.d.ts.map +1 -1
- package/dist/core/listener-execution-materialization.js +3 -4
- package/dist/core/listener-execution-materialization.js.map +1 -1
- package/dist/core/run-workflow.d.ts +12 -1
- package/dist/core/run-workflow.d.ts.map +1 -1
- package/dist/core/run-workflow.js +13 -8
- package/dist/core/run-workflow.js.map +1 -1
- package/dist/core/step-config/agent.d.ts +8 -8
- package/dist/core/step-config/agent.d.ts.map +1 -1
- package/dist/core/step-config/agent.js +12 -10
- package/dist/core/step-config/agent.js.map +1 -1
- package/dist/core/step-config/complete-step-dispatch-config.d.ts +4 -4
- package/dist/core/step-config/complete-step-dispatch-config.d.ts.map +1 -1
- package/dist/core/step-config/complete-step-dispatch-config.js +2 -2
- package/dist/core/step-config/complete-step-dispatch-config.js.map +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.d.ts +3 -3
- package/dist/core/step-config/materialize-job-execution-steps.d.ts.map +1 -1
- package/dist/core/step-config/materialize-job-execution-steps.js +5 -6
- 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 +4 -4
- package/dist/core/step-config/materialize-workflow-model.js.map +1 -1
- package/dist/core/step-config/resolve-job-execution-name.d.ts +1 -1
- package/dist/core/step-config/resolve-job-execution-name.d.ts.map +1 -1
- package/dist/core/step-config/resolve-job-execution-name.js.map +1 -1
- package/dist/core/step-config/resolve-step-config.d.ts +4 -4
- package/dist/core/step-config/resolve-step-config.d.ts.map +1 -1
- package/dist/core/step-config/resolve-step-config.js +6 -6
- package/dist/core/step-config/resolve-step-config.js.map +1 -1
- package/dist/core/step-config/run.d.ts +1 -1
- package/dist/core/step-config/run.d.ts.map +1 -1
- package/dist/core/step-config/run.js.map +1 -1
- package/dist/core/workflow-run-creation.d.ts +3 -3
- package/dist/core/workflow-run-creation.d.ts.map +1 -1
- package/dist/core/workflow-run-creation.js +3 -4
- package/dist/core/workflow-run-creation.js.map +1 -1
- package/dist/db/db.d.ts +16 -4
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/job-listeners.d.ts +7 -1
- package/dist/db/job-listeners.d.ts.map +1 -1
- package/dist/db/job-listeners.js +10 -5
- package/dist/db/job-listeners.js.map +1 -1
- package/dist/db/runner-lease-table.d.ts +5 -5
- package/dist/db/runner-lease-table.d.ts.map +1 -1
- package/dist/db/runner-lease-table.js +3 -2
- package/dist/db/runner-lease-table.js.map +1 -1
- package/dist/db/schema/workflow-run-attempts.d.ts +9 -3
- package/dist/db/schema/workflow-run-attempts.d.ts.map +1 -1
- package/dist/db/schema/workflow-run-attempts.js +2 -1
- package/dist/db/schema/workflow-run-attempts.js.map +1 -1
- package/dist/db/schema/workflow-runs.js +1 -1
- package/dist/db/schema/workflow-runs.js.map +1 -1
- package/dist/db/workflow-runs/job-executions.d.ts +5 -0
- package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
- package/dist/db/workflow-runs/job-executions.js +14 -7
- package/dist/db/workflow-runs/job-executions.js.map +1 -1
- package/dist/db/workflow-runs/jobs.d.ts.map +1 -1
- package/dist/db/workflow-runs/jobs.js +3 -1
- package/dist/db/workflow-runs/jobs.js.map +1 -1
- package/dist/db/workflow-runs/run-create.d.ts +9 -2
- package/dist/db/workflow-runs/run-create.d.ts.map +1 -1
- package/dist/db/workflow-runs/run-create.js +12 -9
- 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 +3 -1
- package/dist/db/workflow-runs/run-rerun.js.map +1 -1
- package/dist/index.d.ts +18 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -37
- package/dist/index.js.map +1 -1
- package/dist/presentation/dto/checkout-token.d.ts +14 -1
- package/dist/presentation/dto/checkout-token.d.ts.map +1 -1
- package/dist/presentation/dto/checkout-token.js.map +1 -1
- package/dist/presentation/index.d.ts +1 -1
- package/dist/presentation/index.d.ts.map +1 -1
- package/dist/presentation/index.js +1 -1
- package/dist/presentation/index.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +18 -0
- package/dist/presentation/inter-module.d.ts.map +1 -0
- package/dist/presentation/inter-module.js +113 -0
- package/dist/presentation/inter-module.js.map +1 -0
- package/dist/presentation/routes/agent-runtime-config.d.ts +6 -1
- package/dist/presentation/routes/agent-runtime-config.d.ts.map +1 -1
- package/dist/presentation/routes/agent-runtime-config.js +59 -57
- package/dist/presentation/routes/agent-runtime-config.js.map +1 -1
- package/dist/presentation/routes/cancel-run.d.ts +2 -1
- package/dist/presentation/routes/cancel-run.d.ts.map +1 -1
- package/dist/presentation/routes/cancel-run.js +37 -34
- package/dist/presentation/routes/cancel-run.js.map +1 -1
- package/dist/presentation/routes/checkout-token.d.ts +8 -1
- package/dist/presentation/routes/checkout-token.d.ts.map +1 -1
- package/dist/presentation/routes/checkout-token.js +65 -47
- package/dist/presentation/routes/checkout-token.js.map +1 -1
- package/dist/presentation/routes/get-run-aggregates.d.ts +2 -1
- package/dist/presentation/routes/get-run-aggregates.d.ts.map +1 -1
- package/dist/presentation/routes/get-run-aggregates.js +44 -53
- package/dist/presentation/routes/get-run-aggregates.js.map +1 -1
- package/dist/presentation/routes/get-run.d.ts +2 -1
- package/dist/presentation/routes/get-run.d.ts.map +1 -1
- package/dist/presentation/routes/get-run.js +53 -50
- package/dist/presentation/routes/get-run.js.map +1 -1
- package/dist/presentation/routes/get-step-secrets.d.ts +3 -1
- package/dist/presentation/routes/get-step-secrets.d.ts.map +1 -1
- package/dist/presentation/routes/get-step-secrets.js +72 -68
- package/dist/presentation/routes/get-step-secrets.js.map +1 -1
- package/dist/presentation/routes/index.d.ts +19 -2
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +38 -30
- package/dist/presentation/routes/index.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 +1 -2
- package/dist/presentation/routes/leased-step.js.map +1 -1
- package/dist/presentation/routes/list-run-attempts.d.ts +2 -1
- package/dist/presentation/routes/list-run-attempts.d.ts.map +1 -1
- package/dist/presentation/routes/list-run-attempts.js +29 -26
- package/dist/presentation/routes/list-run-attempts.js.map +1 -1
- package/dist/presentation/routes/list-runs.d.ts +2 -1
- package/dist/presentation/routes/list-runs.d.ts.map +1 -1
- package/dist/presentation/routes/list-runs.js +51 -60
- package/dist/presentation/routes/list-runs.js.map +1 -1
- package/dist/presentation/routes/next-step.d.ts +10 -1
- package/dist/presentation/routes/next-step.d.ts.map +1 -1
- package/dist/presentation/routes/next-step.js +64 -50
- package/dist/presentation/routes/next-step.js.map +1 -1
- package/dist/presentation/routes/project-access.d.ts +10 -0
- package/dist/presentation/routes/project-access.d.ts.map +1 -0
- package/dist/presentation/routes/project-access.js +17 -0
- package/dist/presentation/routes/project-access.js.map +1 -0
- package/dist/presentation/routes/report-step.d.ts +2 -1
- package/dist/presentation/routes/report-step.d.ts.map +1 -1
- package/dist/presentation/routes/report-step.js +62 -61
- package/dist/presentation/routes/report-step.js.map +1 -1
- package/dist/presentation/routes/require-accessible-run.d.ts +3 -1
- package/dist/presentation/routes/require-accessible-run.d.ts.map +1 -1
- package/dist/presentation/routes/require-accessible-run.js +3 -6
- package/dist/presentation/routes/require-accessible-run.js.map +1 -1
- package/dist/presentation/routes/rerun-run.d.ts +2 -1
- package/dist/presentation/routes/rerun-run.d.ts.map +1 -1
- package/dist/presentation/routes/rerun-run.js +46 -43
- package/dist/presentation/routes/rerun-run.js.map +1 -1
- package/dist/temporal/activities/index.d.ts +44 -9
- package/dist/temporal/activities/index.d.ts.map +1 -1
- package/dist/temporal/activities/index.js +13 -9
- package/dist/temporal/activities/index.js.map +1 -1
- package/dist/temporal/activities/orchestration-activities.d.ts +20 -11
- package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
- package/dist/temporal/activities/orchestration-activities.js +48 -33
- package/dist/temporal/activities/orchestration-activities.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +28 -21
- package/src/core/agent-defaults.test.ts +28 -0
- package/src/core/agent-defaults.ts +36 -0
- package/src/core/agent-tool-capability-warning.test.ts +36 -11
- package/src/core/agent-tool-capability-warning.ts +27 -25
- package/src/core/agent-tools.ts +33 -36
- package/src/core/checkout.test.ts +38 -25
- package/src/core/checkout.ts +41 -14
- package/src/core/entities/workflow-run-attempt.ts +1 -1
- package/src/core/job-execution.ts +19 -9
- package/src/core/job-transition/derive-job-execution-outputs.ts +1 -1
- package/src/core/job-transition/derive-job-success.ts +1 -1
- package/src/core/listener-execution-materialization.test.ts +4 -2
- package/src/core/listener-execution-materialization.ts +6 -9
- package/src/core/run-workflow.test.ts +43 -38
- package/src/core/run-workflow.ts +26 -9
- package/src/core/step-config/agent.ts +24 -26
- package/src/core/step-config/complete-step-dispatch-config.test.ts +22 -23
- package/src/core/step-config/complete-step-dispatch-config.ts +6 -6
- package/src/core/step-config/materialize-job-execution-steps.test.ts +34 -23
- package/src/core/step-config/materialize-job-execution-steps.ts +38 -39
- package/src/core/step-config/materialize-workflow-model.test.ts +94 -82
- package/src/core/step-config/materialize-workflow-model.ts +31 -29
- package/src/core/step-config/resolve-job-execution-name.ts +1 -1
- package/src/core/step-config/resolve-step-config.ts +11 -9
- package/src/core/step-config/run.ts +1 -1
- package/src/core/workflow-run-creation.test.ts +14 -10
- package/src/core/workflow-run-creation.ts +6 -9
- package/src/db/job-listeners.ts +20 -5
- package/src/db/runner-lease-table.ts +2 -2
- package/src/db/schema/workflow-run-attempts.ts +7 -3
- package/src/db/schema/workflow-runs.ts +1 -1
- package/src/db/workflow-runs/job-executions.ts +15 -1
- package/src/db/workflow-runs/jobs.ts +4 -1
- package/src/db/workflow-runs/run-create.test.ts +7 -1
- package/src/db/workflow-runs/run-create.ts +25 -15
- package/src/db/workflow-runs/run-rerun.test.ts +1 -1
- package/src/db/workflow-runs/run-rerun.ts +6 -3
- package/src/index.ts +75 -33
- package/src/presentation/dto/checkout-token.ts +7 -1
- package/src/presentation/index.ts +1 -1
- package/src/presentation/inter-module.test.ts +149 -0
- package/src/presentation/inter-module.ts +132 -0
- package/src/presentation/routes/agent-runtime-config.test.ts +53 -10
- package/src/presentation/routes/agent-runtime-config.ts +89 -64
- package/src/presentation/routes/cancel-run.test.ts +10 -20
- package/src/presentation/routes/cancel-run.ts +30 -27
- package/src/presentation/routes/checkout-token.test.ts +52 -33
- package/src/presentation/routes/checkout-token.ts +109 -49
- package/src/presentation/routes/get-run-aggregates.test.ts +13 -7
- package/src/presentation/routes/get-run-aggregates.ts +54 -57
- package/src/presentation/routes/get-run.test.ts +10 -18
- package/src/presentation/routes/get-run.ts +51 -48
- package/src/presentation/routes/get-step-secrets.test.ts +29 -7
- package/src/presentation/routes/get-step-secrets.ts +72 -61
- package/src/presentation/routes/index.test.ts +16 -1
- package/src/presentation/routes/index.ts +54 -29
- package/src/presentation/routes/leased-step.ts +3 -2
- package/src/presentation/routes/list-run-attempts.test.ts +9 -19
- package/src/presentation/routes/list-run-attempts.ts +21 -18
- package/src/presentation/routes/list-runs.test.ts +13 -7
- package/src/presentation/routes/list-runs.ts +64 -67
- package/src/presentation/routes/next-step.test.ts +30 -11
- package/src/presentation/routes/next-step.ts +68 -48
- package/src/presentation/routes/project-access.ts +16 -0
- package/src/presentation/routes/report-step.test.ts +18 -2
- package/src/presentation/routes/report-step.ts +51 -49
- package/src/presentation/routes/require-accessible-run.ts +5 -2
- package/src/presentation/routes/rerun-run.test.ts +9 -19
- package/src/presentation/routes/rerun-run.ts +39 -36
- package/src/temporal/activities/index.ts +32 -12
- package/src/temporal/activities/orchestration-activities.test.ts +10 -8
- package/src/temporal/activities/orchestration-activities.ts +74 -50
- package/src/temporal/workflows/job-execution-orchestration.test.ts +47 -2
- package/test/env.ts +1 -3
- package/test/factories/project.ts +10 -5
- package/test/factories/workflow-model.test.ts +5 -1
- package/test/factories/workflow-model.ts +1 -1
- package/test/factories/workflow-run.ts +1 -1
- package/test/fixtures/agent-inter-module.ts +27 -0
- package/test/fixtures/annotations-inter-module.ts +5 -0
- package/test/fixtures/auth-inter-module.ts +22 -0
- package/test/fixtures/lease-token.ts +2 -1
- package/test/fixtures/projects-inter-module.ts +8 -0
- package/test/fixtures/runners-inter-module.ts +52 -0
- package/test/fixtures/secrets-inter-module.ts +61 -0
- package/test/globalSetup.ts +11 -11
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/core/source-control.d.ts +0 -5
- package/dist/core/source-control.d.ts.map +0 -1
- package/dist/core/source-control.js +0 -19
- package/dist/core/source-control.js.map +0 -1
- package/src/core/source-control.test.ts +0 -17
- package/src/core/source-control.ts +0 -22
- package/src/temporal/workflows/job-execution-orchestration-timeout.test.ts +0 -165
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipfox/api-workflows",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "6.0.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -26,28 +26,28 @@
|
|
|
26
26
|
"@temporalio/workflow": "1.18.1",
|
|
27
27
|
"drizzle-orm": "^0.45.2",
|
|
28
28
|
"zod": "^4.4.3",
|
|
29
|
-
"@shipfox/api-
|
|
30
|
-
"@shipfox/api-auth": "
|
|
31
|
-
"@shipfox/api-
|
|
32
|
-
"@shipfox/
|
|
33
|
-
"@shipfox/
|
|
34
|
-
"@shipfox/api-
|
|
35
|
-
"@shipfox/api-integration-core": "
|
|
36
|
-
"@shipfox/api-projects": "
|
|
37
|
-
"@shipfox/api-runners": "
|
|
38
|
-
"@shipfox/api-runners-dto": "
|
|
39
|
-
"@shipfox/api-secrets": "
|
|
40
|
-
"@shipfox/api-
|
|
41
|
-
"@shipfox/
|
|
29
|
+
"@shipfox/api-auth-context": "6.0.0",
|
|
30
|
+
"@shipfox/api-auth-dto": "6.0.0",
|
|
31
|
+
"@shipfox/api-agent-dto": "6.0.0",
|
|
32
|
+
"@shipfox/annotations-dto": "6.0.0",
|
|
33
|
+
"@shipfox/api-definitions-dto": "6.0.0",
|
|
34
|
+
"@shipfox/api-projects-dto": "6.0.0",
|
|
35
|
+
"@shipfox/api-integration-core-dto": "6.0.0",
|
|
36
|
+
"@shipfox/api-projects": "6.0.0",
|
|
37
|
+
"@shipfox/api-runners": "6.0.0",
|
|
38
|
+
"@shipfox/api-runners-dto": "6.0.0",
|
|
39
|
+
"@shipfox/api-secrets-dto": "6.0.0",
|
|
40
|
+
"@shipfox/api-workflows-dto": "6.0.0",
|
|
41
|
+
"@shipfox/inter-module": "0.2.0",
|
|
42
42
|
"@shipfox/expression": "1.1.3",
|
|
43
|
-
"@shipfox/node-drizzle": "0.3.
|
|
43
|
+
"@shipfox/node-drizzle": "0.3.2",
|
|
44
44
|
"@shipfox/node-error-monitoring": "0.1.3",
|
|
45
|
-
"@shipfox/node-fastify": "0.2.
|
|
46
|
-
"@shipfox/node-module": "0.
|
|
45
|
+
"@shipfox/node-fastify": "0.2.4",
|
|
46
|
+
"@shipfox/node-module": "0.4.0",
|
|
47
47
|
"@shipfox/node-opentelemetry": "0.5.2",
|
|
48
|
-
"@shipfox/node-outbox": "0.2.
|
|
48
|
+
"@shipfox/node-outbox": "0.2.4",
|
|
49
49
|
"@shipfox/node-postgres": "0.4.2",
|
|
50
|
-
"@shipfox/node-temporal": "0.3.
|
|
50
|
+
"@shipfox/node-temporal": "0.3.2",
|
|
51
51
|
"@shipfox/runner-labels": "0.1.1"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
@@ -60,9 +60,15 @@
|
|
|
60
60
|
"fastify": "^5.3.3",
|
|
61
61
|
"fastify-type-provider-zod": "^6.0.0",
|
|
62
62
|
"fishery": "^2.4.0",
|
|
63
|
-
"@shipfox/
|
|
63
|
+
"@shipfox/node-auth-root-key": "0.2.0",
|
|
64
|
+
"@shipfox/annotations": "6.0.0",
|
|
65
|
+
"@shipfox/api-auth": "6.0.0",
|
|
66
|
+
"@shipfox/api-agent": "6.0.0",
|
|
67
|
+
"@shipfox/api-definitions": "6.0.0",
|
|
68
|
+
"@shipfox/api-integration-core": "6.0.0",
|
|
64
69
|
"@shipfox/biome": "1.8.2",
|
|
65
|
-
"@shipfox/
|
|
70
|
+
"@shipfox/depcruise": "1.0.2",
|
|
71
|
+
"@shipfox/node-jwt": "0.3.0",
|
|
66
72
|
"@shipfox/node-log": "0.3.4",
|
|
67
73
|
"@shipfox/swc": "1.2.6",
|
|
68
74
|
"@shipfox/ts-config": "1.3.8",
|
|
@@ -73,6 +79,7 @@
|
|
|
73
79
|
"build": "shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js",
|
|
74
80
|
"check": "shipfox-biome-check",
|
|
75
81
|
"check:fix": "shipfox-biome-check --write",
|
|
82
|
+
"depcruise": "shipfox-depcruise",
|
|
76
83
|
"test": "shipfox-vitest-run",
|
|
77
84
|
"test:watch": "shipfox-vitest-watch",
|
|
78
85
|
"type": "shipfox-tsc-check",
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
2
|
+
import {createAgentDefaultsResolver} from './agent-defaults.js';
|
|
3
|
+
|
|
4
|
+
describe('createAgentDefaultsResolver', () => {
|
|
5
|
+
test('omits unresolved optional fields from the inter-module input', async () => {
|
|
6
|
+
const resolveAgentConfig = vi.fn().mockResolvedValue({
|
|
7
|
+
harness: 'pi',
|
|
8
|
+
provider: 'anthropic',
|
|
9
|
+
model: 'claude-opus-4-8',
|
|
10
|
+
thinking: 'xhigh',
|
|
11
|
+
});
|
|
12
|
+
const agent = {resolveAgentConfig} as unknown as AgentInterModuleClient;
|
|
13
|
+
const resolve = createAgentDefaultsResolver(agent, crypto.randomUUID());
|
|
14
|
+
|
|
15
|
+
const defaults = await resolve({});
|
|
16
|
+
|
|
17
|
+
expect(defaults).toEqual({
|
|
18
|
+
harness: 'pi',
|
|
19
|
+
provider: 'anthropic',
|
|
20
|
+
model: 'claude-opus-4-8',
|
|
21
|
+
thinking: 'xhigh',
|
|
22
|
+
});
|
|
23
|
+
expect(resolveAgentConfig).toHaveBeenCalledWith({
|
|
24
|
+
workspaceId: expect.any(String),
|
|
25
|
+
config: {},
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type {AgentThinking, Harness, ModelProviderRef} from '@shipfox/api-agent-dto';
|
|
2
|
+
import type {AgentInterModuleClient} from '@shipfox/api-agent-dto/inter-module';
|
|
3
|
+
|
|
4
|
+
export interface AgentDefaultsInput {
|
|
5
|
+
readonly harness?: Harness | undefined;
|
|
6
|
+
readonly provider?: ModelProviderRef | undefined;
|
|
7
|
+
readonly model?: string | undefined;
|
|
8
|
+
readonly thinking?: AgentThinking | undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ResolvedAgentDefaults {
|
|
12
|
+
readonly harness: Harness;
|
|
13
|
+
readonly provider: ModelProviderRef;
|
|
14
|
+
readonly model: string;
|
|
15
|
+
readonly thinking: AgentThinking;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type AgentDefaultsResolver = (
|
|
19
|
+
input: AgentDefaultsInput,
|
|
20
|
+
) => ResolvedAgentDefaults | Promise<ResolvedAgentDefaults>;
|
|
21
|
+
|
|
22
|
+
export function createAgentDefaultsResolver(
|
|
23
|
+
agent: AgentInterModuleClient,
|
|
24
|
+
workspaceId: string | null,
|
|
25
|
+
): AgentDefaultsResolver {
|
|
26
|
+
return async (config) =>
|
|
27
|
+
await agent.resolveAgentConfig({
|
|
28
|
+
workspaceId,
|
|
29
|
+
config: {
|
|
30
|
+
...(config.harness === undefined ? {} : {harness: config.harness}),
|
|
31
|
+
...(config.provider === undefined ? {} : {provider: config.provider}),
|
|
32
|
+
...(config.model === undefined ? {} : {model: config.model}),
|
|
33
|
+
...(config.thinking === undefined ? {} : {thinking: config.thinking}),
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -1,9 +1,39 @@
|
|
|
1
|
+
import type {AnnotationsInterModuleClient} from '@shipfox/annotations-dto/inter-module';
|
|
1
2
|
import type {JobLeaseTokenClaims} from '@shipfox/api-auth';
|
|
2
3
|
import {sql} from 'drizzle-orm';
|
|
3
4
|
import {db} from '#db/db.js';
|
|
4
|
-
import {
|
|
5
|
+
import {runnersTestClient} from '#test/fixtures/runners-inter-module.js';
|
|
6
|
+
import {warnAgentToolCapabilityMismatchOnDispatch as warnAgentToolCapabilityMismatchOnDispatchImpl} from './agent-tool-capability-warning.js';
|
|
5
7
|
import type {Step} from './entities/step.js';
|
|
6
8
|
|
|
9
|
+
async function warnAgentToolCapabilityMismatchOnDispatch(
|
|
10
|
+
params: Omit<
|
|
11
|
+
Parameters<typeof warnAgentToolCapabilityMismatchOnDispatchImpl>[0],
|
|
12
|
+
'annotations' | 'runners'
|
|
13
|
+
>,
|
|
14
|
+
) {
|
|
15
|
+
return await warnAgentToolCapabilityMismatchOnDispatchImpl({
|
|
16
|
+
annotations: annotationsTestClient,
|
|
17
|
+
runners: runnersTestClient,
|
|
18
|
+
...params,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const annotationBodiesByExecution = new Map<string, Map<string, string>>();
|
|
23
|
+
|
|
24
|
+
const annotationsTestClient: AnnotationsInterModuleClient = {
|
|
25
|
+
replaceOrRemoveAnnotation(input) {
|
|
26
|
+
const annotations = annotationBodiesByExecution.get(input.jobExecutionId) ?? new Map();
|
|
27
|
+
annotationBodiesByExecution.set(input.jobExecutionId, annotations);
|
|
28
|
+
if (input.annotation.op === 'remove') {
|
|
29
|
+
annotations.delete(input.context);
|
|
30
|
+
} else {
|
|
31
|
+
annotations.set(input.context, input.annotation.body);
|
|
32
|
+
}
|
|
33
|
+
return Promise.resolve({});
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
7
37
|
function lease(params: Partial<JobLeaseTokenClaims> = {}): JobLeaseTokenClaims {
|
|
8
38
|
const now = Math.floor(Date.now() / 1000);
|
|
9
39
|
return {
|
|
@@ -97,16 +127,11 @@ async function insertRunnerSession(params: {
|
|
|
97
127
|
`);
|
|
98
128
|
}
|
|
99
129
|
|
|
100
|
-
|
|
101
|
-
jobExecutionId
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
FROM annotations_annotations
|
|
106
|
-
WHERE job_execution_id = ${jobExecutionId}
|
|
107
|
-
ORDER BY sequence
|
|
108
|
-
`);
|
|
109
|
-
return [...result.rows];
|
|
130
|
+
function annotationsFor(jobExecutionId: string): Array<{context: string; body: string}> {
|
|
131
|
+
return Array.from(annotationBodiesByExecution.get(jobExecutionId) ?? [], ([context, body]) => ({
|
|
132
|
+
context,
|
|
133
|
+
body,
|
|
134
|
+
}));
|
|
110
135
|
}
|
|
111
136
|
|
|
112
137
|
describe('warnAgentToolCapabilityMismatchOnDispatch', () => {
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type WriteAnnotationsParams,
|
|
6
|
-
writeAnnotations,
|
|
7
|
-
} from '@shipfox/annotations';
|
|
2
|
+
type AnnotationsInterModuleClient,
|
|
3
|
+
annotationsInterModuleContract,
|
|
4
|
+
} from '@shipfox/annotations-dto/inter-module';
|
|
8
5
|
import {
|
|
9
6
|
harnessSchema,
|
|
10
7
|
type MaterializedAgentStepConfigDto,
|
|
11
8
|
materializedAgentStepConfigSchema,
|
|
12
9
|
} from '@shipfox/api-agent-dto';
|
|
13
10
|
import type {LeasedJobContext} from '@shipfox/api-auth-context';
|
|
14
|
-
import {
|
|
11
|
+
import type {RunnersInterModuleClient} from '@shipfox/api-runners-dto/inter-module';
|
|
12
|
+
import {isInterModuleKnownError} from '@shipfox/inter-module';
|
|
15
13
|
import {logger} from '@shipfox/node-opentelemetry';
|
|
16
14
|
import {recordWorkflowAgentToolWarningFailed} from '#metrics/instance.js';
|
|
17
15
|
import type {Step} from './entities/step.js';
|
|
@@ -22,6 +20,8 @@ type WarningFailureReason = 'budget' | 'lookup' | 'write';
|
|
|
22
20
|
type WarningReason = 'known-absence' | 'harness-not-advertised' | 'unknown-or-stale';
|
|
23
21
|
|
|
24
22
|
export async function warnAgentToolCapabilityMismatchOnDispatch(params: {
|
|
23
|
+
annotations: AnnotationsInterModuleClient;
|
|
24
|
+
runners: RunnersInterModuleClient;
|
|
25
25
|
leaseIdentity: LeasedJobContext;
|
|
26
26
|
step: Step;
|
|
27
27
|
}): Promise<void> {
|
|
@@ -34,9 +34,11 @@ export async function warnAgentToolCapabilityMismatchOnDispatch(params: {
|
|
|
34
34
|
const harness = harnessSchema.safeParse(config.harness);
|
|
35
35
|
if (!harness.success) return;
|
|
36
36
|
|
|
37
|
-
let effective: Awaited<
|
|
37
|
+
let effective: Awaited<
|
|
38
|
+
ReturnType<RunnersInterModuleClient['getEffectiveRunnerToolCapabilities']>
|
|
39
|
+
>;
|
|
38
40
|
try {
|
|
39
|
-
effective = await getEffectiveRunnerToolCapabilities({
|
|
41
|
+
effective = await params.runners.getEffectiveRunnerToolCapabilities({
|
|
40
42
|
runnerSessionId: params.leaseIdentity.runnerSessionId,
|
|
41
43
|
});
|
|
42
44
|
} catch (error) {
|
|
@@ -48,11 +50,8 @@ export async function warnAgentToolCapabilityMismatchOnDispatch(params: {
|
|
|
48
50
|
return;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
requestedTools,
|
|
54
|
-
capabilities: effective.capabilities,
|
|
55
|
-
});
|
|
53
|
+
const advertised = new Set(effective.capabilities.harnesses[harness.data]?.tools ?? []);
|
|
54
|
+
const missing = requestedTools.filter((tool) => !advertised.has(tool));
|
|
56
55
|
const context = `agent-tool-capability:${params.step.id}`;
|
|
57
56
|
|
|
58
57
|
const operation =
|
|
@@ -67,17 +66,18 @@ export async function warnAgentToolCapabilityMismatchOnDispatch(params: {
|
|
|
67
66
|
missing,
|
|
68
67
|
reason: warningReason({
|
|
69
68
|
reportFresh: effective.reportFresh,
|
|
70
|
-
harnessKnown: effective.
|
|
69
|
+
harnessKnown: effective.capabilities.harnesses[harness.data] !== undefined,
|
|
71
70
|
}),
|
|
72
71
|
}),
|
|
73
72
|
};
|
|
74
73
|
|
|
75
74
|
try {
|
|
76
|
-
await
|
|
77
|
-
...
|
|
75
|
+
await params.annotations.replaceOrRemoveAnnotation({
|
|
76
|
+
...annotationTargetFromLease(params.leaseIdentity),
|
|
78
77
|
originStepId: params.step.id,
|
|
79
78
|
originStepAttempt: params.step.currentAttempt,
|
|
80
|
-
|
|
79
|
+
context,
|
|
80
|
+
annotation: operation.op === 'remove' ? {op: 'remove'} : operation,
|
|
81
81
|
});
|
|
82
82
|
} catch (error) {
|
|
83
83
|
const reason = isAnnotationBudgetError(error) ? 'budget' : 'write';
|
|
@@ -103,7 +103,7 @@ export async function warnAgentToolCapabilityMismatchOnDispatch(params: {
|
|
|
103
103
|
missing,
|
|
104
104
|
reason: warningReason({
|
|
105
105
|
reportFresh: effective.reportFresh,
|
|
106
|
-
harnessKnown: effective.
|
|
106
|
+
harnessKnown: effective.capabilities.harnesses[harness.data] !== undefined,
|
|
107
107
|
}),
|
|
108
108
|
},
|
|
109
109
|
'Runner missing requested agent tools; dispatch is continuing',
|
|
@@ -173,9 +173,12 @@ function warningReason(params: {reportFresh: boolean; harnessKnown: boolean}): W
|
|
|
173
173
|
return params.reportFresh ? 'harness-not-advertised' : 'unknown-or-stale';
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
function
|
|
176
|
+
function annotationTargetFromLease(
|
|
177
177
|
lease: LeasedJobContext,
|
|
178
|
-
): Omit<
|
|
178
|
+
): Omit<
|
|
179
|
+
Parameters<AnnotationsInterModuleClient['replaceOrRemoveAnnotation']>[0],
|
|
180
|
+
'originStepId' | 'originStepAttempt' | 'context' | 'annotation'
|
|
181
|
+
> {
|
|
179
182
|
return {
|
|
180
183
|
workspaceId: lease.workspaceId,
|
|
181
184
|
projectId: lease.projectId,
|
|
@@ -188,10 +191,9 @@ function writeParamsFromLease(
|
|
|
188
191
|
}
|
|
189
192
|
|
|
190
193
|
function isAnnotationBudgetError(error: unknown): boolean {
|
|
191
|
-
return (
|
|
192
|
-
|
|
193
|
-
error
|
|
194
|
-
error instanceof AnnotationTotalBytesLimitExceededError
|
|
194
|
+
return isInterModuleKnownError(
|
|
195
|
+
annotationsInterModuleContract.methods.replaceOrRemoveAnnotation,
|
|
196
|
+
error,
|
|
195
197
|
);
|
|
196
198
|
}
|
|
197
199
|
|
package/src/core/agent-tools.ts
CHANGED
|
@@ -2,28 +2,28 @@ import type {
|
|
|
2
2
|
MaterializedAgentIntegrationConfigDto,
|
|
3
3
|
MaterializedAgentIntegrationToolConfigDto,
|
|
4
4
|
} from '@shipfox/api-agent-dto';
|
|
5
|
-
import type {WorkflowModel} from '@shipfox/api-definitions';
|
|
5
|
+
import type {WorkflowModel} from '@shipfox/api-definitions-dto';
|
|
6
6
|
import type {
|
|
7
7
|
AgentToolCatalogEntry,
|
|
8
8
|
AgentToolCatalogMethod,
|
|
9
|
-
AgentToolCatalogs,
|
|
10
|
-
GetIntegrationConnectionByIdFn,
|
|
11
9
|
IntegrationProviderKind,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from '@shipfox/api-
|
|
15
|
-
import {getProjectById} from '@shipfox/api-projects';
|
|
10
|
+
IntegrationsModuleClient,
|
|
11
|
+
} from '@shipfox/api-integration-core-dto';
|
|
12
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
16
13
|
import {AgentIntegrationMaterializationError} from './errors.js';
|
|
17
14
|
|
|
18
15
|
type WorkflowModelJob = WorkflowModel['jobs'][number];
|
|
19
16
|
type WorkflowModelAgentStep = Extract<WorkflowModelJob['steps'][number], {kind: 'agent'}>;
|
|
20
17
|
type WorkflowModelStepIntegration = NonNullable<WorkflowModelAgentStep['integrations']>[number];
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
type AgentToolCatalogs = ReadonlyMap<IntegrationProviderKind, readonly AgentToolCatalogEntry[]>;
|
|
19
|
+
type WorkspaceConnectionSnapshot = ReadonlyMap<
|
|
20
|
+
string,
|
|
21
|
+
{
|
|
22
|
+
id: string;
|
|
23
|
+
provider: IntegrationProviderKind;
|
|
24
|
+
capabilities: readonly ('source_control' | 'agent_tools')[];
|
|
25
|
+
}
|
|
26
|
+
>;
|
|
27
27
|
|
|
28
28
|
export interface AgentToolMaterializationContext {
|
|
29
29
|
readonly catalogs: AgentToolCatalogs;
|
|
@@ -51,48 +51,45 @@ interface SelectedToolState {
|
|
|
51
51
|
selectedStandalone: boolean;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
let services: AgentToolMaterializationServices | undefined;
|
|
55
|
-
|
|
56
|
-
export function setAgentToolMaterializationServices(
|
|
57
|
-
nextServices: AgentToolMaterializationServices,
|
|
58
|
-
): void {
|
|
59
|
-
services = nextServices;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function clearAgentToolMaterializationServices(): void {
|
|
63
|
-
services = undefined;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
54
|
export async function loadAgentToolMaterializationContext(params: {
|
|
67
55
|
readonly model: WorkflowModel | null;
|
|
68
56
|
readonly workspaceId: string;
|
|
69
57
|
readonly projectId: string;
|
|
58
|
+
readonly integrations?: IntegrationsModuleClient | undefined;
|
|
59
|
+
readonly projects?: ProjectsModuleClient | undefined;
|
|
70
60
|
readonly jobs?: readonly WorkflowModelJob[] | undefined;
|
|
71
61
|
}): Promise<AgentToolMaterializationContext | undefined> {
|
|
72
62
|
if (!modelHasAgentStepIntegrations(params.model, params.jobs)) return undefined;
|
|
73
|
-
if (services === undefined) {
|
|
74
|
-
throw new AgentIntegrationMaterializationError('Agent tool materialization is not configured');
|
|
75
|
-
}
|
|
76
63
|
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
if (params.projects === undefined) {
|
|
65
|
+
throw new AgentIntegrationMaterializationError('Project access is not configured');
|
|
66
|
+
}
|
|
67
|
+
const {project} = await params.projects.getProjectById({projectId: params.projectId});
|
|
68
|
+
if (project === null) {
|
|
79
69
|
throw new AgentIntegrationMaterializationError(
|
|
80
70
|
`Project ${params.projectId} was not found while materializing agent integrations`,
|
|
81
71
|
);
|
|
82
72
|
}
|
|
83
73
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
74
|
+
if (params.integrations === undefined) {
|
|
75
|
+
throw new AgentIntegrationMaterializationError('Agent tool materialization is not configured');
|
|
76
|
+
}
|
|
77
|
+
const context = await params.integrations.getAgentToolsContext({
|
|
78
|
+
workspaceId: params.workspaceId,
|
|
79
|
+
defaultConnectionId: project.sourceConnectionId,
|
|
80
|
+
});
|
|
81
|
+
const workspaceConnectionSnapshot = new Map(
|
|
82
|
+
context.workspaceConnections.map(({slug, ...connection}) => [slug, connection]),
|
|
83
|
+
);
|
|
84
|
+
const defaultConnection = context.defaultConnection;
|
|
85
|
+
if (defaultConnection === null) {
|
|
89
86
|
throw new AgentIntegrationMaterializationError(
|
|
90
87
|
`Source connection ${project.sourceConnectionId} was not found while materializing agent integrations`,
|
|
91
88
|
);
|
|
92
89
|
}
|
|
93
90
|
|
|
94
91
|
return {
|
|
95
|
-
catalogs:
|
|
92
|
+
catalogs: new Map(context.catalogs.map(({provider, tools}) => [provider, tools])),
|
|
96
93
|
workspaceConnectionSnapshot,
|
|
97
94
|
defaultConnection: {
|
|
98
95
|
id: defaultConnection.id,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
1
|
+
import type {IntegrationsModuleClient} from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';
|
|
3
3
|
import * as workflowRuns from '#db/workflow-runs.js';
|
|
4
4
|
import {jobFactory} from '#test/factories/job.js';
|
|
5
5
|
import {projectFactory} from '#test/factories/project.js';
|
|
@@ -10,16 +10,16 @@ import {
|
|
|
10
10
|
WorkflowRunNotFoundError,
|
|
11
11
|
} from './errors.js';
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
const
|
|
13
|
+
const getProjectById = vi.fn();
|
|
14
|
+
const projects = {getProjectById} as Pick<ProjectsModuleClient, 'getProjectById'>;
|
|
15
15
|
|
|
16
16
|
describe('resolveCheckoutIntent', () => {
|
|
17
17
|
it('resolves connection + repo from the project, using the project workspace', async () => {
|
|
18
18
|
const project = projectFactory.build();
|
|
19
|
-
|
|
19
|
+
getProjectById.mockResolvedValue({project});
|
|
20
20
|
const job = await jobFactory.create({}, {transient: {projectId: project.id}});
|
|
21
21
|
|
|
22
|
-
const intent = await resolveCheckoutIntent(job.id);
|
|
22
|
+
const intent = await resolveCheckoutIntent(job.id, projects as ProjectsModuleClient);
|
|
23
23
|
|
|
24
24
|
expect(intent).toEqual({
|
|
25
25
|
workspaceId: project.workspaceId,
|
|
@@ -31,79 +31,92 @@ describe('resolveCheckoutIntent', () => {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
it('throws JobNotFoundError for an unknown job', async () => {
|
|
34
|
-
const act = resolveCheckoutIntent(crypto.randomUUID());
|
|
34
|
+
const act = resolveCheckoutIntent(crypto.randomUUID(), projects as ProjectsModuleClient);
|
|
35
35
|
|
|
36
36
|
await expect(act).rejects.toBeInstanceOf(JobNotFoundError);
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('resolves the checkout target while the parent job projection is still pending', async () => {
|
|
40
40
|
const project = projectFactory.build();
|
|
41
|
-
|
|
41
|
+
getProjectById.mockResolvedValue({project});
|
|
42
42
|
const job = await jobFactory.create(
|
|
43
43
|
{},
|
|
44
44
|
{transient: {projectId: project.id, status: 'pending'}},
|
|
45
45
|
);
|
|
46
46
|
|
|
47
|
-
const intent = await resolveCheckoutIntent(job.id);
|
|
47
|
+
const intent = await resolveCheckoutIntent(job.id, projects as ProjectsModuleClient);
|
|
48
48
|
|
|
49
49
|
expect(intent.connectionId).toBe(project.sourceConnectionId);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
it('throws WorkflowRunNotFoundError when the run is missing', async () => {
|
|
53
53
|
const project = projectFactory.build();
|
|
54
|
-
|
|
54
|
+
getProjectById.mockResolvedValue({project});
|
|
55
55
|
const job = await jobFactory.create({}, {transient: {projectId: project.id}});
|
|
56
56
|
vi.spyOn(workflowRuns, 'getWorkflowRunByAttemptId').mockResolvedValue(undefined);
|
|
57
57
|
|
|
58
|
-
const act = resolveCheckoutIntent(job.id);
|
|
58
|
+
const act = resolveCheckoutIntent(job.id, projects as ProjectsModuleClient);
|
|
59
59
|
|
|
60
60
|
await expect(act).rejects.toBeInstanceOf(WorkflowRunNotFoundError);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
it('throws CheckoutIntentUnresolvedError when the project is missing', async () => {
|
|
64
64
|
const project = projectFactory.build();
|
|
65
|
-
|
|
65
|
+
getProjectById.mockResolvedValue({project: null});
|
|
66
66
|
const job = await jobFactory.create({}, {transient: {projectId: project.id}});
|
|
67
67
|
|
|
68
|
-
const act = resolveCheckoutIntent(job.id);
|
|
68
|
+
const act = resolveCheckoutIntent(job.id, projects as ProjectsModuleClient);
|
|
69
69
|
|
|
70
70
|
await expect(act).rejects.toBeInstanceOf(CheckoutIntentUnresolvedError);
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
describe('createJobCheckoutSpec', () => {
|
|
75
|
-
it('passes the resolved intent
|
|
75
|
+
it('passes the resolved intent without a ref to the service', async () => {
|
|
76
76
|
const project = projectFactory.build();
|
|
77
|
-
|
|
77
|
+
getProjectById.mockResolvedValue({project});
|
|
78
78
|
const job = await jobFactory.create({}, {transient: {projectId: project.id}});
|
|
79
|
-
const spec
|
|
79
|
+
const spec = {repositoryUrl: 'https://github.com/acme/repo.git', ref: 'main'};
|
|
80
80
|
const createCheckoutSpec = vi.fn().mockResolvedValue(spec);
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
const integrations = {createCheckoutSpec} as Pick<
|
|
82
|
+
IntegrationsModuleClient,
|
|
83
|
+
'createCheckoutSpec'
|
|
84
|
+
>;
|
|
85
|
+
|
|
86
|
+
const result = await createJobCheckoutSpec({
|
|
87
|
+
jobId: job.id,
|
|
88
|
+
integrations: integrations as IntegrationsModuleClient,
|
|
89
|
+
projects: projects as ProjectsModuleClient,
|
|
90
|
+
});
|
|
84
91
|
|
|
85
92
|
expect(result).toEqual({spec, persistCredentials: true});
|
|
86
93
|
expect(createCheckoutSpec).toHaveBeenCalledWith({
|
|
87
94
|
workspaceId: project.workspaceId,
|
|
88
95
|
connectionId: project.sourceConnectionId,
|
|
89
96
|
externalRepositoryId: project.sourceExternalRepositoryId,
|
|
90
|
-
ref: undefined,
|
|
91
97
|
permissions: {contents: 'read'},
|
|
92
98
|
});
|
|
93
99
|
});
|
|
94
100
|
|
|
95
101
|
it('passes requested write contents permission to the service', async () => {
|
|
96
102
|
const project = projectFactory.build();
|
|
97
|
-
|
|
103
|
+
getProjectById.mockResolvedValue({project});
|
|
98
104
|
const job = await jobFactory.create(
|
|
99
105
|
{},
|
|
100
106
|
{transient: {projectId: project.id, checkout: {permissions: {contents: 'write'}}}},
|
|
101
107
|
);
|
|
102
|
-
const spec
|
|
108
|
+
const spec = {repositoryUrl: 'https://github.com/acme/repo.git', ref: 'main'};
|
|
103
109
|
const createCheckoutSpec = vi.fn().mockResolvedValue(spec);
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
const integrations = {createCheckoutSpec} as Pick<
|
|
111
|
+
IntegrationsModuleClient,
|
|
112
|
+
'createCheckoutSpec'
|
|
113
|
+
>;
|
|
114
|
+
|
|
115
|
+
await createJobCheckoutSpec({
|
|
116
|
+
jobId: job.id,
|
|
117
|
+
integrations: integrations as IntegrationsModuleClient,
|
|
118
|
+
projects: projects as ProjectsModuleClient,
|
|
119
|
+
});
|
|
107
120
|
|
|
108
121
|
expect(createCheckoutSpec).toHaveBeenCalledWith(
|
|
109
122
|
expect.objectContaining({permissions: {contents: 'write'}}),
|