@docupace/pipeline 1.0.5-alpha.9 → 1.0.6-alpha.0
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/package.json +5 -1
- package/src/changeset/cli.js +32 -5
- package/src/jenkins/setParams.groovy +59 -0
- package/src/next/cli.js +54 -6
- package/src/next/config.js +31 -0
- package/src/next/deploy.js +73 -6
- package/src/next/jenkins.js +9 -7
- package/src/next/pipline.js +94 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docupace/pipeline",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6-alpha.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,5 +32,9 @@
|
|
|
32
32
|
"eslint-plugin-prettier": "^5.2.1",
|
|
33
33
|
"globals": "^15.14.0",
|
|
34
34
|
"prettier": "^3.4.2"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"test-deploy-core": "dp-next-cli deploy-core-pipeline dev template",
|
|
38
|
+
"test-deploy-from-site": "dp-next-cli deploy-from-site --from-env dev --to-env dev --from-site financialdev --to-site template --deploy-core true"
|
|
35
39
|
}
|
|
36
40
|
}
|
package/src/changeset/cli.js
CHANGED
|
@@ -9,12 +9,36 @@ import { zodResponseFormat } from 'openai/helpers/zod';
|
|
|
9
9
|
import z from 'zod';
|
|
10
10
|
import dotenv from 'dotenv';
|
|
11
11
|
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
12
|
+
import { exec } from 'child_process';
|
|
12
13
|
|
|
13
14
|
const program = new Command();
|
|
14
15
|
|
|
15
16
|
const args = process.argv;
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
async function createChangesetDirectory() {
|
|
19
|
+
try {
|
|
20
|
+
// Use path.join to build a safe path to `.changeset`
|
|
21
|
+
const targetDir = path.join(process.cwd(), '.changeset');
|
|
22
|
+
|
|
23
|
+
// Create the directory recursively if it doesn't exist
|
|
24
|
+
await fs.promises.mkdir(targetDir, { recursive: true });
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error('Error creating .changeset directory:', error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
function run(command) {
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
exec(command, { shell: true }, (error, stdout, stderr) => {
|
|
34
|
+
if (error) {
|
|
35
|
+
reject(error);
|
|
36
|
+
} else {
|
|
37
|
+
resolve({ stdout, stderr });
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
18
42
|
|
|
19
43
|
async function fileExists(filePath) {
|
|
20
44
|
try {
|
|
@@ -155,7 +179,8 @@ program
|
|
|
155
179
|
|
|
156
180
|
try {
|
|
157
181
|
// Step 1: Get the current branch name
|
|
158
|
-
const
|
|
182
|
+
const { stdout: branchStdout } = await run(`git branch --show-current`);
|
|
183
|
+
const branchName = branchStdout.trim();
|
|
159
184
|
console.log(`Current branch: ${branchName}`);
|
|
160
185
|
|
|
161
186
|
// Step 2: Extract Jira ticket number (e.g., matching JIRA-1234 pattern)
|
|
@@ -195,6 +220,7 @@ program
|
|
|
195
220
|
`Generating release notes for ${jiraTicketId} - ${jiraSummary}`,
|
|
196
221
|
);
|
|
197
222
|
|
|
223
|
+
// Step 4: Use OpenAI to generate release notes
|
|
198
224
|
const openaiClient = new OpenAI({
|
|
199
225
|
apiKey: process.env['OPENAI_API_KEY'],
|
|
200
226
|
});
|
|
@@ -231,22 +257,23 @@ program
|
|
|
231
257
|
console.log(`Change type: ${change_type}`);
|
|
232
258
|
console.log(`Release note: ${summary}`);
|
|
233
259
|
|
|
234
|
-
// Step 5: Create a changeset
|
|
260
|
+
// Step 5: Create a changeset .md file
|
|
235
261
|
const changesetContent = `---
|
|
236
262
|
"${componentName}": ${change_type}
|
|
237
263
|
---
|
|
238
264
|
|
|
239
265
|
${summary} [${jiraTicketId}]
|
|
240
|
-
|
|
266
|
+
`;
|
|
241
267
|
const changesetFile = `./.changeset/${jiraTicketId}.md`;
|
|
242
268
|
|
|
243
|
-
await
|
|
269
|
+
await createChangesetDirectory();
|
|
244
270
|
await fs.promises.writeFile(changesetFile, changesetContent);
|
|
245
271
|
console.log(`Created changeset file at ${changesetFile}`);
|
|
246
272
|
|
|
247
273
|
console.log('Done!');
|
|
248
274
|
} catch (err) {
|
|
249
275
|
console.error(`Error: ${err.message}`);
|
|
276
|
+
process.exit(1);
|
|
250
277
|
}
|
|
251
278
|
});
|
|
252
279
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import groovy.json.JsonSlurper
|
|
2
|
+
|
|
3
|
+
import hudson.model.*;
|
|
4
|
+
|
|
5
|
+
def build = Thread.currentThread().executable
|
|
6
|
+
def params = build.getEnvironment(listener)
|
|
7
|
+
|
|
8
|
+
def site = params.get('site')
|
|
9
|
+
def server = "jboss7"
|
|
10
|
+
def environment = params.get('environment')
|
|
11
|
+
|
|
12
|
+
def buildFile=new File("D:\\Docupace\\CustomFolders\\" + environment + "\\" + site + "\\" + server + "\\buildApp.properties")
|
|
13
|
+
|
|
14
|
+
List<String> jboss7controllerResult = []
|
|
15
|
+
|
|
16
|
+
def controllersReport = new File("D:\\Docupace\\controllers_report.json")
|
|
17
|
+
def inputJSON = new JsonSlurper().parseText(controllersReport.text)
|
|
18
|
+
def props = new Properties()
|
|
19
|
+
buildFile.withInputStream { stream -> props.load(stream) }
|
|
20
|
+
def webRootContext = props["web.root.context"]
|
|
21
|
+
if (webRootContext == null || webRootContext =="core") webRootContext = props["docupace.config.client.id"].toLowerCase()
|
|
22
|
+
|
|
23
|
+
webRootContext = webRootContext.replaceFirst('_sso','')
|
|
24
|
+
def map = inputJSON.'content'
|
|
25
|
+
|
|
26
|
+
def Boolean enabled
|
|
27
|
+
|
|
28
|
+
map.each {k,v ->
|
|
29
|
+
v.each{vk, vv -> if (vk == webRootContext ) {
|
|
30
|
+
enabled = false
|
|
31
|
+
if(vv.deploymentsProperty.size()>0) enabled = vv.deploymentsProperty[0].isEnabled
|
|
32
|
+
if (enabled) jboss7controllerResult.push(k)
|
|
33
|
+
else jboss7controllerResult << k
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (jboss7controllerResult.size()>0) {
|
|
39
|
+
if (environment == 'preprod') {
|
|
40
|
+
jboss7controllerResult.remove("dev-corjbdc10.corp.docupace.com")
|
|
41
|
+
jboss7controllerResult.remove("usdoc-s-jbdc1.corp.docupace.com")
|
|
42
|
+
}
|
|
43
|
+
if (environment == 'dev') {
|
|
44
|
+
jboss7controllerResult.remove("qa-corjbdc10.corp.docupace.com")
|
|
45
|
+
jboss7controllerResult.remove("qa-corjbdc20.corp.docupace.com")
|
|
46
|
+
jboss7controllerResult.remove("usdoc-s-jbdc2.corp.docupace.com")
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
println jboss7controllerResult[0]
|
|
51
|
+
|
|
52
|
+
env.jboss7controller = jboss7controllerResult[0]
|
|
53
|
+
|
|
54
|
+
def serverGroup = inputJSON.'content'."${jboss7controller}"."${webRootContext}".'serverGroup'
|
|
55
|
+
|
|
56
|
+
println serverGroup
|
|
57
|
+
|
|
58
|
+
params.put("serverGroup", serverGroup)
|
|
59
|
+
|
package/src/next/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Command } from 'commander';
|
|
|
4
4
|
import { pull } from './pull.js';
|
|
5
5
|
import { sonar } from './sonar.js';
|
|
6
6
|
import { publish } from './publish.js';
|
|
7
|
-
import {
|
|
7
|
+
import { deployFromSite } from './deploy.js';
|
|
8
8
|
import { deployTemplate } from './deploy.js';
|
|
9
9
|
import { copy } from './copy.js';
|
|
10
10
|
import dotenv from 'dotenv';
|
|
@@ -15,7 +15,8 @@ const program = new Command();
|
|
|
15
15
|
|
|
16
16
|
// GIT SHA computation
|
|
17
17
|
import { $ } from 'zx';
|
|
18
|
-
import {
|
|
18
|
+
import { deployCore } from './jenkins.js';
|
|
19
|
+
import {runPipeline, triggerPipelineByName} from './pipline.js';
|
|
19
20
|
const GIT_SHA = (await $`git log --pretty=format:'%h' -n 1`).stdout.trim();
|
|
20
21
|
|
|
21
22
|
program
|
|
@@ -46,9 +47,10 @@ program
|
|
|
46
47
|
.requiredOption('-t, --to-env <toEnv>', 'Target environment')
|
|
47
48
|
.requiredOption('-F, --from-site <fromSite>', 'Source site')
|
|
48
49
|
.requiredOption('-T, --to-site <toSite>', 'Target site')
|
|
50
|
+
.option('-c, --deploy-core <deployCore>', 'Deploy Core', 'false')
|
|
49
51
|
.action(async (options) => {
|
|
50
|
-
const { fromEnv, fromSite, toEnv, toSite } = options;
|
|
51
|
-
await deployFromSite(fromEnv, fromSite, toEnv, toSite);
|
|
52
|
+
const { fromEnv, fromSite, toEnv, toSite, deployCore } = options;
|
|
53
|
+
await deployFromSite(fromEnv, fromSite, toEnv, toSite, deployCore);
|
|
52
54
|
});
|
|
53
55
|
|
|
54
56
|
program
|
|
@@ -61,8 +63,24 @@ program
|
|
|
61
63
|
program
|
|
62
64
|
.command('deploy-core <env> <site>')
|
|
63
65
|
.description('Deploy Core')
|
|
64
|
-
.
|
|
65
|
-
|
|
66
|
+
.option('-l, --liquibase <liquibase>', 'Application name', 'true')
|
|
67
|
+
.option('-b, --branch <branch>', 'Branch', 'master')
|
|
68
|
+
.action(async (env, site, options) => {
|
|
69
|
+
await deployCore(env, site, options.liquibase, options.branch);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
program
|
|
73
|
+
.command('deploy-core-pipeline <env> <site>')
|
|
74
|
+
.description('Deploy Core')
|
|
75
|
+
.option('-l, --liquibase <liquibase>', 'Application name', 'true')
|
|
76
|
+
.option('-b, --branch <branch>', 'Branch', 'master')
|
|
77
|
+
.action(async (env, site, options) => {
|
|
78
|
+
await runPipeline('site-deploy', 'deploy-core', 'main', {
|
|
79
|
+
ENV: env,
|
|
80
|
+
SITE: site,
|
|
81
|
+
LIQUIBASE: options.liquibase,
|
|
82
|
+
BRANCH: options.branch,
|
|
83
|
+
});
|
|
66
84
|
});
|
|
67
85
|
|
|
68
86
|
program
|
|
@@ -77,4 +95,34 @@ program
|
|
|
77
95
|
await copy(application, fromEnv, toEnv, tag);
|
|
78
96
|
});
|
|
79
97
|
|
|
98
|
+
program
|
|
99
|
+
.command('trigger-pipeline')
|
|
100
|
+
.description('Trigger a pipeline by name')
|
|
101
|
+
.requiredOption('-r, --repository <repository>', 'Repository name')
|
|
102
|
+
.requiredOption('-p, --pipeline-name <pipelineName>', 'Pipeline name')
|
|
103
|
+
.requiredOption('-b, --branch <branch>', 'Branch name')
|
|
104
|
+
.option(
|
|
105
|
+
'-v, --variables <key=value>',
|
|
106
|
+
'Pipeline variable as key=value pair',
|
|
107
|
+
(value, previous) => {
|
|
108
|
+
const [key, val] = value.split('=');
|
|
109
|
+
if (!key || val === undefined) {
|
|
110
|
+
throw new Error(`Invalid variable format: ${value}. Use key=value.`);
|
|
111
|
+
}
|
|
112
|
+
return { ...previous, [key]: val };
|
|
113
|
+
},
|
|
114
|
+
{},
|
|
115
|
+
) // Initialize as an empty object
|
|
116
|
+
.action(async (cmdObj) => {
|
|
117
|
+
try {
|
|
118
|
+
const { repository, pipelineName, branch, variables } = cmdObj;
|
|
119
|
+
|
|
120
|
+
// Call the triggerPipelineByName function
|
|
121
|
+
await triggerPipelineByName(repository, pipelineName, branch, variables);
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error('Error triggering pipeline:', error.message);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
80
128
|
program.parse(process.argv);
|
package/src/next/config.js
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
export const environments = ['dev', 'qa', 'uat', 'stage', 'prod'];
|
|
2
2
|
|
|
3
|
+
export const environmentConfig = {
|
|
4
|
+
dev: {
|
|
5
|
+
newUrl: (site) => `${site}.dev.dpai.tech`,
|
|
6
|
+
oldUrl: (site) => `https://www.dev.docupaceinc.com/${site}`,
|
|
7
|
+
},
|
|
8
|
+
qa: {
|
|
9
|
+
newUrl: (site) => `${site}.qa.dpai.tech`,
|
|
10
|
+
oldUrl: (site) => `https://www.preprod.docupaceinc.com/${site}`,
|
|
11
|
+
},
|
|
12
|
+
uat: {
|
|
13
|
+
newUrl: (site) => `${site}.qa.dpai.tech`,
|
|
14
|
+
oldUrl: (site) => `https://www2.paperout.com/${site}_uat`,
|
|
15
|
+
},
|
|
16
|
+
stage: {
|
|
17
|
+
newUrl: (site) => `${site}.stage.dpai.tech`,
|
|
18
|
+
oldUrl: (site) => `https://www2.paperout.com/${site}_staging`,
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
prod: {
|
|
22
|
+
newUrl: (site) => `${site}.dpai.tech`,
|
|
23
|
+
oldUrl: (site) => `https://www2.paperout.com/${site}`,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
3
27
|
export const appInfo = {
|
|
4
28
|
'graphql-server': {
|
|
5
29
|
repositoryName: 'docupace-graphql-server',
|
|
@@ -35,7 +59,14 @@ export const getBitbucketInfo = () => {
|
|
|
35
59
|
return {
|
|
36
60
|
username: process.env.BITBUCKET_USERNAME,
|
|
37
61
|
password: process.env.BITBUCKET_APP_PASSWORD,
|
|
62
|
+
workspace: 'dp-cloud',
|
|
38
63
|
};
|
|
39
64
|
};
|
|
40
65
|
|
|
66
|
+
export const getRepUrl = (repoName) => {
|
|
67
|
+
const { username, password, workspace } = getBitbucketInfo();
|
|
68
|
+
const repoUrl = `https://${username}:${password}@bitbucket.org/${workspace}/${repoName}.git`;
|
|
69
|
+
return repoUrl;
|
|
70
|
+
};
|
|
71
|
+
|
|
41
72
|
export const jfRegistryUrl = 'registry.paperout.com';
|
package/src/next/deploy.js
CHANGED
|
@@ -3,8 +3,11 @@ import path from 'path';
|
|
|
3
3
|
import yaml from 'js-yaml';
|
|
4
4
|
import { $ } from 'zx';
|
|
5
5
|
import lodash from 'lodash';
|
|
6
|
-
import { appInfo,
|
|
6
|
+
import { appInfo, environmentConfig, getRepUrl } from './config.js';
|
|
7
7
|
import { copy } from './copy.js';
|
|
8
|
+
import axios from 'axios';
|
|
9
|
+
import { runPipeline } from './pipline.js';
|
|
10
|
+
import { deployCore } from './jenkins.js';
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* Clone the repository, read the YAML file, and return the parsed data and file paths.
|
|
@@ -21,8 +24,7 @@ function getRepoLocalPath(env) {
|
|
|
21
24
|
|
|
22
25
|
async function cloneEnvRepository(env) {
|
|
23
26
|
const { repoPath, repoName } = getRepoLocalPath(env);
|
|
24
|
-
const
|
|
25
|
-
const repoUrl = `https://${username}:${password}@bitbucket.org/dp-cloud/${repoName}.git`;
|
|
27
|
+
const repoUrl = getRepUrl(repoName);
|
|
26
28
|
console.log(`Cloning repository: ${repoName}`);
|
|
27
29
|
await $`git clone ${repoUrl}`;
|
|
28
30
|
console.log(`Repository cloned to: ${repoPath}`);
|
|
@@ -57,7 +59,7 @@ async function readDeployConfig(application, env, site) {
|
|
|
57
59
|
export async function cloneAndReadDeployConfig(application, env, site) {
|
|
58
60
|
const repoPath = await cloneEnvRepository(env);
|
|
59
61
|
|
|
60
|
-
const { deployConfig, deployConfigFilePath } = readDeployConfig(
|
|
62
|
+
const { deployConfig, deployConfigFilePath } = await readDeployConfig(
|
|
61
63
|
application,
|
|
62
64
|
env,
|
|
63
65
|
site,
|
|
@@ -107,7 +109,7 @@ export async function pushDeployConfig(repoPath, commitMessage) {
|
|
|
107
109
|
console.log('📌 Committing changes to the repository...');
|
|
108
110
|
await $`cd ${repoPath} && git config user.email "gitops@docupace.com"`;
|
|
109
111
|
await $`cd ${repoPath} && git add .`;
|
|
110
|
-
await $`cd ${repoPath} && git commit -m
|
|
112
|
+
await $`cd ${repoPath} && git commit -m ${commitMessage}`;
|
|
111
113
|
await $`cd ${repoPath} && git push`;
|
|
112
114
|
console.log('✅ Changes pushed to the remote repository.');
|
|
113
115
|
|
|
@@ -187,7 +189,72 @@ export async function deploy(application, site) {
|
|
|
187
189
|
console.log('Deployment completed successfully.');
|
|
188
190
|
}
|
|
189
191
|
|
|
190
|
-
|
|
192
|
+
async function getAppInfo(coreUrl) {
|
|
193
|
+
const url = `${coreUrl}/b2b/rest/v1/appinfo`;
|
|
194
|
+
return await axios.get(url);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function getBranchNameFromVersion(version) {
|
|
198
|
+
const match = version.match(/(\d+\.\d+\.[^\-]+)(?:-(\d+)-g([a-f0-9]+))?/);
|
|
199
|
+
|
|
200
|
+
if (!match) {
|
|
201
|
+
throw new Error(`Invalid version format: ${version}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const fullVersion = match[1]; // e.g., 24.19.19, 24.20.alpha3, etc.
|
|
205
|
+
const customBranch = match[2]; // e.g., 4, 58, or 0
|
|
206
|
+
const commitHash = match[3]; // e.g., 668edef58e, 634cf6c904, etc.
|
|
207
|
+
|
|
208
|
+
// If "alpha" is in the version or customBranch is non-zero, use the commit hash
|
|
209
|
+
if (fullVersion.includes('alpha') || (customBranch && customBranch !== '0')) {
|
|
210
|
+
return commitHash;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Otherwise, use the full version
|
|
214
|
+
return fullVersion;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function getCoreBranchName(fromEnv, fromSite) {
|
|
218
|
+
const envConfig = environmentConfig[fromEnv];
|
|
219
|
+
const oldUrl = envConfig.oldUrl(fromSite);
|
|
220
|
+
const newUrl = envConfig.newUrl(fromSite) + '/core';
|
|
221
|
+
|
|
222
|
+
let appinfo;
|
|
223
|
+
try {
|
|
224
|
+
appinfo = await getAppInfo(oldUrl);
|
|
225
|
+
} catch {
|
|
226
|
+
try {
|
|
227
|
+
appinfo = await getAppInfo(newUrl);
|
|
228
|
+
} catch {
|
|
229
|
+
throw new Error('Cannot get app info');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const coreVersion = appinfo.data.core.version;
|
|
234
|
+
const branchName = getBranchNameFromVersion(coreVersion);
|
|
235
|
+
return branchName;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export async function deployFromSite(
|
|
239
|
+
fromEnv,
|
|
240
|
+
fromSite,
|
|
241
|
+
toEnv,
|
|
242
|
+
toSite,
|
|
243
|
+
isDeployCore,
|
|
244
|
+
) {
|
|
245
|
+
if (isDeployCore === 'true') {
|
|
246
|
+
const branchName = await getCoreBranchName(fromEnv, fromSite);
|
|
247
|
+
await deployCore(toEnv, toSite, 'true', branchName);
|
|
248
|
+
|
|
249
|
+
// To be added back when splitting between on prem and in cloud
|
|
250
|
+
/*await runPipeline('site-deploy', 'deploy-core', 'main', {
|
|
251
|
+
ENV: toEnv,
|
|
252
|
+
SITE: toSite,
|
|
253
|
+
LIQUIBASE: 'true',
|
|
254
|
+
BRANCH: branchName,
|
|
255
|
+
});*/
|
|
256
|
+
}
|
|
257
|
+
|
|
191
258
|
// Clone repositories for source and target environments
|
|
192
259
|
const fromRepoPath = await cloneEnvRepository(fromEnv);
|
|
193
260
|
const toRepoPath =
|
package/src/next/jenkins.js
CHANGED
|
@@ -4,19 +4,21 @@ const JENKINS_URL = 'http://devops.corp.docupace.com';
|
|
|
4
4
|
const JOB_NAME = 'auto-deploy-site';
|
|
5
5
|
const USERNAME = process.env.CORE_JENKINS_USERNAME;
|
|
6
6
|
const API_TOKEN = process.env.CORE_JENKINS_API_TOKEN;
|
|
7
|
-
const PARAMETERS = {
|
|
8
|
-
environment: 'dev',
|
|
9
|
-
site: 'TEMPLATE',
|
|
10
|
-
runLiquibase: 'true',
|
|
11
|
-
};
|
|
12
7
|
|
|
13
|
-
export async function
|
|
8
|
+
export async function deployCore(env, site, liquibase, gitBranch) {
|
|
9
|
+
const parameters = {
|
|
10
|
+
environment: env,
|
|
11
|
+
site: site.toUpperCase(),
|
|
12
|
+
runLiquibase: liquibase,
|
|
13
|
+
gitBranch,
|
|
14
|
+
};
|
|
15
|
+
|
|
14
16
|
try {
|
|
15
17
|
// Trigger the job
|
|
16
18
|
console.log('Triggering Jenkins job...');
|
|
17
19
|
const buildResponse = await axios.post(
|
|
18
20
|
`${JENKINS_URL}/job/${JOB_NAME}/buildWithParameters`,
|
|
19
|
-
new URLSearchParams(
|
|
21
|
+
new URLSearchParams(parameters),
|
|
20
22
|
{
|
|
21
23
|
auth: { username: USERNAME, password: API_TOKEN },
|
|
22
24
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { getBitbucketInfo } from './config.js';
|
|
3
|
+
|
|
4
|
+
const BITBUCKET_BASE_URL = 'https://api.bitbucket.org/2.0';
|
|
5
|
+
|
|
6
|
+
export async function triggerPipelineByName(
|
|
7
|
+
repository,
|
|
8
|
+
pipelineName,
|
|
9
|
+
branch,
|
|
10
|
+
variables,
|
|
11
|
+
) {
|
|
12
|
+
const { username, password, workspace } = getBitbucketInfo();
|
|
13
|
+
const url = `${BITBUCKET_BASE_URL}/repositories/${workspace}/${repository}/pipelines/`;
|
|
14
|
+
const auth = {
|
|
15
|
+
username: username,
|
|
16
|
+
password: password,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const payload = {
|
|
20
|
+
target: {
|
|
21
|
+
type: 'pipeline_ref_target',
|
|
22
|
+
ref_type: 'branch',
|
|
23
|
+
ref_name: branch,
|
|
24
|
+
selector: {
|
|
25
|
+
type: 'custom',
|
|
26
|
+
pattern: pipelineName,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
variables: Object.entries(variables).map(([key, value]) => ({
|
|
30
|
+
key,
|
|
31
|
+
value,
|
|
32
|
+
secured: false, // Set to true if the variable should be secure
|
|
33
|
+
})),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const response = await axios.post(url, payload, { auth });
|
|
38
|
+
return response.data;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error(
|
|
41
|
+
'Error triggering custom pipeline:',
|
|
42
|
+
error.response?.data || error.message,
|
|
43
|
+
);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function getPipelineStatus(repository, pipelineUUID) {
|
|
49
|
+
const { username, password, workspace } = getBitbucketInfo();
|
|
50
|
+
const url = `${BITBUCKET_BASE_URL}/repositories/${workspace}/${repository}/pipelines/${pipelineUUID}`;
|
|
51
|
+
const auth = {
|
|
52
|
+
username: username,
|
|
53
|
+
password: password,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const response = await axios.get(url, { auth });
|
|
58
|
+
return response.data.state.name;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error(
|
|
61
|
+
'Error fetching pipeline status:',
|
|
62
|
+
error.response?.data || error.message,
|
|
63
|
+
);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function runPipeline(repository, pipelineName, branch, variables) {
|
|
69
|
+
try {
|
|
70
|
+
console.log(
|
|
71
|
+
`Triggering custom pipeline: ${pipelineName} for branch: ${branch}...`,
|
|
72
|
+
);
|
|
73
|
+
const pipeline = await triggerPipelineByName(
|
|
74
|
+
repository,
|
|
75
|
+
pipelineName,
|
|
76
|
+
branch,
|
|
77
|
+
variables,
|
|
78
|
+
);
|
|
79
|
+
const pipelineUUID = pipeline.uuid;
|
|
80
|
+
|
|
81
|
+
console.log(`Pipeline triggered with UUID: ${pipelineUUID}`);
|
|
82
|
+
let status = '';
|
|
83
|
+
do {
|
|
84
|
+
console.log('Checking pipeline status...');
|
|
85
|
+
await new Promise((resolve) => setTimeout(resolve, 10000)); // Wait 10 seconds
|
|
86
|
+
status = await getPipelineStatus(repository, pipelineUUID);
|
|
87
|
+
console.log(`Pipeline status: ${status}`);
|
|
88
|
+
} while (['IN_PROGRESS', 'PENDING', 'RUNNING'].includes(status));
|
|
89
|
+
|
|
90
|
+
console.log(`Pipeline completed with status: ${status}`);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error('Error monitoring pipeline:', error.message);
|
|
93
|
+
}
|
|
94
|
+
}
|