@docupace/pipeline 1.0.1 → 1.0.2-3.tes2

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/src/next/copy.js CHANGED
@@ -1,27 +1,30 @@
1
1
  import { $ } from 'zx';
2
-
2
+ import { appInfo, getEnvInfo, jfRegistryUrl } from './config.js';
3
3
 
4
4
  /*
5
5
  TARGET_ENV
6
6
  PUBLISH_TAG
7
7
  REPOSITORY_NAME
8
8
  */
9
- export async function copy() {
10
- const JF_REGISTRY_URL = 'registry.paperout.com';
11
- const SOURCE_REGISTRY = `${JF_REGISTRY_URL}/${process.env.REPOSITORY_NAME}-dev-docker-local`;
12
- const TARGET_REGISTRY = `${JF_REGISTRY_URL}/${process.env.REPOSITORY_NAME}-${process.env.TARGET_ENV}-docker-local`;
13
- const IMAGE_NAME = `${process.env.REPOSITORY_NAME}:${process.env.PUBLISH_TAG}`;
14
- const SOURCE_FULL_IMAGE_NAME = `${SOURCE_REGISTRY}/${IMAGE_NAME}`;
15
- const TARGET_FULL_IMAGE_NAME = `${TARGET_REGISTRY}/${IMAGE_NAME}`;
9
+ export async function copy(application, fromEnv, toEnv, tag) {
10
+ const envInfo = getEnvInfo();
11
+ const repositoryName = appInfo[application].repositoryName;
12
+ const fromRegistry = `${jfRegistryUrl}/${repositoryName}-${fromEnv}-docker-local`;
13
+ const toRegistry = `${jfRegistryUrl}/${repositoryName}-${toEnv}-docker-local`;
14
+ const imageName = `${repositoryName}:${tag}`;
15
+ const fromFullImageName = `${fromRegistry}/${imageName}`;
16
+ const toFullImageName = `${toRegistry}/${imageName}`;
16
17
 
17
- console.log(`Copying Docker image: ${SOURCE_FULL_IMAGE_NAME} -> ${TARGET_FULL_IMAGE_NAME}`);
18
+ console.log(
19
+ `Copying Docker image: ${fromFullImageName} -> ${toFullImageName}`,
20
+ );
18
21
 
19
- // Login to source registry
20
- await $`echo ${process.env.JF_REGISTRY_PASSWORD_DEV} | docker login --username ${process.env.JF_REGISTRY_USER_DEV} --password-stdin ${JF_REGISTRY_URL}`;
21
- await $`docker pull ${SOURCE_FULL_IMAGE_NAME}`;
22
- await $`docker tag ${SOURCE_FULL_IMAGE_NAME} ${TARGET_FULL_IMAGE_NAME}`;
22
+ // Login to source registry
23
+ await $`echo ${envInfo[fromEnv].jfrog.password} | docker login --username ${envInfo[fromEnv].jfrog.username} --password-stdin ${jfRegistryUrl}`;
24
+ await $`docker pull ${fromFullImageName}`;
25
+ await $`docker tag ${fromFullImageName} ${toFullImageName}`;
23
26
 
24
- // Login to target registry
25
- await $`echo ${process.env.JF_REGISTRY_PASSWORD_QA} | docker login --username ${process.env.JF_REGISTRY_USER_QA} --password-stdin ${JF_REGISTRY_URL}`;
26
- await $`docker push ${TARGET_FULL_IMAGE_NAME}`;
27
+ // Login to target registry
28
+ await $`echo ${envInfo[toEnv].jfrog.password} | docker login --username ${envInfo[toEnv].jfrog.username} --password-stdin ${jfRegistryUrl}`;
29
+ await $`docker push ${toFullImageName}`;
27
30
  }
@@ -2,10 +2,11 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import yaml from 'js-yaml';
4
4
  import { $ } from 'zx';
5
-
6
- const REPO_NAME = 'gitops-dev';
7
- const REPO_URL = `https://x-token-auth:${process.env.GITOPS_DEV_REP_TOKEN}@bitbucket.org/dp-cloud/${REPO_NAME}.git`;
8
- const GITOPS_BRANCH = 'master';
5
+ import lodash from 'lodash';
6
+ import { appInfo, environmentConfig, getRepUrl } from './config.js';
7
+ import { copy } from './copy.js';
8
+ import axios from 'axios';
9
+ import { deployCore } from './jenkins.js';
9
10
 
10
11
  /**
11
12
  * Clone the repository, read the YAML file, and return the parsed data and file paths.
@@ -13,24 +14,106 @@ const GITOPS_BRANCH = 'master';
13
14
  * @param {string} site - The site name.
14
15
  * @returns {object} - The repository path, file path, and YAML data.
15
16
  */
16
- export async function readDeployConfig(application, site) {
17
- const repoPath = path.join(process.cwd(), REPO_NAME);
18
- const deployConfigFilePath = path.join(repoPath, `dp/${site}/${application}.values.yaml`);
19
17
 
20
- console.log(`Cloning repository: ${REPO_NAME}`);
21
- await $`git clone ${REPO_URL}`;
22
- console.log(`Repository cloned to: ${repoPath}`);
18
+ function getRepoLocalPath(env) {
19
+ const repoName = `gitops-${env}`;
20
+ const repoPath = path.join(process.cwd(), repoName);
21
+ return { repoPath, repoName };
22
+ }
23
23
 
24
- let deployConfig;
25
- try {
26
- deployConfig = yaml.load(fs.readFileSync(deployConfigFilePath, 'utf8'));
27
- console.log(`YAML file loaded from: ${deployConfigFilePath}`);
28
- } catch (error) {
29
- console.error(`Error reading YAML file: ${error.message}`);
30
- process.exit(1);
31
- }
24
+ function getRepoLocalPathByRepoSlug(repoSlug) {
25
+ const repoName = `${repoSlug}`;
26
+ const repoPath = path.join(process.cwd(), repoName);
27
+ return { repoPath, repoName };
28
+ }
32
29
 
33
- return { repoPath, deployConfigFilePath, deployConfig };
30
+ function cleanUpRepoPath(repoPath) {
31
+ // Check and handle repo directory
32
+ if (fs.existsSync(repoPath)) {
33
+ console.log(`${repoPath} directory exists. Removing it...`);
34
+ fs.rmSync(repoPath, {
35
+ recursive: true,
36
+ force: true,
37
+ });
38
+ }
39
+ }
40
+
41
+ export async function cloneEnvRepository(env) {
42
+ const { repoPath, repoName } = getRepoLocalPath(env);
43
+ const repoUrl = getRepUrl(repoName);
44
+ console.log(`Cloning repository: ${repoName}`);
45
+ await cleanUpRepoPath(repoPath);
46
+ await $`git clone --depth 1 ${repoUrl}`;
47
+ console.log(`Repository cloned to: ${repoPath}`);
48
+ return repoPath;
49
+ }
50
+
51
+ export async function cloneRepository(repoSlug) {
52
+ const { repoPath, repoName } = getRepoLocalPathByRepoSlug(repoSlug);
53
+ const repoUrl = getRepUrl(repoName);
54
+
55
+ await cleanUpRepoPath(repoPath);
56
+
57
+ console.log(`Cloning repository: ${repoName}`);
58
+ await $`git clone --depth 1 ${repoUrl}`;
59
+ console.log(`Repository cloned to: ${repoPath}`);
60
+ return repoPath;
61
+ }
62
+
63
+ function getConfigPath(application, env, site, name) {
64
+ const { repoPath } = getRepoLocalPath(env);
65
+ const deployConfigFilePath = path.join(
66
+ repoPath,
67
+ `dp/${site}/${application}.${name}.yaml`,
68
+ );
69
+
70
+ return { repoPath, deployConfigFilePath };
71
+ }
72
+
73
+ function getAppTypesFromRepo(env, site) {
74
+ const { repoPath } = getRepoLocalPath(env);
75
+ const deployConfigFilePath = path.join(repoPath, `dp/${site}`);
76
+ console.log(deployConfigFilePath);
77
+ const applications = [];
78
+ if (fs.existsSync(deployConfigFilePath)) {
79
+ const files = fs.readdirSync(deployConfigFilePath);
80
+ files.forEach((file) => {
81
+ if (file.includes('.values.yaml')) {
82
+ const appName = file.split('.')[0];
83
+ applications.push(appName);
84
+ }
85
+ });
86
+ }
87
+
88
+ return { applications };
89
+ }
90
+
91
+ export async function readDeployConfig(application, env, site, name) {
92
+ const { deployConfigFilePath } = getConfigPath(application, env, site, name);
93
+
94
+ let deployConfig;
95
+ try {
96
+ deployConfig = yaml.load(fs.readFileSync(deployConfigFilePath, 'utf8'));
97
+ console.log(`YAML file loaded from: ${deployConfigFilePath}`);
98
+ } catch (error) {
99
+ console.error(`Error reading YAML file: ${error.message}`);
100
+ process.exit(1);
101
+ }
102
+
103
+ return { deployConfig, deployConfigFilePath };
104
+ }
105
+
106
+ export async function cloneAndReadDeployConfig(application, env, site) {
107
+ const repoPath = await cloneEnvRepository(env);
108
+
109
+ const { deployConfig, deployConfigFilePath } = await readDeployConfig(
110
+ application,
111
+ env,
112
+ site,
113
+ 'values',
114
+ );
115
+
116
+ return { repoPath, deployConfigFilePath, deployConfig };
34
117
  }
35
118
 
36
119
  /**
@@ -40,15 +123,15 @@ export async function readDeployConfig(application, site) {
40
123
  * @returns {object} - The updated YAML data.
41
124
  */
42
125
  export function setTag(deployConfig, tag) {
43
- if (deployConfig.image && deployConfig.image.tag) {
44
- console.log(`Current image tag: ${deployConfig.image.tag}`);
45
- deployConfig.image.tag = tag;
46
- console.log(`Updated image tag to: ${deployConfig.image.tag}`);
47
- } else {
48
- console.error('No "image.tag" field found in the YAML file.');
49
- process.exit(1);
50
- }
51
- return deployConfig;
126
+ if (deployConfig.image && deployConfig.image.tag) {
127
+ console.log(`Current image tag: ${deployConfig.image.tag}`);
128
+ deployConfig.image.tag = tag;
129
+ console.log(`Updated image tag to: ${deployConfig.image.tag}`);
130
+ } else {
131
+ console.error('No "image.tag" field found in the YAML file.');
132
+ process.exit(1);
133
+ }
134
+ return deployConfig;
52
135
  }
53
136
 
54
137
  /**
@@ -57,25 +140,50 @@ export function setTag(deployConfig, tag) {
57
140
  * @param {string} deployConfigFilePath - The path to the YAML file.
58
141
  * @param {object} deployConfig - The updated YAML data.
59
142
  */
60
- export async function writeDeployConfig(repoPath, deployConfigFilePath, deployConfig) {
61
- try {
62
- fs.writeFileSync(deployConfigFilePath, yaml.dump(deployConfig), 'utf8');
63
- console.log(`Updated YAML file saved at: ${deployConfigFilePath}`);
64
- } catch (error) {
65
- console.error(`Error writing YAML file: ${error.message}`);
66
- process.exit(1);
67
- }
68
143
 
69
- console.log('Committing changes to the repository...');
70
- await $`cd ${repoPath} && git config user.email "gitops@docupace.com"`;
71
- await $`cd ${repoPath} && git add ${deployConfigFilePath}`;
72
- await $`cd ${repoPath} && git commit -m "Update image tag to ${deployConfig.image.tag}"`;
73
- await $`cd ${repoPath} && git push origin ${GITOPS_BRANCH}`;
74
- console.log('Changes pushed to the remote repository.');
75
-
76
- console.log('Cleaning up...');
144
+ export async function pushDeployConfig(repoPath, commitMessage) {
145
+ console.log('📌 Checking for updates to commit...');
146
+ // Check if there are any changes to commit
147
+ const status = (
148
+ await $`cd ${repoPath} && git status --porcelain`
149
+ ).stdout.trim();
150
+ if (!status) {
151
+ console.log('✅ No changes to commit. Exiting.');
77
152
  await $`rm -rf ${repoPath}`;
78
- console.log('Cleanup complete.');
153
+ console.log('🧹 Cleanup complete.');
154
+ return;
155
+ }
156
+
157
+ console.log('📌 Committing changes to the repository...');
158
+ await $`cd ${repoPath} && git config user.email "gitops@docupace.com"`;
159
+ await $`cd ${repoPath} && git add .`;
160
+ await $`cd ${repoPath} && git commit -m ${commitMessage}`;
161
+ await $`cd ${repoPath} && git push`;
162
+ console.log('✅ Changes pushed to the remote repository.');
163
+
164
+ console.log('🧹 Cleaning up...');
165
+ await $`rm -rf ${repoPath}`;
166
+ console.log('✅ Cleanup complete.');
167
+ }
168
+
169
+ function writeDeployConfig(deployConfigFilePath, deployConfig) {
170
+ try {
171
+ fs.writeFileSync(deployConfigFilePath, yaml.dump(deployConfig), 'utf8');
172
+ console.log(`✅ Updated YAML file saved at: ${deployConfigFilePath}`);
173
+ } catch (error) {
174
+ console.error(`❌ Error writing YAML file: ${error.message}`);
175
+ process.exit(1);
176
+ }
177
+ }
178
+
179
+ export async function writeAndPushDeployConfig(
180
+ repoPath,
181
+ deployConfigFilePath,
182
+ deployConfig,
183
+ commitMessage,
184
+ ) {
185
+ writeDeployConfig(deployConfigFilePath, deployConfig);
186
+ await pushDeployConfig(repoPath, commitMessage);
79
187
  }
80
188
 
81
189
  /**
@@ -85,34 +193,231 @@ export async function writeDeployConfig(repoPath, deployConfigFilePath, deployCo
85
193
  */
86
194
 
87
195
  async function getDeployTag() {
88
- const gitTag = (await $`git tag --points-at HEAD | grep '^v' | head -n 1`).stdout.trim()
89
- const deployTag = gitTag || `build-${process.env.BITBUCKET_BUILD_NUMBER}`;
90
- return deployTag;
196
+ const gitTag = (
197
+ await $`git tag --points-at HEAD | grep '^v' | head -n 1`
198
+ ).stdout.trim();
199
+ const deployTag = gitTag || `build-${process.env.BITBUCKET_BUILD_NUMBER}`;
200
+ return deployTag;
91
201
  }
92
202
 
93
203
  export async function deployTemplate(site) {
94
- const deployTag = await getDeployTag();
95
- console.log(`Deploying standard template for site: ${site}`);
96
- console.log(`Using deployment tag: ${deployTag}`);
97
- const { repoPath, deployConfigFilePath, deployConfig } = await readDeployConfig('graphql-server', site);
204
+ const deployTag = await getDeployTag();
205
+ console.log(`Deploying standard template for site: ${site}`);
206
+ console.log(`Using deployment tag: ${deployTag}`);
207
+ const { repoPath, deployConfigFilePath, deployConfig } =
208
+ await cloneAndReadDeployConfig('graphql-server', 'dev', site);
209
+
210
+ deployConfig.graphqlServer.standardConfigRemoteBranch = deployTag;
211
+
212
+ await writeAndPushDeployConfig(
213
+ repoPath,
214
+ deployConfigFilePath,
215
+ deployConfig,
216
+ `Update template to ${deployConfig.graphqlServer.standardConfigRemoteBranch}`,
217
+ );
218
+ console.log('Deployment completed successfully.');
219
+ }
220
+
221
+ export async function deploy(application, site) {
222
+ const deployTag = getDeployTag();
98
223
 
99
- deployConfig.graphqlServer.standardConfigRemoteBranch = deployTag;
224
+ console.log(`Deploying application: ${application} for site: ${site}`);
225
+ console.log(`Using deployment tag: ${deployTag}`);
100
226
 
101
- await writeDeployConfig(repoPath, deployConfigFilePath, deployConfig);
102
- console.log('Deployment completed successfully.');
227
+ const { repoPath, deployConfigFilePath, deployConfig } =
228
+ await cloneAndReadDeployConfig(application, 'dev', site);
229
+ const updatedConfigData = setTag(deployConfig, deployTag);
230
+ await writeAndPushDeployConfig(
231
+ repoPath,
232
+ deployConfigFilePath,
233
+ updatedConfigData,
234
+ `Update image tag to ${deployConfig.image.tag}`,
235
+ );
103
236
 
237
+ console.log('Deployment completed successfully.');
104
238
  }
105
239
 
240
+ async function getAppInfo(coreUrl) {
241
+ const url = `${coreUrl}/b2b/rest/v1/appinfo`;
242
+ return await axios.get(url);
243
+ }
106
244
 
107
- export async function deploy(application, site) {
108
- const deployTag = getDeployTag();
245
+ function getBranchNameFromVersion(version) {
246
+ const match = version.match(/(\d+\.\d+\.[^\-]+)(?:-(\d+)-g([a-f0-9]+))?/);
247
+
248
+ if (!match) {
249
+ throw new Error(`Invalid version format: ${version}`);
250
+ }
251
+
252
+ const fullVersion = match[1]; // e.g., 24.19.19, 24.20.alpha3, etc.
253
+ const customBranch = match[2]; // e.g., 4, 58, or 0
254
+ const commitHash = match[3]; // e.g., 668edef58e, 634cf6c904, etc.
255
+
256
+ // If "alpha" is in the version or customBranch is non-zero, use the commit hash
257
+ if (fullVersion.includes('alpha') || (customBranch && customBranch !== '0')) {
258
+ return commitHash;
259
+ }
260
+
261
+ // Otherwise, use the full version
262
+ return fullVersion;
263
+ }
264
+
265
+ async function getCoreBranchName(fromEnv, fromSite) {
266
+ const envConfig = environmentConfig[fromEnv];
267
+ const oldUrl = envConfig.oldUrl(fromSite);
268
+ const newUrl = envConfig.newUrl(fromSite) + '/core';
269
+
270
+ let appinfo;
271
+ try {
272
+ appinfo = await getAppInfo(oldUrl);
273
+ } catch {
274
+ try {
275
+ appinfo = await getAppInfo(newUrl);
276
+ } catch {
277
+ throw new Error('Cannot get app info');
278
+ }
279
+ }
280
+
281
+ const coreVersion = appinfo.data.core.version;
282
+ const branchName = getBranchNameFromVersion(coreVersion);
283
+ return branchName;
284
+ }
285
+
286
+ export async function deployApp(
287
+ application,
288
+ appDetails,
289
+ fromEnv,
290
+ fromSite,
291
+ toEnv,
292
+ toSite,
293
+ ) {
294
+ let changesMade = false;
295
+ console.log(`Processing application: ${application}`);
296
+
297
+ // Read the deployment configuration for the source environment and site
298
+ const { deployConfig: fromDeployConfig } = await readDeployConfig(
299
+ application,
300
+ fromEnv,
301
+ fromSite,
302
+ 'values',
303
+ );
304
+
305
+ if (fromEnv !== toEnv) {
306
+ await copy(application, fromEnv, toEnv, fromDeployConfig.image.tag);
307
+ }
109
308
 
110
- console.log(`Deploying application: ${application} for site: ${site}`);
111
- console.log(`Using deployment tag: ${deployTag}`);
309
+ // Read the deployment configuration for the target environment and site
310
+ const {
311
+ deployConfig: toDeployConfig,
312
+ deployConfigFilePath: toDeployConfigFilePath,
313
+ } = await readDeployConfig(application, toEnv, toSite, 'values');
112
314
 
113
- const { repoPath, deployConfigFilePath, deployConfig } = await readDeployConfig(application, site);
114
- const updatedConfigData = setTag(deployConfig, deployTag);
115
- await writeDeployConfig(repoPath, deployConfigFilePath, updatedConfigData);
315
+ // Update target configuration using attributes specified in appInfo
316
+ for (const attribute of appDetails.deployAttributes) {
317
+ const sourceValue = lodash.get(fromDeployConfig, attribute);
318
+
319
+ if (sourceValue !== undefined) {
320
+ // Update the target configuration with the source value
321
+ lodash.set(toDeployConfig, attribute, sourceValue);
322
+ changesMade = true;
323
+ }
324
+ }
325
+
326
+ const {
327
+ deployConfig: toDeployAppConfig,
328
+ deployConfigFilePath: toDeployAppConfigFilePath,
329
+ } = await readDeployConfig(application, toEnv, toSite, 'app');
330
+
331
+ toDeployAppConfig.revision = fromDeployConfig.image.tag;
332
+
333
+ // Write updated configuration to the target YAML file
334
+ writeDeployConfig(toDeployConfigFilePath, toDeployConfig);
335
+
336
+ writeDeployConfig(toDeployAppConfigFilePath, toDeployAppConfig);
337
+ return changesMade;
338
+ }
339
+
340
+ export async function deployFromSite(
341
+ fromEnv,
342
+ fromSite,
343
+ toEnv,
344
+ toSite,
345
+ isDeployCore,
346
+ ) {
347
+ if (isDeployCore === 'true') {
348
+ const branchName = await getCoreBranchName(fromEnv, fromSite);
349
+
350
+ const coreEnv = toEnv == 'qa' ? 'preprod' : toEnv;
351
+ await deployCore(coreEnv, toSite, 'true', branchName);
352
+
353
+ // To be added back when splitting between on prem and in cloud
354
+ /*await runPipeline('site-deploy', 'deploy-core', 'main', {
355
+ ENV: toEnv,
356
+ SITE: toSite,
357
+ LIQUIBASE: 'true',
358
+ BRANCH: branchName,
359
+ });*/
360
+ }
361
+
362
+ // Clone repositories for source and target environments
363
+ const fromRepoPath = await cloneEnvRepository(fromEnv);
364
+ const toRepoPath =
365
+ toEnv === fromEnv ? fromRepoPath : await cloneEnvRepository(toEnv);
366
+
367
+ // Initialize a flag to track changes
368
+ let changesMade = false;
369
+ const applications = await getAppTypesFromRepo(fromEnv, fromSite);
370
+ console.log(applications);
371
+ // Iterate over applications in appInfo
372
+ let appInfoLocal = {};
373
+ // let appInfoLocal = Object.fromEntries(
374
+ // applications
375
+ // .filter((application) => appInfo[application])
376
+ // .map((application) => [application, appInfo[application]]),
377
+ // );
378
+
379
+ for (const application of applications) {
380
+ if (Object.prototype.hasOwnProperty.call(appInfo, application)) {
381
+ appInfoLocal[application] = appInfo[application];
382
+ }
383
+ }
384
+
385
+ if (Object.keys(appInfoLocal).length === 0) {
386
+ const { deployConfig: toDeployAppConfig } = await readDeployConfig(
387
+ fromSite,
388
+ toEnv,
389
+ toSite,
390
+ 'app',
391
+ );
392
+
393
+ appInfoLocal[fromSite] = {
394
+ repositoryName: toDeployAppConfig.repo,
395
+ deployAttributes: ['image.tag'],
396
+ };
397
+ }
398
+
399
+ for (const [application, appDetails] of Object.entries(appInfo)) {
400
+ let cm = await deployApp(
401
+ application,
402
+ appDetails,
403
+ fromEnv,
404
+ fromSite,
405
+ toEnv,
406
+ toSite,
407
+ );
408
+ if (cm) {
409
+ changesMade = true;
410
+ }
411
+ }
116
412
 
117
- console.log('Deployment completed successfully.');
413
+ // Push all changes if any updates were made
414
+ if (changesMade) {
415
+ await pushDeployConfig(
416
+ toRepoPath,
417
+ `Updated deployment configurations from ${fromEnv}/${fromSite} to ${toEnv}/${toSite}`,
418
+ );
419
+ console.log('✅ All configurations updated and pushed successfully.');
420
+ } else {
421
+ console.log('✅ No changes detected. Nothing to push.');
422
+ }
118
423
  }
@@ -0,0 +1,50 @@
1
+ import { $ } from 'zx';
2
+
3
+
4
+ export async function haproxySync() {
5
+ const repoPath = '/root/repo/docupace-ansible';
6
+ const inventory = path.join(repoPath, 'inventories/preprod/inventory');
7
+
8
+ // Create haproxy.sh
9
+ const scriptContent = `
10
+ #!/bin/bash
11
+
12
+ [[ ! -f ${inventory} ]] && ( echo "Alert: no inventory file: ${inventory}" ; exit 1 )
13
+ cd ${repoPath}
14
+ pwd
15
+ git stash
16
+ git pull origin master
17
+ git checkout master
18
+ git submodule update --remote
19
+ git submodule foreach --recursive git checkout master
20
+ git submodule foreach --recursive git pull origin master
21
+
22
+ ansible-playbook -i inventories/preprod/inventory haproxy.yml -e "cluster=preprod"
23
+
24
+ echo "proceeding"
25
+ echo "committing changes"
26
+ git add preprod-haproxy.cfg
27
+ git commit -m "Sync haproxy"
28
+ git push origin master
29
+ `;
30
+
31
+ await fs.writeFile('haproxy.sh', scriptContent);
32
+
33
+ // Private key
34
+ const haproxyPrivateKey = process.env.HAPROXY_PRIVATE_KEY;
35
+ if (!haproxyPrivateKey) {
36
+ log('Error: HAPROXY_PRIVATE_KEY not set.');
37
+ process.exit(1);
38
+ }
39
+
40
+ await fs.writeFile('private.key', Buffer.from(haproxyPrivateKey, 'base64'));
41
+ await fs.chmod('private.key', 0o600);
42
+
43
+ await $`cat private.key`; // Just to mimic the script's behavior
44
+
45
+ // Copy script to remote
46
+ await $`scp -i private.key -o StrictHostKeyChecking=no haproxy.sh root@10.10.28.198:/tmp/haproxy.sh`;
47
+
48
+ // Execute script on remote
49
+ await $`ssh -i private.key -o StrictHostKeyChecking=no root@10.10.28.198 "bash /tmp/haproxy.sh"`;
50
+ }