@contrail/cli 3.5.3 → 3.5.4-alpha.2a94b1c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -11
- package/dist/commands/workflow-templates/export.d.ts +3 -2
- package/dist/commands/workflow-templates/export.js +117 -30
- package/dist/commands/workflow-templates/load.d.ts +2 -0
- package/dist/commands/workflow-templates/load.js +63 -6
- package/dist/helpers/workflow-templates/helper.d.ts +1 -0
- package/dist/helpers/workflow-templates/helper.js +28 -3
- package/dist/interfaces.d.ts +1 -1
- package/oclif.manifest.json +30 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ $ npm install -g @contrail/cli
|
|
|
17
17
|
$ contrail COMMAND
|
|
18
18
|
running command...
|
|
19
19
|
$ contrail (--version)
|
|
20
|
-
@contrail/cli/3.5.
|
|
20
|
+
@contrail/cli/3.5.4-alpha.2a94b1c linux-x64 node-v24.18.0
|
|
21
21
|
$ contrail --help [COMMAND]
|
|
22
22
|
USAGE
|
|
23
23
|
$ contrail COMMAND
|
|
@@ -97,7 +97,7 @@ To get instructions on how to set up autocomplete for your shell, run `contrail
|
|
|
97
97
|
* [`contrail workflow-templates delete`](#contrail-workflow-templates-delete)
|
|
98
98
|
* [`contrail workflow-templates export`](#contrail-workflow-templates-export)
|
|
99
99
|
* [`contrail workflow-templates list`](#contrail-workflow-templates-list)
|
|
100
|
-
* [`contrail workflow-templates load FILELOCATION`](#contrail-workflow-templates-load-filelocation)
|
|
100
|
+
* [`contrail workflow-templates load [FILELOCATION]`](#contrail-workflow-templates-load-filelocation)
|
|
101
101
|
|
|
102
102
|
## `contrail app create`
|
|
103
103
|
|
|
@@ -1611,25 +1611,31 @@ EXAMPLES
|
|
|
1611
1611
|
|
|
1612
1612
|
## `contrail workflow-templates export`
|
|
1613
1613
|
|
|
1614
|
-
Export all workflows in the org.
|
|
1614
|
+
Export all workflows in the org. By default exports one file per app to the current directory.
|
|
1615
1615
|
|
|
1616
1616
|
```
|
|
1617
1617
|
USAGE
|
|
1618
|
-
$ contrail workflow-templates export [-l error|warn|info|debug] [-e true|false] [-f <value>] [
|
|
1618
|
+
$ contrail workflow-templates export [-l error|warn|info|debug] [-e true|false] [-f <value>] [-d <value>]
|
|
1619
|
+
[--overwrite]
|
|
1619
1620
|
|
|
1620
1621
|
FLAGS
|
|
1622
|
+
-d, --dir=<value> [default: .] Directory to write per-app workflow files
|
|
1621
1623
|
-e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
|
|
1622
1624
|
<options: true|false>
|
|
1623
|
-
-f, --outFile=<value>
|
|
1625
|
+
-f, --outFile=<value> Export all workflows to a single file at this path (overrides per-app export)
|
|
1624
1626
|
-l, --logLevel=<option> The Log Level
|
|
1625
1627
|
<options: error|warn|info|debug>
|
|
1626
1628
|
--overwrite Replaces existing files if they exist
|
|
1627
1629
|
|
|
1628
1630
|
DESCRIPTION
|
|
1629
|
-
Export all workflows in the org.
|
|
1631
|
+
Export all workflows in the org. By default exports one file per app to the current directory.
|
|
1630
1632
|
|
|
1631
1633
|
EXAMPLES
|
|
1632
1634
|
$ contrail workflow-templates export
|
|
1635
|
+
|
|
1636
|
+
$ contrail workflow-templates export --dir ./workflows
|
|
1637
|
+
|
|
1638
|
+
$ contrail workflow-templates export --outFile workflows.yml
|
|
1633
1639
|
```
|
|
1634
1640
|
|
|
1635
1641
|
## `contrail workflow-templates list`
|
|
@@ -1653,27 +1659,32 @@ EXAMPLES
|
|
|
1653
1659
|
$ contrail workflow-templates list
|
|
1654
1660
|
```
|
|
1655
1661
|
|
|
1656
|
-
## `contrail workflow-templates load FILELOCATION`
|
|
1662
|
+
## `contrail workflow-templates load [FILELOCATION]`
|
|
1657
1663
|
|
|
1658
|
-
|
|
1664
|
+
Load workflow templates from a file or scan a directory for per-app workflow files
|
|
1659
1665
|
|
|
1660
1666
|
```
|
|
1661
1667
|
USAGE
|
|
1662
|
-
$ contrail workflow-templates load FILELOCATION [-l error|warn|info|debug] [-e true|false]
|
|
1668
|
+
$ contrail workflow-templates load [FILELOCATION] [-l error|warn|info|debug] [-e true|false] [-d <value>]
|
|
1663
1669
|
|
|
1664
1670
|
ARGUMENTS
|
|
1665
|
-
FILELOCATION
|
|
1671
|
+
FILELOCATION A specific workflow template file to load
|
|
1666
1672
|
|
|
1667
1673
|
FLAGS
|
|
1674
|
+
-d, --dir=<value> [default: .] Directory to scan for workflow files when no file argument is given
|
|
1668
1675
|
-e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
|
|
1669
1676
|
<options: true|false>
|
|
1670
1677
|
-l, --logLevel=<option> The Log Level
|
|
1671
1678
|
<options: error|warn|info|debug>
|
|
1672
1679
|
|
|
1673
1680
|
DESCRIPTION
|
|
1674
|
-
|
|
1681
|
+
Load workflow templates from a file or scan a directory for per-app workflow files
|
|
1675
1682
|
|
|
1676
1683
|
EXAMPLES
|
|
1677
1684
|
$ contrail workflow-templates load <FILE_LOCATION>
|
|
1685
|
+
|
|
1686
|
+
$ contrail workflow-templates load
|
|
1687
|
+
|
|
1688
|
+
$ contrail workflow-templates load --dir ./workflows
|
|
1678
1689
|
```
|
|
1679
1690
|
<!-- commandsstop -->
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { BaseCommand } from '../../basecommand';
|
|
2
|
-
export declare const DEFAULT_FILE_LOCATION = "workflows.yml";
|
|
3
2
|
export default class ExportWorkflows extends BaseCommand {
|
|
4
3
|
static description: string;
|
|
5
4
|
static examples: string[];
|
|
6
5
|
static flags: {
|
|
7
6
|
outFile: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
7
|
+
dir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
8
8
|
overwrite: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
9
|
alwaysConfirmEnv: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
10
10
|
logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
11
11
|
};
|
|
12
12
|
run(): Promise<void>;
|
|
13
13
|
}
|
|
14
|
-
export declare function
|
|
14
|
+
export declare function exportWorkflowsByApp(outputDir: string, overwrite: boolean): Promise<void>;
|
|
15
|
+
export declare function exportWorkflowsToFile(fileLocation: string, overwrite: boolean): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.exportWorkflowsToFile = exports.exportWorkflowsByApp = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const path = tslib_1.__importStar(require("path"));
|
|
6
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
@@ -11,22 +11,29 @@ const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
|
|
|
11
11
|
const core_1 = require("@oclif/core");
|
|
12
12
|
const file_helpers_1 = require("../../helpers/file-helpers");
|
|
13
13
|
const event_workflow_templates_1 = require("../../api/event-workflow-templates");
|
|
14
|
+
const schedules_1 = require("../../api/schedules");
|
|
15
|
+
const apps_1 = require("../../api/apps");
|
|
14
16
|
const helper_1 = require("../../helpers/workflow-templates/helper");
|
|
15
17
|
const basecommand_1 = require("../../basecommand");
|
|
16
|
-
exports.DEFAULT_FILE_LOCATION = 'workflows.yml';
|
|
17
18
|
class ExportWorkflows extends basecommand_1.BaseCommand {
|
|
18
|
-
static description = 'Export all workflows in the org.';
|
|
19
|
+
static description = 'Export all workflows in the org. By default exports one file per app to the current directory.';
|
|
19
20
|
static examples = [
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
'$ contrail workflow-templates export',
|
|
22
|
+
'$ contrail workflow-templates export --dir ./workflows',
|
|
23
|
+
'$ contrail workflow-templates export --outFile workflows.yml',
|
|
22
24
|
];
|
|
23
25
|
static flags = {
|
|
24
26
|
...basecommand_1.BaseCommand.baseFlags,
|
|
25
27
|
outFile: core_1.Flags.string({
|
|
26
28
|
char: 'f',
|
|
27
|
-
description: '
|
|
29
|
+
description: 'Export all workflows to a single file at this path (overrides per-app export)',
|
|
28
30
|
required: false,
|
|
29
|
-
|
|
31
|
+
}),
|
|
32
|
+
dir: core_1.Flags.string({
|
|
33
|
+
char: 'd',
|
|
34
|
+
description: 'Directory to write per-app workflow files',
|
|
35
|
+
required: false,
|
|
36
|
+
default: '.',
|
|
30
37
|
}),
|
|
31
38
|
overwrite: core_1.Flags.boolean({
|
|
32
39
|
description: 'Replaces existing files if they exist',
|
|
@@ -38,7 +45,12 @@ class ExportWorkflows extends basecommand_1.BaseCommand {
|
|
|
38
45
|
try {
|
|
39
46
|
await (0, login_1.authUser)();
|
|
40
47
|
this.log(`${chalk_1.default.blue.bold('START')} Getting Workflows.`);
|
|
41
|
-
|
|
48
|
+
if (this.flags.outFile) {
|
|
49
|
+
await exportWorkflowsToFile(this.flags.outFile, this.flags.overwrite);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
await exportWorkflowsByApp(this.flags.dir ?? '.', this.flags.overwrite);
|
|
53
|
+
}
|
|
42
54
|
this.log(`${chalk_1.default.yellow.bold('WORKFLOWS')} Done`);
|
|
43
55
|
}
|
|
44
56
|
catch (e) {
|
|
@@ -49,31 +61,106 @@ class ExportWorkflows extends basecommand_1.BaseCommand {
|
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
63
|
exports.default = ExportWorkflows;
|
|
52
|
-
async function
|
|
53
|
-
const allWorkflowsInOrg = await
|
|
64
|
+
async function exportWorkflowsByApp(outputDir, overwrite) {
|
|
65
|
+
const [allWorkflowsInOrg, allSchedules, installedApps] = await Promise.all([
|
|
66
|
+
(0, event_workflow_templates_1.getExistingWorkflowTemplates)(),
|
|
67
|
+
(0, schedules_1.getExistingSchedules)(),
|
|
68
|
+
(0, apps_1.getInstalledApps)(),
|
|
69
|
+
]);
|
|
70
|
+
const appIdToIdentifier = new Map(installedApps
|
|
71
|
+
.filter((appOrg) => appOrg.appId && appOrg.app?.identifier)
|
|
72
|
+
.map((appOrg) => [appOrg.appId, appOrg.app.identifier]));
|
|
73
|
+
const workflowsByApp = new Map();
|
|
74
|
+
const unassigned = [];
|
|
75
|
+
for (const workflow of allWorkflowsInOrg) {
|
|
76
|
+
let appIdentifier = workflow.supportingAppId
|
|
77
|
+
? appIdToIdentifier.get(workflow.supportingAppId)
|
|
78
|
+
: undefined;
|
|
79
|
+
// If no supportingAppId, try to extract app identifier from workflow identifier
|
|
80
|
+
// Format: @{appIdentifier}@{randomId}:{workflowName}
|
|
81
|
+
if (!appIdentifier && workflow.identifier) {
|
|
82
|
+
const match = workflow.identifier.match(/^@([^@]+)@/);
|
|
83
|
+
if (match) {
|
|
84
|
+
// Keep the @ prefix in the appIdentifier
|
|
85
|
+
appIdentifier = `@${match[1]}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (appIdentifier) {
|
|
89
|
+
if (!workflowsByApp.has(appIdentifier)) {
|
|
90
|
+
workflowsByApp.set(appIdentifier, []);
|
|
91
|
+
}
|
|
92
|
+
const workflows = workflowsByApp.get(appIdentifier);
|
|
93
|
+
if (workflows) {
|
|
94
|
+
workflows.push(workflow);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
unassigned.push(workflow);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const resolvedDir = path.resolve(process.cwd(), outputDir);
|
|
102
|
+
for (const [appIdentifier, workflows] of workflowsByApp.entries()) {
|
|
103
|
+
const exportObj = { appIdentifier, workflows: [] };
|
|
104
|
+
for (const workflow of workflows) {
|
|
105
|
+
exportObj.workflows.push(await buildExportWorkflow(workflow, allSchedules, appIdentifier));
|
|
106
|
+
}
|
|
107
|
+
const safeAppIdentifier = appIdentifier.replace(/[\\/]/g, '-');
|
|
108
|
+
const filePath = path.join(resolvedDir, `workflows-${safeAppIdentifier}.yml`);
|
|
109
|
+
await writeYamlFile(exportObj, filePath, overwrite);
|
|
110
|
+
console.log(`${chalk_1.default.green('EXPORTED')} ${filePath}`);
|
|
111
|
+
}
|
|
112
|
+
if (unassigned.length > 0) {
|
|
113
|
+
const unassignedObj = { workflows: [] };
|
|
114
|
+
for (const workflow of unassigned) {
|
|
115
|
+
unassignedObj.workflows.push(await buildExportWorkflow(workflow, allSchedules));
|
|
116
|
+
}
|
|
117
|
+
const unassignedFilePath = path.join(resolvedDir, 'workflows-unassigned.yml');
|
|
118
|
+
await writeYamlFile(unassignedObj, unassignedFilePath, overwrite);
|
|
119
|
+
console.log(`${chalk_1.default.yellow('EXPORTED')} ${unassignedFilePath} (unassigned workflows)`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.exportWorkflowsByApp = exportWorkflowsByApp;
|
|
123
|
+
async function exportWorkflowsToFile(fileLocation, overwrite) {
|
|
124
|
+
const [allWorkflowsInOrg, allSchedules] = await Promise.all([
|
|
125
|
+
(0, event_workflow_templates_1.getExistingWorkflowTemplates)(),
|
|
126
|
+
(0, schedules_1.getExistingSchedules)(),
|
|
127
|
+
]);
|
|
54
128
|
const workflowsObj = { workflows: [] };
|
|
55
129
|
for (const workflow of allWorkflowsInOrg) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
130
|
+
workflowsObj.workflows.push(await buildExportWorkflow(workflow, allSchedules));
|
|
131
|
+
}
|
|
132
|
+
const pathToWrite = path.resolve(process.cwd(), fileLocation);
|
|
133
|
+
await writeYamlFile(workflowsObj, pathToWrite, overwrite);
|
|
134
|
+
}
|
|
135
|
+
exports.exportWorkflowsToFile = exportWorkflowsToFile;
|
|
136
|
+
async function buildExportWorkflow(workflow, allSchedules, appIdentifier) {
|
|
137
|
+
const exportWorkflow = lodash_1.default.pick(workflow, [
|
|
138
|
+
'identifier',
|
|
139
|
+
'name',
|
|
140
|
+
'triggerKey',
|
|
141
|
+
'isActive',
|
|
142
|
+
'messageGroup',
|
|
143
|
+
'dynamicMessageGroupId',
|
|
144
|
+
'parallelWorkerCount',
|
|
145
|
+
'workflowDefinition',
|
|
146
|
+
]);
|
|
147
|
+
const schedules = allSchedules.filter((s) => s.ownerReference === `event-workflow-template:${workflow.id}`);
|
|
148
|
+
if (schedules.length > 0) {
|
|
149
|
+
exportWorkflow.crons = schedules.map((s) => ({ name: s.name, cron: s.cron }));
|
|
150
|
+
}
|
|
151
|
+
await (0, helper_1.populateActionIdentifiers)(exportWorkflow);
|
|
152
|
+
// Shortened keys can only be resolved back to a full action identifier on
|
|
153
|
+
// import if an appIdentifier is known. Without one (e.g. unassigned
|
|
154
|
+
// workflows), keep the full identifier so the workflow stays re-importable.
|
|
155
|
+
if (appIdentifier) {
|
|
156
|
+
(0, helper_1.extractShortActionKeys)(exportWorkflow);
|
|
67
157
|
}
|
|
68
|
-
|
|
158
|
+
return exportWorkflow;
|
|
69
159
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const CURRENT_DIR = process.cwd();
|
|
74
|
-
const pathToWrite = path.resolve(path.join(CURRENT_DIR, fileLocation));
|
|
75
|
-
if (fs_1.default.existsSync(pathToWrite)) {
|
|
76
|
-
await (0, file_helpers_1.safeFileOverwrite)(pathToWrite, overwrite);
|
|
160
|
+
async function writeYamlFile(data, absolutePath, overwrite) {
|
|
161
|
+
if (fs_1.default.existsSync(absolutePath)) {
|
|
162
|
+
await (0, file_helpers_1.safeFileOverwrite)(absolutePath, overwrite);
|
|
77
163
|
}
|
|
78
|
-
fs_1.default.
|
|
164
|
+
fs_1.default.mkdirSync(path.dirname(absolutePath), { recursive: true });
|
|
165
|
+
fs_1.default.writeFileSync(absolutePath, js_yaml_1.default.dump(data), 'utf8');
|
|
79
166
|
}
|
|
@@ -3,6 +3,7 @@ export default class LoadWorkflowTemplates extends BaseCommand {
|
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
|
+
dir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
6
7
|
alwaysConfirmEnv: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
7
8
|
logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
8
9
|
};
|
|
@@ -11,3 +12,4 @@ export default class LoadWorkflowTemplates extends BaseCommand {
|
|
|
11
12
|
};
|
|
12
13
|
run(): Promise<void>;
|
|
13
14
|
}
|
|
15
|
+
export declare function importWorkflowsBySelection(dir: string): Promise<void>;
|
|
@@ -1,27 +1,84 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.importWorkflowsBySelection = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const path = tslib_1.__importStar(require("path"));
|
|
6
|
+
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
7
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
|
+
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
3
9
|
const core_1 = require("@oclif/core");
|
|
4
10
|
const login_1 = require("../../auth/login");
|
|
5
11
|
const helper_1 = require("../../helpers/workflow-templates/helper");
|
|
6
12
|
const basecommand_1 = require("../../basecommand");
|
|
7
13
|
class LoadWorkflowTemplates extends basecommand_1.BaseCommand {
|
|
8
|
-
static description = '
|
|
14
|
+
static description = 'Load workflow templates from a file or scan a directory for per-app workflow files';
|
|
9
15
|
static examples = [
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
'$ contrail workflow-templates load <FILE_LOCATION>',
|
|
17
|
+
'$ contrail workflow-templates load',
|
|
18
|
+
'$ contrail workflow-templates load --dir ./workflows',
|
|
12
19
|
];
|
|
13
20
|
static flags = {
|
|
14
21
|
...basecommand_1.BaseCommand.baseFlags,
|
|
22
|
+
dir: core_1.Flags.string({
|
|
23
|
+
char: 'd',
|
|
24
|
+
description: 'Directory to scan for workflow files when no file argument is given',
|
|
25
|
+
required: false,
|
|
26
|
+
default: '.',
|
|
27
|
+
}),
|
|
15
28
|
};
|
|
16
29
|
static args = {
|
|
17
30
|
fileLocation: core_1.Args.string({
|
|
18
|
-
description: '
|
|
19
|
-
required:
|
|
31
|
+
description: 'A specific workflow template file to load',
|
|
32
|
+
required: false,
|
|
20
33
|
}),
|
|
21
34
|
};
|
|
22
35
|
async run() {
|
|
23
36
|
await (0, login_1.authUser)();
|
|
24
|
-
|
|
37
|
+
if (this.args.fileLocation) {
|
|
38
|
+
await (0, helper_1.localDeployWorkflowTemplate)(this.args.fileLocation);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
await importWorkflowsBySelection(this.flags.dir ?? '.');
|
|
42
|
+
}
|
|
25
43
|
}
|
|
26
44
|
}
|
|
27
45
|
exports.default = LoadWorkflowTemplates;
|
|
46
|
+
async function importWorkflowsBySelection(dir) {
|
|
47
|
+
const resolvedDir = path.resolve(process.cwd(), dir);
|
|
48
|
+
const files = fs_1.default
|
|
49
|
+
.readdirSync(resolvedDir)
|
|
50
|
+
.filter((f) => f.startsWith('workflows-') && f.endsWith('.yml') && f !== 'workflows-unassigned.yml')
|
|
51
|
+
.sort();
|
|
52
|
+
if (files.length === 0) {
|
|
53
|
+
console.log(chalk_1.default.yellow(`No workflow files found in ${resolvedDir}`));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const choices = files.map((f) => ({
|
|
57
|
+
name: f,
|
|
58
|
+
value: f,
|
|
59
|
+
checked: true,
|
|
60
|
+
}));
|
|
61
|
+
const { selectedFiles } = await inquirer_1.default.prompt([
|
|
62
|
+
{
|
|
63
|
+
type: 'checkbox',
|
|
64
|
+
name: 'selectedFiles',
|
|
65
|
+
message: 'Select workflow files to import (space to toggle, enter to confirm):',
|
|
66
|
+
choices,
|
|
67
|
+
},
|
|
68
|
+
]);
|
|
69
|
+
if (selectedFiles.length === 0) {
|
|
70
|
+
console.log(chalk_1.default.yellow('No files selected — nothing imported.'));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
//log selected file
|
|
74
|
+
console.log(chalk_1.default.blue.bold('SELECTED WORKFLOW FILES:'));
|
|
75
|
+
selectedFiles.forEach((file) => {
|
|
76
|
+
console.log(` - ${file}`);
|
|
77
|
+
});
|
|
78
|
+
for (const file of selectedFiles) {
|
|
79
|
+
console.log(`\n${chalk_1.default.blue.bold('IMPORTING')} ${file}`);
|
|
80
|
+
await (0, helper_1.localDeployWorkflowTemplate)(path.join(dir, file));
|
|
81
|
+
console.log(`${chalk_1.default.green.bold('DONE')} ${file}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.importWorkflowsBySelection = importWorkflowsBySelection;
|
|
@@ -18,3 +18,4 @@ export declare class WorkflowTemplateDeployer {
|
|
|
18
18
|
export declare function deleteWorkflowTemplates(): Promise<void>;
|
|
19
19
|
export declare function localDeployWorkflowTemplate(saveFileLocation: string): Promise<void>;
|
|
20
20
|
export declare function populateActionIdentifiers(workflowTemplate: WorkflowTemplate): Promise<void>;
|
|
21
|
+
export declare function extractShortActionKeys(workflowTemplate: WorkflowTemplate): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.populateActionIdentifiers = exports.localDeployWorkflowTemplate = exports.deleteWorkflowTemplates = exports.WorkflowTemplateDeployer = exports.getActionByIdentifier = exports.getWorkflowTemplateIdentifier = exports.LocalWorkflowTemplateDeployer = void 0;
|
|
3
|
+
exports.extractShortActionKeys = exports.populateActionIdentifiers = exports.localDeployWorkflowTemplate = exports.deleteWorkflowTemplates = exports.WorkflowTemplateDeployer = exports.getActionByIdentifier = exports.getWorkflowTemplateIdentifier = exports.LocalWorkflowTemplateDeployer = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const util_1 = require("@contrail/util");
|
|
6
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
@@ -44,6 +44,8 @@ class LocalWorkflowTemplateDeployer {
|
|
|
44
44
|
isActive: workflowTemplate.isActive,
|
|
45
45
|
supportingAppId: workflowTemplate.supportingAppId,
|
|
46
46
|
messageGroupId: workflowTemplate.messageGroupId,
|
|
47
|
+
messageGroup: workflowTemplate.messageGroup,
|
|
48
|
+
dynamicMessageGroupId: workflowTemplate.dynamicMessageGroupId,
|
|
47
49
|
parallelWorkerCount: workflowTemplate.parallelWorkerCount,
|
|
48
50
|
};
|
|
49
51
|
const newWorkflowTemplate = await (0, event_workflow_templates_1.createWorkflowTemplate)(newObject);
|
|
@@ -55,8 +57,11 @@ class LocalWorkflowTemplateDeployer {
|
|
|
55
57
|
}
|
|
56
58
|
async populateActionIds(workflowTemplate, workflowKey, appIdentifier) {
|
|
57
59
|
const installedApps = await (0, apps_1.getInstalledApps)();
|
|
58
|
-
const appOrg = installedApps.find((x) => x.app
|
|
60
|
+
const appOrg = installedApps.find((x) => x.app?.identifier === appIdentifier);
|
|
59
61
|
logger_1.default.info('workflow template:', JSON.stringify(workflowTemplate, null, 2));
|
|
62
|
+
if (!appOrg) {
|
|
63
|
+
throw new Error(`Could not find installed app with identifier "${appIdentifier}". Make sure the app is installed in this org before importing workflows.`);
|
|
64
|
+
}
|
|
60
65
|
if (!workflowTemplate?.workflowDefinition?.paths) {
|
|
61
66
|
return;
|
|
62
67
|
}
|
|
@@ -86,7 +91,7 @@ class LocalWorkflowTemplateDeployer {
|
|
|
86
91
|
}
|
|
87
92
|
}
|
|
88
93
|
async createWorkflowSchedule(workflowTemplate, workflowId) {
|
|
89
|
-
if (!workflowTemplate?.crons?.length
|
|
94
|
+
if (!workflowTemplate?.crons?.length) {
|
|
90
95
|
return;
|
|
91
96
|
}
|
|
92
97
|
const crons = [];
|
|
@@ -158,6 +163,8 @@ class LocalWorkflowTemplateDeployer {
|
|
|
158
163
|
triggerKey: workflowTemplate.triggerKey,
|
|
159
164
|
builtIn: workflowTemplate.builtIn,
|
|
160
165
|
workflowDefinition: workflowTemplate.workflowDefinition,
|
|
166
|
+
messageGroupId: workflowTemplate.messageGroupId ?? existingWorkflowTemplate.messageGroupId,
|
|
167
|
+
messageGroup: workflowTemplate.messageGroup ?? existingWorkflowTemplate.messageGroup,
|
|
161
168
|
dynamicMessageGroupId: workflowTemplate.dynamicMessageGroupId ?? existingWorkflowTemplate.dynamicMessageGroupId,
|
|
162
169
|
parallelWorkerCount: workflowTemplate.parallelWorkerCount ?? existingWorkflowTemplate.parallelWorkerCount,
|
|
163
170
|
});
|
|
@@ -283,3 +290,21 @@ async function populateActionIdentifiers(workflowTemplate) {
|
|
|
283
290
|
}
|
|
284
291
|
}
|
|
285
292
|
exports.populateActionIdentifiers = populateActionIdentifiers;
|
|
293
|
+
function extractShortActionKeys(workflowTemplate) {
|
|
294
|
+
if (!workflowTemplate?.workflowDefinition?.paths) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
for (const wfPath of workflowTemplate.workflowDefinition.paths) {
|
|
298
|
+
if (!wfPath?.actionDefinitionConfigs) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
for (const actionConfig of wfPath.actionDefinitionConfigs) {
|
|
302
|
+
if (actionConfig.action?.includes(':')) {
|
|
303
|
+
// Full identifier format: "app-id@version:action-name" -> "action-name"
|
|
304
|
+
actionConfig.action = actionConfig.action.split(':').pop();
|
|
305
|
+
}
|
|
306
|
+
delete actionConfig.identifier;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
exports.extractShortActionKeys = extractShortActionKeys;
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -98,7 +98,7 @@ export interface WorkflowDefinition {
|
|
|
98
98
|
dynamicMessageGroupId?: string;
|
|
99
99
|
}
|
|
100
100
|
export interface WorkflowTemplateDeclaration {
|
|
101
|
-
appIdentifier
|
|
101
|
+
appIdentifier?: string;
|
|
102
102
|
workflows?: WorkflowTemplate[];
|
|
103
103
|
}
|
|
104
104
|
export interface WorkflowTemplate {
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.5.
|
|
2
|
+
"version": "3.5.4-alpha.2a94b1c",
|
|
3
3
|
"commands": {
|
|
4
4
|
"app:create": {
|
|
5
5
|
"id": "app:create",
|
|
@@ -2956,14 +2956,16 @@
|
|
|
2956
2956
|
},
|
|
2957
2957
|
"workflow-templates:export": {
|
|
2958
2958
|
"id": "workflow-templates:export",
|
|
2959
|
-
"description": "Export all workflows in the org.",
|
|
2959
|
+
"description": "Export all workflows in the org. By default exports one file per app to the current directory.",
|
|
2960
2960
|
"strict": true,
|
|
2961
2961
|
"pluginName": "@contrail/cli",
|
|
2962
2962
|
"pluginAlias": "@contrail/cli",
|
|
2963
2963
|
"pluginType": "core",
|
|
2964
2964
|
"aliases": [],
|
|
2965
2965
|
"examples": [
|
|
2966
|
-
"$ contrail workflow-templates export
|
|
2966
|
+
"$ contrail workflow-templates export",
|
|
2967
|
+
"$ contrail workflow-templates export --dir ./workflows",
|
|
2968
|
+
"$ contrail workflow-templates export --outFile workflows.yml"
|
|
2967
2969
|
],
|
|
2968
2970
|
"flags": {
|
|
2969
2971
|
"logLevel": {
|
|
@@ -2997,10 +2999,18 @@
|
|
|
2997
2999
|
"name": "outFile",
|
|
2998
3000
|
"type": "option",
|
|
2999
3001
|
"char": "f",
|
|
3000
|
-
"description": "
|
|
3002
|
+
"description": "Export all workflows to a single file at this path (overrides per-app export)",
|
|
3003
|
+
"required": false,
|
|
3004
|
+
"multiple": false
|
|
3005
|
+
},
|
|
3006
|
+
"dir": {
|
|
3007
|
+
"name": "dir",
|
|
3008
|
+
"type": "option",
|
|
3009
|
+
"char": "d",
|
|
3010
|
+
"description": "Directory to write per-app workflow files",
|
|
3001
3011
|
"required": false,
|
|
3002
3012
|
"multiple": false,
|
|
3003
|
-
"default": "
|
|
3013
|
+
"default": "."
|
|
3004
3014
|
},
|
|
3005
3015
|
"overwrite": {
|
|
3006
3016
|
"name": "overwrite",
|
|
@@ -3056,14 +3066,16 @@
|
|
|
3056
3066
|
},
|
|
3057
3067
|
"workflow-templates:load": {
|
|
3058
3068
|
"id": "workflow-templates:load",
|
|
3059
|
-
"description": "
|
|
3069
|
+
"description": "Load workflow templates from a file or scan a directory for per-app workflow files",
|
|
3060
3070
|
"strict": true,
|
|
3061
3071
|
"pluginName": "@contrail/cli",
|
|
3062
3072
|
"pluginAlias": "@contrail/cli",
|
|
3063
3073
|
"pluginType": "core",
|
|
3064
3074
|
"aliases": [],
|
|
3065
3075
|
"examples": [
|
|
3066
|
-
"$ contrail workflow-templates load <FILE_LOCATION
|
|
3076
|
+
"$ contrail workflow-templates load <FILE_LOCATION>",
|
|
3077
|
+
"$ contrail workflow-templates load",
|
|
3078
|
+
"$ contrail workflow-templates load --dir ./workflows"
|
|
3067
3079
|
],
|
|
3068
3080
|
"flags": {
|
|
3069
3081
|
"logLevel": {
|
|
@@ -3092,13 +3104,22 @@
|
|
|
3092
3104
|
"false"
|
|
3093
3105
|
],
|
|
3094
3106
|
"default": "true"
|
|
3107
|
+
},
|
|
3108
|
+
"dir": {
|
|
3109
|
+
"name": "dir",
|
|
3110
|
+
"type": "option",
|
|
3111
|
+
"char": "d",
|
|
3112
|
+
"description": "Directory to scan for workflow files when no file argument is given",
|
|
3113
|
+
"required": false,
|
|
3114
|
+
"multiple": false,
|
|
3115
|
+
"default": "."
|
|
3095
3116
|
}
|
|
3096
3117
|
},
|
|
3097
3118
|
"args": {
|
|
3098
3119
|
"fileLocation": {
|
|
3099
3120
|
"name": "fileLocation",
|
|
3100
|
-
"description": "
|
|
3101
|
-
"required":
|
|
3121
|
+
"description": "A specific workflow template file to load",
|
|
3122
|
+
"required": false
|
|
3102
3123
|
}
|
|
3103
3124
|
}
|
|
3104
3125
|
},
|