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:
Dan
2024-10-23 13:01:30 +01:00
committed by GitHub
parent 90514a73bb
commit 982906cbad
3 changed files with 89 additions and 0 deletions
+5
View File
@@ -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.
+1
View File
@@ -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);
},
};
}