@tokenfactory/acc-runner 0.44.8 → 0.44.9
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 +38 -0
- package/dist/attachments/codex-stage.d.ts +11 -0
- package/dist/attachments/codex-stage.d.ts.map +1 -0
- package/dist/attachments/codex-stage.js +82 -0
- package/dist/attachments/codex-stage.js.map +1 -0
- package/dist/attachments/fetch-attachment.d.ts +17 -0
- package/dist/attachments/fetch-attachment.d.ts.map +1 -1
- package/dist/attachments/fetch-attachment.js +134 -6
- package/dist/attachments/fetch-attachment.js.map +1 -1
- package/dist/attachments/index.d.ts +2 -1
- package/dist/attachments/index.d.ts.map +1 -1
- package/dist/attachments/index.js +2 -1
- package/dist/attachments/index.js.map +1 -1
- package/dist/build-info.generated.d.ts +1 -1
- package/dist/build-info.generated.js +2 -2
- package/dist/commit-sha.d.ts +31 -0
- package/dist/commit-sha.d.ts.map +1 -0
- package/dist/commit-sha.js +31 -0
- package/dist/commit-sha.js.map +1 -0
- package/dist/companion-run.d.ts.map +1 -1
- package/dist/companion-run.js +14 -1
- package/dist/companion-run.js.map +1 -1
- package/dist/doctor.d.ts +16 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +107 -0
- package/dist/doctor.js.map +1 -1
- package/dist/engines/codex-chat.d.ts +10 -1
- package/dist/engines/codex-chat.d.ts.map +1 -1
- package/dist/engines/codex-chat.js +32 -2
- package/dist/engines/codex-chat.js.map +1 -1
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +7 -1
- package/dist/login.js.map +1 -1
- package/dist/machine-console/index.d.ts +6 -10
- package/dist/machine-console/index.d.ts.map +1 -1
- package/dist/machine-console/index.js +61 -54
- package/dist/machine-console/index.js.map +1 -1
- package/dist/machine-console/transport.d.ts +57 -0
- package/dist/machine-console/transport.d.ts.map +1 -0
- package/dist/machine-console/transport.js +170 -0
- package/dist/machine-console/transport.js.map +1 -0
- package/dist/preview-environments/control-plane.d.ts +11 -0
- package/dist/preview-environments/control-plane.d.ts.map +1 -0
- package/dist/preview-environments/control-plane.js +49 -0
- package/dist/preview-environments/control-plane.js.map +1 -0
- package/dist/preview-environments/http-provider.d.ts +13 -0
- package/dist/preview-environments/http-provider.d.ts.map +1 -0
- package/dist/preview-environments/http-provider.js +64 -0
- package/dist/preview-environments/http-provider.js.map +1 -0
- package/dist/preview-environments/profiles.d.ts +6 -0
- package/dist/preview-environments/profiles.d.ts.map +1 -0
- package/dist/preview-environments/profiles.js +34 -0
- package/dist/preview-environments/profiles.js.map +1 -0
- package/dist/preview-environments/safety.d.ts +7 -0
- package/dist/preview-environments/safety.d.ts.map +1 -0
- package/dist/preview-environments/safety.js +47 -0
- package/dist/preview-environments/safety.js.map +1 -0
- package/dist/preview-environments/service.d.ts +36 -0
- package/dist/preview-environments/service.d.ts.map +1 -0
- package/dist/preview-environments/service.js +149 -0
- package/dist/preview-environments/service.js.map +1 -0
- package/dist/preview-environments/types.d.ts +60 -0
- package/dist/preview-environments/types.d.ts.map +1 -0
- package/dist/preview-environments/types.js +2 -0
- package/dist/preview-environments/types.js.map +1 -0
- package/dist/production-migrations/command.d.ts +3 -0
- package/dist/production-migrations/command.d.ts.map +1 -0
- package/dist/production-migrations/command.js +21 -0
- package/dist/production-migrations/command.js.map +1 -0
- package/dist/production-migrations/executor.d.ts +59 -0
- package/dist/production-migrations/executor.d.ts.map +1 -0
- package/dist/production-migrations/executor.js +161 -0
- package/dist/production-migrations/executor.js.map +1 -0
- package/dist/production-migrations/pg-target.d.ts +22 -0
- package/dist/production-migrations/pg-target.d.ts.map +1 -0
- package/dist/production-migrations/pg-target.js +87 -0
- package/dist/production-migrations/pg-target.js.map +1 -0
- package/dist/production-migrations/profiles.d.ts +5 -0
- package/dist/production-migrations/profiles.d.ts.map +1 -0
- package/dist/production-migrations/profiles.js +39 -0
- package/dist/production-migrations/profiles.js.map +1 -0
- package/dist/production-migrations/service.d.ts +39 -0
- package/dist/production-migrations/service.d.ts.map +1 -0
- package/dist/production-migrations/service.js +166 -0
- package/dist/production-migrations/service.js.map +1 -0
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +17 -0
- package/dist/program.js.map +1 -1
- package/dist/runtime/worktree.d.ts.map +1 -1
- package/dist/runtime/worktree.js +23 -1
- package/dist/runtime/worktree.js.map +1 -1
- package/dist/secure-execution/auto-lease.d.ts +57 -0
- package/dist/secure-execution/auto-lease.d.ts.map +1 -0
- package/dist/secure-execution/auto-lease.js +116 -0
- package/dist/secure-execution/auto-lease.js.map +1 -0
- package/dist/secure-execution/command-policy.d.ts +5 -0
- package/dist/secure-execution/command-policy.d.ts.map +1 -0
- package/dist/secure-execution/command-policy.js +95 -0
- package/dist/secure-execution/command-policy.js.map +1 -0
- package/dist/secure-execution/confinement.d.ts +3 -0
- package/dist/secure-execution/confinement.d.ts.map +1 -0
- package/dist/secure-execution/confinement.js +18 -0
- package/dist/secure-execution/confinement.js.map +1 -0
- package/dist/secure-execution/engine.d.ts +24 -0
- package/dist/secure-execution/engine.d.ts.map +1 -0
- package/dist/secure-execution/engine.js +272 -0
- package/dist/secure-execution/engine.js.map +1 -0
- package/dist/secure-execution/index.d.ts +7 -0
- package/dist/secure-execution/index.d.ts.map +1 -0
- package/dist/secure-execution/index.js +6 -0
- package/dist/secure-execution/index.js.map +1 -0
- package/dist/secure-execution/node-pty.d.ts +11 -0
- package/dist/secure-execution/node-pty.d.ts.map +1 -0
- package/dist/secure-execution/node-pty.js +27 -0
- package/dist/secure-execution/node-pty.js.map +1 -0
- package/dist/secure-execution/types.d.ts +176 -0
- package/dist/secure-execution/types.d.ts.map +1 -0
- package/dist/secure-execution/types.js +2 -0
- package/dist/secure-execution/types.js.map +1 -0
- package/dist/staging-migrations/command.d.ts +2 -0
- package/dist/staging-migrations/command.d.ts.map +1 -0
- package/dist/staging-migrations/command.js +58 -0
- package/dist/staging-migrations/command.js.map +1 -0
- package/dist/staging-migrations/executor.d.ts +49 -0
- package/dist/staging-migrations/executor.d.ts.map +1 -0
- package/dist/staging-migrations/executor.js +125 -0
- package/dist/staging-migrations/executor.js.map +1 -0
- package/dist/staging-migrations/pg-target.d.ts +20 -0
- package/dist/staging-migrations/pg-target.d.ts.map +1 -0
- package/dist/staging-migrations/pg-target.js +63 -0
- package/dist/staging-migrations/pg-target.js.map +1 -0
- package/dist/staging-migrations/profiles.d.ts +5 -0
- package/dist/staging-migrations/profiles.d.ts.map +1 -0
- package/dist/staging-migrations/profiles.js +31 -0
- package/dist/staging-migrations/profiles.js.map +1 -0
- package/dist/staging-migrations/service.d.ts +40 -0
- package/dist/staging-migrations/service.d.ts.map +1 -0
- package/dist/staging-migrations/service.js +157 -0
- package/dist/staging-migrations/service.js.map +1 -0
- package/dist/supervisor.d.ts +15 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +54 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/terminal/http-carrier.d.ts +17 -0
- package/dist/terminal/http-carrier.d.ts.map +1 -0
- package/dist/terminal/http-carrier.js +39 -0
- package/dist/terminal/http-carrier.js.map +1 -0
- package/dist/terminal/pty-adapter.d.ts +88 -0
- package/dist/terminal/pty-adapter.d.ts.map +1 -0
- package/dist/terminal/pty-adapter.js +252 -0
- package/dist/terminal/pty-adapter.js.map +1 -0
- package/dist/terminal/transport-contract.d.ts +115 -0
- package/dist/terminal/transport-contract.d.ts.map +1 -0
- package/dist/terminal/transport-contract.js +2 -0
- package/dist/terminal/transport-contract.js.map +1 -0
- package/dist/terminal/transport.d.ts +32 -0
- package/dist/terminal/transport.d.ts.map +1 -0
- package/dist/terminal/transport.js +208 -0
- package/dist/terminal/transport.js.map +1 -0
- package/dist/watch-chat/wire.d.ts.map +1 -1
- package/dist/watch-chat/wire.js +14 -1
- package/dist/watch-chat/wire.js.map +1 -1
- package/dist/watch.d.ts.map +1 -1
- package/dist/watch.js +32 -0
- package/dist/watch.js.map +1 -1
- package/package.json +6 -1
- package/scripts/com.tokenfactory.acc-runner-dedicated.plist +64 -0
- package/scripts/com.tokenfactory.acc-runner.plist +90 -0
- package/scripts/gen-build-info.d.mts +3 -0
- package/scripts/gen-build-info.mjs +72 -0
- package/scripts/install-launchd.sh +235 -0
- package/scripts/setup-dedicated-runner-darwin.sh +75 -0
- package/scripts/setup-dedicated-runner-linux.sh +173 -0
- package/scripts/uninstall-launchd.sh +67 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { createClient } from "@supabase/supabase-js";
|
|
2
|
+
export class SupabasePreviewControlPlane {
|
|
3
|
+
client;
|
|
4
|
+
constructor(url, serviceRoleKey) {
|
|
5
|
+
if (!url || !serviceRoleKey)
|
|
6
|
+
throw new Error("preview_control_plane_credentials_missing");
|
|
7
|
+
this.client = createClient(url, serviceRoleKey, {
|
|
8
|
+
db: { schema: "acc" },
|
|
9
|
+
auth: { persistSession: false, autoRefreshToken: false },
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
async listCandidates(limit) {
|
|
13
|
+
const { data, error } = await this.client
|
|
14
|
+
.from("preview_environments")
|
|
15
|
+
.select("id,org_id,project_id,repo,pull_request_number,head_sha,provider,provider_credential_profile_ref,deployment_identity_sha,provider_deployment_id,desired_state,observed_state,generation,lease_expires_at,updated_at")
|
|
16
|
+
.neq("observed_state", "archived")
|
|
17
|
+
.order("updated_at", { ascending: true })
|
|
18
|
+
.limit(limit);
|
|
19
|
+
if (error)
|
|
20
|
+
throw new Error(`preview_candidate_read_failed:${error.code ?? "unknown"}`);
|
|
21
|
+
return (data ?? []);
|
|
22
|
+
}
|
|
23
|
+
async recordObservation(input) {
|
|
24
|
+
const { data, error } = await this.client.rpc("record_preview_environment_observation", {
|
|
25
|
+
p_environment_id: input.environmentId,
|
|
26
|
+
p_generation: input.generation,
|
|
27
|
+
p_observed_state: input.observedState,
|
|
28
|
+
p_provider_deployment_id: input.providerDeploymentId,
|
|
29
|
+
p_preview_url: input.previewUrl ?? null,
|
|
30
|
+
p_provider_receipt_sha: input.providerReceiptSha,
|
|
31
|
+
p_failure_code: input.failureCode ?? null,
|
|
32
|
+
p_idempotency_key: input.idempotencyKey,
|
|
33
|
+
});
|
|
34
|
+
if (error)
|
|
35
|
+
throw new Error(`preview_observation_failed:${error.code ?? "unknown"}`);
|
|
36
|
+
return (data ?? {});
|
|
37
|
+
}
|
|
38
|
+
async audit(verb, environmentId, payload) {
|
|
39
|
+
const { error } = await this.client.rpc("log_activity", {
|
|
40
|
+
p_verb: verb,
|
|
41
|
+
p_target_id: environmentId,
|
|
42
|
+
p_target_type: "preview_environment",
|
|
43
|
+
p_payload: payload,
|
|
44
|
+
});
|
|
45
|
+
if (error)
|
|
46
|
+
throw new Error(`preview_audit_failed:${error.code ?? "unknown"}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=control-plane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-plane.js","sourceRoot":"","sources":["../../src/preview-environments/control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD,MAAM,OAAO,2BAA2B;IACrB,MAAM,CAAC;IAExB,YAAY,GAAW,EAAE,cAAsB;QAC7C,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC1F,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE;YAC9C,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;YACrB,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE;SACzD,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAAa;QAChC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM;aACtC,IAAI,CAAC,sBAAsB,CAAC;aAC5B,MAAM,CAAC,oNAAoN,CAAC;aAC5N,GAAG,CAAC,gBAAgB,EAAE,UAAU,CAAC;aACjC,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;aACxC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChB,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;QACvF,OAAO,CAAC,IAAI,IAAI,EAAE,CAA8B,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,KAA8D;QACpF,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,wCAAwC,EAAE;YACtF,gBAAgB,EAAE,KAAK,CAAC,aAAa;YACrC,YAAY,EAAE,KAAK,CAAC,UAAU;YAC9B,gBAAgB,EAAE,KAAK,CAAC,aAAa;YACrC,wBAAwB,EAAE,KAAK,CAAC,oBAAoB;YACpD,aAAa,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACvC,sBAAsB,EAAE,KAAK,CAAC,kBAAkB;YAChD,cAAc,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;YACzC,iBAAiB,EAAE,KAAK,CAAC,cAAc;SACxC,CAAC,CAAC;QACH,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,IAAI,EAAE,CAAoC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,aAAqB,EAAE,OAAgC;QAC/E,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE;YACtD,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,aAAa;YAC1B,aAAa,EAAE,qBAAqB;YACpC,SAAS,EAAE,OAAO;SACnB,CAAC,CAAC;QACH,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;IAChF,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PreviewProviderAdapter, PreviewProviderRequest, PreviewProviderResult } from "./types.js";
|
|
2
|
+
export interface HttpPreviewProviderOptions {
|
|
3
|
+
endpoint: string;
|
|
4
|
+
token: string;
|
|
5
|
+
fetchImpl?: typeof fetch;
|
|
6
|
+
}
|
|
7
|
+
export declare class HttpPreviewProvider implements PreviewProviderAdapter {
|
|
8
|
+
private readonly options;
|
|
9
|
+
private readonly fetchImpl;
|
|
10
|
+
constructor(options: HttpPreviewProviderOptions);
|
|
11
|
+
execute(request: PreviewProviderRequest): Promise<PreviewProviderResult>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=http-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-provider.d.ts","sourceRoot":"","sources":["../../src/preview-environments/http-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AASD,qBAAa,mBAAoB,YAAW,sBAAsB;IAGpD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAEZ,OAAO,EAAE,0BAA0B;IAQ1D,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAyC/E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
function publicPreviewUrl(value) {
|
|
2
|
+
if (typeof value !== "string" || !value.startsWith("https://"))
|
|
3
|
+
return null;
|
|
4
|
+
const url = new URL(value);
|
|
5
|
+
if (url.username || url.password)
|
|
6
|
+
throw new Error("preview_provider_url_credentials_forbidden");
|
|
7
|
+
return url.toString();
|
|
8
|
+
}
|
|
9
|
+
export class HttpPreviewProvider {
|
|
10
|
+
options;
|
|
11
|
+
fetchImpl;
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.options = options;
|
|
14
|
+
const endpoint = new URL(options.endpoint);
|
|
15
|
+
if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password)
|
|
16
|
+
throw new Error("preview_provider_endpoint_invalid");
|
|
17
|
+
if (!options.token)
|
|
18
|
+
throw new Error("preview_provider_token_missing");
|
|
19
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
20
|
+
}
|
|
21
|
+
async execute(request) {
|
|
22
|
+
const response = await this.fetchImpl(this.options.endpoint, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: {
|
|
25
|
+
authorization: `Bearer ${this.options.token}`,
|
|
26
|
+
"content-type": "application/json",
|
|
27
|
+
"idempotency-key": `${request.deploymentIdentity}:${request.generation}:${request.action}`,
|
|
28
|
+
},
|
|
29
|
+
signal: request.signal,
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
action: request.action,
|
|
32
|
+
environment_id: request.environmentId,
|
|
33
|
+
org_id: request.orgId,
|
|
34
|
+
project_id: request.projectId,
|
|
35
|
+
repo: request.repo,
|
|
36
|
+
pull_request_number: request.pullRequestNumber,
|
|
37
|
+
head_sha: request.headSha,
|
|
38
|
+
generation: request.generation,
|
|
39
|
+
deployment_identity_sha: request.deploymentIdentity,
|
|
40
|
+
provider_deployment_id: request.providerDeploymentId,
|
|
41
|
+
lease_expires_at: request.leaseExpiresAt,
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok)
|
|
45
|
+
throw new Error(`preview_provider_http_${response.status}`);
|
|
46
|
+
const body = (await response.json());
|
|
47
|
+
const state = body.observed_state;
|
|
48
|
+
if (!['ready', 'failed', 'stopped', 'archived'].includes(String(state)))
|
|
49
|
+
throw new Error("preview_provider_response_invalid");
|
|
50
|
+
if (request.action === "stop" && !["stopped", "failed"].includes(String(state)))
|
|
51
|
+
throw new Error("preview_provider_stop_state_invalid");
|
|
52
|
+
if (["create", "refresh", "promote"].includes(request.action) && !["ready", "failed"].includes(String(state)))
|
|
53
|
+
throw new Error("preview_provider_active_state_invalid");
|
|
54
|
+
if (body.provider_deployment_id !== request.providerDeploymentId)
|
|
55
|
+
throw new Error("preview_provider_identity_mismatch");
|
|
56
|
+
return {
|
|
57
|
+
providerDeploymentId: request.providerDeploymentId,
|
|
58
|
+
observedState: state,
|
|
59
|
+
previewUrl: publicPreviewUrl(body.preview_url),
|
|
60
|
+
receipt: typeof body.receipt === "object" && body.receipt ? body.receipt : {},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=http-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-provider.js","sourceRoot":"","sources":["../../src/preview-environments/http-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PreviewProviderAdapter } from "./types.js";
|
|
2
|
+
export declare function configuredPreviewProfiles(env?: NodeJS.ProcessEnv): string[];
|
|
3
|
+
export declare function previewEnvironmentServiceEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
4
|
+
export declare function previewEnvironmentCaps(env?: NodeJS.ProcessEnv): Record<string, unknown>;
|
|
5
|
+
export declare function providerForProfile(provider: string, profile: string, env?: NodeJS.ProcessEnv, fetchImpl?: typeof fetch): PreviewProviderAdapter;
|
|
6
|
+
//# sourceMappingURL=profiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/preview-environments/profiles.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAOzD,wBAAgB,yBAAyB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,EAAE,CAMxF;AAED,wBAAgB,gCAAgC,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAM9F;AAED,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGpG;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,CAAC,EAAE,OAAO,KAAK,GACvB,sBAAsB,CASxB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { HttpPreviewProvider } from "./http-provider.js";
|
|
2
|
+
function envStem(profile) {
|
|
3
|
+
if (!/^[A-Za-z0-9_.-]{1,80}$/.test(profile))
|
|
4
|
+
throw new Error("preview_provider_profile_invalid");
|
|
5
|
+
return profile.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
6
|
+
}
|
|
7
|
+
export function configuredPreviewProfiles(env = process.env) {
|
|
8
|
+
return Object.keys(env)
|
|
9
|
+
.flatMap((key) => /^ACC_PREVIEW_PROVIDER_([A-Z0-9_]+)_ENDPOINT$/.exec(key)?.[1] ?? [])
|
|
10
|
+
.filter((stem) => Boolean(env[`ACC_PREVIEW_PROVIDER_${stem}_TOKEN`]))
|
|
11
|
+
.map((stem) => stem.toLowerCase())
|
|
12
|
+
.sort();
|
|
13
|
+
}
|
|
14
|
+
export function previewEnvironmentServiceEnabled(env = process.env) {
|
|
15
|
+
return (env.ACC_PREVIEW_ENVIRONMENT_SERVICE === "1" &&
|
|
16
|
+
Boolean(env.ACC_PREVIEW_CONTROL_PLANE_SERVICE_ROLE_KEY) &&
|
|
17
|
+
configuredPreviewProfiles(env).length > 0);
|
|
18
|
+
}
|
|
19
|
+
export function previewEnvironmentCaps(env = process.env) {
|
|
20
|
+
const profiles = configuredPreviewProfiles(env);
|
|
21
|
+
return profiles.length ? { preview_environments: true, preview_provider_profiles: profiles } : {};
|
|
22
|
+
}
|
|
23
|
+
export function providerForProfile(provider, profile, env = process.env, fetchImpl) {
|
|
24
|
+
const stem = envStem(profile);
|
|
25
|
+
const endpoint = env[`ACC_PREVIEW_PROVIDER_${stem}_ENDPOINT`];
|
|
26
|
+
const token = env[`ACC_PREVIEW_PROVIDER_${stem}_TOKEN`];
|
|
27
|
+
const configuredProvider = env[`ACC_PREVIEW_PROVIDER_${stem}_KIND`]?.toLowerCase();
|
|
28
|
+
if (!endpoint || !token)
|
|
29
|
+
throw new Error("preview_provider_profile_missing");
|
|
30
|
+
if (configuredProvider && configuredProvider !== provider.toLowerCase())
|
|
31
|
+
throw new Error("preview_provider_profile_kind_mismatch");
|
|
32
|
+
return new HttpPreviewProvider({ endpoint, token, fetchImpl });
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/preview-environments/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,SAAS,OAAO,CAAC,OAAe;IAC9B,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACjG,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC5E,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;SACpB,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,8CAA8C,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACrF,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,QAAQ,CAAC,CAAC,CAAC;SACpE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;SACjC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,MAAyB,OAAO,CAAC,GAAG;IACnF,OAAO,CACL,GAAG,CAAC,+BAA+B,KAAK,GAAG;QAC3C,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC;QACvD,yBAAyB,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAC1C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACzE,MAAM,QAAQ,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,IAAI,EAAE,yBAAyB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,QAAgB,EAChB,OAAe,EACf,MAAyB,OAAO,CAAC,GAAG,EACpC,SAAwB;IAExB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC,wBAAwB,IAAI,WAAW,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,GAAG,CAAC,wBAAwB,IAAI,QAAQ,CAAC,CAAC;IACxD,MAAM,kBAAkB,GAAG,GAAG,CAAC,wBAAwB,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACnF,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC7E,IAAI,kBAAkB,IAAI,kBAAkB,KAAK,QAAQ,CAAC,WAAW,EAAE;QACrE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,OAAO,IAAI,mBAAmB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PreviewAction, PreviewEnvironmentLease } from "./types.js";
|
|
2
|
+
export declare function safePreviewCode(error: unknown): string;
|
|
3
|
+
export declare function receiptSha(value: unknown): string;
|
|
4
|
+
export declare function deterministicUuid(...parts: Array<string | number>): string;
|
|
5
|
+
export declare function desiredAction(row: PreviewEnvironmentLease, now?: number, staleAfterMs?: number): PreviewAction | null;
|
|
6
|
+
export declare function validateLease(row: PreviewEnvironmentLease): void;
|
|
7
|
+
//# sourceMappingURL=safety.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/preview-environments/safety.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAKzE,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOtD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAG1E;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,uBAAuB,EAC5B,GAAG,SAAa,EAChB,YAAY,SAAU,GACrB,aAAa,GAAG,IAAI,CAatB;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,uBAAuB,GAAG,IAAI,CAShE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { isCommitSha, isSha256Digest } from "../commit-sha.js";
|
|
3
|
+
const UUID_NAMESPACE = "acc-preview-environment-runner-v1";
|
|
4
|
+
export function safePreviewCode(error) {
|
|
5
|
+
const raw = error instanceof Error ? error.message : "unknown_error";
|
|
6
|
+
return raw
|
|
7
|
+
.replace(/https?:\/\/[^\s]+/gi, "[REDACTED_URL]")
|
|
8
|
+
.replace(/(authorization|password|token|secret|key)[=:]?[^\s]*/gi, "$1=[REDACTED]")
|
|
9
|
+
.replace(/[^a-zA-Z0-9_.:[\] -]/g, "_")
|
|
10
|
+
.slice(0, 180);
|
|
11
|
+
}
|
|
12
|
+
export function receiptSha(value) {
|
|
13
|
+
return createHash("sha256").update(JSON.stringify(value)).digest("hex");
|
|
14
|
+
}
|
|
15
|
+
export function deterministicUuid(...parts) {
|
|
16
|
+
const hex = createHash("sha256").update([UUID_NAMESPACE, ...parts].join(":"), "utf8").digest("hex");
|
|
17
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-a${hex.slice(17, 20)}-${hex.slice(20, 32)}`;
|
|
18
|
+
}
|
|
19
|
+
export function desiredAction(row, now = Date.now(), staleAfterMs = 180_000) {
|
|
20
|
+
const staleProvision = row.observed_state === "provisioning" &&
|
|
21
|
+
Number.isFinite(Date.parse(row.updated_at)) &&
|
|
22
|
+
Date.parse(row.updated_at) + staleAfterMs <= now;
|
|
23
|
+
if (row.desired_state === "active" && ["pending", "failed", "stopped"].includes(row.observed_state))
|
|
24
|
+
return row.generation === 1 ? "create" : "refresh";
|
|
25
|
+
if (row.desired_state === "active" && staleProvision)
|
|
26
|
+
return row.generation === 1 ? "create" : "refresh";
|
|
27
|
+
if (row.desired_state === "promoted" && row.observed_state === "ready")
|
|
28
|
+
return "promote";
|
|
29
|
+
if (row.desired_state === "promoted" && staleProvision)
|
|
30
|
+
return "promote";
|
|
31
|
+
if (row.desired_state === "stopped" && !["stopped", "archived"].includes(row.observed_state))
|
|
32
|
+
return "stop";
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
export function validateLease(row) {
|
|
36
|
+
if (!isCommitSha(row.head_sha))
|
|
37
|
+
throw new Error("preview_commit_invalid");
|
|
38
|
+
if (!isSha256Digest(row.deployment_identity_sha))
|
|
39
|
+
throw new Error("preview_deployment_identity_invalid");
|
|
40
|
+
if (!/^[\w.-]+\/[\w.-]+$/.test(row.repo))
|
|
41
|
+
throw new Error("preview_repo_invalid");
|
|
42
|
+
if (!Number.isInteger(row.pull_request_number) || row.pull_request_number < 1)
|
|
43
|
+
throw new Error("preview_pull_request_invalid");
|
|
44
|
+
if (!Number.isInteger(row.generation) || row.generation < 1)
|
|
45
|
+
throw new Error("preview_generation_invalid");
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../../src/preview-environments/safety.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { RunnerConfig } from "../config.js";
|
|
2
|
+
import type { PreviewControlPlane, PreviewEnvironmentLease, PreviewProviderAdapter } from "./types.js";
|
|
3
|
+
export interface PreviewEnvironmentLogger {
|
|
4
|
+
info(message: string): void;
|
|
5
|
+
error(message: string): void;
|
|
6
|
+
}
|
|
7
|
+
export interface PreviewEnvironmentServiceOptions {
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
pollMs?: number;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
batchSize?: number;
|
|
12
|
+
logger?: PreviewEnvironmentLogger;
|
|
13
|
+
controlPlane?: PreviewControlPlane;
|
|
14
|
+
providerFactory?: (provider: string, profile: string) => PreviewProviderAdapter;
|
|
15
|
+
}
|
|
16
|
+
export declare class PreviewEnvironmentService {
|
|
17
|
+
private readonly runnerId;
|
|
18
|
+
private readonly options;
|
|
19
|
+
private timer;
|
|
20
|
+
private active;
|
|
21
|
+
private stopping;
|
|
22
|
+
private readonly env;
|
|
23
|
+
private readonly logger;
|
|
24
|
+
private readonly pollMs;
|
|
25
|
+
private readonly timeoutMs;
|
|
26
|
+
private readonly staleAfterMs;
|
|
27
|
+
private readonly batchSize;
|
|
28
|
+
private readonly controlPlane;
|
|
29
|
+
constructor(cfg: RunnerConfig, runnerId: string, options?: PreviewEnvironmentServiceOptions);
|
|
30
|
+
start(): void;
|
|
31
|
+
stop(): Promise<void>;
|
|
32
|
+
pollOnce(): Promise<void>;
|
|
33
|
+
process(row: PreviewEnvironmentLease): Promise<"skipped" | "succeeded" | "failed">;
|
|
34
|
+
}
|
|
35
|
+
export { previewEnvironmentCaps, previewEnvironmentServiceEnabled } from "./profiles.js";
|
|
36
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/preview-environments/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAUjD,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,gCAAgC;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,sBAAsB,CAAC;CACjF;AAED,qBAAa,yBAAyB;IAclC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAd1B,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;gBAGjD,GAAG,EAAE,YAAY,EACA,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gCAAqC;IAcjE,KAAK,IAAI,IAAI;IAQP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBzB,OAAO,CAAC,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;CAkFzF;AAMD,OAAO,EAAE,sBAAsB,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { SupabasePreviewControlPlane } from "./control-plane.js";
|
|
2
|
+
import { providerForProfile } from "./profiles.js";
|
|
3
|
+
import { desiredAction, deterministicUuid, receiptSha, safePreviewCode, validateLease, } from "./safety.js";
|
|
4
|
+
export class PreviewEnvironmentService {
|
|
5
|
+
runnerId;
|
|
6
|
+
options;
|
|
7
|
+
timer = null;
|
|
8
|
+
active = false;
|
|
9
|
+
stopping = false;
|
|
10
|
+
env;
|
|
11
|
+
logger;
|
|
12
|
+
pollMs;
|
|
13
|
+
timeoutMs;
|
|
14
|
+
staleAfterMs;
|
|
15
|
+
batchSize;
|
|
16
|
+
controlPlane;
|
|
17
|
+
constructor(cfg, runnerId, options = {}) {
|
|
18
|
+
this.runnerId = runnerId;
|
|
19
|
+
this.options = options;
|
|
20
|
+
this.env = options.env ?? process.env;
|
|
21
|
+
this.logger = options.logger ?? console;
|
|
22
|
+
this.pollMs = bounded(options.pollMs ?? Number(this.env.ACC_PREVIEW_POLL_MS ?? 30_000), 5_000, 300_000);
|
|
23
|
+
this.timeoutMs = bounded(options.timeoutMs ?? Number(this.env.ACC_PREVIEW_ACTION_TIMEOUT_MS ?? 120_000), 5_000, 600_000);
|
|
24
|
+
this.staleAfterMs = Math.max(this.timeoutMs * 2, 180_000);
|
|
25
|
+
this.batchSize = bounded(options.batchSize ?? Number(this.env.ACC_PREVIEW_BATCH_SIZE ?? 10), 1, 50);
|
|
26
|
+
this.controlPlane = options.controlPlane ?? new SupabasePreviewControlPlane(cfg.supabaseUrl, this.env.ACC_PREVIEW_CONTROL_PLANE_SERVICE_ROLE_KEY ?? "");
|
|
27
|
+
}
|
|
28
|
+
start() {
|
|
29
|
+
if (this.timer)
|
|
30
|
+
return;
|
|
31
|
+
this.stopping = false;
|
|
32
|
+
void this.pollOnce();
|
|
33
|
+
this.timer = setInterval(() => void this.pollOnce(), this.pollMs);
|
|
34
|
+
this.timer.unref?.();
|
|
35
|
+
}
|
|
36
|
+
async stop() {
|
|
37
|
+
this.stopping = true;
|
|
38
|
+
if (this.timer)
|
|
39
|
+
clearInterval(this.timer);
|
|
40
|
+
this.timer = null;
|
|
41
|
+
const deadline = Date.now() + this.timeoutMs;
|
|
42
|
+
while (this.active && Date.now() < deadline)
|
|
43
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
44
|
+
}
|
|
45
|
+
async pollOnce() {
|
|
46
|
+
if (this.active || this.stopping)
|
|
47
|
+
return;
|
|
48
|
+
this.active = true;
|
|
49
|
+
try {
|
|
50
|
+
const rows = await this.controlPlane.listCandidates(this.batchSize);
|
|
51
|
+
for (const row of rows) {
|
|
52
|
+
if (this.stopping)
|
|
53
|
+
break;
|
|
54
|
+
await this.process(row);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
this.logger.error(`[acc-runner] preview environment service: ${safePreviewCode(error)}`);
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
this.active = false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async process(row) {
|
|
65
|
+
const action = desiredAction(row, Date.now(), this.staleAfterMs);
|
|
66
|
+
if (!action)
|
|
67
|
+
return "skipped";
|
|
68
|
+
try {
|
|
69
|
+
validateLease(row);
|
|
70
|
+
if (action !== "stop" && action !== "archive" && Date.parse(row.lease_expires_at) <= Date.now())
|
|
71
|
+
throw new Error("preview_lease_expired");
|
|
72
|
+
const providerDeploymentId = row.provider_deployment_id ?? row.deployment_identity_sha;
|
|
73
|
+
const recovering = row.observed_state === "provisioning";
|
|
74
|
+
const claimReceipt = { action, runner_id: this.runnerId, generation: row.generation, recovering };
|
|
75
|
+
const claim = await this.controlPlane.recordObservation({
|
|
76
|
+
environmentId: row.id,
|
|
77
|
+
generation: row.generation,
|
|
78
|
+
observedState: "provisioning",
|
|
79
|
+
providerDeploymentId,
|
|
80
|
+
providerReceiptSha: receiptSha(claimReceipt),
|
|
81
|
+
idempotencyKey: deterministicUuid(row.id, row.generation, action, recovering ? `recover:${row.updated_at}` : "claim"),
|
|
82
|
+
});
|
|
83
|
+
if (claim.idempotent_replay)
|
|
84
|
+
return "skipped";
|
|
85
|
+
const controller = new AbortController();
|
|
86
|
+
const timeout = setTimeout(() => controller.abort(new Error("preview_provider_timeout")), this.timeoutMs);
|
|
87
|
+
try {
|
|
88
|
+
const adapter = this.options.providerFactory?.(row.provider, row.provider_credential_profile_ref) ??
|
|
89
|
+
providerForProfile(row.provider, row.provider_credential_profile_ref, this.env);
|
|
90
|
+
const result = await adapter.execute({
|
|
91
|
+
action,
|
|
92
|
+
environmentId: row.id,
|
|
93
|
+
orgId: row.org_id,
|
|
94
|
+
projectId: row.project_id,
|
|
95
|
+
repo: row.repo,
|
|
96
|
+
pullRequestNumber: row.pull_request_number,
|
|
97
|
+
headSha: row.head_sha,
|
|
98
|
+
generation: row.generation,
|
|
99
|
+
deploymentIdentity: row.deployment_identity_sha,
|
|
100
|
+
providerDeploymentId,
|
|
101
|
+
leaseExpiresAt: row.lease_expires_at,
|
|
102
|
+
signal: controller.signal,
|
|
103
|
+
});
|
|
104
|
+
const providerReceiptSha = receiptSha(result.receipt);
|
|
105
|
+
await this.controlPlane.recordObservation({
|
|
106
|
+
environmentId: row.id,
|
|
107
|
+
generation: row.generation,
|
|
108
|
+
observedState: result.observedState,
|
|
109
|
+
providerDeploymentId: result.providerDeploymentId,
|
|
110
|
+
previewUrl: result.previewUrl,
|
|
111
|
+
providerReceiptSha,
|
|
112
|
+
idempotencyKey: deterministicUuid(row.id, row.generation, action, "complete"),
|
|
113
|
+
});
|
|
114
|
+
await this.controlPlane.audit("preview.environment_runner_completed", row.id, {
|
|
115
|
+
runner_id: this.runnerId,
|
|
116
|
+
action,
|
|
117
|
+
generation: row.generation,
|
|
118
|
+
provider_receipt_sha: providerReceiptSha,
|
|
119
|
+
}).catch((error) => {
|
|
120
|
+
this.logger.error(`[acc-runner] preview audit: ${safePreviewCode(error)}`);
|
|
121
|
+
});
|
|
122
|
+
return "succeeded";
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
clearTimeout(timeout);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
const failureCode = safePreviewCode(error);
|
|
130
|
+
const providerDeploymentId = row.provider_deployment_id ?? row.deployment_identity_sha;
|
|
131
|
+
await this.controlPlane.recordObservation({
|
|
132
|
+
environmentId: row.id,
|
|
133
|
+
generation: row.generation,
|
|
134
|
+
observedState: "failed",
|
|
135
|
+
providerDeploymentId,
|
|
136
|
+
providerReceiptSha: receiptSha({ failureCode }),
|
|
137
|
+
failureCode,
|
|
138
|
+
idempotencyKey: deterministicUuid(row.id, row.generation, action, "failed"),
|
|
139
|
+
}).catch(() => undefined);
|
|
140
|
+
this.logger.error(`[acc-runner] preview environment ${row.id}: ${failureCode}`);
|
|
141
|
+
return "failed";
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function bounded(value, min, max) {
|
|
146
|
+
return Number.isFinite(value) ? Math.max(min, Math.min(max, Math.floor(value))) : min;
|
|
147
|
+
}
|
|
148
|
+
export { previewEnvironmentCaps, previewEnvironmentServiceEnabled } from "./profiles.js";
|
|
149
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/preview-environments/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export type PreviewDesiredState = "active" | "promoted" | "stopped" | "archived";
|
|
2
|
+
export type PreviewObservedState = "pending" | "provisioning" | "ready" | "failed" | "stopped" | "archived";
|
|
3
|
+
export type PreviewAction = "create" | "refresh" | "promote" | "stop" | "archive";
|
|
4
|
+
export interface PreviewEnvironmentLease {
|
|
5
|
+
id: string;
|
|
6
|
+
org_id: string;
|
|
7
|
+
project_id: string;
|
|
8
|
+
repo: string;
|
|
9
|
+
pull_request_number: number;
|
|
10
|
+
head_sha: string;
|
|
11
|
+
provider: string;
|
|
12
|
+
provider_credential_profile_ref: string;
|
|
13
|
+
deployment_identity_sha: string;
|
|
14
|
+
provider_deployment_id: string | null;
|
|
15
|
+
desired_state: PreviewDesiredState;
|
|
16
|
+
observed_state: PreviewObservedState;
|
|
17
|
+
generation: number;
|
|
18
|
+
lease_expires_at: string;
|
|
19
|
+
updated_at: string;
|
|
20
|
+
}
|
|
21
|
+
export interface PreviewProviderRequest {
|
|
22
|
+
action: PreviewAction;
|
|
23
|
+
environmentId: string;
|
|
24
|
+
orgId: string;
|
|
25
|
+
projectId: string;
|
|
26
|
+
repo: string;
|
|
27
|
+
pullRequestNumber: number;
|
|
28
|
+
headSha: string;
|
|
29
|
+
generation: number;
|
|
30
|
+
deploymentIdentity: string;
|
|
31
|
+
providerDeploymentId: string;
|
|
32
|
+
leaseExpiresAt: string;
|
|
33
|
+
signal: AbortSignal;
|
|
34
|
+
}
|
|
35
|
+
export interface PreviewProviderResult {
|
|
36
|
+
providerDeploymentId: string;
|
|
37
|
+
observedState: Exclude<PreviewObservedState, "pending" | "provisioning">;
|
|
38
|
+
previewUrl?: string | null;
|
|
39
|
+
receipt: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
export interface PreviewProviderAdapter {
|
|
42
|
+
execute(request: PreviewProviderRequest): Promise<PreviewProviderResult>;
|
|
43
|
+
}
|
|
44
|
+
export interface PreviewControlPlane {
|
|
45
|
+
listCandidates(limit: number): Promise<PreviewEnvironmentLease[]>;
|
|
46
|
+
recordObservation(input: {
|
|
47
|
+
environmentId: string;
|
|
48
|
+
generation: number;
|
|
49
|
+
observedState: Exclude<PreviewObservedState, "pending">;
|
|
50
|
+
providerDeploymentId: string;
|
|
51
|
+
previewUrl?: string | null;
|
|
52
|
+
providerReceiptSha: string;
|
|
53
|
+
failureCode?: string | null;
|
|
54
|
+
idempotencyKey: string;
|
|
55
|
+
}): Promise<{
|
|
56
|
+
idempotent_replay?: boolean;
|
|
57
|
+
}>;
|
|
58
|
+
audit(verb: string, environmentId: string, payload: Record<string, unknown>): Promise<void>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/preview-environments/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;AACjF,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAC5G,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAElF,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B,EAAE,MAAM,CAAC;IACxC,uBAAuB,EAAE,MAAM,CAAC;IAChC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,aAAa,EAAE,mBAAmB,CAAC;IACnC,cAAc,EAAE,oBAAoB,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC,oBAAoB,EAAE,SAAS,GAAG,cAAc,CAAC,CAAC;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAClE,iBAAiB,CAAC,KAAK,EAAE;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,OAAO,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;QACxD,oBAAoB,EAAE,MAAM,CAAC;QAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC;QAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC7C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/preview-environments/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/production-migrations/command.ts"],"names":[],"mappings":"AAKA,mFAAmF;AACnF,wBAAsB,uCAAuC,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { loadConfig } from "../config.js";
|
|
2
|
+
import { getTokenProvider } from "../token-provider.js";
|
|
3
|
+
import { createRunnerClient } from "../supabase.js";
|
|
4
|
+
import { ProductionMigrationService } from "./service.js";
|
|
5
|
+
/** Explicit single-promotion entrypoint; the claim RPC is always the authority. */
|
|
6
|
+
export async function applyApprovedProductionMigrationCommand(promotionId) {
|
|
7
|
+
if (!/^[0-9a-f-]{36}$/i.test(promotionId))
|
|
8
|
+
throw new Error("invalid production promotion id");
|
|
9
|
+
const cfg = loadConfig();
|
|
10
|
+
const session = await getTokenProvider().load();
|
|
11
|
+
if (!session?.runner_id)
|
|
12
|
+
throw new Error("runner login required");
|
|
13
|
+
const sb = createRunnerClient(cfg, session.access_token, session.realtime_config);
|
|
14
|
+
const service = new ProductionMigrationService(sb, cfg, session.runner_id, {
|
|
15
|
+
env: { ...process.env, ACC_PRODUCTION_MIGRATION_PROMOTION_IDS: promotionId },
|
|
16
|
+
});
|
|
17
|
+
const outcome = await service.claimAndRun(promotionId);
|
|
18
|
+
if (outcome !== "succeeded")
|
|
19
|
+
throw new Error(`production migration ${outcome}`);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/production-migrations/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE1D,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,uCAAuC,CAAC,WAAmB;IAC/E,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAC9F,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,MAAM,gBAAgB,EAAE,CAAC,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAClE,MAAM,EAAE,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAClF,MAAM,OAAO,GAAG,IAAI,0BAA0B,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE;QACzE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,sCAAsC,EAAE,WAAW,EAAE;KAC7E,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IACvD,IAAI,OAAO,KAAK,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;AAClF,CAAC"}
|