Skip to content

Commit 4bfb0cc

Browse files
authored
Merge pull request #62 from appcircleio/feature/be-6106-upload
#BE-6106 Upload Environment Variables as a JSON File
2 parents c51cdd3 + 74dea3c commit 4bfb0cc

8 files changed

Lines changed: 250 additions & 13 deletions

File tree

docs/build/variable/group/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ appcircle build variable group [command] [options]
1616

1717
- [`list`](list.md)
1818
- [`create`](create.md)
19+
- [`upload`](upload.md)
1920

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# `appcircle build variable group upload`
2+
3+
Upload environment variables from JSON file to a variable group.
4+
5+
```plaintext
6+
appcircle build variable group upload [options]
7+
```
8+
9+
## Examples
10+
11+
```plaintext
12+
$ appcircle build variable group upload --variableGroupId "Variable Group ID" --filePath "/path/to/variables.json"
13+
```
14+
15+
## Options
16+
17+
```plaintext
18+
--variableGroupId <uuid> Variable Group ID
19+
--filePath <string> JSON file path
20+
```
21+
22+
## Options inherited from parent commands
23+
24+
```plaintext
25+
--help Show help for command
26+
```
27+
28+
## JSON File Format
29+
30+
The JSON file should be in the following format:
31+
32+
```json
33+
[
34+
{
35+
"key": "VARIABLE_NAME",
36+
"value": "variable_value",
37+
"isSecret": false,
38+
"isFile": false,
39+
"id": "VARIABLE_NAME"
40+
},
41+
...
42+
]
43+
```

docs/publish/variable/group/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ appcircle publish profile variable group [command] [options]
1616

1717
- [`list`](list.md)
1818
- [`view`](view.md)
19+
- [`upload`](upload.md)
1920
- [`download`](download.md)
2021

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# `appcircle publish variable group upload`
2+
3+
Upload publish environment variables from JSON file to a variable group.
4+
5+
```plaintext
6+
appcircle publish variable group upload [options]
7+
```
8+
9+
## Examples
10+
11+
```plaintext
12+
$ appcircle publish variable group upload --publishVariableGroupId "Variable Group ID" --filePath "/path/to/variables.json"
13+
```
14+
15+
## Options
16+
17+
```plaintext
18+
--publishVariableGroupId <uuid> Variable Group ID
19+
--filePath <string> JSON file path
20+
```
21+
22+
## Options inherited from parent commands
23+
24+
```plaintext
25+
--help Show help for command
26+
```
27+
28+
## JSON File Format
29+
30+
The JSON file should be in the following format:
31+
32+
```json
33+
[
34+
{
35+
"key": "VARIABLE_NAME",
36+
"value": "variable_value",
37+
"isSecret": false,
38+
"isFile": false,
39+
"id": "VARIABLE_NAME"
40+
},
41+
...
42+
]
43+
```

src/core/command-runner.ts

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
createEnvironmentVariableGroup,
3535
getEnvironmentVariables,
3636
createEnvironmentVariable,
37+
uploadEnvironmentVariablesFromFile,
3738
getEnterpriseProfiles,
3839
getEnterpriseAppVersions,
3940
publishEnterpriseAppVersion,
@@ -68,6 +69,7 @@ import {
6869
getPublishProfileDetailById,
6970
getPublishVariableGroups,
7071
getPublishVariableListByGroupId,
72+
uploadPublishEnvironmentVariablesFromFile,
7173
deletePublishProfile,
7274
renamePublishProfile,
7375
getAppVersions,
@@ -453,6 +455,39 @@ const handlePublishCommand = async (command: ProgramCommand, params: any) => {
453455
fullCommandName: command.fullCommandName,
454456
data: variables.variables,
455457
});
458+
} else if (command.fullCommandName === `${PROGRAM_NAME}-publish-variable-group-upload`) {
459+
const spinner = createOra('Loading environment variables from JSON file...').start();
460+
try {
461+
if (!params.filePath) {
462+
spinner.fail('JSON file path is required');
463+
process.exit(1);
464+
}
465+
466+
const expandedPath = path.resolve(params.filePath.replace('~', os.homedir()));
467+
468+
if (!fs.existsSync(expandedPath)) {
469+
spinner.fail('File not found');
470+
process.exit(1);
471+
}
472+
473+
try {
474+
const fileContent = fs.readFileSync(expandedPath, 'utf8');
475+
JSON.parse(fileContent);
476+
} catch (err) {
477+
spinner.fail('Invalid file');
478+
process.exit(1);
479+
}
480+
481+
params.filePath = expandedPath;
482+
483+
const responseData = await uploadPublishEnvironmentVariablesFromFile(params as any);
484+
if (responseData) {
485+
spinner.succeed('Environment variables uploaded successfully');
486+
}
487+
} catch (e) {
488+
spinner.fail('Failed to upload environment variables');
489+
throw e;
490+
}
456491
} else if (command.fullCommandName === `${PROGRAM_NAME}-publish-variable-group-download`) {
457492
const spinner = createOra('Downloading publish environment variables...').start();
458493
try {
@@ -514,15 +549,15 @@ const handlePublishCommand = async (command: ProgramCommand, params: any) => {
514549
fullCommandName: command.fullCommandName,
515550
data: appVersions,
516551
});
517-
}else if(command.fullCommandName === `${PROGRAM_NAME}-publish-profile-version-view`){
552+
} else if(command.fullCommandName === `${PROGRAM_NAME}-publish-profile-version-view`){
518553
const spinner = createOra('Fetching...').start();
519554
const appVersion = await getAppVersionDetail(params);
520555
spinner.succeed();
521556
commandWriter(CommandTypes.PUBLISH, {
522557
fullCommandName: command.fullCommandName,
523558
data: appVersion,
524559
});
525-
}else if(command.fullCommandName === `${PROGRAM_NAME}-publish-profile-version-update-release-note`){
560+
} else if(command.fullCommandName === `${PROGRAM_NAME}-publish-profile-version-update-release-note`){
526561
const spinner = createOra('Try to update relase note of the app version').start();
527562
try{
528563
await setAppVersionReleaseNote(params);
@@ -531,15 +566,15 @@ const handlePublishCommand = async (command: ProgramCommand, params: any) => {
531566
spinner.fail('Update failed');
532567
throw e;
533568
}
534-
}else if (command.fullCommandName === `${PROGRAM_NAME}-publish-active-list`){
569+
} else if (command.fullCommandName === `${PROGRAM_NAME}-publish-active-list`){
535570
const spinner = createOra('Fetching...').start();
536571
const responseData = await getActivePublishes();
537572
spinner.succeed();
538573
commandWriter(CommandTypes.PUBLISH, {
539574
fullCommandName: command.fullCommandName,
540575
data: responseData,
541576
});
542-
}else if (command.fullCommandName === `${PROGRAM_NAME}-publish-view`){
577+
} else if (command.fullCommandName === `${PROGRAM_NAME}-publish-view`){
543578
const spinner = createOra('Fetching...').start();
544579
const responseData = await getPublisDetailById(params);
545580
spinner.succeed();
@@ -669,6 +704,41 @@ const handleBuildCommand = async (command: ProgramCommand, params:any) => {
669704
fullCommandName: command.fullCommandName,
670705
data: { ...responseData, name: params.name },
671706
});
707+
} else if(command.fullCommandName === `${PROGRAM_NAME}-build-variable-group-upload`){
708+
const spinner = createOra('Loading environment variables from JSON file...').start();
709+
try {
710+
if (!params.filePath) {
711+
spinner.fail('JSON file path is required');
712+
process.exit(1);
713+
}
714+
715+
const expandedPath = path.resolve(params.filePath.replace('~', os.homedir()));
716+
717+
if (!fs.existsSync(expandedPath)) {
718+
spinner.fail('File not found');
719+
process.exit(1);
720+
}
721+
722+
try {
723+
const fileContent = fs.readFileSync(expandedPath, 'utf8');
724+
JSON.parse(fileContent);
725+
} catch (err) {
726+
spinner.fail('Invalid file');
727+
process.exit(1);
728+
}
729+
730+
params.filePath = expandedPath;
731+
732+
const responseData = await uploadEnvironmentVariablesFromFile(params as any);
733+
spinner.succeed('Environment variables uploaded successfully');
734+
commandWriter(CommandTypes.BUILD, {
735+
fullCommandName: command.fullCommandName,
736+
data: responseData,
737+
});
738+
} catch (e) {
739+
spinner.fail('Failed to upload environment variables');
740+
throw e;
741+
}
672742
} else if(command.fullCommandName === `${PROGRAM_NAME}-build-variable-view`){
673743
const spinner = createOra('Fetching...').start();
674744
const responseData = await getEnvironmentVariables(params);

src/core/commands.ts

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,27 @@ export const Commands: CommandType[] = [
476476
valueType: 'string',
477477
},
478478
],
479+
},
480+
{
481+
command: "upload",
482+
description: 'Upload environment variables from JSON file',
483+
longDescription: 'Upload environment variables from a JSON file to a variable group',
484+
params: [
485+
{
486+
name: 'variableGroupId',
487+
description: 'Variable Group ID',
488+
type: CommandParameterTypes.SELECT,
489+
valueType: 'uuid',
490+
required: true
491+
},
492+
{
493+
name: 'filePath',
494+
description: 'JSON file path',
495+
type: CommandParameterTypes.STRING,
496+
valueType: 'path',
497+
required: true
498+
}
499+
],
479500
}
480501
]
481502
},
@@ -1483,9 +1504,9 @@ export const Commands: CommandType[] = [
14831504
],
14841505
},
14851506
{
1486-
command: "download",
1487-
description: 'Download publish environment variables as JSON',
1488-
longDescription: 'Download publish environment variables as JSON file',
1507+
command: "upload",
1508+
description: 'Upload publish environment variables from JSON file',
1509+
longDescription: 'Upload publish environment variables from a JSON file to a variable group',
14891510
params: [
14901511
{
14911512
name: 'publishVariableGroupId',
@@ -1495,15 +1516,34 @@ export const Commands: CommandType[] = [
14951516
required: true
14961517
},
14971518
{
1498-
name: 'path',
1499-
description: '[OPTIONAL] The path for JSON file to be downloaded',
1500-
longDescription:'[OPTIONAL] The path for JSON file to be downloaded (Defaults to the current directory)',
1519+
name: 'filePath',
1520+
description: 'JSON file path',
15011521
type: CommandParameterTypes.STRING,
1502-
valueType: 'string',
1503-
required: false,
1522+
valueType: 'path',
1523+
required: true
15041524
}
15051525
],
1526+
},
1527+
{
1528+
command: "download",
1529+
description: 'Download environment variables as JSON',
1530+
params: [
1531+
{
1532+
name: 'variableGroupId',
1533+
description: 'Variable Groups ID',
1534+
type: CommandParameterTypes.SELECT,
1535+
valueType: 'uuid',
1536+
},
1537+
{
1538+
name: 'path',
1539+
description: '[OPTIONAL] The path for JSON file to be downloaded',
1540+
longDescription:'[OPTIONAL] The path for JSON file to be downloaded (Defaults to the current directory)',
1541+
type: CommandParameterTypes.STRING,
1542+
valueType: 'string',
1543+
required: false,
15061544
}
1545+
],
1546+
},
15071547
]
15081548
}
15091549
]

src/services/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,26 @@ export async function getEnvironmentVariables(options: OptionsType<{ variableGro
256256
return environmentVariables.data;
257257
}
258258

259+
export async function uploadEnvironmentVariablesFromFile(options: OptionsType<{ variableGroupId: string; filePath: string }>) {
260+
const form = new FormData();
261+
form.append('variableGroupId', options.variableGroupId);
262+
form.append('envVariablesFile', fs.createReadStream(options.filePath));
263+
264+
const response = await appcircleApi.post(
265+
`build/v1/variable-groups/${options.variableGroupId}/upload-variables-file`,
266+
form,
267+
{
268+
maxContentLength: Infinity,
269+
maxBodyLength: Infinity,
270+
headers: {
271+
...getHeaders(),
272+
...form.getHeaders(),
273+
},
274+
}
275+
);
276+
return response.data;
277+
}
278+
259279
async function createTextEnvironmentVariable(options: OptionsType<{ variableGroupId: string; value: string; isSecret: boolean; key: string }>) {
260280
const response = await appcircleApi.post(
261281
`build/v1/variable-groups/${options.variableGroupId}/variables`,

src/services/publish.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import fs from 'fs';
32
import FormData from 'form-data';
43
import { ProgramError } from '../core/ProgramError';
@@ -224,4 +223,24 @@ export async function deletePublishProfile(options: OptionsType<{ platform: stri
224223
});
225224
return commitFileResponse.data;
226225
}
226+
227+
export async function uploadPublishEnvironmentVariablesFromFile(options: OptionsType<{ publishVariableGroupId: string; filePath: string }>) {
228+
const form = new FormData();
229+
form.append('variableGroupId', options.publishVariableGroupId);
230+
form.append('envVariablesFile', fs.createReadStream(options.filePath));
231+
232+
const response = await appcircleApi.post(
233+
`publish/v1/variable-groups/${options.publishVariableGroupId}/upload-variables-file`,
234+
form,
235+
{
236+
maxContentLength: Infinity,
237+
maxBodyLength: Infinity,
238+
headers: {
239+
...getHeaders(),
240+
...form.getHeaders(),
241+
},
242+
}
243+
);
244+
return response.data;
245+
}
227246

0 commit comments

Comments
 (0)