Skip to content

Commit

Permalink
[PDE-5660] feat(cli): Require --force flag when updating production…
Browse files Browse the repository at this point in the history
… integration version environment variables via `env:set` or `env:unset` (#942)

* initial commit

* headers are always strings

* review suggestions
  • Loading branch information
rnegron authored Jan 14, 2025
1 parent 28e4756 commit 44d599e
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 18 deletions.
2 changes: 2 additions & 0 deletions packages/cli/docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ resources convert and relate to different actions.
* `key-value pairs...` | The key-value pairs to set. Keys are case-insensitive. Each pair should be space separated and pairs should be separated by an `=`. For example: `A=123 B=456`

**Flags**
* `-f, --force` | Force the update of environment variables regardless if the app version is production or not. Use with caution.
* `-d, --debug` | Show extra debugging output.

**Examples**
Expand All @@ -242,6 +243,7 @@ resources convert and relate to different actions.
* `keys...` | The keys to unset. Keys are case-insensitive.

**Flags**
* `-f, --force` | Force the update of environment variables regardless if the app version is production or not. Use with caution.
* `-d, --debug` | Show extra debugging output.

**Examples**
Expand Down
39 changes: 28 additions & 11 deletions packages/cli/src/oclif/commands/env/set.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { Args } = require('@oclif/core');
const { Args, Flags } = require('@oclif/core');
const { cyan } = require('colors/safe');
const { omit } = require('lodash');

Expand Down Expand Up @@ -45,21 +45,30 @@ class SetEnvCommand extends BaseCommand {
}

const url = `/apps/${app.id}/versions/${version}/multi-environment`;
const requestOptions = {
body: payload,
method: 'POST',
};

if (this.flags.force) {
requestOptions.extraHeaders = {
'X-Force-Env-Var-Update': 'true',
};
}

try {
// currently, this returns nothing
await callAPI(
url,
{
body: payload,
method: 'POST',
},
true,
);
await callAPI(url, requestOptions, true);

this.log(successMessage(version));
this.logJSON(payload);
} catch (e) {
if (e.statusCode === 409) {
this.error(
`App version ${version} is the production version. Are you sure you want to set potentially live environment variables?` +
` If so, run this command again with the --force flag.`,
);
}

// comes back as json: { errors: [ 'The following keys failed to update: 3QER, 4WER' ] },
const failedKeys = e.json.errors[0].split('update: ')[1].split(', ');
const successfulResult = omit(payload, failedKeys);
Expand All @@ -85,7 +94,15 @@ SetEnvCommand.args = {
'The key-value pairs to set. Keys are case-insensitive. Each pair should be space separated and pairs should be separated by an `=`. For example: `A=123 B=456`',
}),
};
SetEnvCommand.flags = buildFlags();
SetEnvCommand.flags = buildFlags({
commandFlags: {
force: Flags.boolean({
char: 'f',
description:
'Force the update of environment variables regardless if the app version is production or not. Use with caution.',
}),
},
});
SetEnvCommand.description = `Set environment variables for a version.`;
SetEnvCommand.examples = [`zapier env:set 1.2.3 SECRET=12345 OTHER=4321`];
SetEnvCommand.strict = false;
Expand Down
38 changes: 31 additions & 7 deletions packages/cli/src/oclif/commands/env/unset.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { Args } = require('@oclif/core');
const { Args, Flags } = require('@oclif/core');
const { cyan } = require('colors/safe');

const BaseCommand = require('../../ZapierBaseCommand');
Expand Down Expand Up @@ -42,13 +42,29 @@ class UnsetEnvCommand extends BaseCommand {
}

const url = `/apps/${app.id}/versions/${version}/multi-environment`;

// currently, this returns nothing
// also, no need to cath errors here, since invalid keys don't get tripped over if the env var didn't exist in the first place
await callAPI(url, {
const requestOptions = {
body: payload,
method: 'POST',
});
};

if (this.flags.force) {
requestOptions.extraHeaders = {
'X-Force-Env-Var-Update': 'true',
};
}

try {
await callAPI(url, requestOptions);
} catch (e) {
if (e.statusCode === 409) {
this.error(
`App version ${version} is the production version. Are you sure you want to unset potentially live environment variables?` +
` If so, run this command again with the --force flag.`,
);
} else {
throw e;
}
}

this.log(successMessage(version));
this.logJSON(keysToUnset);
Expand All @@ -64,7 +80,15 @@ UnsetEnvCommand.args = {
description: 'The keys to unset. Keys are case-insensitive.',
}),
};
UnsetEnvCommand.flags = buildFlags();
UnsetEnvCommand.flags = buildFlags({
commandFlags: {
force: Flags.boolean({
char: 'f',
description:
'Force the update of environment variables regardless if the app version is production or not. Use with caution.',
}),
},
});
UnsetEnvCommand.description = `Unset environment variables for a version.`;
UnsetEnvCommand.examples = [`zapier env:unset 1.2.3 SECRET OTHER`];
UnsetEnvCommand.strict = false;
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/utils/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const callAPI = async (
method: options.method || 'GET',
body: options.body ? JSON.stringify(options.body) : null,
headers: {
...options.extraHeaders, // extra headers first so they don't override defaults
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'User-Agent': `${constants.PACKAGE_NAME}/${constants.PACKAGE_VERSION}`,
Expand Down

0 comments on commit 44d599e

Please sign in to comment.