@docupace/pipeline 1.0.53 → 1.0.55

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.
Files changed (44) hide show
  1. package/.prettierrc.cjs +12 -12
  2. package/README.md +135 -135
  3. package/bin/azuread_update_callbacks_for_app.sh +58 -58
  4. package/bin/next-changeset-validate.sh +8 -8
  5. package/eslint.config.js +26 -26
  6. package/next/changeset.sh +75 -75
  7. package/next/copy.sh +34 -34
  8. package/next/deploy.sh +40 -40
  9. package/next/execute.sh +123 -123
  10. package/next/sonar.sh +23 -23
  11. package/package.json +50 -50
  12. package/src/auth0/alias.js +72 -72
  13. package/src/auth0/cli.js +0 -0
  14. package/src/auth0/export.js +43 -43
  15. package/src/auth0/metadata.js +132 -132
  16. package/src/auth0/vault.js +107 -107
  17. package/src/changeset/changeset-config.js +34 -34
  18. package/src/changeset/cli.js +200 -200
  19. package/src/changeset/create.js +205 -205
  20. package/src/changeset/package-util.js +86 -86
  21. package/src/changeset/util.js +43 -43
  22. package/src/changeset/validate.js +84 -84
  23. package/src/changeset/version.js +102 -102
  24. package/src/jenkins/setParams.groovy +58 -58
  25. package/src/next/alias.js +53 -53
  26. package/src/next/apache.js +81 -73
  27. package/src/next/cli.js +228 -228
  28. package/src/next/config.js +137 -136
  29. package/src/next/connect.js +227 -227
  30. package/src/next/copy.js +61 -61
  31. package/src/next/deploy.js +595 -583
  32. package/src/next/haproxy.js +71 -71
  33. package/src/next/jira.js +84 -84
  34. package/src/next/logger.js +17 -17
  35. package/src/next/pipline.js +114 -114
  36. package/src/next/publish.js +71 -71
  37. package/src/next/pull.js +7 -7
  38. package/src/next/sonar.js +23 -23
  39. package/src/next/util.js +93 -93
  40. package/src/next/vault.js +45 -45
  41. package/terraform/apply.sh +37 -37
  42. package/terraform/init.sh +72 -72
  43. package/terraform/plan.sh +76 -76
  44. package/terraform/validate.sh +17 -17
@@ -1,73 +1,81 @@
1
- import fs from 'fs-extra';
2
- import { $ } from 'zx';
3
-
4
- function log(msg) {
5
- console.log(`[*] ${msg}`);
6
- }
7
-
8
- export async function addApacheSite() {
9
- if (
10
- !process.env.ENVIRONMENT ||
11
- !['dev', 'qa', 'uat', 'stage','www3'].includes(process.env.ENVIRONMENT)
12
- ) {
13
- log('Error: wront ENVIRONMENT');
14
- process.exit(1);
15
- }
16
- if (!process.env.SITE) {
17
- log('Error: SITE cannot be empty.');
18
- process.exit(1);
19
- }
20
-
21
- const apacheEnvHostMap = {
22
- dev: {
23
- host1: 'dev-apalb01a.corp.docupace.com',
24
- host2: 'dev-apalb01b.corp.docupace.com',
25
- repo: 'iis-preprod',
26
- },
27
- qa: {
28
- host1: 'qa-apalb01a.corp.docupace.com',
29
- host2: 'qa-apalb01b.corp.docupace.com',
30
- repo: 'iis-preprod',
31
- },
32
- uat: {
33
- host1: 'uat-apalb01a.edc.docupace.internal',
34
- host2: 'uat-apalb01b.edc.docupace.internal',
35
- repo: 'iis-www2',
36
- },
37
- stage: {
38
- host1: 'stg-apalb01a.edc.docupace.internal',
39
- host2: 'stg-apalb01b.edc.docupace.internal',
40
- repo: 'iis-www2',
41
- },
42
- www3: {
43
- host1: 'prd-apalb05a.edc.docupace.internal',
44
- host2: 'prd-apalb05b.edc.docupace.internal',
45
- repo: 'iis-www2',
46
- },
47
- };
48
-
49
- // Save private key from base64
50
- const haproxyPrivateKey = process.env.HAPROXY_PRIVATE_KEY;
51
- if (!haproxyPrivateKey) {
52
- log('Error: HAPROXY_PRIVATE_KEY not set.');
53
- process.exit(1);
54
- }
55
-
56
- await fs.writeFile('private.key', Buffer.from(haproxyPrivateKey, 'base64'));
57
- await fs.chmod('private.key', 0o600);
58
-
59
- console.log('Running command');
60
- const sshCmd = (server, script) =>
61
- $`ssh -i private.key -o StrictHostKeyChecking=no root@${server} ${script}`;
62
-
63
- // The script is run twice in the Bash version
64
- await sshCmd(
65
- apacheEnvHostMap[process.env.ENVIRONMENT].host1,
66
- `/root/repo/${apacheEnvHostMap[process.env.ENVIRONMENT].repo}/scripts/addsite/add_core_site.sh ${process.env.ENVIRONMENT} ${process.env.SITE}`,
67
- );
68
-
69
- await sshCmd(
70
- apacheEnvHostMap[process.env.ENVIRONMENT].host2,
71
- `/root/repo/${apacheEnvHostMap[process.env.ENVIRONMENT].repo}/scripts/addsite/add_core_site.sh ${process.env.ENVIRONMENT} ${process.env.SITE}`,
72
- );
73
- }
1
+ import fs from 'fs-extra';
2
+ import { $ } from 'zx';
3
+
4
+ function log(msg) {
5
+ console.log(`[*] ${msg}`);
6
+ }
7
+
8
+ export async function addApacheSite() {
9
+ if (
10
+ !process.env.ENVIRONMENT ||
11
+ !['dev', 'qa', 'uat', 'stage','www3'].includes(process.env.ENVIRONMENT)
12
+ ) {
13
+ log('Error: wront ENVIRONMENT');
14
+ process.exit(1);
15
+ }
16
+ if (!process.env.SITE) {
17
+ log('Error: SITE cannot be empty.');
18
+ process.exit(1);
19
+ }
20
+
21
+ const apacheEnvHostMap = {
22
+ dev: {
23
+ host1: 'dev-apalb01a.corp.docupace.com',
24
+ host2: 'dev-apalb01b.corp.docupace.com',
25
+ repo: 'iis-preprod',
26
+ },
27
+ qa: {
28
+ host1: 'qa-apalb01a.corp.docupace.com',
29
+ host2: 'qa-apalb01b.corp.docupace.com',
30
+ repo: 'iis-preprod',
31
+ },
32
+ uat: {
33
+ host1: 'uat-apalb01a.edc.docupace.internal',
34
+ host2: 'uat-apalb01b.edc.docupace.internal',
35
+ repo: 'iis-www2',
36
+ },
37
+ stage: {
38
+ host1: 'stg-apalb01a.edc.docupace.internal',
39
+ host2: 'stg-apalb01b.edc.docupace.internal',
40
+ repo: 'iis-www2',
41
+ },
42
+ www3: {
43
+ host1: 'prd-apalb05a.edc.docupace.internal',
44
+ host2: 'prd-apalb05b.edc.docupace.internal',
45
+ repo: 'iis-www2',
46
+ },
47
+ };
48
+
49
+ // Save private key from base64
50
+ const haproxyPrivateKey = process.env.HAPROXY_PRIVATE_KEY;
51
+ if (!haproxyPrivateKey) {
52
+ log('Error: HAPROXY_PRIVATE_KEY not set.');
53
+ process.exit(1);
54
+ }
55
+
56
+ await fs.writeFile('private.key', Buffer.from(haproxyPrivateKey, 'base64'));
57
+ await fs.chmod('private.key', 0o600);
58
+
59
+ console.log('Running command');
60
+ const sshCmd = (server, script) =>
61
+ $`ssh -i private.key -o StrictHostKeyChecking=no root@${server} ${script}`;
62
+
63
+ // The script is run twice in the Bash version
64
+ await sshCmd(
65
+ apacheEnvHostMap[process.env.ENVIRONMENT].host1,
66
+ `/root/tomcat_repo_sync.sh`,
67
+ );
68
+ await sshCmd(
69
+ apacheEnvHostMap[process.env.ENVIRONMENT].host1,
70
+ `/root/repo/${apacheEnvHostMap[process.env.ENVIRONMENT].repo}/scripts/addsite/add_core_site.sh ${process.env.ENVIRONMENT} ${process.env.SITE}`,
71
+ );
72
+
73
+ await sshCmd(
74
+ apacheEnvHostMap[process.env.ENVIRONMENT].host2,
75
+ `/root/tomcat_repo_sync.sh`,
76
+ );
77
+ await sshCmd(
78
+ apacheEnvHostMap[process.env.ENVIRONMENT].host2,
79
+ `/root/repo/${apacheEnvHostMap[process.env.ENVIRONMENT].repo}/scripts/addsite/add_core_site.sh ${process.env.ENVIRONMENT} ${process.env.SITE}`,
80
+ );
81
+ }
package/src/next/cli.js CHANGED
@@ -1,228 +1,228 @@
1
- #!/usr/bin/env node
2
-
3
- import { Command } from 'commander';
4
- import { pull } from './pull.js';
5
- import { sonar } from './sonar.js';
6
- import { publish } from './publish.js';
7
- import {
8
- deployAppWithTag,
9
- deployFromSite,
10
- deployTemplate,
11
- getDefaultDeploySite,
12
- getDeployTag,
13
- } from './deploy.js';
14
- import { copy, copy2 } from './copy.js';
15
- import { vaultAddSiteData } from './vault.js';
16
- import { addApacheSite } from './apache.js';
17
- import { haproxySync } from './haproxy.js';
18
- import { connectClone } from './connect.js';
19
- import dotenv from 'dotenv';
20
- import { $ } from 'zx';
21
- import { deployConnect, deployCore } from './jenkins.js';
22
- import { runPipeline } from './pipline.js';
23
-
24
- dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
25
-
26
- const program = new Command();
27
-
28
- const GIT_SHA = (await $`git log --pretty=format:'%h' -n 1`).stdout.trim();
29
-
30
- program
31
- .command('pull <imageName>')
32
- .description('Pull a Docker image from the registry')
33
- .action(async (imageName) => {
34
- await pull(imageName);
35
- });
36
-
37
- program
38
- .command('sonar')
39
- .description('Run Sonar analysis')
40
- .action(async () => {
41
- await sonar(GIT_SHA);
42
- });
43
-
44
- program
45
- .command('addApacheSite')
46
- .description('Add site to apache')
47
- .action(async () => {
48
- await addApacheSite();
49
- });
50
-
51
- program
52
- .command('connectClone')
53
- .description('Clone connect site')
54
- .action(async () => {
55
- await connectClone();
56
- });
57
-
58
- program
59
- .command('haproxySync')
60
- .description('Sync haproxy config')
61
- .action(async () => {
62
- await haproxySync();
63
- });
64
-
65
- program
66
- .command('vaultAddSiteData')
67
- .description('Add m2m auth0 data to vault')
68
- .requiredOption('-s, --site-name <siteName>', 'Site name')
69
- .requiredOption(
70
- '-p, --site-config-remote-path <siteConfigRemotePath>',
71
- 'Site Config Remote Path',
72
- )
73
- .action(async (options) => {
74
- const { siteName, siteConfigRemotePath } = options;
75
- await vaultAddSiteData(siteName, siteConfigRemotePath);
76
- });
77
-
78
- program
79
- .command('publish')
80
- .description('Publish a Docker image')
81
- .action(async () => {
82
- await publish(GIT_SHA);
83
- });
84
-
85
- program
86
- .command('deploy-from-site')
87
- .description('Deploy an application for a specific site')
88
- .requiredOption('-f, --from-env <fromEnv>', 'Source environment')
89
- .requiredOption('-t, --to-env <toEnv>', 'Target environment')
90
- .requiredOption('-F, --from-site <fromSite>', 'Source site')
91
- .requiredOption('-T, --to-site <toSite>', 'Target site')
92
- .option('-c, --deploy-core <deployCore>', 'Deploy Core', 'false')
93
- .option('-C, --deploy-connect <deployConnect>', 'Deploy Connect', 'false')
94
- .action(async (options) => {
95
- const { fromEnv, fromSite, toEnv, toSite, deployCore, deployConnect } =
96
- options;
97
- await deployFromSite(
98
- fromEnv,
99
- fromSite,
100
- toEnv,
101
- toSite,
102
- deployCore,
103
- deployConnect,
104
- );
105
- });
106
-
107
- program
108
- .command('deploy-template [tagPrefix]')
109
- .description('Deploy an application for a specific site')
110
- .action(async (tagPrefix) => {
111
- const deployTag = await getDeployTag(tagPrefix);
112
- const sites = await getDefaultDeploySite(deployTag);
113
- for (const { env, site } of sites) {
114
- await deployTemplate(env, site, deployTag);
115
- }
116
- });
117
-
118
- program
119
- .command('deployTemplate')
120
- .description('Deploy an application for a specific site')
121
- .action(async () => {
122
- const deployTag = await getDeployTag();
123
- const sites = await getDefaultDeploySite(deployTag);
124
- for (const { env, site } of sites) {
125
- await deployTemplate(env, site, deployTag);
126
- }
127
- });
128
-
129
- program
130
- .command('deploy-app <application>')
131
- .description('Deploy an application for a specific site')
132
- .action(async (application) => {
133
- const deployTag = await getDeployTag();
134
- const sites = await getDefaultDeploySite(deployTag);
135
- for (const { env, site } of sites) {
136
- await deployAppWithTag(application, env, site, deployTag);
137
- }
138
- });
139
-
140
- program
141
- .command('deploy-mono-app <tag> <application>')
142
- .description('Deploy an application for a specific site')
143
- .action(async (tag, application) => {
144
- const deployTag = await getDeployTag(tag);
145
- const version = 'v' + deployTag.split('@')[1];
146
- const sites = await getDefaultDeploySite(version);
147
- for (const { env, site } of sites) {
148
- await deployAppWithTag(application, env, site, version);
149
- }
150
- });
151
-
152
- program
153
- .command('deploy-core <env> <site>')
154
- .description('Deploy Core')
155
- .option('-l, --liquibase <liquibase>', 'Application name', 'true')
156
- .option('-b, --branch <branch>', 'Branch', 'master')
157
- .action(async (env, site, options) => {
158
- await deployCore(env, site, options.liquibase, options.branch);
159
- });
160
-
161
- program
162
- .command('deploy-connect <env> <site>')
163
- .description('Deploy Core')
164
- .option('-l, --liquibase <liquibase>', 'Application name', 'true')
165
- .option('-b, --branch <branch>', 'Branch', 'master')
166
- .action(async (env, site, options) => {
167
- await deployConnect(env, site, options.liquibase, options.branch);
168
- });
169
-
170
- program
171
- .command('deploy-core-pipeline <env> <site>')
172
- .description('Deploy Core')
173
- .option('-l, --liquibase <liquibase>', 'Application name', 'true')
174
- .option('-b, --branch <branch>', 'Branch', 'master')
175
- .action(async (env, site, options) => {
176
- await runPipeline('site-deploy', 'deploy-core', 'main', {
177
- ENV: env,
178
- SITE: site,
179
- LIQUIBASE: options.liquibase,
180
- BRANCH: options.branch,
181
- });
182
- });
183
-
184
- program
185
- .command('copy')
186
- .description('Copy a Docker image between registries')
187
- .requiredOption('-r, --repository <repository>', 'Repostory name')
188
- .requiredOption('-f, --from-env <fromEnv>', 'Source environment')
189
- .requiredOption('-t, --to-env <toEnv>', 'Target environment')
190
- .requiredOption('-g, --tag <tag>', 'Image tag')
191
- .requiredOption('-a, --application <application>', 'Application name')
192
- .action(async (options) => {
193
- const { repository, fromEnv, toEnv, tag, application } = options;
194
- await copy2(repository, fromEnv, toEnv, tag, application);
195
- });
196
-
197
- program
198
- .command('run-pipeline')
199
- .description('Trigger a pipeline by name')
200
- .requiredOption('-r, --repository <repository>', 'Repository name')
201
- .requiredOption('-p, --pipeline-name <pipelineName>', 'Pipeline name')
202
- .requiredOption('-b, --branch <branch>', 'Branch name')
203
- .option(
204
- '-v, --variables <key=value>',
205
- 'Pipeline variable as key=value pair',
206
- (value, previous) => {
207
- const [key, val] = value.split('=');
208
- if (!key || val === undefined) {
209
- throw new Error(`Invalid variable format: ${value}. Use key=value.`);
210
- }
211
- return { ...previous, [key]: val };
212
- },
213
- {},
214
- )
215
- .option('-w, --wait', 'Wait for the pipeline to complete', false) // Defaults to false
216
- .action(async (cmdObj) => {
217
- try {
218
- const { repository, pipelineName, branch, variables, wait } = cmdObj;
219
-
220
- // Call the triggerPipelineByName function
221
- await runPipeline(repository, pipelineName, branch, variables, wait);
222
- } catch (error) {
223
- console.error('Error triggering pipeline:', error.message);
224
- process.exit(1);
225
- }
226
- });
227
-
228
- program.parse(process.argv);
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import { pull } from './pull.js';
5
+ import { sonar } from './sonar.js';
6
+ import { publish } from './publish.js';
7
+ import {
8
+ deployAppWithTag,
9
+ deployFromSite,
10
+ deployTemplate,
11
+ getDefaultDeploySite,
12
+ getDeployTag,
13
+ } from './deploy.js';
14
+ import { copy, copy2 } from './copy.js';
15
+ import { vaultAddSiteData } from './vault.js';
16
+ import { addApacheSite } from './apache.js';
17
+ import { haproxySync } from './haproxy.js';
18
+ import { connectClone } from './connect.js';
19
+ import dotenv from 'dotenv';
20
+ import { $ } from 'zx';
21
+ import { deployConnect, deployCore } from './jenkins.js';
22
+ import { runPipeline } from './pipline.js';
23
+
24
+ dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
25
+
26
+ const program = new Command();
27
+
28
+ const GIT_SHA = (await $`git log --pretty=format:'%h' -n 1`).stdout.trim();
29
+
30
+ program
31
+ .command('pull <imageName>')
32
+ .description('Pull a Docker image from the registry')
33
+ .action(async (imageName) => {
34
+ await pull(imageName);
35
+ });
36
+
37
+ program
38
+ .command('sonar')
39
+ .description('Run Sonar analysis')
40
+ .action(async () => {
41
+ await sonar(GIT_SHA);
42
+ });
43
+
44
+ program
45
+ .command('addApacheSite')
46
+ .description('Add site to apache')
47
+ .action(async () => {
48
+ await addApacheSite();
49
+ });
50
+
51
+ program
52
+ .command('connectClone')
53
+ .description('Clone connect site')
54
+ .action(async () => {
55
+ await connectClone();
56
+ });
57
+
58
+ program
59
+ .command('haproxySync')
60
+ .description('Sync haproxy config')
61
+ .action(async () => {
62
+ await haproxySync();
63
+ });
64
+
65
+ program
66
+ .command('vaultAddSiteData')
67
+ .description('Add m2m auth0 data to vault')
68
+ .requiredOption('-s, --site-name <siteName>', 'Site name')
69
+ .requiredOption(
70
+ '-p, --site-config-remote-path <siteConfigRemotePath>',
71
+ 'Site Config Remote Path',
72
+ )
73
+ .action(async (options) => {
74
+ const { siteName, siteConfigRemotePath } = options;
75
+ await vaultAddSiteData(siteName, siteConfigRemotePath);
76
+ });
77
+
78
+ program
79
+ .command('publish')
80
+ .description('Publish a Docker image')
81
+ .action(async () => {
82
+ await publish(GIT_SHA);
83
+ });
84
+
85
+ program
86
+ .command('deploy-from-site')
87
+ .description('Deploy an application for a specific site')
88
+ .requiredOption('-f, --from-env <fromEnv>', 'Source environment')
89
+ .requiredOption('-t, --to-env <toEnv>', 'Target environment')
90
+ .requiredOption('-F, --from-site <fromSite>', 'Source site')
91
+ .requiredOption('-T, --to-site <toSite>', 'Target site')
92
+ .option('-c, --deploy-core <deployCore>', 'Deploy Core', 'false')
93
+ .option('-C, --deploy-connect <deployConnect>', 'Deploy Connect', 'false')
94
+ .action(async (options) => {
95
+ const { fromEnv, fromSite, toEnv, toSite, deployCore, deployConnect } =
96
+ options;
97
+ await deployFromSite(
98
+ fromEnv,
99
+ fromSite,
100
+ toEnv,
101
+ toSite,
102
+ deployCore,
103
+ deployConnect,
104
+ );
105
+ });
106
+
107
+ program
108
+ .command('deploy-template [tagPrefix]')
109
+ .description('Deploy an application for a specific site')
110
+ .action(async (tagPrefix) => {
111
+ const deployTag = await getDeployTag(tagPrefix);
112
+ const sites = await getDefaultDeploySite(deployTag);
113
+ for (const { env, site } of sites) {
114
+ await deployTemplate(env, site, deployTag);
115
+ }
116
+ });
117
+
118
+ program
119
+ .command('deployTemplate')
120
+ .description('Deploy an application for a specific site')
121
+ .action(async () => {
122
+ const deployTag = await getDeployTag();
123
+ const sites = await getDefaultDeploySite(deployTag);
124
+ for (const { env, site } of sites) {
125
+ await deployTemplate(env, site, deployTag);
126
+ }
127
+ });
128
+
129
+ program
130
+ .command('deploy-app <application>')
131
+ .description('Deploy an application for a specific site')
132
+ .action(async (application) => {
133
+ const deployTag = await getDeployTag();
134
+ const sites = await getDefaultDeploySite(deployTag);
135
+ for (const { env, site } of sites) {
136
+ await deployAppWithTag(application, env, site, deployTag);
137
+ }
138
+ });
139
+
140
+ program
141
+ .command('deploy-mono-app <tag> <application>')
142
+ .description('Deploy an application for a specific site')
143
+ .action(async (tag, application) => {
144
+ const deployTag = await getDeployTag(tag);
145
+ const version = 'v' + deployTag.split('@')[1];
146
+ const sites = await getDefaultDeploySite(version);
147
+ for (const { env, site } of sites) {
148
+ await deployAppWithTag(application, env, site, version);
149
+ }
150
+ });
151
+
152
+ program
153
+ .command('deploy-core <env> <site>')
154
+ .description('Deploy Core')
155
+ .option('-l, --liquibase <liquibase>', 'Application name', 'true')
156
+ .option('-b, --branch <branch>', 'Branch', 'master')
157
+ .action(async (env, site, options) => {
158
+ await deployCore(env, site, options.liquibase, options.branch);
159
+ });
160
+
161
+ program
162
+ .command('deploy-connect <env> <site>')
163
+ .description('Deploy Core')
164
+ .option('-l, --liquibase <liquibase>', 'Application name', 'true')
165
+ .option('-b, --branch <branch>', 'Branch', 'master')
166
+ .action(async (env, site, options) => {
167
+ await deployConnect(env, site, options.liquibase, options.branch);
168
+ });
169
+
170
+ program
171
+ .command('deploy-core-pipeline <env> <site>')
172
+ .description('Deploy Core')
173
+ .option('-l, --liquibase <liquibase>', 'Application name', 'true')
174
+ .option('-b, --branch <branch>', 'Branch', 'master')
175
+ .action(async (env, site, options) => {
176
+ await runPipeline('site-deploy', 'deploy-core', 'main', {
177
+ ENV: env,
178
+ SITE: site,
179
+ LIQUIBASE: options.liquibase,
180
+ BRANCH: options.branch,
181
+ });
182
+ });
183
+
184
+ program
185
+ .command('copy')
186
+ .description('Copy a Docker image between registries')
187
+ .requiredOption('-r, --repository <repository>', 'Repostory name')
188
+ .requiredOption('-f, --from-env <fromEnv>', 'Source environment')
189
+ .requiredOption('-t, --to-env <toEnv>', 'Target environment')
190
+ .requiredOption('-g, --tag <tag>', 'Image tag')
191
+ .requiredOption('-a, --application <application>', 'Application name')
192
+ .action(async (options) => {
193
+ const { repository, fromEnv, toEnv, tag, application } = options;
194
+ await copy2(repository, fromEnv, toEnv, tag, application);
195
+ });
196
+
197
+ program
198
+ .command('run-pipeline')
199
+ .description('Trigger a pipeline by name')
200
+ .requiredOption('-r, --repository <repository>', 'Repository name')
201
+ .requiredOption('-p, --pipeline-name <pipelineName>', 'Pipeline name')
202
+ .requiredOption('-b, --branch <branch>', 'Branch name')
203
+ .option(
204
+ '-v, --variables <key=value>',
205
+ 'Pipeline variable as key=value pair',
206
+ (value, previous) => {
207
+ const [key, val] = value.split('=');
208
+ if (!key || val === undefined) {
209
+ throw new Error(`Invalid variable format: ${value}. Use key=value.`);
210
+ }
211
+ return { ...previous, [key]: val };
212
+ },
213
+ {},
214
+ )
215
+ .option('-w, --wait', 'Wait for the pipeline to complete', false) // Defaults to false
216
+ .action(async (cmdObj) => {
217
+ try {
218
+ const { repository, pipelineName, branch, variables, wait } = cmdObj;
219
+
220
+ // Call the triggerPipelineByName function
221
+ await runPipeline(repository, pipelineName, branch, variables, wait);
222
+ } catch (error) {
223
+ console.error('Error triggering pipeline:', error.message);
224
+ process.exit(1);
225
+ }
226
+ });
227
+
228
+ program.parse(process.argv);