@treeseed/sdk 0.11.0 → 0.12.4
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/README.md +9 -4
- package/dist/agent-capacity.d.ts +916 -0
- package/dist/agent-capacity.js +1600 -0
- package/dist/agent-tools.d.ts +37 -0
- package/dist/agent-tools.js +301 -0
- package/dist/api/app.d.ts +1 -1
- package/dist/api/auth/d1-database.d.ts +2 -2
- package/dist/api/auth/d1-provider.d.ts +4 -4
- package/dist/api/auth/d1-store.d.ts +2 -2
- package/dist/api/auth/memory-provider.d.ts +1 -1
- package/dist/api/auth/tokens.d.ts +1 -1
- package/dist/api/config.d.ts +3 -1
- package/dist/api/config.js +34 -10
- package/dist/api/http.d.ts +2 -2
- package/dist/api/index.d.ts +10 -10
- package/dist/api/index.js +4 -2
- package/dist/api/operations-routes.d.ts +3 -3
- package/dist/api/operations.d.ts +1 -1
- package/dist/api/providers.d.ts +1 -1
- package/dist/api/providers.js +21 -4
- package/dist/api/railway.d.ts +3 -2
- package/dist/api/sdk-dispatch.d.ts +4 -4
- package/dist/api/sdk-routes.d.ts +2 -2
- package/dist/api/templates.d.ts +2 -2
- package/dist/api/types.d.ts +3 -2
- package/dist/capacity-provider.d.ts +117 -60
- package/dist/capacity-provider.js +215 -43
- package/dist/capacity.d.ts +2 -2
- package/dist/cli-tools.d.ts +1 -1
- package/dist/content-operations.d.ts +97 -0
- package/dist/content-operations.js +250 -0
- package/dist/content-store.d.ts +4 -4
- package/dist/control-plane-client.d.ts +13 -18
- package/dist/control-plane-client.js +8 -86
- package/dist/control-plane.d.ts +2 -2
- package/dist/copilot.d.ts +3 -0
- package/dist/copilot.js +16 -1
- package/dist/d1-http.d.ts +1 -1
- package/dist/d1-store.d.ts +32 -57
- package/dist/d1-store.js +115 -318
- package/dist/db/d1.d.ts +1 -232
- package/dist/db/index.d.ts +3 -3
- package/dist/db/market-schema.d.ts +49037 -11843
- package/dist/db/market-schema.js +1788 -50
- package/dist/db/node-sqlite.d.ts +1 -232
- package/dist/db/schema.d.ts +0 -462
- package/dist/db/schema.js +2 -22
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +0 -11
- package/dist/fixture-support.js +52 -4
- package/dist/governance.d.ts +133 -0
- package/dist/governance.js +285 -0
- package/dist/graph/build.d.ts +2 -2
- package/dist/graph/context-query-contracts.d.ts +1 -1
- package/dist/graph/dsl.d.ts +1 -1
- package/dist/graph/query.d.ts +4 -4
- package/dist/graph/ranking.d.ts +1 -1
- package/dist/graph/schema.d.ts +1 -1
- package/dist/graph.d.ts +11 -11
- package/dist/guarantees/index.d.ts +425 -0
- package/dist/guarantees/index.js +1146 -0
- package/dist/hosting/apps.d.ts +1 -1
- package/dist/hosting/builtins.d.ts +1 -1
- package/dist/hosting/builtins.js +9 -198
- package/dist/hosting/contracts.d.ts +3 -2
- package/dist/hosting/graph.d.ts +24 -21
- package/dist/hosting/graph.js +280 -294
- package/dist/hosting/index.d.ts +4 -4
- package/dist/index.d.ts +88 -74
- package/dist/index.js +81 -10
- package/dist/local-dev/managed-dev.d.ts +85 -0
- package/dist/local-dev/managed-dev.js +368 -0
- package/dist/managed-dependencies.d.ts +9 -0
- package/dist/managed-dependencies.js +10 -8
- package/dist/market-client.d.ts +265 -7
- package/dist/market-client.js +381 -9
- package/dist/model-registry.d.ts +1 -1
- package/dist/model-registry.js +19 -19
- package/dist/operations/agent-tools.d.ts +2 -11
- package/dist/operations/agent-tools.js +2 -14
- package/dist/operations/providers/default.d.ts +1 -1
- package/dist/operations/providers/default.js +20 -37
- package/dist/operations/repository-operations.d.ts +26 -2
- package/dist/operations/repository-operations.js +159 -1
- package/dist/operations/runtime.d.ts +3 -3
- package/dist/operations/services/bootstrap-runner.d.ts +1 -1
- package/dist/operations/services/build-warning-policy.d.ts +34 -0
- package/dist/operations/services/build-warning-policy.js +81 -82
- package/dist/operations/services/commit-message-provider.js +4 -4
- package/dist/operations/services/config-runtime.d.ts +73 -19
- package/dist/operations/services/config-runtime.js +276 -100
- package/dist/operations/services/deploy.d.ts +41 -622
- package/dist/operations/services/deploy.js +181 -213
- package/dist/operations/services/deployment-readiness.d.ts +1 -1
- package/dist/operations/services/deployment-readiness.js +38 -7
- package/dist/operations/services/git-remote-policy.js +12 -4
- package/dist/operations/services/git-runner.d.ts +66 -0
- package/dist/operations/services/git-runner.js +479 -0
- package/dist/operations/services/git-workflow.d.ts +43 -5
- package/dist/operations/services/git-workflow.js +242 -20
- package/dist/operations/services/github-actions-verification.d.ts +3 -1
- package/dist/operations/services/github-actions-verification.js +11 -3
- package/dist/operations/services/github-api.js +21 -5
- package/dist/operations/services/github-automation.d.ts +3 -3
- package/dist/operations/services/github-automation.js +15 -18
- package/dist/operations/services/github-credentials.js +2 -1
- package/dist/operations/services/hosted-service-checks.d.ts +19 -1
- package/dist/operations/services/hosted-service-checks.js +162 -11
- package/dist/operations/services/hosting-audit.d.ts +2 -2
- package/dist/operations/services/hosting-audit.js +7 -7
- package/dist/operations/services/hub-launch.d.ts +1 -1
- package/dist/operations/services/hub-provider-launch.d.ts +5 -5
- package/dist/operations/services/hub-provider-launch.js +19 -14
- package/dist/operations/services/live-hosted-service-checks.d.ts +2 -1
- package/dist/operations/services/live-hosted-service-checks.js +193 -80
- package/dist/operations/services/local-dev.js +0 -1
- package/dist/operations/services/managed-host-security.d.ts +1 -1
- package/dist/operations/services/managed-repositories.d.ts +37 -0
- package/dist/operations/services/managed-repositories.js +177 -0
- package/dist/operations/services/operations-runner-smoke.d.ts +3 -2
- package/dist/operations/services/operations-runner-smoke.js +22 -4
- package/dist/operations/services/package-adapters.d.ts +77 -2
- package/dist/operations/services/package-adapters.js +627 -56
- package/dist/operations/services/package-reference-policy.d.ts +12 -88
- package/dist/operations/services/package-reference-policy.js +81 -213
- package/dist/operations/services/project-host-operations.d.ts +4 -4
- package/dist/operations/services/project-platform.d.ts +19 -193
- package/dist/operations/services/project-platform.js +31 -103
- package/dist/operations/services/project-web-monitor.d.ts +2 -2
- package/dist/operations/services/project-web-monitor.js +97 -2
- package/dist/operations/services/railway-api.d.ts +36 -7
- package/dist/operations/services/railway-api.js +331 -100
- package/dist/operations/services/railway-deploy.d.ts +7 -95
- package/dist/operations/services/railway-deploy.js +334 -742
- package/dist/operations/services/release-history.js +3 -4
- package/dist/operations/services/release-proof-ledger.d.ts +13 -0
- package/dist/operations/services/release-proof-ledger.js +81 -0
- package/dist/operations/services/release-proof-planner.d.ts +48 -0
- package/dist/operations/services/release-proof-planner.js +195 -0
- package/dist/operations/services/release-proof-runner.d.ts +16 -0
- package/dist/operations/services/release-proof-runner.js +169 -0
- package/dist/operations/services/release-proof.d.ts +81 -0
- package/dist/operations/services/release-proof.js +79 -0
- package/dist/operations/services/repository-save-orchestrator.d.ts +6 -7
- package/dist/operations/services/repository-save-orchestrator.js +353 -174
- package/dist/operations/services/runtime-paths.d.ts +1 -3
- package/dist/operations/services/runtime-paths.js +0 -4
- package/dist/operations/services/runtime-tools.d.ts +1 -192
- package/dist/operations/services/runtime-tools.js +4 -444
- package/dist/operations/services/save-deploy-preflight.js +9 -1
- package/dist/operations/services/template-host-bindings.d.ts +2 -2
- package/dist/operations/services/template-host-bindings.js +3 -2
- package/dist/operations/services/template-registry.d.ts +6 -6
- package/dist/operations/services/template-registry.js +33 -14
- package/dist/operations/services/template-secret-sync.d.ts +3 -3
- package/dist/operations/services/workflow-timing.d.ts +25 -0
- package/dist/operations/services/workflow-timing.js +79 -0
- package/dist/operations/services/workspace-dependency-mode.js +41 -4
- package/dist/operations/services/workspace-preflight.js +8 -8
- package/dist/operations/services/workspace-save-script.d.ts +4 -4
- package/dist/operations/services/workspace-save.d.ts +1 -0
- package/dist/operations/services/workspace-save.js +41 -18
- package/dist/operations/services/workspace-tools.js +40 -6
- package/dist/operations-registry.d.ts +1 -1
- package/dist/operations-registry.js +5 -6
- package/dist/operations-types.d.ts +1 -1
- package/dist/operations.d.ts +17 -11
- package/dist/operations.js +57 -3
- package/dist/platform/book-export.js +2 -0
- package/dist/platform/books-data.d.ts +1 -1
- package/dist/platform/config.d.ts +27 -0
- package/dist/platform/config.js +100 -0
- package/dist/platform/content-runtime-source.d.ts +54 -0
- package/dist/platform/content-runtime-source.js +169 -0
- package/dist/platform/contracts.d.ts +6 -1
- package/dist/platform/deploy-config.d.ts +1 -1
- package/dist/platform/deploy-config.js +7 -1
- package/dist/platform/deploy-runtime.d.ts +1 -1
- package/dist/platform/desired-state.d.ts +63 -0
- package/dist/platform/desired-state.js +1021 -0
- package/dist/platform/env.yaml +414 -19
- package/dist/platform/environment.d.ts +2 -2
- package/dist/platform/environment.js +54 -22
- package/dist/platform/local-content-materialization.d.ts +9 -0
- package/dist/platform/local-content-materialization.js +212 -0
- package/dist/platform/plugin.d.ts +5 -5
- package/dist/platform/plugins/runtime.d.ts +3 -3
- package/dist/platform/plugins/runtime.js +62 -1
- package/dist/platform/plugins.d.ts +6 -6
- package/dist/platform/published-content-pipeline.d.ts +3 -3
- package/dist/platform/published-content-pipeline.js +5 -1
- package/dist/platform/published-content.d.ts +4 -3
- package/dist/platform/site-config-schema.d.ts +1 -0
- package/dist/platform/site-config-schema.js +4 -1
- package/dist/platform/tenant/runtime-config.d.ts +152 -2
- package/dist/platform/tenant-config.d.ts +1 -1
- package/dist/platform/utils/site-config-schema.d.ts +154 -0
- package/dist/platform/utils/site-config-schema.js +400 -461
- package/dist/platform-operation-store.d.ts +1 -1
- package/dist/plugin-default.d.ts +1 -1
- package/dist/plugin-default.js +27 -12
- package/dist/project-import.d.ts +91 -0
- package/dist/project-import.js +257 -0
- package/dist/project-workflow.d.ts +1 -1
- package/dist/reconcile/bootstrap-systems.d.ts +2 -2
- package/dist/reconcile/bootstrap-systems.js +3 -3
- package/dist/reconcile/builtin-adapters.d.ts +7 -1
- package/dist/reconcile/builtin-adapters.js +2924 -346
- package/dist/reconcile/contracts.d.ts +15 -2
- package/dist/reconcile/desired-state.d.ts +2 -193
- package/dist/reconcile/desired-state.js +24 -33
- package/dist/reconcile/engine.d.ts +60 -397
- package/dist/reconcile/engine.js +182 -18
- package/dist/reconcile/index.d.ts +10 -10
- package/dist/reconcile/live-acceptance.d.ts +22 -1
- package/dist/reconcile/live-acceptance.js +456 -44
- package/dist/reconcile/providers/docker-private.d.ts +54 -0
- package/dist/reconcile/providers/docker-private.js +101 -0
- package/dist/reconcile/providers/github-private.d.ts +65 -0
- package/dist/reconcile/providers/github-private.js +119 -0
- package/dist/reconcile/providers/local-private.d.ts +28 -0
- package/dist/reconcile/providers/local-private.js +75 -0
- package/dist/reconcile/providers/railway-iac.d.ts +66 -0
- package/dist/reconcile/providers/railway-iac.js +275 -0
- package/dist/reconcile/providers/release-private.d.ts +92 -0
- package/dist/reconcile/providers/release-private.js +152 -0
- package/dist/reconcile/registry.d.ts +2 -2
- package/dist/reconcile/registry.js +16 -1
- package/dist/reconcile/state.d.ts +1 -1
- package/dist/reconcile/state.js +3 -40
- package/dist/reconcile/units.d.ts +1 -1
- package/dist/reconcile/units.js +7 -1
- package/dist/remote.d.ts +6 -6
- package/dist/scenes/artifacts.d.ts +16 -0
- package/dist/scenes/artifacts.js +61 -0
- package/dist/scenes/auth.d.ts +2 -0
- package/dist/scenes/auth.js +28 -0
- package/dist/scenes/base-url.d.ts +12 -0
- package/dist/scenes/base-url.js +123 -0
- package/dist/scenes/builtin-plugins.d.ts +2 -0
- package/dist/scenes/builtin-plugins.js +447 -0
- package/dist/scenes/checkpoints.d.ts +14 -0
- package/dist/scenes/checkpoints.js +33 -0
- package/dist/scenes/device-matrix.d.ts +2 -0
- package/dist/scenes/device-matrix.js +97 -0
- package/dist/scenes/devices.d.ts +11 -0
- package/dist/scenes/devices.js +22 -0
- package/dist/scenes/diagnostics.d.ts +5 -0
- package/dist/scenes/diagnostics.js +22 -0
- package/dist/scenes/diagram-providers.d.ts +2 -0
- package/dist/scenes/diagram-providers.js +181 -0
- package/dist/scenes/diagram-validation.d.ts +22 -0
- package/dist/scenes/diagram-validation.js +74 -0
- package/dist/scenes/environment.d.ts +2 -0
- package/dist/scenes/environment.js +65 -0
- package/dist/scenes/evidence-bundle.d.ts +5 -0
- package/dist/scenes/evidence-bundle.js +42 -0
- package/dist/scenes/evidence-report.d.ts +10 -0
- package/dist/scenes/evidence-report.js +73 -0
- package/dist/scenes/evidence.d.ts +16 -0
- package/dist/scenes/evidence.js +277 -0
- package/dist/scenes/index.d.ts +48 -0
- package/dist/scenes/index.js +312 -0
- package/dist/scenes/inspect.d.ts +9 -0
- package/dist/scenes/inspect.js +64 -0
- package/dist/scenes/loader.d.ts +3 -0
- package/dist/scenes/loader.js +38 -0
- package/dist/scenes/logs.d.ts +2 -0
- package/dist/scenes/logs.js +47 -0
- package/dist/scenes/operations.d.ts +3 -0
- package/dist/scenes/operations.js +128 -0
- package/dist/scenes/phase0.d.ts +9 -0
- package/dist/scenes/phase0.js +637 -0
- package/dist/scenes/planner.d.ts +12 -0
- package/dist/scenes/planner.js +166 -0
- package/dist/scenes/playwright-adapter.d.ts +2 -0
- package/dist/scenes/playwright-adapter.js +63 -0
- package/dist/scenes/plugins.d.ts +5 -0
- package/dist/scenes/plugins.js +115 -0
- package/dist/scenes/progress.d.ts +17 -0
- package/dist/scenes/progress.js +24 -0
- package/dist/scenes/publish-destinations.d.ts +12 -0
- package/dist/scenes/publish-destinations.js +99 -0
- package/dist/scenes/publish-plan-report.d.ts +10 -0
- package/dist/scenes/publish-plan-report.js +70 -0
- package/dist/scenes/publish-plan.d.ts +15 -0
- package/dist/scenes/publish-plan.js +248 -0
- package/dist/scenes/publish-redaction.d.ts +16 -0
- package/dist/scenes/publish-redaction.js +148 -0
- package/dist/scenes/publish-release-record.d.ts +13 -0
- package/dist/scenes/publish-release-record.js +34 -0
- package/dist/scenes/publish-report.d.ts +10 -0
- package/dist/scenes/publish-report.js +67 -0
- package/dist/scenes/publish.d.ts +16 -0
- package/dist/scenes/publish.js +298 -0
- package/dist/scenes/registry.d.ts +12 -0
- package/dist/scenes/registry.js +65 -0
- package/dist/scenes/remotion-adapter.d.ts +3 -0
- package/dist/scenes/remotion-adapter.js +94 -0
- package/dist/scenes/remotion-composition-registry.d.ts +2 -0
- package/dist/scenes/remotion-composition-registry.js +12 -0
- package/dist/scenes/remotion-compositions.d.ts +15 -0
- package/dist/scenes/remotion-compositions.js +464 -0
- package/dist/scenes/remotion-diagrams.d.ts +9 -0
- package/dist/scenes/remotion-diagrams.js +188 -0
- package/dist/scenes/remotion-input.d.ts +13 -0
- package/dist/scenes/remotion-input.js +291 -0
- package/dist/scenes/remotion-visuals.d.ts +29 -0
- package/dist/scenes/remotion-visuals.js +198 -0
- package/dist/scenes/render-media-assets.d.ts +9 -0
- package/dist/scenes/render-media-assets.js +117 -0
- package/dist/scenes/render-report.d.ts +10 -0
- package/dist/scenes/render-report.js +27 -0
- package/dist/scenes/render.d.ts +2 -0
- package/dist/scenes/render.js +218 -0
- package/dist/scenes/reporter.d.ts +3 -0
- package/dist/scenes/reporter.js +101 -0
- package/dist/scenes/resume.d.ts +2 -0
- package/dist/scenes/resume.js +79 -0
- package/dist/scenes/runner.d.ts +2 -0
- package/dist/scenes/runner.js +674 -0
- package/dist/scenes/schema.d.ts +6 -0
- package/dist/scenes/schema.js +994 -0
- package/dist/scenes/seed.d.ts +2 -0
- package/dist/scenes/seed.js +83 -0
- package/dist/scenes/segments.d.ts +15 -0
- package/dist/scenes/segments.js +79 -0
- package/dist/scenes/selectors.d.ts +3 -0
- package/dist/scenes/selectors.js +21 -0
- package/dist/scenes/timeline.d.ts +11 -0
- package/dist/scenes/timeline.js +26 -0
- package/dist/scenes/timeouts.d.ts +6 -0
- package/dist/scenes/timeouts.js +17 -0
- package/dist/scenes/training-captions.d.ts +14 -0
- package/dist/scenes/training-captions.js +98 -0
- package/dist/scenes/training-report.d.ts +10 -0
- package/dist/scenes/training-report.js +78 -0
- package/dist/scenes/training-transcript.d.ts +24 -0
- package/dist/scenes/training-transcript.js +204 -0
- package/dist/scenes/training.d.ts +10 -0
- package/dist/scenes/training.js +134 -0
- package/dist/scenes/types.d.ts +1872 -0
- package/dist/scenes/types.js +8 -0
- package/dist/scenes/visual-audit-contact-sheets.d.ts +6 -0
- package/dist/scenes/visual-audit-contact-sheets.js +119 -0
- package/dist/scenes/visual-audit-fixtures.d.ts +25 -0
- package/dist/scenes/visual-audit-fixtures.js +210 -0
- package/dist/scenes/visual-audit-report.d.ts +11 -0
- package/dist/scenes/visual-audit-report.js +85 -0
- package/dist/scenes/visual-audit-review.d.ts +23 -0
- package/dist/scenes/visual-audit-review.js +829 -0
- package/dist/scenes/visual-audit-routes.d.ts +13 -0
- package/dist/scenes/visual-audit-routes.js +308 -0
- package/dist/scenes/visual-audit.d.ts +3 -0
- package/dist/scenes/visual-audit.js +596 -0
- package/dist/scripts/build-dist.js +154 -40
- package/dist/scripts/check-build-warnings.js +42 -53
- package/dist/scripts/cleanup-markdown.js +1 -1
- package/dist/scripts/cli-test-fixtures.js +24 -28
- package/dist/scripts/migrate-journey-csv-to-guarantees.js +140 -0
- package/dist/scripts/package-tools.js +12 -1
- package/dist/scripts/prepare.js +3 -7
- package/dist/scripts/release-verify.js +2 -5
- package/dist/scripts/run-fixture-astro-command.js +1 -1
- package/dist/scripts/template-catalog.test.js +68 -82
- package/dist/scripts/tenant-dev.js +0 -10
- package/dist/scripts/test-cloudflare-local.js +1 -1
- package/dist/scripts/test-scaffold.js +0 -1
- package/dist/scripts/test-smoke.js +3 -3
- package/dist/scripts/treeseed-build-dist.js +4 -7
- package/dist/scripts/treeseed-release-verify.js +1 -1
- package/dist/scripts/verify-driver.js +30 -21
- package/dist/scripts/workflow-commands.test.js +18 -27
- package/dist/scripts/workspace-command-e2e.js +1 -1
- package/dist/scripts/workspace-lint.js +6 -0
- package/dist/scripts/workspace-release-test.js +90 -1
- package/dist/scripts/workspace-test.js +6 -0
- package/dist/sdk-dispatch.d.ts +1 -1
- package/dist/sdk-dispatch.js +0 -16
- package/dist/sdk-fields.d.ts +1 -1
- package/dist/sdk-filters.d.ts +1 -1
- package/dist/sdk-types.d.ts +1184 -113
- package/dist/sdk-types.js +393 -0
- package/dist/sdk.d.ts +74 -79
- package/dist/sdk.js +27 -36
- package/dist/secrets-capability.d.ts +421 -0
- package/dist/secrets-capability.js +530 -0
- package/dist/seeds/normalize.js +1 -0
- package/dist/seeds/planner.js +38 -0
- package/dist/seeds/schema.js +293 -4
- package/dist/seeds/types.d.ts +60 -0
- package/dist/seeds/types.js +9 -1
- package/dist/service-credentials.d.ts +54 -0
- package/dist/service-credentials.js +112 -0
- package/dist/stores/cursor-store.d.ts +2 -2
- package/dist/stores/envelopes.d.ts +1 -1
- package/dist/stores/helpers.d.ts +1 -1
- package/dist/stores/lease-store.d.ts +2 -2
- package/dist/stores/message-store.d.ts +2 -2
- package/dist/stores/operational-store.d.ts +3 -26
- package/dist/stores/operational-store.js +0 -225
- package/dist/stores/project-workflow-store.d.ts +2 -2
- package/dist/stores/run-store.d.ts +2 -3
- package/dist/stores/run-store.js +0 -98
- package/dist/stores/subscription-store.d.ts +2 -3
- package/dist/stores/subscription-store.js +0 -100
- package/dist/template-catalog.d.ts +1 -1
- package/dist/template-launch-requirements.d.ts +2 -2
- package/dist/template-launch-ui.d.ts +2 -2
- package/dist/treedx/adapters.d.ts +6 -6
- package/dist/treedx/client.d.ts +1 -1
- package/dist/treedx/errors.d.ts +1 -1
- package/dist/treedx/federated-client.d.ts +3 -3
- package/dist/treedx/graph-adapter.d.ts +2 -2
- package/dist/treedx/index.d.ts +14 -14
- package/dist/treedx/market-integration.d.ts +1 -1
- package/dist/treedx/ports.d.ts +30 -30
- package/dist/treedx/query-adapter.d.ts +3 -3
- package/dist/treedx/registry-client.d.ts +2 -2
- package/dist/treedx/repository-adapter.d.ts +4 -4
- package/dist/treedx/repository-adapter.js +14 -3
- package/dist/treedx/sdk-integration.d.ts +3 -3
- package/dist/treedx/types.d.ts +2 -2
- package/dist/treedx/workspace-adapter.d.ts +2 -2
- package/dist/treedx-backends.d.ts +13 -11
- package/dist/treedx-backends.js +52 -50
- package/dist/treedx-client.d.ts +3 -0
- package/dist/treedx-client.js +10 -1
- package/dist/treeseed/services/compose.yml +2 -3
- package/dist/treeseed/template-catalog/catalog.fixture.json +4 -4
- package/dist/types/agents.d.ts +256 -0
- package/dist/types/agents.js +42 -1
- package/dist/verification.d.ts +1 -0
- package/dist/verification.js +143 -14
- package/dist/workflow/operations.d.ts +510 -559
- package/dist/workflow/operations.js +1891 -1342
- package/dist/workflow/policy.js +19 -7
- package/dist/workflow/runs.d.ts +9 -3
- package/dist/workflow/runs.js +66 -26
- package/dist/workflow/session.d.ts +4 -1
- package/dist/workflow/session.js +50 -10
- package/dist/workflow/worktrees.d.ts +6 -2
- package/dist/workflow/worktrees.js +98 -15
- package/dist/workflow-state.d.ts +5 -5
- package/dist/workflow-state.js +27 -17
- package/dist/workflow-support.d.ts +26 -25
- package/dist/workflow-support.js +27 -31
- package/dist/workflow.d.ts +46 -16
- package/dist/workflow.js +19 -7
- package/drizzle/d1/0000_treeseed_d1.sql +0 -18
- package/drizzle/market/0000_market_control_plane.sql +1793 -1499
- package/drizzle/market/0005_agent_capacity_coordination.sql +145 -0
- package/drizzle/market/0006_provider_assignment_lifecycle.sql +9 -0
- package/drizzle/market/0007_agent_architecture_gap_closure.sql +157 -0
- package/drizzle/market/0008_agent_capacity_operational_closure.sql +27 -0
- package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +29 -0
- package/drizzle/market/0010_secrets_capability_persistence.sql +130 -0
- package/drizzle/market/0011_github_app_adapter.sql +47 -0
- package/drizzle/market/0012_workday_test_runs.sql +44 -0
- package/drizzle/market/0013_runtime_task_lifecycle.sql +39 -0
- package/drizzle/market/0014_governance_pipeline.sql +189 -0
- package/package.json +75 -18
- package/scripts/{verify-driver.mjs → verify-driver.ts} +19 -4
- package/templates/github/deploy-web.workflow.yml +12 -8
- package/dist/operations/services/mailpit-runtime.d.ts +0 -20
- package/dist/operations/services/mailpit-runtime.js +0 -67
- package/dist/operations/services/release-candidate.d.ts +0 -60
- package/dist/operations/services/release-candidate.js +0 -953
- package/dist/scripts/ensure-mailpit.js +0 -48
- package/dist/scripts/logs-mailpit.js +0 -2
- package/dist/scripts/run-ts.js +0 -45
- package/dist/scripts/stop-mailpit.js +0 -5
- package/dist/scripts/treeseed-run-ts.js +0 -45
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { relative, resolve } from "node:path";
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, relative, resolve } from "node:path";
|
|
4
3
|
import { parse as parseYaml } from "yaml";
|
|
5
4
|
import { workspacePackages, workspaceRoot } from "./workspace-tools.js";
|
|
5
|
+
import { runTreeseedGit } from "./git-runner.js";
|
|
6
|
+
import { resolveTreeseedLaunchEnvironment } from "./config-runtime.js";
|
|
7
|
+
import { resolveGitHubCredentialForRepository } from "./github-credentials.js";
|
|
8
|
+
import {
|
|
9
|
+
createGitHubApiClient,
|
|
10
|
+
getLatestGitHubWorkflowRun
|
|
11
|
+
} from "./github-api.js";
|
|
12
|
+
import { resolveTreeseedDockerhubToken, resolveTreeseedDockerhubUsername } from "../../service-credentials.js";
|
|
13
|
+
import { inspectTreeseedContentStructure } from "../../platform/content-runtime-source.js";
|
|
14
|
+
import {
|
|
15
|
+
SEED_CONTENT_PUBLISH_TARGETS,
|
|
16
|
+
SEED_CONTENT_RUNTIME_SOURCES,
|
|
17
|
+
SEED_LOCAL_CONTENT_MATERIALIZATIONS,
|
|
18
|
+
SEED_PROJECT_TOPOLOGIES
|
|
19
|
+
} from "../../seeds/types.js";
|
|
6
20
|
function readJsonFile(filePath) {
|
|
7
21
|
try {
|
|
8
22
|
return JSON.parse(readFileSync(filePath, "utf8"));
|
|
@@ -42,6 +56,49 @@ function commandFromScript(dir, script, label) {
|
|
|
42
56
|
}
|
|
43
57
|
return { label, command: "bash", args: ["-lc", trimmed], cwd: dir };
|
|
44
58
|
}
|
|
59
|
+
function normalizePackageSlug(id) {
|
|
60
|
+
const raw = id.startsWith("@treeseed/") ? id.slice("@treeseed/".length) : id;
|
|
61
|
+
return raw.toLowerCase().replace(/^treeseed-/u, "").replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "") || "package";
|
|
62
|
+
}
|
|
63
|
+
function enumValue(value, allowed, fallback) {
|
|
64
|
+
return typeof value === "string" && allowed.includes(value) ? value : fallback;
|
|
65
|
+
}
|
|
66
|
+
function normalizeTreeseedPackageProjectArchitecture(value, packageId) {
|
|
67
|
+
const record = stringRecord(value);
|
|
68
|
+
if (Object.keys(record).length === 0) return null;
|
|
69
|
+
const publishTarget = stringRecord(record.contentPublishTarget);
|
|
70
|
+
const packageSlug = normalizePackageSlug(packageId);
|
|
71
|
+
const targetKind = enumValue(publishTarget.kind, SEED_CONTENT_PUBLISH_TARGETS, "cloudflare_r2");
|
|
72
|
+
return {
|
|
73
|
+
topology: enumValue(record.topology, SEED_PROJECT_TOPOLOGIES, "single_repository_site"),
|
|
74
|
+
rootPath: stringValue(record.rootPath) ?? ".",
|
|
75
|
+
sitePath: stringValue(record.sitePath) ?? "docs",
|
|
76
|
+
contentPath: stringValue(record.contentPath) ?? "docs",
|
|
77
|
+
contentRuntimeSource: enumValue(record.contentRuntimeSource, SEED_CONTENT_RUNTIME_SOURCES, "r2_published_manifest"),
|
|
78
|
+
localContentMaterialization: enumValue(record.localContentMaterialization, SEED_LOCAL_CONTENT_MATERIALIZATIONS, "none"),
|
|
79
|
+
contentPublishTarget: {
|
|
80
|
+
kind: targetKind,
|
|
81
|
+
...stringValue(publishTarget.bucket) ? { bucket: stringValue(publishTarget.bucket) } : {},
|
|
82
|
+
prefix: stringValue(publishTarget.prefix) ?? `packages/${packageSlug}`,
|
|
83
|
+
...stringValue(publishTarget.manifestPath) ? { manifestPath: stringValue(publishTarget.manifestPath) } : {}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function docsSiteReadiness(dir, architecture) {
|
|
88
|
+
if (!architecture) return null;
|
|
89
|
+
const diagnostic = inspectTreeseedContentStructure({ projectRoot: dir, architecture });
|
|
90
|
+
const readiness = diagnostic.status === "ready" ? "ready" : diagnostic.status === "unsupported_structure" ? "unsupported_structure" : "site_not_prepared";
|
|
91
|
+
return {
|
|
92
|
+
status: readiness,
|
|
93
|
+
diagnostic
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function deploymentSourceModeForBranch(metadata, branch) {
|
|
97
|
+
const source = stringRecord(metadata.deploymentSource);
|
|
98
|
+
const normalizedBranch = branch === "prod" || branch === "production" || branch === "main" ? "prod" : branch === "staging" ? "staging" : "local";
|
|
99
|
+
const configured = stringValue(source[normalizedBranch]);
|
|
100
|
+
return configured === "git" || configured === "image" ? configured : normalizedBranch === "prod" ? "image" : stringValue(source.staging) === "git" ? "git" : null;
|
|
101
|
+
}
|
|
45
102
|
function nodeTypeScriptAdapter(pkg) {
|
|
46
103
|
const manifest = readTreeseedPackageManifest(pkg.dir);
|
|
47
104
|
const scripts = pkg.packageJson?.scripts && typeof pkg.packageJson.scripts === "object" && !Array.isArray(pkg.packageJson.scripts) ? pkg.packageJson.scripts : {};
|
|
@@ -49,8 +106,15 @@ function nodeTypeScriptAdapter(pkg) {
|
|
|
49
106
|
const repository = stringValue(manifest?.repository) ?? normalizeGitHubRepositorySlug(pkg.packageJson?.repository);
|
|
50
107
|
const id = stringValue(manifest?.id) ?? String(pkg.name);
|
|
51
108
|
const name = stringValue(manifest?.name) ?? String(pkg.name);
|
|
52
|
-
const
|
|
53
|
-
const
|
|
109
|
+
const dockerArtifacts = manifestDockerArtifacts(manifest?.artifacts);
|
|
110
|
+
const dockerImages = stringRecord(manifest?.dockerImages);
|
|
111
|
+
const dockerImageReleaseWorkflow = stringValue(dockerImages.releaseWorkflow);
|
|
112
|
+
const dockerImageArchitectures = stringArray(dockerImages.architectures);
|
|
113
|
+
const publishTargetRaw = stringValue(manifest?.publishTarget);
|
|
114
|
+
const publishTarget = dockerArtifacts.length > 0 && publishTargetRaw === "docker" ? dockerArtifacts[0].name : publishTargetRaw ?? "npm";
|
|
115
|
+
const hostedVerifyWorkflow = stringValue(manifest?.hostedVerifyWorkflow) ?? stringValue(stringRecord(manifest?.releaseGate).workflow) ?? (existsSync(resolve(pkg.dir, ".github/workflows/deploy.yml")) ? "deploy.yml" : null);
|
|
116
|
+
const projectArchitecture = normalizeTreeseedPackageProjectArchitecture(manifest?.projectArchitecture, id);
|
|
117
|
+
const docsReadiness = docsSiteReadiness(pkg.dir, projectArchitecture);
|
|
54
118
|
const verifyLocal = typeof scripts["verify:local"] === "string" ? "verify:local" : typeof scripts.verify === "string" ? "verify" : typeof scripts["verify:action"] === "string" ? "verify:action" : null;
|
|
55
119
|
return {
|
|
56
120
|
id,
|
|
@@ -67,13 +131,39 @@ function nodeTypeScriptAdapter(pkg) {
|
|
|
67
131
|
local: commandFromScript(pkg.dir, manifestVerify.local, "local") ?? (verifyLocal ? { label: verifyLocal, command: "npm", args: ["run", verifyLocal], cwd: pkg.dir } : null),
|
|
68
132
|
release: commandFromScript(pkg.dir, manifestVerify.release, "release") ?? (typeof scripts["release:publish"] === "string" ? { label: "release:publish", command: "npm", args: ["run", "release:publish"], cwd: pkg.dir } : null)
|
|
69
133
|
},
|
|
70
|
-
artifacts:
|
|
134
|
+
artifacts: dockerArtifacts.length > 0 ? dockerArtifacts.map((artifact) => ({
|
|
135
|
+
provider: "docker",
|
|
136
|
+
name: artifact.name,
|
|
137
|
+
dockerfile: artifact.dockerfile,
|
|
138
|
+
context: artifact.context,
|
|
139
|
+
target: artifact.target,
|
|
140
|
+
role: artifact.role,
|
|
141
|
+
architectures: artifact.architectures
|
|
142
|
+
})) : [{ provider: "npm", name: String(pkg.name) }],
|
|
71
143
|
releaseChecks: [
|
|
72
|
-
{ kind: "github-workflow", name: "publish workflow", detail: ".github/workflows/publish.yml" },
|
|
73
|
-
{ kind: "npm-pack-dry-run", name: "npm pack", detail: "npm pack --dry-run" }
|
|
144
|
+
{ kind: "github-workflow", name: "publish workflow", detail: dockerImageReleaseWorkflow ? `.github/workflows/${dockerImageReleaseWorkflow}` : ".github/workflows/publish.yml" },
|
|
145
|
+
...dockerArtifacts.length > 0 ? dockerArtifacts.map((artifact) => ({ kind: "docker-manifest", name: `${artifact.name} Docker image manifest`, detail: `${artifact.name}:<version>` })) : [{ kind: "npm-pack-dry-run", name: "npm pack", detail: "npm pack --dry-run" }]
|
|
74
146
|
],
|
|
75
147
|
metadata: {
|
|
76
148
|
...repository ? { repository } : {},
|
|
149
|
+
deploymentSource: stringRecord(manifest?.deploymentSource),
|
|
150
|
+
...dockerArtifacts.length > 0 ? {
|
|
151
|
+
dockerArtifacts,
|
|
152
|
+
dockerImageReleaseWorkflow: dockerImageReleaseWorkflow ? `.github/workflows/${dockerImageReleaseWorkflow}` : ".github/workflows/publish.yml",
|
|
153
|
+
dockerImageArchitectures,
|
|
154
|
+
imageHosting: stringRecord(dockerImages.hosting)
|
|
155
|
+
} : {},
|
|
156
|
+
type: stringValue(manifest?.type) ?? null,
|
|
157
|
+
githubEnvironments: stringArray(manifest?.githubEnvironments),
|
|
158
|
+
requiredSecrets: stringArray(manifest?.requiredSecrets),
|
|
159
|
+
workflowTemplateVersion: stringValue(manifest?.workflowTemplateVersion) ?? null,
|
|
160
|
+
localDev: stringRecord(manifest?.localDev),
|
|
161
|
+
capacityProvider: stringRecord(manifest?.capacityProvider),
|
|
162
|
+
...projectArchitecture ? {
|
|
163
|
+
projectArchitecture,
|
|
164
|
+
docsSiteReadiness: docsReadiness?.status ?? "site_not_prepared",
|
|
165
|
+
docsSiteDiagnostic: docsReadiness?.diagnostic ?? null
|
|
166
|
+
} : {},
|
|
77
167
|
...hostedVerifyWorkflow ? {
|
|
78
168
|
hostedVerifyWorkflow: hostedVerifyWorkflow.startsWith(".github/workflows/") ? hostedVerifyWorkflow : `.github/workflows/${hostedVerifyWorkflow}`
|
|
79
169
|
} : {},
|
|
@@ -101,6 +191,24 @@ function stringValue(value) {
|
|
|
101
191
|
function stringArray(value) {
|
|
102
192
|
return Array.isArray(value) ? value.map((entry) => stringValue(entry)).filter((entry) => Boolean(entry)) : [];
|
|
103
193
|
}
|
|
194
|
+
function manifestDockerArtifacts(value) {
|
|
195
|
+
if (!Array.isArray(value)) return [];
|
|
196
|
+
return value.map((entry) => {
|
|
197
|
+
const record = stringRecord(entry);
|
|
198
|
+
if (stringValue(record.provider) !== "docker") return null;
|
|
199
|
+
const name = stringValue(record.name);
|
|
200
|
+
if (!name) return null;
|
|
201
|
+
return {
|
|
202
|
+
provider: "docker",
|
|
203
|
+
name,
|
|
204
|
+
dockerfile: stringValue(record.dockerfile),
|
|
205
|
+
context: stringValue(record.context),
|
|
206
|
+
target: stringValue(record.target),
|
|
207
|
+
role: stringValue(record.role),
|
|
208
|
+
architectures: stringArray(record.architectures)
|
|
209
|
+
};
|
|
210
|
+
}).filter((entry) => Boolean(entry));
|
|
211
|
+
}
|
|
104
212
|
function beamPackageAdapter(root, dir) {
|
|
105
213
|
const manifest = readTreeseedPackageManifest(dir);
|
|
106
214
|
const hasMixProject = existsSync(resolve(dir, "apps/api/mix.exs")) || existsSync(resolve(dir, "mix.exs"));
|
|
@@ -113,18 +221,13 @@ function beamPackageAdapter(root, dir) {
|
|
|
113
221
|
const versionSource = resolve(dir, versionSourceRel);
|
|
114
222
|
const image = typeof manifest?.image === "string" && manifest.image.trim() ? manifest.image.trim() : id === "treedx" ? "treeseed/treedx" : null;
|
|
115
223
|
const repository = stringValue(manifest?.repository) ?? (id === "treedx" ? "treeseed-ai/treedx" : null);
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
const hostedVerifyWorkflow = stringValue(stringRecord(manifest?.releaseGate).workflow) ?? (existsSync(resolve(dir, ".github/workflows/release-gate.yml")) ? "release-gate.yml" : null);
|
|
120
|
-
const developmentImageDefaultBranch = stringValue(developmentImages.defaultBranch) ?? "staging";
|
|
121
|
-
const developmentImageTagPrefix = stringValue(developmentImages.tagPrefix) ?? "dev";
|
|
122
|
-
const developmentImageMovingTag = developmentImages.movingTag === false ? false : true;
|
|
123
|
-
const developmentImageArchitectures = stringArray(developmentImages.architectures);
|
|
224
|
+
const hostedVerifyWorkflow = stringValue(manifest?.hostedVerifyWorkflow) ?? stringValue(stringRecord(manifest?.releaseGate).workflow) ?? (existsSync(resolve(dir, ".github/workflows/release-gate.yml")) ? "release-gate.yml" : null);
|
|
225
|
+
const projectArchitecture = normalizeTreeseedPackageProjectArchitecture(manifest?.projectArchitecture, id);
|
|
226
|
+
const docsReadiness = docsSiteReadiness(dir, projectArchitecture);
|
|
124
227
|
const verify = manifest?.verify && typeof manifest.verify === "object" && !Array.isArray(manifest.verify) ? manifest.verify : {};
|
|
125
228
|
const fast = verify.fast ?? (existsSync(resolve(dir, "scripts/test-treedx-fast.sh")) ? "scripts/test-treedx-fast.sh" : null);
|
|
126
229
|
const local = verify.local ?? (existsSync(resolve(dir, "scripts/test-all.sh")) ? "scripts/test-all.sh" : null);
|
|
127
|
-
const releaseGate = manifest?.releaseGate ?? verify.release ?? (existsSync(resolve(dir, "scripts/release-gate.sh")) ? "scripts/release-gate.sh" : null);
|
|
230
|
+
const releaseGate = stringValue(manifest?.releaseGate) ?? verify.release ?? (existsSync(resolve(dir, "scripts/release-gate.sh")) ? "scripts/release-gate.sh" : null);
|
|
128
231
|
const version = readMixProjectVersion(versionSource);
|
|
129
232
|
const shaTag = "sha-<short-sha>";
|
|
130
233
|
return {
|
|
@@ -142,37 +245,56 @@ function beamPackageAdapter(root, dir) {
|
|
|
142
245
|
local: commandFromScript(dir, local, "local"),
|
|
143
246
|
release: commandFromScript(dir, releaseGate, "release")
|
|
144
247
|
},
|
|
145
|
-
artifacts: image ? [{
|
|
248
|
+
artifacts: image ? [{
|
|
249
|
+
provider: "docker",
|
|
250
|
+
name: image,
|
|
251
|
+
tags: version ? [version, shaTag] : [shaTag],
|
|
252
|
+
dockerfile: "Dockerfile",
|
|
253
|
+
context: ".",
|
|
254
|
+
target: null,
|
|
255
|
+
role: id,
|
|
256
|
+
architectures: stringArray(stringRecord(manifest?.dockerImages).architectures)
|
|
257
|
+
}] : [],
|
|
146
258
|
releaseChecks: image ? [{ kind: "docker-manifest", name: "Docker image manifest", detail: `${image}:${version ?? "<version>"}` }] : [],
|
|
147
259
|
metadata: {
|
|
148
260
|
hasCargo: existsSync(resolve(dir, "Cargo.toml")),
|
|
149
261
|
hasDockerfile: existsSync(resolve(dir, "Dockerfile")),
|
|
150
262
|
repository,
|
|
263
|
+
deploymentSource: stringRecord(manifest?.deploymentSource),
|
|
264
|
+
imageHosting: stringRecord(stringRecord(manifest?.dockerImages).hosting),
|
|
151
265
|
versionSource: versionSourceRel,
|
|
152
|
-
...developmentImageWorkflow ? {
|
|
153
|
-
developmentImageWorkflow: developmentImageWorkflow.startsWith(".github/workflows/") ? developmentImageWorkflow : `.github/workflows/${developmentImageWorkflow}`,
|
|
154
|
-
developmentImageDefaultBranch,
|
|
155
|
-
developmentImageTagPrefix,
|
|
156
|
-
developmentImageMovingTag,
|
|
157
|
-
developmentImageArchitectures,
|
|
158
|
-
developmentImageTagPattern: `${image}:${developmentImageTagPrefix}-<branch-slug>-<short-sha>`,
|
|
159
|
-
developmentImageMovingTagPattern: developmentImageMovingTag ? `${image}:${developmentImageTagPrefix}-<branch-slug>` : null,
|
|
160
|
-
developmentImageHosting: Object.keys(developmentImageHosting).length > 0 ? developmentImageHosting : null
|
|
161
|
-
} : {},
|
|
162
266
|
...hostedVerifyWorkflow ? {
|
|
163
267
|
hostedVerifyWorkflow: hostedVerifyWorkflow.startsWith(".github/workflows/") ? hostedVerifyWorkflow : `.github/workflows/${hostedVerifyWorkflow}`
|
|
268
|
+
} : {},
|
|
269
|
+
type: stringValue(manifest?.type) ?? null,
|
|
270
|
+
githubEnvironments: stringArray(manifest?.githubEnvironments),
|
|
271
|
+
requiredSecrets: stringArray(manifest?.requiredSecrets),
|
|
272
|
+
workflowTemplateVersion: stringValue(manifest?.workflowTemplateVersion) ?? null,
|
|
273
|
+
...projectArchitecture ? {
|
|
274
|
+
projectArchitecture,
|
|
275
|
+
docsSiteReadiness: docsReadiness?.status ?? "site_not_prepared",
|
|
276
|
+
docsSiteDiagnostic: docsReadiness?.diagnostic ?? null
|
|
164
277
|
} : {}
|
|
165
278
|
}
|
|
166
279
|
};
|
|
167
280
|
}
|
|
168
281
|
function gitOutput(cwd, args) {
|
|
169
|
-
const result =
|
|
170
|
-
if (result.status !== 0) {
|
|
171
|
-
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
|
|
172
|
-
throw new Error(stderr || `git ${args.join(" ")} failed in ${cwd}.`);
|
|
173
|
-
}
|
|
282
|
+
const result = runTreeseedGit(args, { cwd, mode: "read" });
|
|
174
283
|
return result.stdout.trim();
|
|
175
284
|
}
|
|
285
|
+
function gitRevisionSha(cwd, revision) {
|
|
286
|
+
try {
|
|
287
|
+
return gitOutput(cwd, ["rev-parse", revision]);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
if (/^[A-Za-z0-9._/-]+$/u.test(revision) && !revision.startsWith("origin/")) {
|
|
290
|
+
try {
|
|
291
|
+
return gitOutput(cwd, ["rev-parse", `origin/${revision}`]);
|
|
292
|
+
} catch {
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
throw error;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
176
298
|
function branchSlug(value) {
|
|
177
299
|
const normalized = value.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, 40);
|
|
178
300
|
return normalized || "branch";
|
|
@@ -182,30 +304,58 @@ function planTreeseedPackageDevelopmentImage(root = workspaceRoot(), idOrName, {
|
|
|
182
304
|
if (!adapter) {
|
|
183
305
|
throw new Error(`Treeseed package adapter ${idOrName} was not discovered.`);
|
|
184
306
|
}
|
|
185
|
-
const
|
|
307
|
+
const firstDockerArtifact = adapter.artifacts.find((artifact) => artifact.provider === "docker") ?? null;
|
|
308
|
+
const imageName = typeof adapter.publishTarget === "string" && adapter.publishTarget.trim() ? adapter.publishTarget.trim() : firstDockerArtifact?.name ?? null;
|
|
186
309
|
if (!imageName) {
|
|
187
310
|
throw new Error(`${adapter.id} does not declare a publish image target.`);
|
|
188
311
|
}
|
|
189
312
|
const metadata = adapter.metadata;
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
const selectedBranch = branch ?? stringValue(metadata.developmentImageDefaultBranch) ?? "staging";
|
|
195
|
-
const sha = gitOutput(adapter.dir, ["rev-parse", selectedBranch]);
|
|
196
|
-
const slug = branchSlug(selectedBranch);
|
|
313
|
+
const selectedBranch = branch ?? "staging";
|
|
314
|
+
const deploymentSourceMode = deploymentSourceModeForBranch(metadata, selectedBranch);
|
|
315
|
+
const sha = gitRevisionSha(adapter.dir, selectedBranch);
|
|
197
316
|
const shortSha = sha.slice(0, 12);
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
317
|
+
const deploymentEnvironment = selectedBranch === "main" ? "prod" : selectedBranch;
|
|
318
|
+
const imagePublicationRequired = (deploymentSourceMode ?? "image") === "image";
|
|
319
|
+
if (deploymentEnvironment !== "prod" && imagePublicationRequired) {
|
|
320
|
+
throw new Error(`${adapter.id} non-production package image planning is tagless and must use deploymentSource git.`);
|
|
321
|
+
}
|
|
322
|
+
const workflow = imagePublicationRequired ? stringValue(metadata.dockerImageReleaseWorkflow)?.replace(/^\.github\/workflows\//u, "") ?? "publish.yml" : "source-build";
|
|
323
|
+
const productionImageTag = deploymentEnvironment === "prod" ? adapter.version : null;
|
|
324
|
+
if (deploymentEnvironment === "prod" && (!productionImageTag || !/^\d+\.\d+\.\d+$/u.test(productionImageTag))) {
|
|
325
|
+
throw new Error(`${adapter.id} production image publication requires a stable semantic package version.`);
|
|
326
|
+
}
|
|
327
|
+
const immutableTag = productionImageTag;
|
|
328
|
+
const movingTag = null;
|
|
329
|
+
const architectures = stringArray(metadata.dockerImageArchitectures);
|
|
330
|
+
const dockerArtifacts = Array.isArray(metadata.dockerArtifacts) ? metadata.dockerArtifacts.map((entry) => {
|
|
331
|
+
const record = stringRecord(entry);
|
|
332
|
+
const artifactImageName = stringValue(record.name);
|
|
333
|
+
if (!artifactImageName) return null;
|
|
334
|
+
return {
|
|
335
|
+
role: stringValue(record.role) ?? artifactImageName.split("/").at(-1)?.replace(/^agent-/u, "") ?? artifactImageName,
|
|
336
|
+
imageName: artifactImageName,
|
|
337
|
+
target: stringValue(record.target),
|
|
338
|
+
architectures: stringArray(record.architectures)
|
|
339
|
+
};
|
|
340
|
+
}).filter((entry) => Boolean(entry)) : [];
|
|
341
|
+
const imageHosting = stringRecord(metadata.imageHosting);
|
|
342
|
+
const app = stringValue(imageHosting.app);
|
|
343
|
+
const overrideEnvVar = stringValue(imageHosting.envVar);
|
|
344
|
+
const environment = deploymentEnvironment === "prod" ? "prod" : stringValue(imageHosting.environment) ?? selectedBranch;
|
|
345
|
+
const imageRef = immutableTag ? `${imageName}:${immutableTag}` : null;
|
|
346
|
+
const movingImageRef = null;
|
|
208
347
|
const hostingImageRef = movingImageRef ?? imageRef;
|
|
348
|
+
const roleImages = dockerArtifacts.length > 0 ? dockerArtifacts.map((artifact) => {
|
|
349
|
+
const artifactArchitectures = artifact.architectures.length > 0 ? artifact.architectures : architectures;
|
|
350
|
+
return {
|
|
351
|
+
role: artifact.role,
|
|
352
|
+
imageName: artifact.imageName,
|
|
353
|
+
target: artifact.target,
|
|
354
|
+
immutableRef: immutableTag ? `${artifact.imageName}:${immutableTag}` : null,
|
|
355
|
+
movingRef: null,
|
|
356
|
+
archImageRefs: immutableTag ? artifactArchitectures.map((arch) => `${artifact.imageName}:${immutableTag}-${arch}`) : []
|
|
357
|
+
};
|
|
358
|
+
}) : void 0;
|
|
209
359
|
return {
|
|
210
360
|
package: {
|
|
211
361
|
id: adapter.id,
|
|
@@ -222,16 +372,24 @@ function planTreeseedPackageDevelopmentImage(root = workspaceRoot(), idOrName, {
|
|
|
222
372
|
refs: {
|
|
223
373
|
imageName,
|
|
224
374
|
branch: selectedBranch,
|
|
225
|
-
branchSlug:
|
|
375
|
+
branchSlug: branchSlug(selectedBranch),
|
|
226
376
|
sha,
|
|
227
377
|
shortSha,
|
|
228
378
|
immutableTag,
|
|
229
379
|
movingTag,
|
|
230
380
|
imageRef,
|
|
231
381
|
movingImageRef,
|
|
232
|
-
archImageRefs: architectures.map((arch) => `${imageName}:${immutableTag}-${arch}`)
|
|
382
|
+
archImageRefs: immutableTag ? architectures.map((arch) => `${imageName}:${immutableTag}-${arch}`) : [],
|
|
383
|
+
...roleImages ? { roleImages } : {}
|
|
384
|
+
},
|
|
385
|
+
deploymentSource: {
|
|
386
|
+
environment: deploymentEnvironment,
|
|
387
|
+
mode: deploymentSourceMode ?? "image",
|
|
388
|
+
repository: stringValue(metadata.repository) ?? `${adapter.id}`,
|
|
389
|
+
commitSha: sha,
|
|
390
|
+
imagePublicationRequired
|
|
233
391
|
},
|
|
234
|
-
hosting: app && overrideEnvVar ? {
|
|
392
|
+
hosting: imagePublicationRequired && app && overrideEnvVar && hostingImageRef ? {
|
|
235
393
|
app,
|
|
236
394
|
environment,
|
|
237
395
|
overrideEnvVar,
|
|
@@ -260,7 +418,13 @@ function discoverTreeseedPackageAdapters(root = workspaceRoot()) {
|
|
|
260
418
|
});
|
|
261
419
|
}
|
|
262
420
|
function findTreeseedPackageAdapter(root, idOrName) {
|
|
263
|
-
|
|
421
|
+
const normalized = idOrName.trim();
|
|
422
|
+
return discoverTreeseedPackageAdapters(root).find((adapter) => {
|
|
423
|
+
const scopedId = adapter.id.startsWith("@treeseed/") ? adapter.id.slice("@treeseed/".length) : null;
|
|
424
|
+
const scopedName = adapter.name.startsWith("@treeseed/") ? adapter.name.slice("@treeseed/".length) : null;
|
|
425
|
+
const directoryName = adapter.relativeDir.split("/").at(-1);
|
|
426
|
+
return adapter.id === normalized || adapter.name === normalized || scopedId === normalized || scopedName === normalized || directoryName === normalized;
|
|
427
|
+
}) ?? null;
|
|
264
428
|
}
|
|
265
429
|
function packageAdapterPlanSummary(root = workspaceRoot()) {
|
|
266
430
|
return discoverTreeseedPackageAdapters(root).map((adapter) => ({
|
|
@@ -279,10 +443,417 @@ function packageAdapterPlanSummary(root = workspaceRoot()) {
|
|
|
279
443
|
metadata: adapter.metadata
|
|
280
444
|
}));
|
|
281
445
|
}
|
|
446
|
+
async function runTreeseedPackageImageWorkflow(options) {
|
|
447
|
+
const root = options.root ?? workspaceRoot();
|
|
448
|
+
const branch = options.branch ?? "staging";
|
|
449
|
+
const imagePlan = planTreeseedPackageDevelopmentImage(root, options.packageId, { branch });
|
|
450
|
+
const selectedWorkflow = options.workflow ?? imagePlan.workflow;
|
|
451
|
+
const execute = options.execute === true;
|
|
452
|
+
const syncConfig = options.syncConfig === true;
|
|
453
|
+
const configEnv = resolveTreeseedLaunchEnvironment({
|
|
454
|
+
tenantRoot: root,
|
|
455
|
+
scope: "staging",
|
|
456
|
+
baseEnv: options.env ?? process.env
|
|
457
|
+
});
|
|
458
|
+
const dockerHubUsername = resolveTreeseedDockerhubUsername(configEnv);
|
|
459
|
+
const dockerHubToken = resolveTreeseedDockerhubToken(configEnv);
|
|
460
|
+
const dockerHub = {
|
|
461
|
+
usernameConfigured: Boolean(dockerHubUsername),
|
|
462
|
+
tokenConfigured: Boolean(dockerHubToken),
|
|
463
|
+
requiredSecrets: imagePlan.deploymentSource?.imagePublicationRequired === false ? [] : ["TREESEED_DOCKERHUB_TOKEN"],
|
|
464
|
+
requiredVariables: imagePlan.deploymentSource?.imagePublicationRequired === false ? [] : ["TREESEED_DOCKERHUB_USERNAME"]
|
|
465
|
+
};
|
|
466
|
+
const credential = resolveGitHubCredentialForRepository(imagePlan.repository, { values: configEnv, env: options.env ?? process.env });
|
|
467
|
+
const githubClientEnv = credential.token ? { ...configEnv, TREESEED_GITHUB_TOKEN: credential.token, GH_TOKEN: credential.token, GITHUB_TOKEN: credential.token } : configEnv;
|
|
468
|
+
const report = {
|
|
469
|
+
ok: true,
|
|
470
|
+
action: execute ? "dispatch" : "plan",
|
|
471
|
+
package: imagePlan.package,
|
|
472
|
+
repository: imagePlan.repository,
|
|
473
|
+
workflow: selectedWorkflow,
|
|
474
|
+
branch: imagePlan.branch,
|
|
475
|
+
refs: imagePlan.refs,
|
|
476
|
+
deploymentSource: imagePlan.deploymentSource,
|
|
477
|
+
credential: {
|
|
478
|
+
repository: credential.repository,
|
|
479
|
+
envName: credential.envName,
|
|
480
|
+
configured: credential.configured,
|
|
481
|
+
source: credential.source,
|
|
482
|
+
fallbackUsed: credential.fallbackUsed
|
|
483
|
+
},
|
|
484
|
+
dockerHub,
|
|
485
|
+
hosting: imagePlan.hosting,
|
|
486
|
+
reconcile: {
|
|
487
|
+
lifecycle: syncConfig || execute ? ["refresh", "diff", "plan", "validate", "apply", "refresh", "verify", "persist"] : ["refresh", "diff", "plan"],
|
|
488
|
+
resources: [
|
|
489
|
+
`package-workflow:${imagePlan.package.id}`,
|
|
490
|
+
...imagePlan.deploymentSource?.imagePublicationRequired === false ? [`source-build:${imagePlan.repository}#${imagePlan.deploymentSource.commitSha}`] : imagePlan.refs.roleImages ? imagePlan.refs.roleImages.map((entry) => `package-image:${entry.imageName}`) : [`package-image:${imagePlan.refs.imageName}`]
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
if (syncConfig) {
|
|
495
|
+
const environment = imagePlan.hosting?.environment ?? "staging";
|
|
496
|
+
report.syncedConfig = {
|
|
497
|
+
environment,
|
|
498
|
+
blocked: true,
|
|
499
|
+
reason: imagePlan.deploymentSource?.imagePublicationRequired === false ? "Staging source-build policy does not sync Docker image credentials or image override variables." : "Package image config sync is reconciler-owned. Use trsd package image --sync-config so github-secret-binding and github-variable-binding resources apply through adapters.",
|
|
500
|
+
secrets: dockerHubToken ? [{ name: "TREESEED_DOCKERHUB_TOKEN", existed: null }] : [],
|
|
501
|
+
variables: dockerHubUsername ? [{ name: "TREESEED_DOCKERHUB_USERNAME", existed: null }] : []
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
if (execute) {
|
|
505
|
+
const client = createGitHubApiClient({ env: githubClientEnv });
|
|
506
|
+
report.dispatch = {
|
|
507
|
+
blocked: true,
|
|
508
|
+
reason: imagePlan.deploymentSource?.imagePublicationRequired === false ? "Staging deployment source is GitHub source build; routine development Docker image publication is disabled." : "Package image workflow dispatch is reconciler-owned. Use trsd package image --execute so github-workflow-dispatch/package-image resources apply through adapters."
|
|
509
|
+
};
|
|
510
|
+
if (imagePlan.deploymentSource?.imagePublicationRequired !== false) {
|
|
511
|
+
report.latestWorkflowRun = await getLatestGitHubWorkflowRun(imagePlan.repository, {
|
|
512
|
+
client,
|
|
513
|
+
workflow: selectedWorkflow,
|
|
514
|
+
branch: imagePlan.branch
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return { imagePlan, selectedWorkflow, dockerHub, credential, report };
|
|
519
|
+
}
|
|
520
|
+
function validateTreeseedPackageManifests(root = workspaceRoot()) {
|
|
521
|
+
return discoverTreeseedPackageAdapters(root).map((adapter) => {
|
|
522
|
+
const errors = [];
|
|
523
|
+
const warnings = [];
|
|
524
|
+
if (!adapter.manifestPath || adapter.manifestPath.endsWith("package.json")) {
|
|
525
|
+
errors.push("missing treeseed.package.yaml");
|
|
526
|
+
}
|
|
527
|
+
if (!adapter.id.trim()) errors.push("missing package id");
|
|
528
|
+
if (!adapter.name.trim()) errors.push("missing package name");
|
|
529
|
+
if (!["node-typescript", "beam-elixir-rust"].includes(adapter.kind)) {
|
|
530
|
+
errors.push(`unsupported package kind ${adapter.kind}`);
|
|
531
|
+
}
|
|
532
|
+
if (adapter.verifyCommands.local == null) {
|
|
533
|
+
errors.push("missing local verification command");
|
|
534
|
+
}
|
|
535
|
+
if (!adapter.metadata.projectArchitecture) {
|
|
536
|
+
warnings.push("package does not declare projectArchitecture metadata");
|
|
537
|
+
}
|
|
538
|
+
if (adapter.releaseChecks.length === 0) {
|
|
539
|
+
warnings.push("package declares no release checks");
|
|
540
|
+
}
|
|
541
|
+
const hasDockerArtifact = adapter.artifacts.some((artifact) => artifact.provider === "docker");
|
|
542
|
+
if (hasDockerArtifact) {
|
|
543
|
+
const deploymentSource = stringRecord(adapter.metadata.deploymentSource);
|
|
544
|
+
if (stringValue(deploymentSource.staging) !== "git") {
|
|
545
|
+
errors.push("docker package must declare deploymentSource.staging: git");
|
|
546
|
+
}
|
|
547
|
+
if (stringValue(deploymentSource.prod) !== "image") {
|
|
548
|
+
errors.push("docker package must declare deploymentSource.prod: image");
|
|
549
|
+
}
|
|
550
|
+
const architectures = stringArray(adapter.metadata.dockerImageArchitectures);
|
|
551
|
+
if (!architectures.includes("amd64") || !architectures.includes("arm64")) {
|
|
552
|
+
errors.push("docker package must declare amd64 and arm64 architectures");
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
for (const artifact of adapter.artifacts) {
|
|
556
|
+
if (artifact.provider === "docker" && !artifact.name.startsWith("treeseed/")) {
|
|
557
|
+
errors.push(`docker artifact ${artifact.name} must publish under treeseed/*`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return {
|
|
561
|
+
packageId: adapter.id,
|
|
562
|
+
path: adapter.relativeDir,
|
|
563
|
+
manifestPath: adapter.manifestPath,
|
|
564
|
+
ok: errors.length === 0,
|
|
565
|
+
errors,
|
|
566
|
+
warnings
|
|
567
|
+
};
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
function deriveTreeseedPackageProjectResources(root = workspaceRoot(), options = {}) {
|
|
571
|
+
const team = options.team ?? "team:treeseed";
|
|
572
|
+
return discoverTreeseedPackageAdapters(root).map((adapter) => {
|
|
573
|
+
const architecture = adapter.metadata.projectArchitecture;
|
|
574
|
+
const repository = stringValue(adapter.metadata.repository);
|
|
575
|
+
if (!architecture || !repository) return null;
|
|
576
|
+
const [owner, name] = repository.split("/");
|
|
577
|
+
if (!owner || !name) return null;
|
|
578
|
+
const slug = normalizePackageSlug(adapter.id);
|
|
579
|
+
return {
|
|
580
|
+
key: `project:treeseed/${slug}`,
|
|
581
|
+
team,
|
|
582
|
+
slug,
|
|
583
|
+
name: adapter.name,
|
|
584
|
+
description: `${adapter.name} first-party package project.`,
|
|
585
|
+
kind: "package",
|
|
586
|
+
repository: {
|
|
587
|
+
role: "primary",
|
|
588
|
+
provider: "github",
|
|
589
|
+
owner,
|
|
590
|
+
name,
|
|
591
|
+
gitUrl: `https://github.com/${owner}/${name}.git`,
|
|
592
|
+
defaultBranch: "main",
|
|
593
|
+
checkoutPath: adapter.relativeDir
|
|
594
|
+
},
|
|
595
|
+
architecture,
|
|
596
|
+
metadata: {
|
|
597
|
+
packageId: adapter.id,
|
|
598
|
+
packagePath: adapter.relativeDir,
|
|
599
|
+
visibility: "public",
|
|
600
|
+
docsSiteReadiness: stringValue(adapter.metadata.docsSiteReadiness) ?? "site_not_prepared",
|
|
601
|
+
releaseOwnership: "treeseed.package.yaml"
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
}).filter((entry) => Boolean(entry));
|
|
605
|
+
}
|
|
606
|
+
function workflowNameForTemplate(adapter, template) {
|
|
607
|
+
const publishWorkflow = "publish.yml";
|
|
608
|
+
const configuredReleaseGate = stringValue(adapter.metadata.hostedVerifyWorkflow)?.replace(/^\.github\/workflows\//u, "") ?? "verify.yml";
|
|
609
|
+
if (template === "docker-image") return publishWorkflow;
|
|
610
|
+
if (template === "release-gate") {
|
|
611
|
+
return configuredReleaseGate === publishWorkflow ? "release-gate.yml" : configuredReleaseGate;
|
|
612
|
+
}
|
|
613
|
+
return publishWorkflow;
|
|
614
|
+
}
|
|
615
|
+
function renderTreeseedPackageWorkflow(adapter, template) {
|
|
616
|
+
const verifyCommand = template === "release-gate" ? adapter.verifyCommands.release ?? adapter.verifyCommands.local : adapter.verifyCommands.local;
|
|
617
|
+
const verify = verifyCommand ? formatWorkflowRunCommand(verifyCommand.command, verifyCommand.args) : "npm run verify:local";
|
|
618
|
+
const setup = resolveWorkflowSetupCommand(adapter);
|
|
619
|
+
const dockerArtifacts = adapter.artifacts.filter((artifact) => artifact.provider === "docker");
|
|
620
|
+
if (template === "npm-publish") {
|
|
621
|
+
return `name: Publish ${adapter.name}
|
|
622
|
+
|
|
623
|
+
on:
|
|
624
|
+
push:
|
|
625
|
+
tags:
|
|
626
|
+
- "*.*.*"
|
|
627
|
+
workflow_dispatch:
|
|
628
|
+
|
|
629
|
+
jobs:
|
|
630
|
+
publish:
|
|
631
|
+
if: startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-')
|
|
632
|
+
runs-on: ubuntu-latest
|
|
633
|
+
permissions:
|
|
634
|
+
contents: write
|
|
635
|
+
environment: production
|
|
636
|
+
steps:
|
|
637
|
+
- uses: actions/checkout@v4
|
|
638
|
+
with:
|
|
639
|
+
submodules: recursive
|
|
640
|
+
- uses: actions/setup-node@v4
|
|
641
|
+
with:
|
|
642
|
+
node-version: 22
|
|
643
|
+
registry-url: https://registry.npmjs.org
|
|
644
|
+
- run: ${setup}
|
|
645
|
+
- run: ${verify}
|
|
646
|
+
- run: npm publish --access public
|
|
647
|
+
env:
|
|
648
|
+
NODE_AUTH_TOKEN: \${{ secrets.NPM_TOKEN }}
|
|
649
|
+
- name: Create GitHub release
|
|
650
|
+
env:
|
|
651
|
+
GH_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
652
|
+
run: gh release create "\${GITHUB_REF_NAME}" --generate-notes --verify-tag
|
|
653
|
+
`;
|
|
654
|
+
}
|
|
655
|
+
if (template === "docker-image") {
|
|
656
|
+
const environment = "production";
|
|
657
|
+
const imageSetup = adapter.kind === "node-typescript" ? resolveDockerImageWorkflowSetupCommand() : null;
|
|
658
|
+
const anyTarget = dockerArtifacts.some((artifact) => typeof artifact.target === "string" && artifact.target.trim().length > 0);
|
|
659
|
+
const dockerContextPrepareCommand = isRecord(adapter.metadata.scripts) && typeof adapter.metadata.scripts["capacity-provider:build"] === "string" ? "npm run capacity-provider:build -- --prepare-only" : null;
|
|
660
|
+
const trigger = ` tags:
|
|
661
|
+
- "*.*.*"`;
|
|
662
|
+
const jobCondition = "startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-')";
|
|
663
|
+
const computeTagsStep = ` - name: Compute image tags
|
|
664
|
+
id: tags
|
|
665
|
+
run: |
|
|
666
|
+
version="\${GITHUB_REF_NAME#v}"
|
|
667
|
+
echo "base=\${version}" >> "$GITHUB_OUTPUT"
|
|
668
|
+
echo "moving=" >> "$GITHUB_OUTPUT"
|
|
669
|
+
`;
|
|
670
|
+
const releaseStep = ` release:
|
|
671
|
+
needs: manifest
|
|
672
|
+
if: ${jobCondition}
|
|
673
|
+
runs-on: ubuntu-24.04
|
|
674
|
+
permissions:
|
|
675
|
+
contents: write
|
|
676
|
+
steps:
|
|
677
|
+
- uses: actions/checkout@v4
|
|
678
|
+
- name: Create GitHub release
|
|
679
|
+
env:
|
|
680
|
+
GH_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
681
|
+
run: gh release create "\${GITHUB_REF_NAME}" --generate-notes --verify-tag
|
|
682
|
+
`;
|
|
683
|
+
return `name: Publish Image ${adapter.name}
|
|
684
|
+
|
|
685
|
+
on:
|
|
686
|
+
workflow_dispatch:
|
|
687
|
+
push:
|
|
688
|
+
${trigger}
|
|
689
|
+
|
|
690
|
+
jobs:
|
|
691
|
+
build:
|
|
692
|
+
if: ${jobCondition}
|
|
693
|
+
runs-on: \${{ matrix.runner }}
|
|
694
|
+
permissions:
|
|
695
|
+
contents: write
|
|
696
|
+
packages: write
|
|
697
|
+
environment: ${environment}
|
|
698
|
+
strategy:
|
|
699
|
+
matrix:
|
|
700
|
+
include:
|
|
701
|
+
${dockerArtifacts.flatMap((artifact) => [
|
|
702
|
+
` - image: ${artifact.name}${anyTarget ? `
|
|
703
|
+
target: ${artifact.target ?? ""}` : ""}
|
|
704
|
+
arch: amd64
|
|
705
|
+
platform: linux/amd64
|
|
706
|
+
runner: ubuntu-24.04`,
|
|
707
|
+
` - image: ${artifact.name}${anyTarget ? `
|
|
708
|
+
target: ${artifact.target ?? ""}` : ""}
|
|
709
|
+
arch: arm64
|
|
710
|
+
platform: linux/arm64
|
|
711
|
+
runner: ubuntu-24.04-arm`
|
|
712
|
+
]).join("\n") || ` - image: treeseed/unknown
|
|
713
|
+
arch: amd64
|
|
714
|
+
platform: linux/amd64
|
|
715
|
+
runner: ubuntu-24.04`}
|
|
716
|
+
steps:
|
|
717
|
+
- uses: actions/checkout@v4
|
|
718
|
+
with:
|
|
719
|
+
submodules: recursive
|
|
720
|
+
${imageSetup ? ` - run: ${imageSetup}
|
|
721
|
+
` : ""}${dockerContextPrepareCommand ? ` - run: ${dockerContextPrepareCommand}
|
|
722
|
+
` : ""}${computeTagsStep} - uses: docker/setup-buildx-action@v3
|
|
723
|
+
- uses: docker/login-action@v3
|
|
724
|
+
with:
|
|
725
|
+
username: \${{ vars.TREESEED_DOCKERHUB_USERNAME }}
|
|
726
|
+
password: \${{ secrets.TREESEED_DOCKERHUB_TOKEN }}
|
|
727
|
+
- uses: docker/build-push-action@v6
|
|
728
|
+
with:
|
|
729
|
+
context: .
|
|
730
|
+
${anyTarget ? " target: ${{ matrix.target }}\n" : ""} platforms: \${{ matrix.platform }}
|
|
731
|
+
push: true
|
|
732
|
+
tags: \${{ matrix.image }}:\${{ steps.tags.outputs.base }}-\${{ matrix.arch }}
|
|
733
|
+
|
|
734
|
+
manifest:
|
|
735
|
+
needs: build
|
|
736
|
+
if: ${jobCondition}
|
|
737
|
+
runs-on: ubuntu-24.04
|
|
738
|
+
permissions:
|
|
739
|
+
contents: read
|
|
740
|
+
packages: write
|
|
741
|
+
environment: ${environment}
|
|
742
|
+
strategy:
|
|
743
|
+
matrix:
|
|
744
|
+
include:
|
|
745
|
+
${dockerArtifacts.map((artifact) => ` - image: ${artifact.name}`).join("\n") || " - image: treeseed/unknown"}
|
|
746
|
+
steps:
|
|
747
|
+
- uses: docker/setup-buildx-action@v3
|
|
748
|
+
- uses: docker/login-action@v3
|
|
749
|
+
with:
|
|
750
|
+
username: \${{ vars.TREESEED_DOCKERHUB_USERNAME }}
|
|
751
|
+
password: \${{ secrets.TREESEED_DOCKERHUB_TOKEN }}
|
|
752
|
+
${computeTagsStep} - name: Publish multi-architecture manifest
|
|
753
|
+
run: |
|
|
754
|
+
docker buildx imagetools create \\
|
|
755
|
+
-t "\${{ matrix.image }}:\${{ steps.tags.outputs.base }}" \\
|
|
756
|
+
"\${{ matrix.image }}:\${{ steps.tags.outputs.base }}-amd64" \\
|
|
757
|
+
"\${{ matrix.image }}:\${{ steps.tags.outputs.base }}-arm64"
|
|
758
|
+
${releaseStep}`;
|
|
759
|
+
}
|
|
760
|
+
const needsNodeSetup = adapter.kind === "node-typescript";
|
|
761
|
+
const needsBeamSetup = adapter.kind === "beam-elixir-rust";
|
|
762
|
+
return `name: Verify ${adapter.name}
|
|
763
|
+
|
|
764
|
+
on:
|
|
765
|
+
push:
|
|
766
|
+
pull_request:
|
|
767
|
+
workflow_dispatch:
|
|
768
|
+
|
|
769
|
+
jobs:
|
|
770
|
+
verify:
|
|
771
|
+
runs-on: ubuntu-latest
|
|
772
|
+
steps:
|
|
773
|
+
- uses: actions/checkout@v4
|
|
774
|
+
with:
|
|
775
|
+
submodules: recursive
|
|
776
|
+
${needsNodeSetup ? ` - uses: actions/setup-node@v4
|
|
777
|
+
with:
|
|
778
|
+
node-version: 22
|
|
779
|
+
- run: ${setup}
|
|
780
|
+
` : ""}${needsBeamSetup ? ` - uses: erlef/setup-beam@v1
|
|
781
|
+
with:
|
|
782
|
+
otp-version: "27"
|
|
783
|
+
elixir-version: "1.17.3"
|
|
784
|
+
- run: mix local.hex --force && mix local.rebar --force
|
|
785
|
+
` : ""} - run: ${verify}
|
|
786
|
+
`;
|
|
787
|
+
}
|
|
788
|
+
function resolveWorkflowSetupCommand(adapter) {
|
|
789
|
+
const scripts = adapter.metadata.scripts;
|
|
790
|
+
if (isRecord(scripts) && typeof scripts["release:setup"] === "string") {
|
|
791
|
+
return 'npm run release:setup || (echo "dependency install failed; retrying" && npm run release:setup)';
|
|
792
|
+
}
|
|
793
|
+
return 'npm ci || (echo "dependency install failed; retrying" && npm ci)';
|
|
794
|
+
}
|
|
795
|
+
function resolveDockerImageWorkflowSetupCommand() {
|
|
796
|
+
return 'npm ci --ignore-scripts || (echo "dependency install failed; retrying" && npm ci --ignore-scripts)';
|
|
797
|
+
}
|
|
798
|
+
function isRecord(value) {
|
|
799
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
800
|
+
}
|
|
801
|
+
function formatWorkflowRunCommand(command, args) {
|
|
802
|
+
return [command, ...args].map(shellQuoteWorkflowArg).join(" ");
|
|
803
|
+
}
|
|
804
|
+
function shellQuoteWorkflowArg(value) {
|
|
805
|
+
if (/^[A-Za-z0-9_./:@%+=,-]+$/u.test(value)) return value;
|
|
806
|
+
return `'${value.replace(/'/gu, `'\\''`)}'`;
|
|
807
|
+
}
|
|
808
|
+
function workflowTemplatesForAdapter(adapter) {
|
|
809
|
+
const hasDocker = adapter.artifacts.some((artifact) => artifact.provider === "docker");
|
|
810
|
+
const hasNpm = adapter.artifacts.some((artifact) => artifact.provider === "npm");
|
|
811
|
+
return [
|
|
812
|
+
...hasNpm ? ["npm-publish"] : [],
|
|
813
|
+
...hasDocker ? ["docker-image"] : [],
|
|
814
|
+
"release-gate"
|
|
815
|
+
];
|
|
816
|
+
}
|
|
817
|
+
function syncTreeseedPackageWorkflows({
|
|
818
|
+
root = workspaceRoot(),
|
|
819
|
+
packageId,
|
|
820
|
+
execute = false
|
|
821
|
+
} = {}) {
|
|
822
|
+
const adapters = packageId && packageId !== "all" ? [findTreeseedPackageAdapter(root, packageId)].filter((entry) => Boolean(entry)) : discoverTreeseedPackageAdapters(root);
|
|
823
|
+
const results = [];
|
|
824
|
+
for (const adapter of adapters) {
|
|
825
|
+
for (const template of workflowTemplatesForAdapter(adapter)) {
|
|
826
|
+
const workflow = workflowNameForTemplate(adapter, template);
|
|
827
|
+
const path = resolve(adapter.dir, ".github", "workflows", workflow);
|
|
828
|
+
const rendered = renderTreeseedPackageWorkflow(adapter, template);
|
|
829
|
+
const current = existsSync(path) ? readFileSync(path, "utf8") : null;
|
|
830
|
+
const changed = current !== rendered;
|
|
831
|
+
if (execute && changed) {
|
|
832
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
833
|
+
writeFileSync(path, rendered, "utf8");
|
|
834
|
+
}
|
|
835
|
+
results.push({
|
|
836
|
+
packageId: adapter.id,
|
|
837
|
+
path,
|
|
838
|
+
workflow,
|
|
839
|
+
template,
|
|
840
|
+
exists: current != null,
|
|
841
|
+
changed,
|
|
842
|
+
written: execute && changed
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
return results;
|
|
847
|
+
}
|
|
282
848
|
export {
|
|
849
|
+
deriveTreeseedPackageProjectResources,
|
|
283
850
|
discoverTreeseedPackageAdapters,
|
|
284
851
|
findTreeseedPackageAdapter,
|
|
285
852
|
packageAdapterPlanSummary,
|
|
286
853
|
planTreeseedPackageDevelopmentImage,
|
|
287
|
-
readMixProjectVersion
|
|
854
|
+
readMixProjectVersion,
|
|
855
|
+
renderTreeseedPackageWorkflow,
|
|
856
|
+
runTreeseedPackageImageWorkflow,
|
|
857
|
+
syncTreeseedPackageWorkflows,
|
|
858
|
+
validateTreeseedPackageManifests
|
|
288
859
|
};
|