Skip to content

Commit dc5511f

Browse files
committed
feat(cli): import synced secret env vars as secrets
1 parent d756d07 commit dc5511f

2 files changed

Lines changed: 87 additions & 13 deletions

File tree

packages/cli-v3/src/build/extensions.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,46 @@ function applyLayerToManifest(layer: BuildLayer, manifest: BuildManifest): Build
185185
}
186186
}
187187

188+
if (layer.deploy?.secretEnv) {
189+
$manifest.deploy.env ??= {};
190+
$manifest.deploy.sync ??= {};
191+
$manifest.deploy.sync.secretEnv ??= {};
192+
193+
for (const [key, value] of Object.entries(layer.deploy.secretEnv)) {
194+
if (!value) {
195+
continue;
196+
}
197+
198+
if (layer.deploy.override || $manifest.deploy.env[key] === undefined) {
199+
const existingValue = $manifest.deploy.env[key];
200+
201+
if (existingValue !== value) {
202+
$manifest.deploy.sync.secretEnv[key] = value;
203+
}
204+
}
205+
}
206+
}
207+
208+
if (layer.deploy?.secretParentEnv) {
209+
$manifest.deploy.env ??= {};
210+
$manifest.deploy.sync ??= {};
211+
$manifest.deploy.sync.secretParentEnv ??= {};
212+
213+
for (const [key, value] of Object.entries(layer.deploy.secretParentEnv)) {
214+
if (!value) {
215+
continue;
216+
}
217+
218+
if (layer.deploy.override || $manifest.deploy.env[key] === undefined) {
219+
const existingValue = $manifest.deploy.env[key];
220+
221+
if (existingValue !== value) {
222+
$manifest.deploy.sync.secretParentEnv[key] = value;
223+
}
224+
}
225+
}
226+
}
227+
188228
if (layer.dependencies) {
189229
const externals = $manifest.externals ?? [];
190230

packages/cli-v3/src/commands/deploy.ts

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -454,16 +454,24 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
454454
}
455455
}
456456

457+
const childVars = buildManifest.deploy.sync?.env ?? {};
458+
const parentVars = buildManifest.deploy.sync?.parentEnv ?? {};
459+
const secretChildVars = buildManifest.deploy.sync?.secretEnv ?? {};
460+
const secretParentVars = buildManifest.deploy.sync?.secretParentEnv ?? {};
461+
457462
const hasVarsToSync =
458-
Object.keys(buildManifest.deploy.sync?.env || {}).length > 0 ||
463+
Object.keys(childVars).length > 0 ||
464+
Object.keys(secretChildVars).length > 0 ||
459465
// Only sync parent variables if this is a branch environment
460-
(branch && Object.keys(buildManifest.deploy.sync?.parentEnv || {}).length > 0);
466+
(branch &&
467+
(Object.keys(parentVars).length > 0 || Object.keys(secretParentVars).length > 0));
461468

462469
if (hasVarsToSync) {
463-
const childVars = buildManifest.deploy.sync?.env ?? {};
464-
const parentVars = buildManifest.deploy.sync?.parentEnv ?? {};
465-
466-
const numberOfEnvVars = Object.keys(childVars).length + Object.keys(parentVars).length;
470+
const numberOfEnvVars =
471+
Object.keys(childVars).length +
472+
Object.keys(parentVars).length +
473+
Object.keys(secretChildVars).length +
474+
Object.keys(secretParentVars).length;
467475
const vars = numberOfEnvVars === 1 ? "var" : "vars";
468476

469477
if (!options.skipSyncEnvVars) {
@@ -475,7 +483,9 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
475483
resolvedConfig.project,
476484
options.env,
477485
childVars,
478-
parentVars
486+
parentVars,
487+
secretChildVars,
488+
secretParentVars
479489
);
480490

481491
if (!uploadResult.success) {
@@ -768,13 +778,37 @@ export async function syncEnvVarsWithServer(
768778
projectRef: string,
769779
environmentSlug: string,
770780
envVars: Record<string, string>,
771-
parentEnvVars?: Record<string, string>
781+
parentEnvVars?: Record<string, string>,
782+
secretEnvVars?: Record<string, string>,
783+
secretParentEnvVars?: Record<string, string>
772784
) {
773-
return await apiClient.importEnvVars(projectRef, environmentSlug, {
774-
variables: envVars,
775-
parentVariables: parentEnvVars,
776-
override: true,
777-
});
785+
const hasNonSecret =
786+
Object.keys(envVars).length > 0 || Object.keys(parentEnvVars ?? {}).length > 0;
787+
const hasSecret =
788+
Object.keys(secretEnvVars ?? {}).length > 0 ||
789+
Object.keys(secretParentEnvVars ?? {}).length > 0;
790+
791+
// The import API applies isSecret per call, so secret and non-secret vars go in separate calls.
792+
let result: Awaited<ReturnType<typeof apiClient.importEnvVars>> | undefined;
793+
794+
if (hasNonSecret) {
795+
result = await apiClient.importEnvVars(projectRef, environmentSlug, {
796+
variables: envVars,
797+
parentVariables: parentEnvVars,
798+
override: true,
799+
});
800+
}
801+
802+
if (hasSecret && (!result || result.success)) {
803+
result = await apiClient.importEnvVars(projectRef, environmentSlug, {
804+
variables: secretEnvVars ?? {},
805+
parentVariables: secretParentEnvVars,
806+
override: true,
807+
isSecret: true,
808+
});
809+
}
810+
811+
return result!;
778812
}
779813

780814
async function failDeploy(

0 commit comments

Comments
 (0)