@noodleseed/one 0.23.0 → 0.25.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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/author-loop.d.ts +1 -0
- package/dist/commands/author-loop.d.ts.map +1 -1
- package/dist/commands/author-loop.js +4 -0
- package/dist/commands/author-loop.js.map +1 -1
- package/dist/commands/catalog-data-core.d.ts.map +1 -1
- package/dist/commands/catalog-data-core.js +17 -3
- package/dist/commands/catalog-data-core.js.map +1 -1
- package/dist/commands/catalog-data-resources.js +2 -2
- package/dist/commands/catalog-data-resources.js.map +1 -1
- package/dist/commands/catalog-render.d.ts.map +1 -1
- package/dist/commands/catalog-render.js +6 -0
- package/dist/commands/catalog-render.js.map +1 -1
- package/dist/commands/config-values.d.ts +14 -1
- package/dist/commands/config-values.d.ts.map +1 -1
- package/dist/commands/config-values.js +51 -3
- package/dist/commands/config-values.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +2 -2
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/commands/deploy-status-ops.d.ts +1 -1
- package/dist/commands/deploy-status-ops.d.ts.map +1 -1
- package/dist/commands/deploy-status-ops.js +8 -4
- package/dist/commands/deploy-status-ops.js.map +1 -1
- package/dist/commands/devtools.d.ts +11 -0
- package/dist/commands/devtools.d.ts.map +1 -0
- package/dist/commands/devtools.js +123 -0
- package/dist/commands/devtools.js.map +1 -0
- package/dist/commands/mcp-apps.d.ts +0 -1
- package/dist/commands/mcp-apps.d.ts.map +1 -1
- package/dist/commands/mcp-apps.js +71 -122
- package/dist/commands/mcp-apps.js.map +1 -1
- package/dist/commands/shared.d.ts +6 -0
- package/dist/commands/shared.d.ts.map +1 -1
- package/dist/commands/shared.js +19 -0
- package/dist/commands/shared.js.map +1 -1
- package/dist/deploy.d.ts +1 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +5 -1
- package/dist/deploy.js.map +1 -1
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +13 -1
- package/dist/dev.js.map +1 -1
- package/dist/fire.js +1 -1
- package/dist/fire.js.map +1 -1
- package/dist/flavor.d.ts +1 -1
- package/dist/flavor.d.ts.map +1 -1
- package/dist/flavor.js +12 -2
- package/dist/flavor.js.map +1 -1
- package/dist/project-scaffold-templates.d.ts.map +1 -1
- package/dist/project-scaffold-templates.js +2 -0
- package/dist/project-scaffold-templates.js.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +50 -1
- package/dist/validate.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +96 -51
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js +66 -4
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-operations-refs.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-operations-refs.js +8 -3
- package/node_modules/@noodle-borg/agent-kit/dist/skill-operations-refs.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/authoring/dist/connectors.d.ts +18 -1
- package/node_modules/@noodle-borg/authoring/dist/connectors.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/connectors.js +17 -4
- package/node_modules/@noodle-borg/authoring/dist/connectors.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/recording.js +24 -5
- package/node_modules/@noodle-borg/authoring/dist/recording.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +57 -3
- package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/auth-variables.js +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/auth-variables.js.map +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/call-graph.d.ts +14 -0
- package/node_modules/@noodle-borg/connector-defs/dist/call-graph.d.ts.map +1 -0
- package/node_modules/@noodle-borg/connector-defs/dist/call-graph.js +66 -0
- package/node_modules/@noodle-borg/connector-defs/dist/call-graph.js.map +1 -0
- package/node_modules/@noodle-borg/connector-defs/dist/compile-auth.d.ts +21 -0
- package/node_modules/@noodle-borg/connector-defs/dist/compile-auth.d.ts.map +1 -0
- package/node_modules/@noodle-borg/connector-defs/dist/compile-auth.js +102 -0
- package/node_modules/@noodle-borg/connector-defs/dist/compile-auth.js.map +1 -0
- package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts +19 -4
- package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts.map +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/compile.js +67 -99
- package/node_modules/@noodle-borg/connector-defs/dist/compile.js.map +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/index.d.ts +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts +168 -10
- package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/schema.js +72 -5
- package/node_modules/@noodle-borg/connector-defs/dist/schema.js.map +1 -1
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts +6 -0
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts.map +1 -1
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.js +2 -0
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.js.map +1 -1
- package/node_modules/@noodle-borg/runtime/dist/execute.d.ts.map +1 -1
- package/node_modules/@noodle-borg/runtime/dist/execute.js +87 -62
- package/node_modules/@noodle-borg/runtime/dist/execute.js.map +1 -1
- package/node_modules/@noodle-borg/runtime/dist/result.d.ts +1 -1
- package/node_modules/@noodle-borg/runtime/dist/result.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/credential-broker.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/credential-broker.js +113 -11
- package/node_modules/@noodle-borg/service/dist/credential-broker.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/github/app-client.d.ts +28 -5
- package/node_modules/@noodle-borg/service/dist/github/app-client.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/github/app-client.js +116 -7
- package/node_modules/@noodle-borg/service/dist/github/app-client.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/github/builder-auth.d.ts +12 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-auth.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-auth.js +19 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-auth.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-main.d.ts +3 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-main.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-main.js +9 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-main.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-runner.d.ts +21 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-runner.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-runner.js +192 -0
- package/node_modules/@noodle-borg/service/dist/github/builder-runner.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/cloud-run-job-executor.d.ts +45 -0
- package/node_modules/@noodle-borg/service/dist/github/cloud-run-job-executor.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/cloud-run-job-executor.js +64 -0
- package/node_modules/@noodle-borg/service/dist/github/cloud-run-job-executor.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-pipeline.d.ts +64 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-pipeline.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-pipeline.js +121 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-pipeline.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-run-executor.d.ts +33 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-run-executor.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-run-executor.js +14 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-run-executor.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-run-reconciler.d.ts +36 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-run-reconciler.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-run-reconciler.js +107 -0
- package/node_modules/@noodle-borg/service/dist/github/deploy-run-reconciler.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/fast-lane-classifier.d.ts +38 -0
- package/node_modules/@noodle-borg/service/dist/github/fast-lane-classifier.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/fast-lane-classifier.js +60 -0
- package/node_modules/@noodle-borg/service/dist/github/fast-lane-classifier.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/local-compile.d.ts +24 -0
- package/node_modules/@noodle-borg/service/dist/github/local-compile.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/local-compile.js +98 -0
- package/node_modules/@noodle-borg/service/dist/github/local-compile.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/local-process-executor.d.ts +39 -0
- package/node_modules/@noodle-borg/service/dist/github/local-process-executor.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/local-process-executor.js +67 -0
- package/node_modules/@noodle-borg/service/dist/github/local-process-executor.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/run-access-mode.d.ts +18 -0
- package/node_modules/@noodle-borg/service/dist/github/run-access-mode.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/run-access-mode.js +32 -0
- package/node_modules/@noodle-borg/service/dist/github/run-access-mode.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/run-token.d.ts +41 -0
- package/node_modules/@noodle-borg/service/dist/github/run-token.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/github/run-token.js +59 -0
- package/node_modules/@noodle-borg/service/dist/github/run-token.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/http-util.d.ts +7 -1
- package/node_modules/@noodle-borg/service/dist/http-util.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/http-util.js +14 -0
- package/node_modules/@noodle-borg/service/dist/http-util.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.d.ts +13 -2
- package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.js +12 -1
- package/node_modules/@noodle-borg/service/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/main.js +72 -0
- package/node_modules/@noodle-borg/service/dist/main.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/options.d.ts +26 -3
- package/node_modules/@noodle-borg/service/dist/options.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-helpers.d.ts +12 -0
- package/node_modules/@noodle-borg/service/dist/registry-helpers.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-helpers.js +3 -0
- package/node_modules/@noodle-borg/service/dist/registry-helpers.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/registry-types.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry.d.ts +7 -29
- package/node_modules/@noodle-borg/service/dist/registry.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry.js +62 -57
- package/node_modules/@noodle-borg/service/dist/registry.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/asset-control-plane.d.ts +3 -2
- package/node_modules/@noodle-borg/service/dist/routes/asset-control-plane.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/asset-control-plane.js +36 -8
- package/node_modules/@noodle-borg/service/dist/routes/asset-control-plane.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts +3 -2
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +100 -12
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/github-dispatch.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-dispatch.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/github-dispatch.js +36 -1
- package/node_modules/@noodle-borg/service/dist/routes/github-dispatch.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/github-run-claim.d.ts +13 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-run-claim.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-run-claim.js +84 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-run-claim.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-run-status.d.ts +5 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-run-status.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-run-status.js +73 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-run-status.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-webhook.d.ts +23 -1
- package/node_modules/@noodle-borg/service/dist/routes/github-webhook.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/github-webhook.js +41 -0
- package/node_modules/@noodle-borg/service/dist/routes/github-webhook.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/paths.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/routes/paths.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/paths.js +10 -0
- package/node_modules/@noodle-borg/service/dist/routes/paths.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/run-deploy-auth.d.ts +85 -0
- package/node_modules/@noodle-borg/service/dist/routes/run-deploy-auth.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/run-deploy-auth.js +90 -0
- package/node_modules/@noodle-borg/service/dist/routes/run-deploy-auth.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve.js +31 -0
- package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.js +8 -13
- package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/github-connections-json-file.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/store/github-connections-json-file.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/github-connections-json-file.js +5 -0
- package/node_modules/@noodle-borg/service/dist/store/github-connections-json-file.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/github-connections.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/store/github-connections.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/github-connections.js +5 -0
- package/node_modules/@noodle-borg/service/dist/store/github-connections.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/github-deploy-run-contract.d.ts +120 -0
- package/node_modules/@noodle-borg/service/dist/store/github-deploy-run-contract.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/github-deploy-run-contract.js +6 -0
- package/node_modules/@noodle-borg/service/dist/store/github-deploy-run-contract.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/github-runs-json-file.d.ts +6 -1
- package/node_modules/@noodle-borg/service/dist/store/github-runs-json-file.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/github-runs-json-file.js +18 -1
- package/node_modules/@noodle-borg/service/dist/store/github-runs-json-file.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/github-runs.d.ts +22 -1
- package/node_modules/@noodle-borg/service/dist/store/github-runs.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/github-runs.js +39 -2
- package/node_modules/@noodle-borg/service/dist/store/github-runs.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.d.ts +13 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.js +115 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-github.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-github.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-github.js +6 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-github.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts +15 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.js +22 -2
- package/node_modules/@noodle-borg/service/dist/store/postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store.d.ts +22 -99
- package/node_modules/@noodle-borg/service/dist/store.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const trimTrailingSlash = (url) => url.replace(/\/+$/, '');
|
|
2
|
+
/** Build a redacted one-line summary from a route's own (secret-free) `{ error, code }` body. */
|
|
3
|
+
async function summarizeHttpFailure(stage, res) {
|
|
4
|
+
let code;
|
|
5
|
+
let message;
|
|
6
|
+
try {
|
|
7
|
+
const body = (await res.json());
|
|
8
|
+
if (typeof body.code === 'string')
|
|
9
|
+
code = body.code;
|
|
10
|
+
if (typeof body.error === 'string')
|
|
11
|
+
message = body.error;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
// A non-JSON error body carries no structured reason; the status code still localizes the failure.
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
summary: `${stage} failed (HTTP ${res.status}${code !== undefined ? `, ${code}` : ''})${message !== undefined ? `: ${message}` : ''}`,
|
|
18
|
+
...(code !== undefined ? { code } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export async function runDeployPipeline(deps) {
|
|
22
|
+
const { run, runToken, compile, httpFetch } = deps;
|
|
23
|
+
const baseUrl = trimTrailingSlash(deps.serviceBaseUrl);
|
|
24
|
+
const statusUrl = `${baseUrl}/v1/github/runs/${encodeURIComponent(run.runId)}/status`;
|
|
25
|
+
const tenantBase = `${baseUrl}/v1/orgs/${encodeURIComponent(run.orgSlug)}/apps/${encodeURIComponent(run.appSlug)}/envs/${encodeURIComponent(run.envName)}`;
|
|
26
|
+
const report = async (to, patch) => {
|
|
27
|
+
try {
|
|
28
|
+
await httpFetch(statusUrl, {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: { 'content-type': 'application/json', authorization: `Bearer ${runToken}` },
|
|
31
|
+
body: JSON.stringify({ to, ...patch }),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Best-effort: a failed status report is observability loss, not a deploy failure.
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const fail = async (stage, errorSummary) => {
|
|
39
|
+
await report('failed', { errorSummary });
|
|
40
|
+
return { status: 'failed', stage, errorSummary };
|
|
41
|
+
};
|
|
42
|
+
let stage = 'compile';
|
|
43
|
+
try {
|
|
44
|
+
await report('building');
|
|
45
|
+
const compiled = await compile(run);
|
|
46
|
+
if (!compiled.ok)
|
|
47
|
+
return await fail('compile', compiled.errorSummary);
|
|
48
|
+
await report('deploying');
|
|
49
|
+
let hostedAssets;
|
|
50
|
+
const assets = compiled.input.assets ?? [];
|
|
51
|
+
if (assets.length > 0) {
|
|
52
|
+
stage = 'preflight';
|
|
53
|
+
const preflightRes = await httpFetch(`${tenantBase}/assets/preflight`, {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
headers: { 'content-type': 'application/json', 'x-noodle-run-token': runToken },
|
|
56
|
+
body: JSON.stringify({ assets: assets.map((asset) => asset.prepared) }),
|
|
57
|
+
});
|
|
58
|
+
if (!preflightRes.ok) {
|
|
59
|
+
const failure = await summarizeHttpFailure('asset preflight', preflightRes);
|
|
60
|
+
return await fail('preflight', failure.summary);
|
|
61
|
+
}
|
|
62
|
+
const plan = (await preflightRes.json());
|
|
63
|
+
stage = 'upload';
|
|
64
|
+
for (const upload of plan.uploads ?? []) {
|
|
65
|
+
const asset = assets.find((candidate) => candidate.prepared.logicalId === upload.logicalId);
|
|
66
|
+
if (asset === undefined) {
|
|
67
|
+
return await fail('upload', `upload: preflight planned an unknown asset "${upload.logicalId}"`);
|
|
68
|
+
}
|
|
69
|
+
const putRes = await httpFetch(upload.uploadUrl, {
|
|
70
|
+
method: upload.method,
|
|
71
|
+
headers: upload.headers,
|
|
72
|
+
body: asset.bytes,
|
|
73
|
+
});
|
|
74
|
+
if (!putRes.ok) {
|
|
75
|
+
return await fail('upload', `upload: asset "${upload.logicalId}" PUT failed (HTTP ${putRes.status})`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
hostedAssets = plan.assets;
|
|
79
|
+
}
|
|
80
|
+
stage = 'deploy';
|
|
81
|
+
const deployRes = await httpFetch(`${tenantBase}/deploy`, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
headers: { 'content-type': 'application/json', 'x-noodle-run-token': runToken },
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
manifest: compiled.input.manifest,
|
|
86
|
+
...(compiled.input.connectors !== undefined
|
|
87
|
+
? { connectors: compiled.input.connectors }
|
|
88
|
+
: {}),
|
|
89
|
+
...(compiled.input.serverVersion !== undefined
|
|
90
|
+
? { serverVersion: compiled.input.serverVersion }
|
|
91
|
+
: {}),
|
|
92
|
+
...(compiled.input.declaredAccessMode !== undefined
|
|
93
|
+
? { accessMode: compiled.input.declaredAccessMode }
|
|
94
|
+
: {}),
|
|
95
|
+
...(hostedAssets !== undefined ? { hostedAssets } : {}),
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
if (!deployRes.ok) {
|
|
99
|
+
const failure = await summarizeHttpFailure('deploy', deployRes);
|
|
100
|
+
if (failure.code === 'run_superseded') {
|
|
101
|
+
await report('superseded');
|
|
102
|
+
return { status: 'superseded' };
|
|
103
|
+
}
|
|
104
|
+
return await fail('deploy', failure.summary);
|
|
105
|
+
}
|
|
106
|
+
const deployed = (await deployRes.json());
|
|
107
|
+
if (typeof deployed.deploymentId !== 'string') {
|
|
108
|
+
return await fail('deploy', 'deploy: service returned no deploymentId');
|
|
109
|
+
}
|
|
110
|
+
await report('deployed', { deploymentId: deployed.deploymentId });
|
|
111
|
+
return { status: 'deployed', deploymentId: deployed.deploymentId };
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// An unexpected throw (network fault, etc.) still lands the run in `failed` with a redacted,
|
|
115
|
+
// stage-tagged summary — never a silent hang. Only the error's name is included; never a message
|
|
116
|
+
// that could carry a URL, token, or body.
|
|
117
|
+
const name = error instanceof Error ? error.name : 'Error';
|
|
118
|
+
return await fail(stage, `${stage}: unexpected error (${name})`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=deploy-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-pipeline.js","sourceRoot":"","sources":["../../src/github/deploy-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DeployRunRecord } from '../store.js';
|
|
2
|
+
/**
|
|
3
|
+
* The isolation seam for GHD-3 (ADR 0132 Decision 6). The dispatcher hands an accepted, non-blocked
|
|
4
|
+
* run to an executor; the executor runs the untrusted-compile → trusted-deploy pipeline somewhere
|
|
5
|
+
* isolated and reports progress back through `POST /v1/github/runs/{runId}/status` using the
|
|
6
|
+
* `runToken`. The executor is the ONLY thing that varies by environment:
|
|
7
|
+
*
|
|
8
|
+
* - `CloudRunJobExecutor` (C3, production) — triggers one Cloud Run Job execution per run.
|
|
9
|
+
* - `LocalProcessExecutor` (C2, dev/self-host/E2E) — runs the pipeline as a local child process.
|
|
10
|
+
* - {@link FakeDeployRunExecutor} (tests) — records dispatches, runs nothing.
|
|
11
|
+
*
|
|
12
|
+
* `dispatch` is fire-and-forget from the caller's view (the webhook must answer GitHub immediately);
|
|
13
|
+
* it resolves once the execution is *launched*, not *finished*. It must never throw into the request
|
|
14
|
+
* path — an executor that can't launch records the failure out-of-band and the sweeper retries.
|
|
15
|
+
*/
|
|
16
|
+
export interface DeployRunDispatchInput {
|
|
17
|
+
readonly run: DeployRunRecord;
|
|
18
|
+
/** Run-scoped credential the executor uses to report status + deploy (never the sandbox's). */
|
|
19
|
+
readonly runToken: string;
|
|
20
|
+
/** Base URL the executor calls back to (the status/deploy routes). */
|
|
21
|
+
readonly serviceBaseUrl: string;
|
|
22
|
+
}
|
|
23
|
+
export interface DeployRunExecutor {
|
|
24
|
+
dispatch(input: DeployRunDispatchInput): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/** Test double: captures every dispatch, launches nothing. */
|
|
27
|
+
export declare class FakeDeployRunExecutor implements DeployRunExecutor {
|
|
28
|
+
#private;
|
|
29
|
+
readonly dispatches: DeployRunDispatchInput[];
|
|
30
|
+
constructor(onDispatch?: (input: DeployRunDispatchInput) => void | Promise<void>);
|
|
31
|
+
dispatch(input: DeployRunDispatchInput): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=deploy-run-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-run-executor.d.ts","sourceRoot":"","sources":["../../src/github/deploy-run-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED,8DAA8D;AAC9D,qBAAa,qBAAsB,YAAW,iBAAiB;;IAC7D,QAAQ,CAAC,UAAU,EAAE,sBAAsB,EAAE,CAAM;gBAIvC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1E,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAI7D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Test double: captures every dispatch, launches nothing. */
|
|
2
|
+
export class FakeDeployRunExecutor {
|
|
3
|
+
dispatches = [];
|
|
4
|
+
/** Optional hook so a test can assert the token/base or simulate a launch failure. */
|
|
5
|
+
#onDispatch;
|
|
6
|
+
constructor(onDispatch) {
|
|
7
|
+
this.#onDispatch = onDispatch;
|
|
8
|
+
}
|
|
9
|
+
async dispatch(input) {
|
|
10
|
+
this.dispatches.push(input);
|
|
11
|
+
await this.#onDispatch?.(input);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=deploy-run-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-run-executor.js","sourceRoot":"","sources":["../../src/github/deploy-run-executor.ts"],"names":[],"mappings":"AA4BA,8DAA8D;AAC9D,MAAM,OAAO,qBAAqB;IACvB,UAAU,GAA6B,EAAE,CAAC;IACnD,sFAAsF;IAC7E,WAAW,CAAwE;IAE5F,YAAY,UAAoE;QAC9E,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAA6B;QAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Logger } from '@noodle-borg/transport-http';
|
|
2
|
+
import type { GithubConnectionStore, GithubDeployRunStore } from '../store.js';
|
|
3
|
+
import type { DeployRunExecutor } from './deploy-run-executor.js';
|
|
4
|
+
export declare const GITHUB_RUN_RECONCILE_INTERVAL_MS = 60000;
|
|
5
|
+
export declare const GITHUB_RUN_TIMEOUT_MS = 180000;
|
|
6
|
+
export declare const GITHUB_RUN_QUEUED_REDISPATCH_GRACE_MS = 30000;
|
|
7
|
+
export interface GithubDeployRunReconcilerOptions {
|
|
8
|
+
readonly runStore: GithubDeployRunStore;
|
|
9
|
+
readonly connectionStore: GithubConnectionStore;
|
|
10
|
+
readonly executor: DeployRunExecutor;
|
|
11
|
+
readonly webhookSecret: string;
|
|
12
|
+
readonly serviceBaseUrl: string;
|
|
13
|
+
readonly clock?: () => Date;
|
|
14
|
+
readonly logger?: Logger;
|
|
15
|
+
readonly intervalMs?: number;
|
|
16
|
+
readonly runTimeoutMs?: number;
|
|
17
|
+
readonly queuedRedispatchGraceMs?: number;
|
|
18
|
+
readonly limitPerConnection?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface GithubDeployRunReconcileResult {
|
|
21
|
+
readonly connections: number;
|
|
22
|
+
readonly inspected: number;
|
|
23
|
+
readonly dispatched: number;
|
|
24
|
+
readonly failed: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Idempotent GitHub deploy-run reconciler. Webhook dispatch is intentionally fire-and-forget; this
|
|
28
|
+
* loop is the recovery path for missed Cloud Run Job launches and abandoned in-flight runs.
|
|
29
|
+
*/
|
|
30
|
+
export declare class GithubDeployRunReconciler {
|
|
31
|
+
#private;
|
|
32
|
+
constructor(options: GithubDeployRunReconcilerOptions);
|
|
33
|
+
maybeSweep(): void;
|
|
34
|
+
sweepNow(): Promise<GithubDeployRunReconcileResult>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=deploy-run-reconciler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-run-reconciler.d.ts","sourceRoot":"","sources":["../../src/github/deploy-run-reconciler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAmB,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,eAAO,MAAM,gCAAgC,QAAS,CAAC;AACvD,eAAO,MAAM,qBAAqB,SAAU,CAAC;AAC7C,eAAO,MAAM,qCAAqC,QAAS,CAAC;AAE5D,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC;IAChD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,yBAAyB;;gBAexB,OAAO,EAAE,gCAAgC;IAerD,UAAU,IAAI,IAAI;IAcZ,QAAQ,IAAI,OAAO,CAAC,8BAA8B,CAAC;CA6D1D"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { noopLogger } from '@noodle-borg/transport-http';
|
|
2
|
+
import { resolveGithubStateSecret } from './install-nonce.js';
|
|
3
|
+
import { signRunToken } from './run-token.js';
|
|
4
|
+
export const GITHUB_RUN_RECONCILE_INTERVAL_MS = 60_000;
|
|
5
|
+
export const GITHUB_RUN_TIMEOUT_MS = 180_000;
|
|
6
|
+
export const GITHUB_RUN_QUEUED_REDISPATCH_GRACE_MS = 30_000;
|
|
7
|
+
/**
|
|
8
|
+
* Idempotent GitHub deploy-run reconciler. Webhook dispatch is intentionally fire-and-forget; this
|
|
9
|
+
* loop is the recovery path for missed Cloud Run Job launches and abandoned in-flight runs.
|
|
10
|
+
*/
|
|
11
|
+
export class GithubDeployRunReconciler {
|
|
12
|
+
#runStore;
|
|
13
|
+
#connectionStore;
|
|
14
|
+
#executor;
|
|
15
|
+
#webhookSecret;
|
|
16
|
+
#serviceBaseUrl;
|
|
17
|
+
#clock;
|
|
18
|
+
#logger;
|
|
19
|
+
#intervalMs;
|
|
20
|
+
#runTimeoutMs;
|
|
21
|
+
#queuedRedispatchGraceMs;
|
|
22
|
+
#limitPerConnection;
|
|
23
|
+
#lastSweepStartedAt = Number.NEGATIVE_INFINITY;
|
|
24
|
+
#inFlight = false;
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.#runStore = options.runStore;
|
|
27
|
+
this.#connectionStore = options.connectionStore;
|
|
28
|
+
this.#executor = options.executor;
|
|
29
|
+
this.#webhookSecret = resolveGithubStateSecret(options.webhookSecret);
|
|
30
|
+
this.#serviceBaseUrl = options.serviceBaseUrl.replace(/\/+$/, '');
|
|
31
|
+
this.#clock = options.clock ?? (() => new Date());
|
|
32
|
+
this.#logger = options.logger ?? noopLogger;
|
|
33
|
+
this.#intervalMs = options.intervalMs ?? GITHUB_RUN_RECONCILE_INTERVAL_MS;
|
|
34
|
+
this.#runTimeoutMs = options.runTimeoutMs ?? GITHUB_RUN_TIMEOUT_MS;
|
|
35
|
+
this.#queuedRedispatchGraceMs =
|
|
36
|
+
options.queuedRedispatchGraceMs ?? GITHUB_RUN_QUEUED_REDISPATCH_GRACE_MS;
|
|
37
|
+
this.#limitPerConnection = options.limitPerConnection ?? 50;
|
|
38
|
+
}
|
|
39
|
+
maybeSweep() {
|
|
40
|
+
const now = this.#clock().getTime();
|
|
41
|
+
if (this.#inFlight || now - this.#lastSweepStartedAt < this.#intervalMs)
|
|
42
|
+
return;
|
|
43
|
+
this.#lastSweepStartedAt = now;
|
|
44
|
+
this.#inFlight = true;
|
|
45
|
+
void this.sweepNow()
|
|
46
|
+
.catch(() => {
|
|
47
|
+
this.#logger.warn('github.run.reconcile_failed', { status: 500 });
|
|
48
|
+
})
|
|
49
|
+
.finally(() => {
|
|
50
|
+
this.#inFlight = false;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async sweepNow() {
|
|
54
|
+
const now = this.#clock();
|
|
55
|
+
const connections = await this.#connectionStore.listRepoConnections();
|
|
56
|
+
let inspected = 0;
|
|
57
|
+
let dispatched = 0;
|
|
58
|
+
let failed = 0;
|
|
59
|
+
for (const connection of connections) {
|
|
60
|
+
const result = await this.#runStore.listDeployRuns(connection.orgSlug, connection.appSlug, {
|
|
61
|
+
limit: this.#limitPerConnection,
|
|
62
|
+
});
|
|
63
|
+
for (const run of result.runs) {
|
|
64
|
+
if (run.githubRepositoryId !== connection.githubRepositoryId)
|
|
65
|
+
continue;
|
|
66
|
+
inspected += 1;
|
|
67
|
+
if (run.blockedReason !== undefined)
|
|
68
|
+
continue;
|
|
69
|
+
if (run.status === 'queued') {
|
|
70
|
+
if (!this.#isOlderThan(run.createdAt, now, this.#queuedRedispatchGraceMs))
|
|
71
|
+
continue;
|
|
72
|
+
await this.#dispatch(run);
|
|
73
|
+
dispatched += 1;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if ((run.status === 'building' || run.status === 'deploying') &&
|
|
77
|
+
this.#isOlderThan(run.startedAt ?? run.createdAt, now, this.#runTimeoutMs)) {
|
|
78
|
+
const transition = await this.#runStore.transitionDeployRun(run.orgSlug, run.runId, 'failed', {
|
|
79
|
+
errorSummary: `github build worker timed out after ${Math.round(this.#runTimeoutMs / 1000)}s`,
|
|
80
|
+
});
|
|
81
|
+
if (transition.ok)
|
|
82
|
+
failed += 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { connections: connections.length, inspected, dispatched, failed };
|
|
87
|
+
}
|
|
88
|
+
async #dispatch(run) {
|
|
89
|
+
const runToken = signRunToken({
|
|
90
|
+
runId: run.runId,
|
|
91
|
+
org: run.orgSlug,
|
|
92
|
+
app: run.appSlug,
|
|
93
|
+
env: run.envName,
|
|
94
|
+
issuedAt: this.#clock().getTime(),
|
|
95
|
+
}, this.#webhookSecret);
|
|
96
|
+
await this.#executor
|
|
97
|
+
.dispatch({ run, runToken, serviceBaseUrl: this.#serviceBaseUrl })
|
|
98
|
+
.catch(() => {
|
|
99
|
+
this.#logger.warn('github.run.dispatch_failed', { status: 200, runId: run.runId });
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
#isOlderThan(iso, now, thresholdMs) {
|
|
103
|
+
const started = Date.parse(iso);
|
|
104
|
+
return Number.isFinite(started) && now.getTime() - started >= thresholdMs;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=deploy-run-reconciler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-run-reconciler.js","sourceRoot":"","sources":["../../src/github/deploy-run-reconciler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fast-lane eligibility classifier (GHD-3, ADR 0132 Decision 2). A canonical Noodle app imports only
|
|
3
|
+
* the SDK and local files — nothing to install — so its git deploy is structurally *seconds*. This
|
|
4
|
+
* gate enforces exactly that BEFORE any user source executes: a repo whose `package.json` declares
|
|
5
|
+
* third-party dependencies is rejected up front with a structured reason, never compiled. The slow
|
|
6
|
+
* lane (frozen installs) is a later, separate decision behind the same executor seam.
|
|
7
|
+
*
|
|
8
|
+
* Pure over the parsed `package.json` (no fs, no network) so it runs identically in the untrusted
|
|
9
|
+
* sandbox and in unit tests.
|
|
10
|
+
*/
|
|
11
|
+
/** SDK package names an app may depend on without leaving the fast lane. */
|
|
12
|
+
export declare const FAST_LANE_ALLOWED_DEPENDENCIES: ReadonlySet<string>;
|
|
13
|
+
export type FastLaneClassification = {
|
|
14
|
+
readonly eligible: true;
|
|
15
|
+
} | {
|
|
16
|
+
readonly eligible: false;
|
|
17
|
+
readonly reason: 'unsupported_dependencies';
|
|
18
|
+
readonly unsupported: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
interface PackageJsonShape {
|
|
21
|
+
readonly dependencies?: Readonly<Record<string, unknown>>;
|
|
22
|
+
readonly devDependencies?: Readonly<Record<string, unknown>>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Classify a repo from its parsed `package.json` (or `undefined` when the repo has none — a bare
|
|
26
|
+
* `server.ts` app is fast-lane eligible). Any dependency or devDependency outside the SDK allowlist
|
|
27
|
+
* makes the repo slow-lane (unsupported in the MVP): the offending names are returned so the failure
|
|
28
|
+
* can name them.
|
|
29
|
+
*/
|
|
30
|
+
export declare function classifyFastLane(pkg: PackageJsonShape | undefined): FastLaneClassification;
|
|
31
|
+
/**
|
|
32
|
+
* Parse a raw `package.json` string, then classify. Malformed JSON is treated as "no package.json"
|
|
33
|
+
* (fast-lane eligible) — the compile step will surface any real problem — rather than failing the
|
|
34
|
+
* run on a formatting quirk. Callers that need strict parsing should classify the parsed object.
|
|
35
|
+
*/
|
|
36
|
+
export declare function classifyFastLaneFromRaw(raw: string | undefined): FastLaneClassification;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=fast-lane-classifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fast-lane-classifier.d.ts","sourceRoot":"","sources":["../../src/github/fast-lane-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4EAA4E;AAC5E,eAAO,MAAM,8BAA8B,EAAE,WAAW,CAAC,MAAM,CAM7D,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,GAC3B;IACE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC,CAAC;AAEN,UAAU,gBAAgB;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,SAAS,GAAG,sBAAsB,CAe1F;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,sBAAsB,CAOvF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fast-lane eligibility classifier (GHD-3, ADR 0132 Decision 2). A canonical Noodle app imports only
|
|
3
|
+
* the SDK and local files — nothing to install — so its git deploy is structurally *seconds*. This
|
|
4
|
+
* gate enforces exactly that BEFORE any user source executes: a repo whose `package.json` declares
|
|
5
|
+
* third-party dependencies is rejected up front with a structured reason, never compiled. The slow
|
|
6
|
+
* lane (frozen installs) is a later, separate decision behind the same executor seam.
|
|
7
|
+
*
|
|
8
|
+
* Pure over the parsed `package.json` (no fs, no network) so it runs identically in the untrusted
|
|
9
|
+
* sandbox and in unit tests.
|
|
10
|
+
*/
|
|
11
|
+
/** SDK package names an app may depend on without leaving the fast lane. */
|
|
12
|
+
export const FAST_LANE_ALLOWED_DEPENDENCIES = new Set([
|
|
13
|
+
'@noodleseed/one',
|
|
14
|
+
// The widget runtime the SDK's React surface compiles against — provisioned in the builder image,
|
|
15
|
+
// never installed from a lockfile.
|
|
16
|
+
'react',
|
|
17
|
+
'react-dom',
|
|
18
|
+
]);
|
|
19
|
+
/**
|
|
20
|
+
* Classify a repo from its parsed `package.json` (or `undefined` when the repo has none — a bare
|
|
21
|
+
* `server.ts` app is fast-lane eligible). Any dependency or devDependency outside the SDK allowlist
|
|
22
|
+
* makes the repo slow-lane (unsupported in the MVP): the offending names are returned so the failure
|
|
23
|
+
* can name them.
|
|
24
|
+
*/
|
|
25
|
+
export function classifyFastLane(pkg) {
|
|
26
|
+
if (pkg === undefined)
|
|
27
|
+
return { eligible: true };
|
|
28
|
+
const names = new Set();
|
|
29
|
+
for (const record of [pkg.dependencies, pkg.devDependencies]) {
|
|
30
|
+
if (record === undefined)
|
|
31
|
+
continue;
|
|
32
|
+
for (const name of Object.keys(record)) {
|
|
33
|
+
if (!FAST_LANE_ALLOWED_DEPENDENCIES.has(name))
|
|
34
|
+
names.add(name);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (names.size === 0)
|
|
38
|
+
return { eligible: true };
|
|
39
|
+
return {
|
|
40
|
+
eligible: false,
|
|
41
|
+
reason: 'unsupported_dependencies',
|
|
42
|
+
unsupported: [...names].sort(),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse a raw `package.json` string, then classify. Malformed JSON is treated as "no package.json"
|
|
47
|
+
* (fast-lane eligible) — the compile step will surface any real problem — rather than failing the
|
|
48
|
+
* run on a formatting quirk. Callers that need strict parsing should classify the parsed object.
|
|
49
|
+
*/
|
|
50
|
+
export function classifyFastLaneFromRaw(raw) {
|
|
51
|
+
if (raw === undefined)
|
|
52
|
+
return { eligible: true };
|
|
53
|
+
try {
|
|
54
|
+
return classifyFastLane(JSON.parse(raw));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return { eligible: true };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=fast-lane-classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fast-lane-classifier.js","sourceRoot":"","sources":["../../src/github/fast-lane-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,8BAA8B,GAAwB,IAAI,GAAG,CAAC;IACzE,iBAAiB;IACjB,kGAAkG;IAClG,mCAAmC;IACnC,OAAO;IACP,WAAW;CACZ,CAAC,CAAC;AAeH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAiC;IAChE,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QAC7D,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,8BAA8B,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAChD,OAAO;QACL,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,0BAA0B;QAClC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE;KAC/B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAuB;IAC7D,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjD,IAAI,CAAC;QACH,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CompileStageResult } from './deploy-pipeline.js';
|
|
2
|
+
/**
|
|
3
|
+
* The untrusted compile stage for the local/self-host build worker (GHD-3, ADR 0132 Decision 2/5).
|
|
4
|
+
* It reads a checked-out source directory and returns manifest data — it is NEVER handed the run token
|
|
5
|
+
* (the pipeline enforces that seam). The manifest emission itself is injected as {@link ManifestExporter}
|
|
6
|
+
* so the executor can run the real `noodle export manifest` subprocess while unit tests supply a
|
|
7
|
+
* manifest directly (no binary, no child process). Debuggability: the default exporter runs the exact
|
|
8
|
+
* command a human debugs with — `noodle export manifest` in the repo.
|
|
9
|
+
*
|
|
10
|
+
* Order matters for the fast-lane guarantee: the dependency gate runs BEFORE any source executes, so a
|
|
11
|
+
* repo with third-party deps is rejected up front with a named reason, never compiled.
|
|
12
|
+
*/
|
|
13
|
+
export type ManifestExporter = (input: {
|
|
14
|
+
readonly sourceDir: string;
|
|
15
|
+
readonly entrypoint: string;
|
|
16
|
+
}) => Promise<{
|
|
17
|
+
readonly manifest: string;
|
|
18
|
+
readonly connectors?: string;
|
|
19
|
+
}>;
|
|
20
|
+
export interface LocalCompileOptions {
|
|
21
|
+
readonly exportManifest: ManifestExporter;
|
|
22
|
+
}
|
|
23
|
+
export declare function createLocalCompile(options: LocalCompileOptions): (sourceDir: string) => Promise<CompileStageResult>;
|
|
24
|
+
//# sourceMappingURL=local-compile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-compile.d.ts","sourceRoot":"","sources":["../../src/github/local-compile.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,sBAAsB,CAAC;AAG9E;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,KAAK,OAAO,CAAC;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE3E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,cAAc,EAAE,gBAAgB,CAAC;CAC3C;AA2CD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,mBAAmB,GAC3B,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CA8DpD"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { manifestSchema, prepareLocalAssets } from '@noodle-borg/compiler';
|
|
4
|
+
import { classifyFastLane } from './fast-lane-classifier.js';
|
|
5
|
+
async function readJsonFile(path) {
|
|
6
|
+
try {
|
|
7
|
+
return JSON.parse(await readFile(path, 'utf8'));
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function truncate(text, max = 240) {
|
|
14
|
+
return text.length > max ? `${text.slice(0, max)}…` : text;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the manifest's local hosted assets (widget bundles, images) to upload-ready pairs: the wire
|
|
18
|
+
* metadata (absolutePath stripped) plus the bytes. Reuses the compiler's `prepareLocalAssets` so the
|
|
19
|
+
* git build worker and the CLI deploy path share one asset contract.
|
|
20
|
+
*/
|
|
21
|
+
async function prepareAssetsForUpload(manifest, rootDir) {
|
|
22
|
+
let raw;
|
|
23
|
+
try {
|
|
24
|
+
raw = JSON.parse(manifest);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const parsed = manifestSchema.safeParse(raw);
|
|
30
|
+
if (!parsed.success)
|
|
31
|
+
return [];
|
|
32
|
+
const prepared = prepareLocalAssets(parsed.data, { rootDir });
|
|
33
|
+
if (prepared.errors.length > 0) {
|
|
34
|
+
throw new Error(prepared.errors.map((error) => error.message).join('; '));
|
|
35
|
+
}
|
|
36
|
+
const assets = [];
|
|
37
|
+
for (const asset of prepared.assets) {
|
|
38
|
+
const { absolutePath, ...wire } = asset;
|
|
39
|
+
assets.push({ prepared: wire, bytes: new Uint8Array(await readFile(absolutePath)) });
|
|
40
|
+
}
|
|
41
|
+
return assets;
|
|
42
|
+
}
|
|
43
|
+
export function createLocalCompile(options) {
|
|
44
|
+
return async (sourceDir) => {
|
|
45
|
+
// 1. Fast-lane dependency gate — reject third-party deps BEFORE running any source.
|
|
46
|
+
const pkg = await readJsonFile(join(sourceDir, 'package.json'));
|
|
47
|
+
const classification = classifyFastLane(pkg);
|
|
48
|
+
if (!classification.eligible) {
|
|
49
|
+
const noun = classification.unsupported.length === 1 ? 'dependency' : 'dependencies';
|
|
50
|
+
const list = classification.unsupported.map((name) => `"${name}"`).join(', ');
|
|
51
|
+
return {
|
|
52
|
+
ok: false,
|
|
53
|
+
errorSummary: `compile: unsupported ${noun} ${list} — the git build worker compiles Noodle-native source only (SDK + local files); deploy with the CLI instead`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// 2. Entrypoint + declared access mode from committed noodle.json (the "declared" inherit source).
|
|
57
|
+
const noodleJson = await readJsonFile(join(sourceDir, 'noodle.json'));
|
|
58
|
+
const entrypoint = typeof noodleJson?.entrypoint === 'string' ? noodleJson.entrypoint : 'server.ts';
|
|
59
|
+
const declaredAccessMode = typeof noodleJson?.accessMode === 'string' ? noodleJson.accessMode : undefined;
|
|
60
|
+
// 3. Compile the manifest (untrusted — this runs the app's source).
|
|
61
|
+
let exported;
|
|
62
|
+
try {
|
|
63
|
+
exported = await options.exportManifest({
|
|
64
|
+
sourceDir,
|
|
65
|
+
entrypoint: join(sourceDir, entrypoint),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const name = error instanceof Error ? error.name : 'Error';
|
|
70
|
+
const message = error instanceof Error ? error.message : '';
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
errorSummary: `compile: ${entrypoint} failed to compile (${name})${message !== '' ? `: ${truncate(message)}` : ''}`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// 4. Prepare local hosted assets for the pipeline to upload.
|
|
77
|
+
let assets;
|
|
78
|
+
try {
|
|
79
|
+
assets = await prepareAssetsForUpload(exported.manifest, sourceDir);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
return {
|
|
83
|
+
ok: false,
|
|
84
|
+
errorSummary: `compile: hosted asset preparation failed: ${error instanceof Error ? truncate(error.message) : 'unknown error'}`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
ok: true,
|
|
89
|
+
input: {
|
|
90
|
+
manifest: exported.manifest,
|
|
91
|
+
...(exported.connectors !== undefined ? { connectors: exported.connectors } : {}),
|
|
92
|
+
...(declaredAccessMode !== undefined ? { declaredAccessMode } : {}),
|
|
93
|
+
...(assets.length > 0 ? { assets } : {}),
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=local-compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-compile.js","sourceRoot":"","sources":["../../src/github/local-compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { DeployRunRecord } from '../store.js';
|
|
2
|
+
import type { DeployRunDispatchInput, DeployRunExecutor } from './deploy-run-executor.js';
|
|
3
|
+
import { type ManifestExporter } from './local-compile.js';
|
|
4
|
+
/** A checked-out working copy of the run's source, plus an optional cleanup for its temp storage. */
|
|
5
|
+
export interface RepoCheckout {
|
|
6
|
+
readonly sourceDir: string;
|
|
7
|
+
readonly cleanup?: () => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export interface LocalProcessExecutorDeps {
|
|
10
|
+
/**
|
|
11
|
+
* Fetch the run's source into a local directory — a git clone at `commitSha` in prod/self-host, a
|
|
12
|
+
* fixture directory in tests. This is the deferred credential-broker/git seam; it lives here so the
|
|
13
|
+
* rest of the pipeline never sees an installation token.
|
|
14
|
+
*/
|
|
15
|
+
readonly checkout: (run: DeployRunRecord) => Promise<RepoCheckout>;
|
|
16
|
+
/** How the untrusted source becomes a manifest — the real adapter runs `noodle export manifest`. */
|
|
17
|
+
readonly exportManifest: ManifestExporter;
|
|
18
|
+
/** Injected so tests use a fake and prod uses global `fetch`. */
|
|
19
|
+
readonly httpFetch?: typeof fetch;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The C2 / self-host / E2E executor (GHD-3, ADR 0132 Decision 6): runs the untrusted-compile →
|
|
23
|
+
* trusted-deploy pipeline as a local async task. `checkout` (fetch source) and `exportManifest`
|
|
24
|
+
* (source → manifest) are the only environment-specific seams, and both are folded into the pipeline's
|
|
25
|
+
* untrusted `compile` closure — so a checkout OR compile failure lands the run at `failed` with a
|
|
26
|
+
* compile-stage `errorSummary`, never a hang.
|
|
27
|
+
*
|
|
28
|
+
* `dispatch` is fire-and-forget: it launches the task and resolves immediately (the webhook must answer
|
|
29
|
+
* GitHub at once) and never throws into the caller. `settled()` lets tests and graceful shutdown await
|
|
30
|
+
* the launched work.
|
|
31
|
+
*/
|
|
32
|
+
export declare class LocalProcessExecutor implements DeployRunExecutor {
|
|
33
|
+
#private;
|
|
34
|
+
constructor(deps: LocalProcessExecutorDeps);
|
|
35
|
+
dispatch(input: DeployRunDispatchInput): Promise<void>;
|
|
36
|
+
/** Await every launched pipeline — for tests and graceful shutdown. */
|
|
37
|
+
settled(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=local-process-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-process-executor.d.ts","sourceRoot":"","sources":["../../src/github/local-process-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE/E,qGAAqG;AACrG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IACnE,oGAAoG;IACpG,QAAQ,CAAC,cAAc,EAAE,gBAAgB,CAAC;IAC1C,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AAED;;;;;;;;;;GAUG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;;gBAMhD,IAAI,EAAE,wBAAwB;IAM1C,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtD,uEAAuE;IACjE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAiC/B"}
|