Files
kuber/shared/build-protocol.ts
T
2026-10-06 15:31:51 +00:00

104 lines
2.7 KiB
TypeScript

export const BUILD_PROTOCOL_VERSION = 1 as const;
export type Sha256Digest = `sha256:${string}`;
export type BuildArchitecture = "amd64" | "arm64";
export type WorkspaceFile = {
path: string;
type: "file" | "symlink";
digest: Sha256Digest;
size: number;
mode: 0o644 | 0o755 | 0o777;
};
export type WorkspaceManifest = {
version: typeof BUILD_PROTOCOL_VERSION;
files: WorkspaceFile[];
};
export type BuildSpec = {
/** Absent means the legacy BuildKit Dockerfile builder. */
builder?: "buildkit" | "buildpacks";
/** GitHub release CNB package, optionally pinned with #sha256=<hex>. */
buildpackUri?: string;
architecture: BuildArchitecture;
image: string;
context: string;
dockerfile?: string;
target?: string;
buildArgs: string[];
workspace: Sha256Digest;
};
export type BuildRequest = {
version: typeof BUILD_PROTOCOL_VERSION;
id: string;
project: string;
service: string;
spec: BuildSpec;
/** Additional service destinations for the same build artifact. */
destinations?: Array<{ service: string; image: string }>;
};
export type BuildState = "queued" | "running" | "succeeded" | "failed";
export type BuildPhase =
| "queued"
| "creating"
| "starting"
| "running"
| "done";
export type BuildStatus = {
version: typeof BUILD_PROTOCOL_VERSION;
id: string;
state: BuildState;
/** Optional lifecycle detail; absent on older persisted builds and servers. */
phase?: BuildPhase;
createdAt: string;
startedAt?: string;
finishedAt?: string;
digest?: Sha256Digest;
error?: string;
};
export type BuildEvent =
| { type: "status"; status: BuildStatus }
| { type: "log"; id: string; sequence: number; message: string };
export function isSha256Digest(value: unknown): value is Sha256Digest {
return typeof value === "string" && /^sha256:[a-f0-9]{64}$/.test(value);
}
export function validateBuildpackUri(value: unknown): asserts value is string {
if (typeof value !== "string" || value.length > 4096 || /[\s\\]/.test(value))
throw new Error("Invalid buildpack URI");
let url: URL;
try {
url = new URL(value);
} catch {
throw new Error("Invalid buildpack URI");
}
if (
url.protocol !== "https:" ||
url.hostname !== "github.com" ||
url.port ||
url.username ||
url.password ||
url.search ||
!/^\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/releases\/download\/[^/]+\/[^/]+\.cnb$/.test(
url.pathname,
) ||
(url.hash && !/^#sha256=[a-f0-9]{64}$/.test(url.hash))
)
throw new Error(
"Buildpack URI must be an HTTPS GitHub release .cnb URL (optional #sha256=<hex>)",
);
}
export function assertSha256Digest(
value: unknown,
): asserts value is Sha256Digest {
if (!isSha256Digest(value))
throw new Error(`Invalid SHA-256 digest: ${value}`);
}