Vercel sync env vars extension (#1425)
* Added vercelSyncEnvVars extension * Updated extension and added try catch * VercelEnvironment fix Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Added changeset * Moved vercelSynvEnvVars to code and updated core.ts * Fixed import * removed type --------- Co-authored-by: Matt Aitken <matt@mattaitken.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@trigger.dev/build": patch
|
||||
---
|
||||
|
||||
Added a Vercel sync env vars extension. Given a Vercel projectId and access token it will sync Vercel env vars when deploying Trigger.dev tasks.
|
||||
@@ -3,3 +3,4 @@ export * from "./core/additionalPackages.js";
|
||||
export * from "./core/syncEnvVars.js";
|
||||
export * from "./core/aptGet.js";
|
||||
export * from "./core/ffmpeg.js";
|
||||
export * from "./core/vercelSyncEnvVars.js";
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { BuildExtension } from "@trigger.dev/core/v3/build";
|
||||
import { syncEnvVars } from "../core.js";
|
||||
|
||||
export function syncVercelEnvVars(
|
||||
options?: { projectId?: string; vercelAccessToken?: string },
|
||||
): BuildExtension {
|
||||
const sync = syncEnvVars(async (ctx) => {
|
||||
const projectId = options?.projectId ?? process.env.VERCEL_PROJECT_ID ??
|
||||
ctx.env.VERCEL_PROJECT_ID;
|
||||
const vercelAccessToken = options?.vercelAccessToken ??
|
||||
process.env.VERCEL_ACCESS_TOKEN ??
|
||||
ctx.env.VERCEL_ACCESS_TOKEN;
|
||||
|
||||
if (!projectId) {
|
||||
throw new Error(
|
||||
"vercelSyncEnvVars: you did not pass in a projectId or set the VERCEL_PROJECT_ID env var.",
|
||||
);
|
||||
}
|
||||
|
||||
if (!vercelAccessToken) {
|
||||
throw new Error(
|
||||
"vercelSyncEnvVars: you did not pass in a vercelAccessToken or set the VERCEL_ACCESS_TOKEN env var.",
|
||||
);
|
||||
}
|
||||
|
||||
const environmentMap = {
|
||||
prod: "production",
|
||||
staging: "preview",
|
||||
dev: "development",
|
||||
} as const;
|
||||
|
||||
const vercelEnvironment =
|
||||
environmentMap[ctx.environment as keyof typeof environmentMap];
|
||||
|
||||
if (!vercelEnvironment) {
|
||||
throw new Error(
|
||||
`Invalid environment '${ctx.environment}'. Expected 'prod', 'staging', or 'dev'.`,
|
||||
);
|
||||
}
|
||||
const vercelApiUrl =
|
||||
`https://api.vercel.com/v8/projects/${projectId}/env?decrypt=true`;
|
||||
|
||||
try {
|
||||
const response = await fetch(vercelApiUrl, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${vercelAccessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
const filteredEnvs = data.envs
|
||||
.filter(
|
||||
(env: { type: string; value: string; target: string[] }) =>
|
||||
env.value &&
|
||||
env.target.includes(vercelEnvironment),
|
||||
)
|
||||
.map((env: { key: string; value: string }) => ({
|
||||
name: env.key,
|
||||
value: env.value,
|
||||
}));
|
||||
|
||||
return filteredEnvs;
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"Error fetching or processing Vercel environment variables:",
|
||||
error,
|
||||
);
|
||||
throw error; // Re-throw the error to be handled by the caller
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
name: "SyncVercelEnvVarsExtension",
|
||||
async onBuildComplete(context, manifest) {
|
||||
await sync.onBuildComplete?.(context, manifest);
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user