@docupace/pipeline 1.0.8-6.xray → 1.0.9
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/eslint.config.js +2 -25
- package/next/execute.sh +2 -8
- package/package.json +7 -23
- package/src/changeset/cli.js +195 -151
- package/src/changeset/validate.js +1 -45
- package/src/jenkins/setParams.groovy +2 -1
- package/src/next/cli.js +15 -111
- package/src/next/config.js +7 -72
- package/src/next/copy.js +1 -32
- package/src/next/deploy.js +75 -514
- package/src/next/jenkins.js +2 -3
- package/src/next/pipline.js +1 -0
- package/src/next/publish.js +30 -53
- package/README.md +0 -136
- package/bin/azuread_update_callbacks_for_app.sh +0 -58
- package/bin/xray.sh +0 -273
- package/bitbucket-pipelines.yml +0 -142
- package/jest.config.js +0 -15
- package/src/auth0/alias.js +0 -79
- package/src/auth0/alias.test.js +0 -172
- package/src/auth0/cli.js +0 -82
- package/src/auth0/configure.js +0 -902
- package/src/auth0/configure.test.js +0 -167
- package/src/auth0/export.js +0 -48
- package/src/auth0/export.test.js +0 -103
- package/src/auth0/metadata.js +0 -141
- package/src/auth0/metadata.test.js +0 -186
- package/src/auth0/vault.js +0 -60
- package/src/auth0/vault.test.js +0 -134
- package/src/changeset/changelog-wiki.js +0 -328
- package/src/changeset/changeset-config.js +0 -34
- package/src/changeset/create.js +0 -215
- package/src/changeset/package-util.js +0 -87
- package/src/changeset/util.js +0 -43
- package/src/changeset/version.js +0 -102
- package/src/jfrog/xray-scan.yaml +0 -29
- package/src/lib/merge-driver.js +0 -204
- package/src/merge/cli-merge-all.js +0 -521
- package/src/merge/cli-merge.js +0 -572
- package/src/merge/cli-resolve.js +0 -399
- package/src/merge/cli.js +0 -38
- package/src/merge/common.js +0 -7
- package/src/merge/merge-changelog.js +0 -87
- package/src/merge/merge-package.js +0 -106
- package/src/merge/merge-types.js +0 -82
- package/src/merge/pr.js +0 -231
- package/src/micro/cli.js +0 -51
- package/src/micro/ms-deploy.js +0 -451
- package/src/micro/ms-publish.js +0 -186
- package/src/next/alias.js +0 -53
- package/src/next/apache.js +0 -81
- package/src/next/connect.js +0 -226
- package/src/next/git-to-semver.js +0 -79
- package/src/next/haproxy.js +0 -76
- package/src/next/jira.js +0 -84
- package/src/next/logger.js +0 -17
- package/src/next/test.js +0 -5
- package/src/next/util.js +0 -95
- package/src/next/vault.js +0 -45
- package/terraform/apply.sh +0 -41
- package/terraform/import.sh +0 -111
- package/terraform/init.sh +0 -78
- package/terraform/plan.sh +0 -95
- package/terraform/validate.sh +0 -17
package/src/next/deploy.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
1
|
import fs from 'fs';
|
|
3
|
-
import yaml from 'js-yaml';
|
|
4
|
-
import lodash from 'lodash';
|
|
5
2
|
import path from 'path';
|
|
6
|
-
import
|
|
3
|
+
import yaml from 'js-yaml';
|
|
7
4
|
import { $ } from 'zx';
|
|
5
|
+
import lodash from 'lodash';
|
|
8
6
|
import { appInfo, environmentConfig, getRepUrl } from './config.js';
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
7
|
+
import { copy } from './copy.js';
|
|
8
|
+
import axios from 'axios';
|
|
9
|
+
import { runPipeline } from './pipline.js';
|
|
10
|
+
import { deployCore } from './jenkins.js';
|
|
13
11
|
|
|
14
12
|
/**
|
|
15
13
|
* Clone the repository, read the YAML file, and return the parsed data and file paths.
|
|
@@ -24,130 +22,11 @@ function getRepoLocalPath(env) {
|
|
|
24
22
|
return { repoPath, repoName };
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
async function
|
|
28
|
-
toEnv,
|
|
29
|
-
toSite,
|
|
30
|
-
getComparedVersion,
|
|
31
|
-
connectDeployPath,
|
|
32
|
-
) {
|
|
33
|
-
const connectToEnv = toEnv == 'qa' ? 'preprod' : toEnv;
|
|
34
|
-
const filePath = path.join(
|
|
35
|
-
connectDeployPath,
|
|
36
|
-
'envs',
|
|
37
|
-
connectToEnv,
|
|
38
|
-
toSite,
|
|
39
|
-
'dock.sh',
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
let content = fs.readFileSync(filePath, 'utf8');
|
|
44
|
-
content = content.replace(
|
|
45
|
-
/IMAGE_VERSION=.*/,
|
|
46
|
-
`IMAGE_VERSION=git-commit-${getComparedVersion}`,
|
|
47
|
-
);
|
|
48
|
-
fs.writeFileSync(filePath, content, 'utf8');
|
|
49
|
-
|
|
50
|
-
// Git commands to stage, commit and push changes
|
|
51
|
-
await $`cd ${connectDeployPath} && git config user.email "gitops@docupace.com"`;
|
|
52
|
-
|
|
53
|
-
if (process.env.BITBUCKET_STEP_TRIGGERER_UUID) {
|
|
54
|
-
try {
|
|
55
|
-
const response = await axios.get(
|
|
56
|
-
`https://api.bitbucket.org/2.0/users/${process.env.BITBUCKET_STEP_TRIGGERER_UUID}`,
|
|
57
|
-
);
|
|
58
|
-
const triggererUsername = response.data.display_name;
|
|
59
|
-
console.log(`📌 Run triggered by: ${triggererUsername}`);
|
|
60
|
-
await $`cd ${connectDeployPath} && git config user.name ${triggererUsername}`;
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.warn('Failed to fetch Bitbucket user info:', error.message);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
await $`cd ${connectDeployPath} && git add .`;
|
|
67
|
-
await $`cd ${connectDeployPath} && git commit -m "Update Connect version for ${toSite} in ${toEnv} to ${getComparedVersion}" || echo "No changes to commit"`;
|
|
68
|
-
await $`cd ${connectDeployPath} && git push`;
|
|
69
|
-
|
|
70
|
-
console.log('🧹 Cleaning up...');
|
|
71
|
-
await $`rm -rf ${connectDeployPath}`;
|
|
72
|
-
console.log('✅ Cleanup complete.');
|
|
73
|
-
} catch (error) {
|
|
74
|
-
console.error('Error updating Connect version:', error);
|
|
75
|
-
throw error;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async function fetchLoginFooter(env, site, isNewUrl) {
|
|
80
|
-
const url = isNewUrl
|
|
81
|
-
? environmentConfig[env].newUrl(site)
|
|
82
|
-
: environmentConfig[env].oldUrl(site);
|
|
83
|
-
const endpoint = isNewUrl ? '/connect/loginFooter' : '_ui/loginFooter';
|
|
84
|
-
return await axios.get(`${url}${endpoint}`);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async function compareGetConnectSiteVersions(fromEnv, fromSite, toEnv, toSite) {
|
|
88
|
-
try {
|
|
89
|
-
let fromResponse, toResponse;
|
|
90
|
-
try {
|
|
91
|
-
fromResponse = await fetchLoginFooter(fromEnv, fromSite, true);
|
|
92
|
-
} catch {
|
|
93
|
-
fromResponse = await fetchLoginFooter(fromEnv, fromSite, false);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
toResponse = await fetchLoginFooter(toEnv, toSite, true);
|
|
98
|
-
} catch {
|
|
99
|
-
toResponse = await fetchLoginFooter(toEnv, toSite, false);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const fromMatch = fromResponse.data.match(/UI Build: ([a-f0-9]*)/);
|
|
103
|
-
const toMatch = toResponse.data.match(/UI Build: ([a-f0-9]*)/);
|
|
104
|
-
|
|
105
|
-
if (fromMatch && fromMatch[1] && toMatch && toMatch[1]) {
|
|
106
|
-
if (fromMatch[1] !== toMatch[1]) {
|
|
107
|
-
return fromMatch[1];
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return false;
|
|
111
|
-
} catch (error) {
|
|
112
|
-
console.error('Error fetching Connect versions:', error);
|
|
113
|
-
throw error;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
function getRepoLocalPathByRepoSlug(repoSlug) {
|
|
117
|
-
const repoName = `${repoSlug}`;
|
|
118
|
-
const repoPath = path.join(process.cwd(), repoName);
|
|
119
|
-
return { repoPath, repoName };
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function cleanUpRepoPath(repoPath) {
|
|
123
|
-
// Check and handle repo directory
|
|
124
|
-
if (fs.existsSync(repoPath)) {
|
|
125
|
-
console.log(`${repoPath} directory exists. Removing it...`);
|
|
126
|
-
fs.rmSync(repoPath, {
|
|
127
|
-
recursive: true,
|
|
128
|
-
force: true,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export async function cloneEnvRepository(env) {
|
|
25
|
+
async function cloneEnvRepository(env) {
|
|
134
26
|
const { repoPath, repoName } = getRepoLocalPath(env);
|
|
135
27
|
const repoUrl = getRepUrl(repoName);
|
|
136
28
|
console.log(`Cloning repository: ${repoName}`);
|
|
137
|
-
await
|
|
138
|
-
await $`git clone --depth 1 ${repoUrl}`;
|
|
139
|
-
console.log(`Repository cloned to: ${repoPath}`);
|
|
140
|
-
return repoPath;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export async function cloneRepository(repoSlug) {
|
|
144
|
-
const { repoPath, repoName } = getRepoLocalPathByRepoSlug(repoSlug);
|
|
145
|
-
const repoUrl = getRepUrl(repoName);
|
|
146
|
-
|
|
147
|
-
await cleanUpRepoPath(repoPath);
|
|
148
|
-
|
|
149
|
-
console.log(`Cloning repository: ${repoName}`);
|
|
150
|
-
await $`git clone --depth 1 ${repoUrl}`;
|
|
29
|
+
await $`git clone ${repoUrl}`;
|
|
151
30
|
console.log(`Repository cloned to: ${repoPath}`);
|
|
152
31
|
return repoPath;
|
|
153
32
|
}
|
|
@@ -162,24 +41,7 @@ function getConfigPath(application, env, site, name) {
|
|
|
162
41
|
return { repoPath, deployConfigFilePath };
|
|
163
42
|
}
|
|
164
43
|
|
|
165
|
-
function
|
|
166
|
-
const { repoPath } = getRepoLocalPath(env);
|
|
167
|
-
const deployConfigFilePath = path.join(repoPath, `dp/${site}`);
|
|
168
|
-
const applications = [];
|
|
169
|
-
if (fs.existsSync(deployConfigFilePath)) {
|
|
170
|
-
const files = fs.readdirSync(deployConfigFilePath);
|
|
171
|
-
files.forEach((file) => {
|
|
172
|
-
if (file.includes('.values.yaml')) {
|
|
173
|
-
const appName = file.split('.')[0];
|
|
174
|
-
applications.push(appName);
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return { applications };
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export async function readDeployConfig(application, env, site, name) {
|
|
44
|
+
async function readDeployConfig(application, env, site, name) {
|
|
183
45
|
const { deployConfigFilePath } = getConfigPath(application, env, site, name);
|
|
184
46
|
|
|
185
47
|
let deployConfig;
|
|
@@ -247,20 +109,6 @@ export async function pushDeployConfig(repoPath, commitMessage) {
|
|
|
247
109
|
|
|
248
110
|
console.log('📌 Committing changes to the repository...');
|
|
249
111
|
await $`cd ${repoPath} && git config user.email "gitops@docupace.com"`;
|
|
250
|
-
|
|
251
|
-
if (process.env.BITBUCKET_STEP_TRIGGERER_UUID) {
|
|
252
|
-
try {
|
|
253
|
-
const response = await axios.get(
|
|
254
|
-
`https://api.bitbucket.org/2.0/users/${process.env.BITBUCKET_STEP_TRIGGERER_UUID}`,
|
|
255
|
-
);
|
|
256
|
-
const triggererUsername = response.data.display_name;
|
|
257
|
-
console.log(`📌 Run triggered by: ${triggererUsername}`);
|
|
258
|
-
await $`cd ${repoPath} && git config user.name ${triggererUsername}`;
|
|
259
|
-
} catch (error) {
|
|
260
|
-
console.warn('Failed to fetch Bitbucket user info:', error.message);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
112
|
await $`cd ${repoPath} && git add .`;
|
|
265
113
|
await $`cd ${repoPath} && git commit -m ${commitMessage}`;
|
|
266
114
|
await $`cd ${repoPath} && git push`;
|
|
@@ -297,62 +145,22 @@ export async function writeAndPushDeployConfig(
|
|
|
297
145
|
* @param {string} site - The site name.
|
|
298
146
|
*/
|
|
299
147
|
|
|
300
|
-
|
|
148
|
+
async function getDeployTag() {
|
|
301
149
|
const gitTag = (
|
|
302
|
-
await $`git tag --points-at HEAD | grep '
|
|
150
|
+
await $`git tag --points-at HEAD | grep '^v' | head -n 1`
|
|
303
151
|
).stdout.trim();
|
|
304
152
|
const deployTag = gitTag || `build-${process.env.BITBUCKET_BUILD_NUMBER}`;
|
|
305
153
|
return deployTag;
|
|
306
154
|
}
|
|
307
155
|
|
|
308
|
-
function
|
|
309
|
-
const
|
|
310
|
-
const match = tag.match(semverRegex);
|
|
311
|
-
|
|
312
|
-
if (!match) {
|
|
313
|
-
throw new Error(`Invalid tag format: ${tag}`);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const [_, major, minor, patch, preRelease] = match;
|
|
317
|
-
const isAlpha = preRelease && preRelease.toLowerCase().includes('alpha');
|
|
318
|
-
|
|
319
|
-
return config
|
|
320
|
-
.filter((entry) => {
|
|
321
|
-
if (entry.version.toLowerCase() === 'alpha' && isAlpha) {
|
|
322
|
-
return true;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
const [entryMajor, entryMinor] = entry.version.split('.');
|
|
326
|
-
return (
|
|
327
|
-
!isAlpha &&
|
|
328
|
-
parseInt(entryMajor) === parseInt(major) &&
|
|
329
|
-
parseInt(entryMinor) === parseInt(minor)
|
|
330
|
-
);
|
|
331
|
-
})
|
|
332
|
-
.map((entry) => ({ env: entry.env, site: entry.site }));
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
export async function getDefaultDeploySite(deployTag) {
|
|
336
|
-
const repPath = await cloneEnvRepository('dev');
|
|
337
|
-
const autoDeployConfigPath = path.resolve(repPath, 'auto-deploy.yaml');
|
|
338
|
-
const autoDeployConfig = yaml.load(
|
|
339
|
-
fs.readFileSync(autoDeployConfigPath, 'utf8'),
|
|
340
|
-
);
|
|
341
|
-
return getDeploymentTargets(deployTag, autoDeployConfig);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
export async function deployTemplate(
|
|
345
|
-
env,
|
|
346
|
-
site,
|
|
347
|
-
deployTag,
|
|
348
|
-
templateType = 'standardConfigRemoteBranch',
|
|
349
|
-
) {
|
|
156
|
+
export async function deployTemplate(site) {
|
|
157
|
+
const deployTag = await getDeployTag();
|
|
350
158
|
console.log(`Deploying standard template for site: ${site}`);
|
|
351
159
|
console.log(`Using deployment tag: ${deployTag}`);
|
|
352
160
|
const { repoPath, deployConfigFilePath, deployConfig } =
|
|
353
|
-
await cloneAndReadDeployConfig('graphql-server',
|
|
161
|
+
await cloneAndReadDeployConfig('graphql-server', 'dev', site);
|
|
354
162
|
|
|
355
|
-
deployConfig.graphqlServer
|
|
163
|
+
deployConfig.graphqlServer.standardConfigRemoteBranch = deployTag;
|
|
356
164
|
|
|
357
165
|
await writeAndPushDeployConfig(
|
|
358
166
|
repoPath,
|
|
@@ -363,69 +171,15 @@ export async function deployTemplate(
|
|
|
363
171
|
console.log('Deployment completed successfully.');
|
|
364
172
|
}
|
|
365
173
|
|
|
366
|
-
export async function
|
|
174
|
+
export async function deploy(application, site) {
|
|
175
|
+
const deployTag = getDeployTag();
|
|
176
|
+
|
|
367
177
|
console.log(`Deploying application: ${application} for site: ${site}`);
|
|
368
178
|
console.log(`Using deployment tag: ${deployTag}`);
|
|
369
|
-
const appDetails = appInfo[application];
|
|
370
|
-
|
|
371
|
-
const repoPath = await cloneEnvRepository(env);
|
|
372
|
-
const { deployConfigFilePath: valuesFilePath } = getConfigPath(
|
|
373
|
-
application,
|
|
374
|
-
env,
|
|
375
|
-
site,
|
|
376
|
-
'values',
|
|
377
|
-
);
|
|
378
|
-
const { deployConfigFilePath: appFilePath } = getConfigPath(
|
|
379
|
-
application,
|
|
380
|
-
env,
|
|
381
|
-
site,
|
|
382
|
-
'app',
|
|
383
|
-
);
|
|
384
|
-
|
|
385
|
-
if (!fs.existsSync(valuesFilePath) || !fs.existsSync(appFilePath)) {
|
|
386
|
-
const missingFiles = [];
|
|
387
|
-
if (!fs.existsSync(valuesFilePath))
|
|
388
|
-
missingFiles.push(`${application}.values.yaml`);
|
|
389
|
-
if (!fs.existsSync(appFilePath))
|
|
390
|
-
missingFiles.push(`${application}.app.yaml`);
|
|
391
|
-
console.log(
|
|
392
|
-
`⚠️ Skipping deployment to ${site}: config file(s) missing: ${missingFiles.join(', ')}`,
|
|
393
|
-
);
|
|
394
|
-
console.log(
|
|
395
|
-
` This site may not be configured for ${application} application`,
|
|
396
|
-
);
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
if (env !== 'dev') {
|
|
401
|
-
await copy2(
|
|
402
|
-
appDetails.repositoryName,
|
|
403
|
-
'dev',
|
|
404
|
-
env,
|
|
405
|
-
deployTag,
|
|
406
|
-
appDetails.imageName,
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
179
|
|
|
410
|
-
const {
|
|
411
|
-
application,
|
|
412
|
-
env,
|
|
413
|
-
site,
|
|
414
|
-
'values',
|
|
415
|
-
);
|
|
180
|
+
const { repoPath, deployConfigFilePath, deployConfig } =
|
|
181
|
+
await cloneAndReadDeployConfig(application, 'dev', site);
|
|
416
182
|
const updatedConfigData = setTag(deployConfig, deployTag);
|
|
417
|
-
|
|
418
|
-
const {
|
|
419
|
-
deployConfig: toDeployAppConfig,
|
|
420
|
-
deployConfigFilePath: toDeployAppConfigFilePath,
|
|
421
|
-
} = await readDeployConfig(application, env, site, 'app');
|
|
422
|
-
|
|
423
|
-
toDeployAppConfig.revision = appDetails.getAppRevision
|
|
424
|
-
? appDetails.getAppRevision(updatedConfigData)
|
|
425
|
-
: updatedConfigData.image.tag;
|
|
426
|
-
|
|
427
|
-
writeDeployConfig(toDeployAppConfigFilePath, toDeployAppConfig);
|
|
428
|
-
|
|
429
183
|
await writeAndPushDeployConfig(
|
|
430
184
|
repoPath,
|
|
431
185
|
deployConfigFilePath,
|
|
@@ -441,27 +195,24 @@ async function getAppInfo(coreUrl) {
|
|
|
441
195
|
return await axios.get(url);
|
|
442
196
|
}
|
|
443
197
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
let newVersion;
|
|
450
|
-
if (parsed.prerelease.length > 0) {
|
|
451
|
-
newVersion = parsed.build[1].slice(1);
|
|
452
|
-
} else if (parsed.build[0] != '0') {
|
|
453
|
-
console.error(`❌ This version is a custom branch. Deployment canceled.`);
|
|
454
|
-
process.exit(1);
|
|
455
|
-
} else {
|
|
456
|
-
newVersion = 'v' + parsed.version;
|
|
457
|
-
}
|
|
458
|
-
console.log(`Extracted version ${newVersion} from ${version}`);
|
|
459
|
-
return newVersion;
|
|
460
|
-
} catch {
|
|
461
|
-
console.log(`Error parsing version : ${version}`);
|
|
462
|
-
console.log('Parsed Object:');
|
|
463
|
-
console.log(parsed);
|
|
198
|
+
function getBranchNameFromVersion(version) {
|
|
199
|
+
const match = version.match(/(\d+\.\d+\.[^\-]+)(?:-(\d+)-g([a-f0-9]+))?/);
|
|
200
|
+
|
|
201
|
+
if (!match) {
|
|
202
|
+
throw new Error(`Invalid version format: ${version}`);
|
|
464
203
|
}
|
|
204
|
+
|
|
205
|
+
const fullVersion = match[1]; // e.g., 24.19.19, 24.20.alpha3, etc.
|
|
206
|
+
const customBranch = match[2]; // e.g., 4, 58, or 0
|
|
207
|
+
const commitHash = match[3]; // e.g., 668edef58e, 634cf6c904, etc.
|
|
208
|
+
|
|
209
|
+
// If "alpha" is in the version or customBranch is non-zero, use the commit hash
|
|
210
|
+
if (fullVersion.includes('alpha') || (customBranch && customBranch !== '0')) {
|
|
211
|
+
return commitHash;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Otherwise, use the full version
|
|
215
|
+
return fullVersion;
|
|
465
216
|
}
|
|
466
217
|
|
|
467
218
|
async function getCoreBranchName(fromEnv, fromSite) {
|
|
@@ -485,178 +236,13 @@ async function getCoreBranchName(fromEnv, fromSite) {
|
|
|
485
236
|
return branchName;
|
|
486
237
|
}
|
|
487
238
|
|
|
488
|
-
export async function deployApp(
|
|
489
|
-
application,
|
|
490
|
-
appDetails,
|
|
491
|
-
fromEnv,
|
|
492
|
-
fromSite,
|
|
493
|
-
toEnv,
|
|
494
|
-
toSite,
|
|
495
|
-
) {
|
|
496
|
-
let changesMade = false;
|
|
497
|
-
console.log(`Processing application: ${application}`);
|
|
498
|
-
|
|
499
|
-
// Read the deployment configuration for the source environment and site
|
|
500
|
-
const { deployConfig: fromDeployConfig } = await readDeployConfig(
|
|
501
|
-
application,
|
|
502
|
-
fromEnv,
|
|
503
|
-
fromSite,
|
|
504
|
-
'values',
|
|
505
|
-
);
|
|
506
|
-
|
|
507
|
-
if (fromEnv !== toEnv) {
|
|
508
|
-
await copy2(
|
|
509
|
-
appDetails.repositoryName,
|
|
510
|
-
fromEnv,
|
|
511
|
-
toEnv,
|
|
512
|
-
fromDeployConfig.image.tag,
|
|
513
|
-
appDetails.imageName,
|
|
514
|
-
);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// Read the deployment configuration for the target environment and site
|
|
518
|
-
const {
|
|
519
|
-
deployConfig: toDeployConfig,
|
|
520
|
-
deployConfigFilePath: toDeployConfigFilePath,
|
|
521
|
-
} = await readDeployConfig(application, toEnv, toSite, 'values');
|
|
522
|
-
|
|
523
|
-
// Update target configuration using attributes specified in appInfo
|
|
524
|
-
for (const attribute of appDetails.deployAttributes) {
|
|
525
|
-
const sourceValue = lodash.get(fromDeployConfig, attribute);
|
|
526
|
-
|
|
527
|
-
if (sourceValue !== undefined) {
|
|
528
|
-
// Update the target configuration with the source value
|
|
529
|
-
lodash.set(toDeployConfig, attribute, sourceValue);
|
|
530
|
-
changesMade = true;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
if (appDetails.updateConfigFunction) {
|
|
535
|
-
appDetails.updateConfigFunction(toDeployConfig);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
const {
|
|
539
|
-
deployConfig: toDeployAppConfig,
|
|
540
|
-
deployConfigFilePath: toDeployAppConfigFilePath,
|
|
541
|
-
} = await readDeployConfig(application, toEnv, toSite, 'app');
|
|
542
|
-
|
|
543
|
-
toDeployAppConfig.revision = appDetails.getAppRevision
|
|
544
|
-
? appDetails.getAppRevision(fromDeployConfig)
|
|
545
|
-
: fromDeployConfig.image.tag;
|
|
546
|
-
|
|
547
|
-
// Write updated configuration to the target YAML file
|
|
548
|
-
writeDeployConfig(toDeployConfigFilePath, toDeployConfig);
|
|
549
|
-
|
|
550
|
-
writeDeployConfig(toDeployAppConfigFilePath, toDeployAppConfig);
|
|
551
|
-
return changesMade;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
239
|
export async function deployFromSite(
|
|
555
240
|
fromEnv,
|
|
556
241
|
fromSite,
|
|
557
242
|
toEnv,
|
|
558
243
|
toSite,
|
|
559
244
|
isDeployCore,
|
|
560
|
-
isDeployConnect,
|
|
561
|
-
jiraTicket,
|
|
562
245
|
) {
|
|
563
|
-
console.log(
|
|
564
|
-
`Deploying changes from ${fromSite} in ${fromEnv} to ${toSite} in ${toEnv}${jiraTicket ? ` approved by JIRA ticket ${jiraTicket}` : ''}`,
|
|
565
|
-
);
|
|
566
|
-
|
|
567
|
-
if (toEnv === 'prod') {
|
|
568
|
-
if (!jiraTicket) {
|
|
569
|
-
console.error(
|
|
570
|
-
'The deployment to prod environment requires a JIRA ticket to be provided',
|
|
571
|
-
);
|
|
572
|
-
process.exit(1);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
try {
|
|
576
|
-
const response = await makeJiraRequest(`/rest/api/2/issue/${jiraTicket}`);
|
|
577
|
-
const docupacecInstance = response.fields.customfield_10045.value;
|
|
578
|
-
const siteUrl = response.fields.customfield_10041;
|
|
579
|
-
const status = response.fields.status.name;
|
|
580
|
-
const jiraBaseUrl = response.self.split('/rest/api')[0];
|
|
581
|
-
const jiraTicketUrl = `${jiraBaseUrl}/browse/${response.key}`;
|
|
582
|
-
|
|
583
|
-
console.log(`Docupace Instance: ${docupacecInstance}`);
|
|
584
|
-
console.log(`Docupace Site URL: ${siteUrl}`);
|
|
585
|
-
console.log(`JIRA Ticket Status: ${status}`);
|
|
586
|
-
console.log(`JIRA Ticket URL: ${jiraTicketUrl}`);
|
|
587
|
-
|
|
588
|
-
const allowedStatuses = ['To Do', 'In Progress'];
|
|
589
|
-
if (!allowedStatuses.includes(status)) {
|
|
590
|
-
console.error(
|
|
591
|
-
`The JIRA ticket status must be "To Do" or "In Progress", but got "${status}"`,
|
|
592
|
-
);
|
|
593
|
-
console.error(`Please check the JIRA ticket: ${jiraTicketUrl}`);
|
|
594
|
-
process.exit(1);
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
if (!siteUrl.includes(toSite)) {
|
|
598
|
-
console.error(
|
|
599
|
-
`The toSite "${toSite}" must be present in the Docupace Site URL: "${siteUrl}"`,
|
|
600
|
-
);
|
|
601
|
-
console.error(`Please check the JIRA ticket: ${jiraTicketUrl}`);
|
|
602
|
-
process.exit(1);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (docupacecInstance !== 'Production') {
|
|
606
|
-
console.error(
|
|
607
|
-
`The deployment to prod environment requires Docupace Instance to be "Production", but got "${docupacecInstance}"`,
|
|
608
|
-
);
|
|
609
|
-
console.error(`Please check the JIRA ticket: ${jiraTicketUrl}`);
|
|
610
|
-
process.exit(1);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
if (fromSite !== toSite) {
|
|
614
|
-
console.error(
|
|
615
|
-
`The deployment to prod environment requires fromSite and toSite to be equal, but fromSite: "${fromSite}", toSite: "${toSite}"`,
|
|
616
|
-
);
|
|
617
|
-
console.error(`Please check the JIRA ticket: ${jiraTicketUrl}`);
|
|
618
|
-
process.exit(1);
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
console.log('Production deployment validations passed');
|
|
622
|
-
} catch (error) {
|
|
623
|
-
console.error(`Failed to make a Jira request: ${error.message}`);
|
|
624
|
-
process.exit(1);
|
|
625
|
-
}
|
|
626
|
-
} else if (jiraTicket) {
|
|
627
|
-
try {
|
|
628
|
-
const response = await makeJiraRequest(`/rest/api/2/issue/${jiraTicket}`);
|
|
629
|
-
const siteUrl = response.fields.customfield_10041;
|
|
630
|
-
const status = response.fields.status.name;
|
|
631
|
-
const jiraBaseUrl = response.self.split('/rest/api')[0];
|
|
632
|
-
const jiraTicketUrl = `${jiraBaseUrl}/browse/${response.key}`;
|
|
633
|
-
|
|
634
|
-
console.log(`Docupace Site URL: ${siteUrl}`);
|
|
635
|
-
console.log(`JIRA Ticket Status: ${status}`);
|
|
636
|
-
console.log(`JIRA Ticket URL: ${jiraTicketUrl}`);
|
|
637
|
-
|
|
638
|
-
const allowedStatuses = ['To Do', 'In Progress'];
|
|
639
|
-
if (!allowedStatuses.includes(status)) {
|
|
640
|
-
console.error(
|
|
641
|
-
`The JIRA ticket status must be "To Do" or "In Progress", but got "${status}"`,
|
|
642
|
-
);
|
|
643
|
-
console.error(`Please check the JIRA ticket: ${jiraTicketUrl}`);
|
|
644
|
-
process.exit(1);
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
if (!siteUrl.includes(toSite)) {
|
|
648
|
-
console.error(
|
|
649
|
-
`The toSite "${toSite}" must be present in the Docupace Site URL: "${siteUrl}"`,
|
|
650
|
-
);
|
|
651
|
-
console.error(`Please check the JIRA ticket: ${jiraTicketUrl}`);
|
|
652
|
-
process.exit(1);
|
|
653
|
-
}
|
|
654
|
-
} catch (error) {
|
|
655
|
-
console.error(`Failed to make a Jira request: ${error.message}`);
|
|
656
|
-
process.exit(1);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
|
|
660
246
|
if (isDeployCore === 'true') {
|
|
661
247
|
const branchName = await getCoreBranchName(fromEnv, fromSite);
|
|
662
248
|
|
|
@@ -672,30 +258,6 @@ export async function deployFromSite(
|
|
|
672
258
|
});*/
|
|
673
259
|
}
|
|
674
260
|
|
|
675
|
-
if (isDeployConnect === 'true') {
|
|
676
|
-
const branch = '';
|
|
677
|
-
const getComparedVersion = await compareGetConnectSiteVersions(
|
|
678
|
-
fromEnv,
|
|
679
|
-
fromSite,
|
|
680
|
-
toEnv,
|
|
681
|
-
toSite,
|
|
682
|
-
);
|
|
683
|
-
if (getComparedVersion) {
|
|
684
|
-
console.log('Version to deploy is: ', getComparedVersion);
|
|
685
|
-
const connectDeployPath = await cloneRepository('connect-deploy');
|
|
686
|
-
// update target version set to git-commit-${getCommparedVersion}}
|
|
687
|
-
await updateAndCommitConnectVersion(
|
|
688
|
-
toEnv,
|
|
689
|
-
toSite,
|
|
690
|
-
getComparedVersion,
|
|
691
|
-
connectDeployPath,
|
|
692
|
-
);
|
|
693
|
-
// save and deploy
|
|
694
|
-
const runLiquibase = true;
|
|
695
|
-
await deployConnect(toEnv, toSite, runLiquibase, branch);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
|
|
699
261
|
// Clone repositories for source and target environments
|
|
700
262
|
const fromRepoPath = await cloneEnvRepository(fromEnv);
|
|
701
263
|
const toRepoPath =
|
|
@@ -703,53 +265,52 @@ export async function deployFromSite(
|
|
|
703
265
|
|
|
704
266
|
// Initialize a flag to track changes
|
|
705
267
|
let changesMade = false;
|
|
706
|
-
const applications = await getAppTypesFromRepo(toEnv, toSite);
|
|
707
|
-
console.log(applications);
|
|
708
|
-
// Iterate over applications in appInfo
|
|
709
|
-
|
|
710
|
-
let appInfoLocal = Object.fromEntries(
|
|
711
|
-
applications.applications
|
|
712
|
-
.filter((application) =>
|
|
713
|
-
Object.prototype.hasOwnProperty.call(appInfo, application),
|
|
714
|
-
)
|
|
715
|
-
.map((application) => [application, appInfo[application]]),
|
|
716
|
-
);
|
|
717
268
|
|
|
718
|
-
//
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
// appInfoLocal[application] = appInfo[application];
|
|
722
|
-
// }
|
|
723
|
-
// }
|
|
269
|
+
// Iterate over applications in appInfo
|
|
270
|
+
for (const [application, appDetails] of Object.entries(appInfo)) {
|
|
271
|
+
console.log(`Processing application: ${application}`);
|
|
724
272
|
|
|
725
|
-
|
|
726
|
-
const { deployConfig:
|
|
273
|
+
// Read the deployment configuration for the source environment and site
|
|
274
|
+
const { deployConfig: fromDeployConfig } = await readDeployConfig(
|
|
275
|
+
application,
|
|
276
|
+
fromEnv,
|
|
727
277
|
fromSite,
|
|
728
|
-
|
|
729
|
-
toSite,
|
|
730
|
-
'app',
|
|
278
|
+
'values',
|
|
731
279
|
);
|
|
732
280
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
};
|
|
737
|
-
}
|
|
281
|
+
if (fromEnv !== toEnv) {
|
|
282
|
+
await copy(application, fromEnv, toEnv, fromDeployConfig.image.tag);
|
|
283
|
+
}
|
|
738
284
|
|
|
739
|
-
|
|
285
|
+
// Read the deployment configuration for the target environment and site
|
|
286
|
+
const {
|
|
287
|
+
deployConfig: toDeployConfig,
|
|
288
|
+
deployConfigFilePath: toDeployConfigFilePath,
|
|
289
|
+
} = await readDeployConfig(application, toEnv, toSite, 'values');
|
|
740
290
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
if (cm) {
|
|
751
|
-
changesMade = true;
|
|
291
|
+
// Update target configuration using attributes specified in appInfo
|
|
292
|
+
for (const attribute of appDetails.deployAttributes) {
|
|
293
|
+
const sourceValue = lodash.get(fromDeployConfig, attribute);
|
|
294
|
+
|
|
295
|
+
if (sourceValue !== undefined) {
|
|
296
|
+
// Update the target configuration with the source value
|
|
297
|
+
lodash.set(toDeployConfig, attribute, sourceValue);
|
|
298
|
+
changesMade = true;
|
|
299
|
+
}
|
|
752
300
|
}
|
|
301
|
+
|
|
302
|
+
const {
|
|
303
|
+
deployConfig: toDeployAppConfig,
|
|
304
|
+
deployConfigFilePath: toDeployAppConfigFilePath,
|
|
305
|
+
} = await readDeployConfig(application, toEnv, toSite, 'app');
|
|
306
|
+
|
|
307
|
+
toDeployAppConfig.revision = fromDeployConfig.image.tag;
|
|
308
|
+
|
|
309
|
+
// Write updated configuration to the target YAML file
|
|
310
|
+
writeDeployConfig(toDeployConfigFilePath, toDeployConfig);
|
|
311
|
+
|
|
312
|
+
writeDeployConfig(toDeployAppConfigFilePath, toDeployAppConfig);
|
|
313
|
+
|
|
753
314
|
}
|
|
754
315
|
|
|
755
316
|
// Push all changes if any updates were made
|