Files
kuber/command/ci.ts
T

81 lines
2.0 KiB
TypeScript

import { defineCommand } from "citty";
import {
apiRequest,
type ApiRequestInit,
type ApiRequestOptions,
} from "../lib/api";
import { ctx } from "../lib/context";
import { resolveTrustIdentity } from "../lib/trust";
import { runUp } from "./up";
type CiRequest = <T>(
path: string,
init?: ApiRequestInit,
options?: ApiRequestOptions,
) => Promise<T>;
function requireApiKey(value: string | undefined): string {
const token = value?.trim();
if (!token)
throw new Error("KUBER_API_KEY or --api-key is required for kuber ci");
return token;
}
export function apiKeyRequest(token: string): CiRequest {
return (path, init = {}, options = {}) => {
const headers = new Headers(init.headers);
headers.set("authorization", `Bearer ${token}`);
return apiRequest(
path,
{ ...init, headers },
{ ...options, authenticated: false },
);
};
}
export async function runCi(
build: boolean,
grantTrust: boolean,
token: string,
request: CiRequest = apiKeyRequest(token),
): Promise<void> {
const { project, cwd } = ctx();
const trust = await resolveTrustIdentity(project, cwd);
if (grantTrust) {
await request(`/workspaces/${encodeURIComponent(project)}/trust`, {
method: "POST",
json: { fingerprint: trust.fingerprint },
});
}
await runUp(build, request, { trust: grantTrust ? trust : undefined });
}
export const ci = defineCommand({
meta: {
name: "ci",
description: "Deploy using an API key without a session",
},
args: {
apiKey: {
type: "string",
description: "API key (defaults to KUBER_API_KEY)",
},
trust: {
type: "boolean",
description: "Grant current directory trust before deploying",
},
build: {
type: "boolean",
default: true,
negativeDescription: "Resolve existing images without building",
},
},
async run({ args }) {
await runCi(
args.build,
Boolean(args.trust),
requireApiKey(args.apiKey ?? process.env.KUBER_API_KEY),
);
},
});