Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/fresh-bats-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"trigger.dev": minor
"@trigger.dev/build": minor
---

Added support for the secret flag on variables in the syncEnvVars extension
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export async function action({ params, request }: ActionFunctionArgs) {
variables: Object.entries(body.variables).map(([key, value]) => ({
key,
value,
isSecret: body.secrets?.[key] ?? false,
})),
lastUpdatedBy: body.source,
});
Expand All @@ -58,6 +59,7 @@ export async function action({ params, request }: ActionFunctionArgs) {
variables: Object.entries(body.parentVariables).map(([key, value]) => ({
key,
value,
isSecret: body.parentSecrets?.[key] ?? false,
})),
lastUpdatedBy: body.source,
});
Comment thread
julienvanbeveren marked this conversation as resolved.
Expand Down
26 changes: 23 additions & 3 deletions packages/build/src/extensions/core/syncEnvVars.ts
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Secrets data dropped in syncEnvVars: never stored in build manifest

The callSyncEnvVarsFn function correctly computes secrets and parentSecrets from user callbacks (lines 148-224), but the syncEnvVars function silently drops them when calling context.addLayer() at lines 117-124 — only env and parentEnv are passed in the deploy object. Additionally, the BuildLayer interface (packages/core/src/v3/build/extensions.ts:63-66) and the build manifest schema (packages/core/src/v3/schemas/build.ts:52-57) don't define secrets/parentSecrets fields, so there's no way to carry this data through the manifest pipeline. As a result, the entire "secret flag on variables" feature advertised by this PR is non-functional — isSecret will always resolve to false on the server side (body.secrets?.[key] ?? false).

(Refers to lines 117-124)

Prompt for agents
The secrets data computed in callSyncEnvVarsFn is dropped at line 117 because context.addLayer() only receives env and parentEnv. To fix this:

1. Add secrets and parentSecrets fields to BuildLayer.deploy in packages/core/src/v3/build/extensions.ts (the BuildLayer interface around line 63).
2. Add secrets and parentSecrets fields to the deploy.sync schema in packages/core/src/v3/schemas/build.ts (around line 52-57).
3. In packages/build/src/extensions/core/syncEnvVars.ts, pass result.secrets and result.parentSecrets through context.addLayer() in the deploy object.
4. In packages/cli-v3/src/build/extensions.ts, handle the new secrets/parentSecrets fields when processing layers (around lines 147-186) and store them in the manifest.
5. In packages/cli-v3/src/commands/deploy.ts, read the secrets from buildManifest.deploy.sync and pass them to syncEnvVarsWithServer (see BUG-0002).
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BuildContext, BuildExtension } from "@trigger.dev/core/v3/build";

export type SyncEnvVarsBody =
| Record<string, string>
| Array<{ name: string; value: string; isParentEnv?: boolean }>;
| Array<{ name: string; value: string; isParentEnv?: boolean; isSecret?: boolean }>;

export type SyncEnvVarsResult =
| SyncEnvVarsBody
Expand Down Expand Up @@ -151,9 +151,19 @@ async function callSyncEnvVarsFn(
environment: string,
branch: string | undefined,
context: BuildContext
): Promise<{ env: Record<string, string>; parentEnv?: Record<string, string> } | undefined> {
): Promise<{
env: Record<string, string>;
secrets?: Record<string, boolean>;
parentEnv?: Record<string, string>;
parentSecrets?: Record<string, boolean>;
} | undefined> {
if (syncEnvVarsFn && typeof syncEnvVarsFn === "function") {
let resolvedEnvVars: { env: Record<string, string>; parentEnv?: Record<string, string> } = {
let resolvedEnvVars: {
env: Record<string, string>;
secrets?: Record<string, boolean>;
parentEnv?: Record<string, string>;
parentSecrets?: Record<string, boolean>;
} = {
env: {},
};
let result;
Expand Down Expand Up @@ -186,10 +196,20 @@ async function callSyncEnvVarsFn(
if (item.isParentEnv) {
if (!resolvedEnvVars.parentEnv) {
resolvedEnvVars.parentEnv = {};
resolvedEnvVars.parentSecrets = {};
}
resolvedEnvVars.parentEnv[item.name] = item.value;
if (item.isSecret && resolvedEnvVars.parentSecrets) {
resolvedEnvVars.parentSecrets[item.name] = true;
}
} else {
resolvedEnvVars.env[item.name] = item.value;
if (item.isSecret) {
if (!resolvedEnvVars.secrets) {
resolvedEnvVars.secrets = {};
}
resolvedEnvVars.secrets[item.name] = true;
}
}
}
}
Expand Down
24 changes: 12 additions & 12 deletions packages/cli-v3/src/commands/deploy.ts
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 syncEnvVarsWithServer called without secrets/parentSecrets arguments in deploy.ts

The syncEnvVarsWithServer function signature was updated to accept secrets and parentSecrets parameters (lines 768-769), but the call site at lines 472-478 only passes childVars and parentVars, omitting the new parameters. Even once the build manifest carries secrets data (see the related manifest schema issue), this call site still needs to be updated to pass them. The same issue exists in the other call site at packages/cli-v3/src/commands/workers/build.ts:272-278 where the function signature wasn't even updated.

(Refers to lines 472-478)

Prompt for agents
The call to syncEnvVarsWithServer at line 472 needs to also pass the secrets and parentSecrets from the build manifest. Once the manifest schema is updated to carry secrets data (see the related BuildLayer/manifest issue), read secrets and parentSecrets from buildManifest.deploy.sync and pass them as the 6th and 7th arguments.

Also update the duplicate call site in packages/cli-v3/src/commands/workers/build.ts around line 272 and its local syncEnvVarsWithServer function at line 448 to accept and forward secrets/parentSecrets as well.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Original file line number Diff line number Diff line change
Expand Up @@ -501,9 +501,8 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
const version = deployment.version;

const rawDeploymentLink = `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project}/deployments/${deployment.shortCode}`;
const rawTestLink = `${authorization.dashboardUrl}/projects/v3/${
resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`;
const rawTestLink = `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`;

const deploymentLink = cliLink("View deployment", rawDeploymentLink);
const testLink = cliLink("Test tasks", rawTestLink);
Expand Down Expand Up @@ -745,18 +744,16 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
TRIGGER_VERSION: version,
TRIGGER_DEPLOYMENT_SHORT_CODE: deployment.shortCode,
TRIGGER_DEPLOYMENT_URL: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project}/deployments/${deployment.shortCode}`,
TRIGGER_TEST_URL: `${authorization.dashboardUrl}/projects/v3/${
resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
TRIGGER_TEST_URL: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
},
outputs: {
deploymentVersion: version,
workerVersion: version,
deploymentShortCode: deployment.shortCode,
deploymentUrl: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project}/deployments/${deployment.shortCode}`,
testUrl: `${authorization.dashboardUrl}/projects/v3/${
resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
testUrl: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
needsPromotion: options.skipPromotion ? "true" : "false",
},
});
Expand All @@ -767,11 +764,15 @@ export async function syncEnvVarsWithServer(
projectRef: string,
environmentSlug: string,
envVars: Record<string, string>,
parentEnvVars?: Record<string, string>
parentEnvVars?: Record<string, string>,
secrets?: Record<string, boolean>,
parentSecrets?: Record<string, boolean>
) {
return await apiClient.importEnvVars(projectRef, environmentSlug, {
variables: envVars,
parentVariables: parentEnvVars,
secrets,
parentSecrets,
override: true,
});
}
Expand Down Expand Up @@ -799,8 +800,7 @@ async function failDeploy(
checkLogsForErrors(logs);

outro(
`${chalkError(`${prefix}:`)} ${
error.message
`${chalkError(`${prefix}:`)} ${error.message
}. Full build logs have been saved to ${logPath}`
);

Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/v3/apiClient/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ export interface ImportEnvironmentVariablesParams {
* To specify the variables, you can pass them in as a record of key-value pairs. e.g. `{ "key1": "value1", "key2": "value2" }`
*/
variables: Record<string, string>;
/**
* Optional parent variables to be imported. These are used when dealing with branch environments.
*/
parentVariables?: Record<string, string>;
/**
* Optional map of which variables should be marked as secrets. The keys should match the keys in `variables`.
*/
secrets?: Record<string, boolean>;
/**
* Optional map of which parent variables should be marked as secrets. The keys should match the keys in `parentVariables`.
*/
parentSecrets?: Record<string, boolean>;
Comment thread
julienvanbeveren marked this conversation as resolved.
override?: boolean;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/v3/schemas/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,8 @@ export type UpdateEnvironmentVariableRequestBody = z.infer<
export const ImportEnvironmentVariablesRequestBody = z.object({
variables: z.record(z.string()),
parentVariables: z.record(z.string()).optional(),
secrets: z.record(z.boolean()).optional(),
parentSecrets: z.record(z.boolean()).optional(),
override: z.boolean().optional(),
source: z
.discriminatedUnion("type", [
Expand Down