Skip to content

Commit 422485f

Browse files
committed
Support pushing to existing secret and sensitive variables
1 parent 1c964d2 commit 422485f

File tree

2 files changed

+45
-24
lines changed

2 files changed

+45
-24
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This is the log of notable changes to EAS CLI and related packages.
1515
- Remove random branch name generation for --auto branch name non-vcs fallback. ([#2747](https://github.com/expo/eas-cli/pull/2747) by [@wschurman](https://github.com/wschurman))
1616
- Upgrade @expo/multipart-body-parser. ([#2751](https://github.com/expo/eas-cli/pull/2751) by [@wschurman](https://github.com/wschurman))
1717
- Pass env var flag to worker deployments. ([#2763](https://github.com/expo/eas-cli/pull/2763) by [@kadikraman](https://github.com/kadikraman))
18+
- Support pushing existing secret and sensitive environment variables. ([#2765](https://github.com/expo/eas-cli/pull/2765) by [@khamilowicz](https://github.com/khamilowicz))
1819

1920
### 🧹 Chores
2021

packages/eas-cli/src/commands/env/push.ts

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
import { EnvironmentVariablesQuery } from '../../graphql/queries/EnvironmentVariablesQuery';
1919
import Log from '../../log';
2020
import { confirmAsync, promptAsync } from '../../prompts';
21+
import uniq from '../../utils/expodash/uniq';
2122
import { promptVariableEnvironmentAsync } from '../../utils/prompts';
2223
import { isEnvironment } from '../../utils/variableUtils';
2324

@@ -32,6 +33,10 @@ export default class EnvPush extends EasCommand {
3233

3334
static override flags = {
3435
...EASMultiEnvironmentFlag,
36+
force: Flags.boolean({
37+
description: 'Overwrite existing variables without prompting',
38+
default: false,
39+
}),
3540
path: Flags.string({
3641
description: 'Path to the input `.env` file',
3742
default: '.env.local',
@@ -50,7 +55,7 @@ export default class EnvPush extends EasCommand {
5055
async runAsync(): Promise<void> {
5156
const { args, flags } = await this.parse(EnvPush);
5257

53-
let { environment: environments, path: envPath } = this.parseFlagsAndArgs(flags, args);
58+
let { environment: environments, path: envPath, force } = this.parseFlagsAndArgs(flags, args);
5459

5560
const {
5661
projectId,
@@ -59,7 +64,7 @@ export default class EnvPush extends EasCommand {
5964
nonInteractive: false,
6065
});
6166

62-
if (!environments) {
67+
if (!environments?.length) {
6368
environments = await promptVariableEnvironmentAsync({
6469
nonInteractive: false,
6570
multiple: true,
@@ -101,6 +106,10 @@ export default class EnvPush extends EasCommand {
101106
variable => variable.scope === EnvironmentVariableScope.Shared
102107
);
103108

109+
let variablesToOverwrite: string[] = existingDifferentVariables.map(
110+
variable => variable.name
111+
);
112+
104113
if (existingDifferentSharedVariables.length > 0) {
105114
const existingDifferentSharedVariablesNames = existingDifferentSharedVariables.map(
106115
variable => variable.name
@@ -113,7 +122,7 @@ export default class EnvPush extends EasCommand {
113122
throw new Error('Account-wide variables cannot be overwritten by eas env:push command');
114123
}
115124

116-
if (existingDifferentVariables.length > 0) {
125+
if (existingDifferentVariables.length > 0 && !force) {
117126
Log.warn(`Some variables already exist in the ${displayedEnvironment} environment.`);
118127
const variableNames = existingDifferentVariables.map(variable => variable.name);
119128

@@ -128,15 +137,11 @@ export default class EnvPush extends EasCommand {
128137
message: confirmationMessage,
129138
});
130139

131-
let variablesToOverwrite: string[] = [];
132-
133140
if (!confirm && existingDifferentVariables.length === 0) {
134141
throw new Error('No new variables to push.');
135142
}
136143

137-
if (confirm) {
138-
variablesToOverwrite = existingDifferentVariables.map(variable => variable.name);
139-
} else {
144+
if (!confirm) {
140145
const promptResult = await promptAsync({
141146
type: 'multiselect',
142147
name: 'variablesToOverwrite',
@@ -152,28 +157,35 @@ export default class EnvPush extends EasCommand {
152157
});
153158
variablesToOverwrite = promptResult.variablesToOverwrite;
154159
}
160+
}
155161

156-
for (const existingVariable of existingVariables) {
157-
const name = existingVariable.name;
158-
if (variablesToOverwrite.includes(name)) {
159-
updateVariables[name]['overwrite'] = true;
160-
} else {
161-
delete updateVariables[name];
162+
for (const existingVariable of existingVariables) {
163+
const { name } = existingVariable;
164+
if (variablesToOverwrite.includes(name)) {
165+
updateVariables[name]['overwrite'] = true;
166+
updateVariables[name]['environments'] = uniq([
167+
...environments,
168+
...(existingVariable.environments ?? []),
169+
]);
170+
if (existingVariable.visibility) {
171+
updateVariables[name]['visibility'] = existingVariable.visibility;
162172
}
173+
} else {
174+
delete updateVariables[name];
163175
}
164176
}
165177

166-
// Check if any of the sensitive variables already exist in the environment. Prompt the user to overwrite them.
178+
// Check if any of the secret variables already exist in the environment. Prompt the user to overwrite them.
167179
const existingSensitiveVariables = existingVariables.filter(
168180
variable => variable.visibility !== EnvironmentVariableVisibility.Public
169181
);
170182

171-
if (existingSensitiveVariables.length > 0) {
183+
if (existingSensitiveVariables.length > 0 && !force) {
172184
const existingSensitiveVariablesNames = existingSensitiveVariables.map(
173185
variable => `- ${variable.name}`
174186
);
175187
const confirm = await confirmAsync({
176-
message: `You are about to overwrite sensitive variables.\n${existingSensitiveVariablesNames.join(
188+
message: `You are about to overwrite secret variables.\n${existingSensitiveVariablesNames.join(
177189
'\n'
178190
)}\n Do you want to continue?`,
179191
});
@@ -199,20 +211,28 @@ export default class EnvPush extends EasCommand {
199211
}
200212

201213
parseFlagsAndArgs(
202-
flags: { path: string; environment: EnvironmentVariableEnvironment[] | undefined },
214+
flags: {
215+
path: string;
216+
environment: EnvironmentVariableEnvironment[] | undefined;
217+
force: boolean;
218+
},
203219
{ environment }: Record<string, string>
204-
): { environment?: EnvironmentVariableEnvironment[]; path: string } {
205-
if (environment && !isEnvironment(environment.toUpperCase())) {
220+
): { environment?: EnvironmentVariableEnvironment[]; path: string; force: boolean } {
221+
const environments = [...(flags.environment ?? []), environment]
222+
.filter(Boolean)
223+
.map(e => e.toUpperCase());
224+
225+
if (environments.some(environment => !isEnvironment(environment))) {
206226
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
207227
}
208228

209-
const environments =
210-
flags.environment ??
211-
(environment ? [environment.toUpperCase() as EnvironmentVariableEnvironment] : undefined);
229+
if (environments.length === 0 && flags.force) {
230+
throw new Error('At least one environment must be specified.');
231+
}
212232

213233
return {
214234
...flags,
215-
environment: environments,
235+
environment: environments as EnvironmentVariableEnvironment[],
216236
};
217237
}
218238

0 commit comments

Comments
 (0)