@docupace/pipeline 1.0.40 → 1.0.43

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,55 +1,55 @@
1
- import { $ } from 'zx';
2
- import { appInfo, getEnvInfo, jfRegistryUrl } from './config.js';
3
-
4
- /*
5
- TARGET_ENV
6
- PUBLISH_TAG
7
- REPOSITORY_NAME
8
- */
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}`;
17
-
18
- console.log(
19
- `Copying Docker image: ${fromFullImageName} -> ${toFullImageName}`,
20
- );
21
-
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}`;
26
-
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}`;
30
- }
31
-
32
- export async function copy2(repositoryName, fromEnv, toEnv, tag) {
33
- console.log(
34
- `Copying repository ${repositoryName} from ${fromEnv} to ${toEnv} for tag ${tag}`,
35
- );
36
- const envInfo = getEnvInfo();
37
- const fromRegistry = `${jfRegistryUrl}/${repositoryName}-${fromEnv}-docker-local`;
38
- const toRegistry = `${jfRegistryUrl}/${repositoryName}-${toEnv}-docker-local`;
39
- const imageName = `${repositoryName}:${tag}`;
40
- const fromFullImageName = `${fromRegistry}/${imageName}`;
41
- const toFullImageName = `${toRegistry}/${imageName}`;
42
-
43
- console.log(
44
- `Copying Docker image: ${fromFullImageName} -> ${toFullImageName}`,
45
- );
46
-
47
- // Login to source registry
48
- await $`echo ${envInfo[fromEnv].jfrog.password} | docker login --username ${envInfo[fromEnv].jfrog.username} --password-stdin ${jfRegistryUrl}`;
49
- await $`docker pull ${fromFullImageName}`;
50
- await $`docker tag ${fromFullImageName} ${toFullImageName}`;
51
-
52
- // Login to target registry
53
- await $`echo ${envInfo[toEnv].jfrog.password} | docker login --username ${envInfo[toEnv].jfrog.username} --password-stdin ${jfRegistryUrl}`;
54
- await $`docker push ${toFullImageName}`;
55
- }
1
+ import { $ } from 'zx';
2
+ import { appInfo, getEnvInfo, jfRegistryUrl } from './config.js';
3
+
4
+ /*
5
+ TARGET_ENV
6
+ PUBLISH_TAG
7
+ REPOSITORY_NAME
8
+ */
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}`;
17
+
18
+ console.log(
19
+ `Copying Docker image: ${fromFullImageName} -> ${toFullImageName}`,
20
+ );
21
+
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}`;
26
+
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}`;
30
+ }
31
+
32
+ export async function copy2(repositoryName, fromEnv, toEnv, tag) {
33
+ console.log(
34
+ `Copying repository ${repositoryName} from ${fromEnv} to ${toEnv} for tag ${tag}`,
35
+ );
36
+ const envInfo = getEnvInfo();
37
+ const fromRegistry = `${jfRegistryUrl}/${repositoryName}-${fromEnv}-docker-local`;
38
+ const toRegistry = `${jfRegistryUrl}/${repositoryName}-${toEnv}-docker-local`;
39
+ const imageName = `${repositoryName}:${tag}`;
40
+ const fromFullImageName = `${fromRegistry}/${imageName}`;
41
+ const toFullImageName = `${toRegistry}/${imageName}`;
42
+
43
+ console.log(
44
+ `Copying Docker image: ${fromFullImageName} -> ${toFullImageName}`,
45
+ );
46
+
47
+ // Login to source registry
48
+ await $`echo ${envInfo[fromEnv].jfrog.password} | docker login --username ${envInfo[fromEnv].jfrog.username} --password-stdin ${jfRegistryUrl}`;
49
+ await $`docker pull ${fromFullImageName}`;
50
+ await $`docker tag ${fromFullImageName} ${toFullImageName}`;
51
+
52
+ // Login to target registry
53
+ await $`echo ${envInfo[toEnv].jfrog.password} | docker login --username ${envInfo[toEnv].jfrog.username} --password-stdin ${jfRegistryUrl}`;
54
+ await $`docker push ${toFullImageName}`;
55
+ }
@@ -2,7 +2,8 @@ import { $ } from 'zx';
2
2
  import fs from 'fs-extra';
3
3
  import path from 'path';
4
4
 
5
- export async function haproxySync(cluster) {
5
+ export async function haproxySync() {
6
+ const cluster = process.env.HAPROXY_CLUSTER;
6
7
  if (cluster !== 'preprod' && cluster !== 'stage') {
7
8
  console.log('Error: Cluster must be preprod or stage');
8
9
  process.exit(1);
@@ -13,8 +14,14 @@ export async function haproxySync(cluster) {
13
14
 
14
15
  // Create haproxy.sh
15
16
  const cluserHostMap = {
16
- preprod: '10.10.28.198',
17
- stage: '10.12.28.10',
17
+ preprod: {
18
+ host: '10.10.28.198',
19
+ branch: 'master',
20
+ },
21
+ stage: {
22
+ host: '10.12.28.10',
23
+ branch: 'INFP-6565-haproxy-prod-implementation',
24
+ },
18
25
  };
19
26
 
20
27
  const scriptContent = `
@@ -24,13 +31,14 @@ export async function haproxySync(cluster) {
24
31
  cd ${repoPath}
25
32
  pwd
26
33
  git stash
34
+ git fetch --all
27
35
  git pull origin master
28
- git checkout master
36
+ git checkout ${cluserHostMap[cluster].branch}
29
37
  git submodule update --remote
30
38
  git submodule foreach --recursive git checkout master
31
39
  git submodule foreach --recursive git pull origin master
32
40
 
33
- ansible-playbook -i inventories/${cluster}/inventory haproxy.yml -e "cluster=${cluster}"
41
+ ansible-playbook -i inventories/${cluster}/inventory haproxy.yml -e "cluster=${cluster} -e build=true"
34
42
 
35
43
  echo "proceeding"
36
44
  echo "committing changes"
@@ -52,8 +60,8 @@ export async function haproxySync(cluster) {
52
60
  await fs.chmod('private.key', 0o600);
53
61
 
54
62
  // Copy script to remote
55
- await $`scp -i private.key -o StrictHostKeyChecking=no haproxy.sh root@${cluserHostMap[cluster]}:/tmp/haproxy.sh`;
63
+ await $`scp -i private.key -o StrictHostKeyChecking=no haproxy.sh root@${cluserHostMap[cluster].host}:/tmp/haproxy.sh`;
56
64
 
57
65
  // Execute script on remote
58
- await $`ssh -i private.key -o StrictHostKeyChecking=no root@${cluserHostMap[cluster]} "bash /tmp/haproxy.sh"`;
66
+ await $`ssh -i private.key -o StrictHostKeyChecking=no root@${cluserHostMap[cluster].host} "bash /tmp/haproxy.sh"`;
59
67
  }
package/src/next/jira.js CHANGED
@@ -1,83 +1,83 @@
1
- import axios from 'axios';
2
-
3
- // Create preconfigured axios instance for Jira
4
- const jiraClient = axios.create({
5
- baseURL: 'https://docupacellc.atlassian.net',
6
- auth: {
7
- username: process.env.JIRA_API_EMAIL,
8
- password: process.env.JIRA_API_KEY,
9
- },
10
- headers: {
11
- 'Content-Type': 'application/json',
12
- },
13
- });
14
-
15
- const packageComponents = {
16
- 'docupace-ui': 'next-ui',
17
- 'docupace-graphql-server': 'graphql-server',
18
- '@docupace/template': 'template',
19
- };
20
- /**
21
- * Updates the component version custom field in Jira
22
- * @param {string} issueKey - The Jira issue key
23
- * @param {string} component - The component name
24
- * @param {string} version - The version to set
25
- */
26
- export async function updateComponentVersion(issueKey, packageName, version) {
27
- const component = packageComponents[packageName] ?? packageName;
28
- console.log(
29
- `Updating ${issueKey} for package ${packageName} translated to component ${component} with version ${version}`,
30
- );
31
- try {
32
- // First get current field value
33
- const response = await jiraClient.get(
34
- `/rest/api/2/issue/${issueKey}?fields=customfield_10458`,
35
- );
36
-
37
- let currentValue = response.data.fields.customfield_10458 || '';
38
- let components = new Map();
39
-
40
- // Parse existing components
41
- if (currentValue) {
42
- currentValue.split(';').forEach((entry) => {
43
- const [comp, ver] = entry.split(':');
44
- components.set(comp, ver);
45
- });
46
- }
47
-
48
- // Update or add new component version
49
- components.set(component, version);
50
-
51
- // Convert back to string format
52
- const newValue = Array.from(components.entries())
53
- .map(([comp, ver]) => `${comp}:${ver}`)
54
- .join(';');
55
-
56
- // Update the field
57
- await jiraClient.put(`/rest/api/2/issue/${issueKey}`, {
58
- fields: {
59
- customfield_10458: newValue,
60
- },
61
- });
62
-
63
- console.log(`Updated component versions for ${issueKey}: ${newValue}`);
64
- } catch (error) {
65
- console.error(`Error updating Jira component version: ${error.message}`);
66
- }
67
- }
68
-
69
- /**
70
- * Makes a request to the Jira API using preconfigured client
71
- * @param {string} endpoint - The API endpoint (starting with /)
72
- * @param {Object} options - Request options (method, body, etc)
73
- * @returns {Promise<any>} The response data
74
- */
75
- export async function makeJiraRequest(endpoint, options = {}) {
76
- try {
77
- const response = await jiraClient.get(endpoint, options);
78
- return response.data;
79
- } catch (error) {
80
- console.error(`Error making Jira request: ${error.message}`);
81
- throw error;
82
- }
83
- }
1
+ import axios from 'axios';
2
+
3
+ // Create preconfigured axios instance for Jira
4
+ const jiraClient = axios.create({
5
+ baseURL: 'https://docupacellc.atlassian.net',
6
+ auth: {
7
+ username: process.env.JIRA_API_EMAIL,
8
+ password: process.env.JIRA_API_KEY,
9
+ },
10
+ headers: {
11
+ 'Content-Type': 'application/json',
12
+ },
13
+ });
14
+
15
+ const packageComponents = {
16
+ 'docupace-ui': 'next-ui',
17
+ 'docupace-graphql-server': 'graphql-server',
18
+ '@docupace/template': 'template',
19
+ };
20
+ /**
21
+ * Updates the component version custom field in Jira
22
+ * @param {string} issueKey - The Jira issue key
23
+ * @param {string} component - The component name
24
+ * @param {string} version - The version to set
25
+ */
26
+ export async function updateComponentVersion(issueKey, packageName, version) {
27
+ const component = packageComponents[packageName] ?? packageName;
28
+ console.log(
29
+ `Updating ${issueKey} for package ${packageName} translated to component ${component} with version ${version}`,
30
+ );
31
+ try {
32
+ // First get current field value
33
+ const response = await jiraClient.get(
34
+ `/rest/api/2/issue/${issueKey}?fields=customfield_10458`,
35
+ );
36
+
37
+ let currentValue = response.data.fields.customfield_10458 || '';
38
+ let components = new Map();
39
+
40
+ // Parse existing components
41
+ if (currentValue) {
42
+ currentValue.split(';').forEach((entry) => {
43
+ const [comp, ver] = entry.split(':');
44
+ components.set(comp, ver);
45
+ });
46
+ }
47
+
48
+ // Update or add new component version
49
+ components.set(component, version);
50
+
51
+ // Convert back to string format
52
+ const newValue = Array.from(components.entries())
53
+ .map(([comp, ver]) => `${comp}:${ver}`)
54
+ .join(';');
55
+
56
+ // Update the field
57
+ await jiraClient.put(`/rest/api/2/issue/${issueKey}`, {
58
+ fields: {
59
+ customfield_10458: newValue,
60
+ },
61
+ });
62
+
63
+ console.log(`Updated component versions for ${issueKey}: ${newValue}`);
64
+ } catch (error) {
65
+ console.error(`Error updating Jira component version: ${error.message}`);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Makes a request to the Jira API using preconfigured client
71
+ * @param {string} endpoint - The API endpoint (starting with /)
72
+ * @param {Object} options - Request options (method, body, etc)
73
+ * @returns {Promise<any>} The response data
74
+ */
75
+ export async function makeJiraRequest(endpoint, options = {}) {
76
+ try {
77
+ const response = await jiraClient.get(endpoint, options);
78
+ return response.data;
79
+ } catch (error) {
80
+ console.error(`Error making Jira request: ${error.message}`);
81
+ throw error;
82
+ }
83
+ }
@@ -1,114 +1,114 @@
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
- const BITBUCKET_WS_URL = 'https://bitbucket.org/dp-cloud';
7
-
8
- async function triggerPipelineByName(
9
- repository,
10
- pipelineName,
11
- branch,
12
- variables,
13
- ) {
14
- const { username, password, workspace } = getBitbucketInfo();
15
- const url = `${BITBUCKET_BASE_URL}/repositories/${workspace}/${repository}/pipelines/`;
16
- const auth = {
17
- username: username,
18
- password: password,
19
- };
20
-
21
- const payload = {
22
- target: {
23
- type: 'pipeline_ref_target',
24
- ref_type: 'branch',
25
- ref_name: branch,
26
- selector: {
27
- type: 'custom',
28
- pattern: pipelineName,
29
- },
30
- },
31
- variables: variables
32
- ? Object.entries(variables).map(([key, value]) => ({
33
- key,
34
- value,
35
- secured: false, // Set to true if the variable should be secure
36
- }))
37
- : undefined,
38
- };
39
-
40
- try {
41
- const response = await axios.post(url, payload, { auth });
42
- return response.data;
43
- } catch (error) {
44
- console.error(
45
- 'Error triggering custom pipeline:',
46
- error.response?.data || error.message,
47
- );
48
- throw error;
49
- }
50
- }
51
-
52
- async function getPipelineStatus(repository, pipelineUUID) {
53
- const { username, password, workspace } = getBitbucketInfo();
54
- const url = `${BITBUCKET_BASE_URL}/repositories/${workspace}/${repository}/pipelines/${pipelineUUID}`;
55
- const auth = {
56
- username: username,
57
- password: password,
58
- };
59
-
60
- try {
61
- const response = await axios.get(url, { auth });
62
- return response.data.state.name;
63
- } catch (error) {
64
- console.error(
65
- 'Error fetching pipeline status:',
66
- error.response?.data || error.message,
67
- );
68
- throw error;
69
- }
70
- }
71
-
72
- export async function runPipeline(
73
- repository,
74
- pipelineName,
75
- branch,
76
- variables,
77
- wait = false,
78
- ) {
79
- try {
80
- console.log(
81
- `Triggering custom pipeline: ${pipelineName} for branch: ${branch}...`,
82
- );
83
- const pipeline = await triggerPipelineByName(
84
- repository,
85
- pipelineName,
86
- branch,
87
- variables,
88
- );
89
-
90
- const pipelineUUID = pipeline.uuid;
91
- const buildNumber = pipeline.build_number;
92
-
93
- console.log(`Pipeline triggered with UUID: ${pipelineUUID}`);
94
- console.log(
95
- `See results here: ${BITBUCKET_WS_URL}/${repository}/piplines/results/${buildNumber}`,
96
- );
97
-
98
- if (!wait) {
99
- return;
100
- }
101
-
102
- let status = '';
103
- do {
104
- console.log('Checking pipeline status...');
105
- await new Promise((resolve) => setTimeout(resolve, 10000)); // Wait 10 seconds
106
- status = await getPipelineStatus(repository, pipelineUUID);
107
- console.log(`Pipeline status: ${status}`);
108
- } while (['IN_PROGRESS', 'PENDING', 'RUNNING'].includes(status));
109
-
110
- console.log(`Pipeline completed with status: ${status}`);
111
- } catch (error) {
112
- console.error('Error monitoring pipeline:', error.message);
113
- }
114
- }
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
+ const BITBUCKET_WS_URL = 'https://bitbucket.org/dp-cloud';
7
+
8
+ async function triggerPipelineByName(
9
+ repository,
10
+ pipelineName,
11
+ branch,
12
+ variables,
13
+ ) {
14
+ const { username, password, workspace } = getBitbucketInfo();
15
+ const url = `${BITBUCKET_BASE_URL}/repositories/${workspace}/${repository}/pipelines/`;
16
+ const auth = {
17
+ username: username,
18
+ password: password,
19
+ };
20
+
21
+ const payload = {
22
+ target: {
23
+ type: 'pipeline_ref_target',
24
+ ref_type: 'branch',
25
+ ref_name: branch,
26
+ selector: {
27
+ type: 'custom',
28
+ pattern: pipelineName,
29
+ },
30
+ },
31
+ variables: variables
32
+ ? Object.entries(variables).map(([key, value]) => ({
33
+ key,
34
+ value,
35
+ secured: false, // Set to true if the variable should be secure
36
+ }))
37
+ : undefined,
38
+ };
39
+
40
+ try {
41
+ const response = await axios.post(url, payload, { auth });
42
+ return response.data;
43
+ } catch (error) {
44
+ console.error(
45
+ 'Error triggering custom pipeline:',
46
+ error.response?.data || error.message,
47
+ );
48
+ throw error;
49
+ }
50
+ }
51
+
52
+ async function getPipelineStatus(repository, pipelineUUID) {
53
+ const { username, password, workspace } = getBitbucketInfo();
54
+ const url = `${BITBUCKET_BASE_URL}/repositories/${workspace}/${repository}/pipelines/${pipelineUUID}`;
55
+ const auth = {
56
+ username: username,
57
+ password: password,
58
+ };
59
+
60
+ try {
61
+ const response = await axios.get(url, { auth });
62
+ return response.data.state.name;
63
+ } catch (error) {
64
+ console.error(
65
+ 'Error fetching pipeline status:',
66
+ error.response?.data || error.message,
67
+ );
68
+ throw error;
69
+ }
70
+ }
71
+
72
+ export async function runPipeline(
73
+ repository,
74
+ pipelineName,
75
+ branch,
76
+ variables,
77
+ wait = false,
78
+ ) {
79
+ try {
80
+ console.log(
81
+ `Triggering custom pipeline: ${pipelineName} for branch: ${branch}...`,
82
+ );
83
+ const pipeline = await triggerPipelineByName(
84
+ repository,
85
+ pipelineName,
86
+ branch,
87
+ variables,
88
+ );
89
+
90
+ const pipelineUUID = pipeline.uuid;
91
+ const buildNumber = pipeline.build_number;
92
+
93
+ console.log(`Pipeline triggered with UUID: ${pipelineUUID}`);
94
+ console.log(
95
+ `See results here: ${BITBUCKET_WS_URL}/${repository}/piplines/results/${buildNumber}`,
96
+ );
97
+
98
+ if (!wait) {
99
+ return;
100
+ }
101
+
102
+ let status = '';
103
+ do {
104
+ console.log('Checking pipeline status...');
105
+ await new Promise((resolve) => setTimeout(resolve, 10000)); // Wait 10 seconds
106
+ status = await getPipelineStatus(repository, pipelineUUID);
107
+ console.log(`Pipeline status: ${status}`);
108
+ } while (['IN_PROGRESS', 'PENDING', 'RUNNING'].includes(status));
109
+
110
+ console.log(`Pipeline completed with status: ${status}`);
111
+ } catch (error) {
112
+ console.error('Error monitoring pipeline:', error.message);
113
+ }
114
+ }
@@ -1,48 +1,48 @@
1
- import { $ } from 'zx';
2
-
3
- export async function publish(GIT_SHA) {
4
- const BITBUCKET_REPO_SLUG = process.env.BITBUCKET_REPO_SLUG;
5
- const BUILD_IMAGE_NAME = `${BITBUCKET_REPO_SLUG}:build-${process.env.BITBUCKET_BUILD_NUMBER}`;
6
- const IMAGE_NAME = `${BITBUCKET_REPO_SLUG}:sha-${GIT_SHA}`;
7
- const JF_REGISTRY_FULL_URL = `${process.env.JF_REGISTRY_URL}/${process.env.JF_REGISTRY_REPO_NAME}`;
8
-
9
- console.log(`Publishing Docker image: ${IMAGE_NAME}`);
10
-
11
- // Docker login
12
- await $`echo ${process.env.JF_REGISTRY_PASSWORD_DEV} | docker login --username ${process.env.JF_REGISTRY_USER_DEV} --password-stdin ${process.env.JF_REGISTRY_URL}`;
13
-
14
- // Check if the image already exists
15
- try {
16
- await $`docker manifest inspect ${JF_REGISTRY_FULL_URL}/${IMAGE_NAME}`;
17
- console.log(
18
- `Tag sha-${GIT_SHA} already exists in the remote repository. Skipping push.`,
19
- );
20
- } catch {
21
- await $`docker tag ${IMAGE_NAME} ${JF_REGISTRY_FULL_URL}/${IMAGE_NAME}`;
22
- await $`docker push ${JF_REGISTRY_FULL_URL}/${IMAGE_NAME}`;
23
- }
24
-
25
- // Tag and push build image
26
- await $`docker tag ${IMAGE_NAME} ${JF_REGISTRY_FULL_URL}/${BUILD_IMAGE_NAME}`;
27
- await $`docker push ${JF_REGISTRY_FULL_URL}/${BUILD_IMAGE_NAME}`;
28
-
29
- // Fetch Git tags pointing to the current HEAD
30
- const gitTagsOutput = (await $`git tag --points-at HEAD`).stdout.trim();
31
- const gitTags = gitTagsOutput.split('\n').filter((tag) => tag);
32
-
33
- // Tag and push each Git tag as a Docker tag
34
- if (gitTags.length > 0) {
35
- console.log(`Found Git tags pointing to HEAD: ${gitTags.join(', ')}`);
36
- for (const gitTag of gitTags) {
37
- const dockerTag = `${JF_REGISTRY_FULL_URL}/${BITBUCKET_REPO_SLUG}:${gitTag}`;
38
- console.log(`Tagging and pushing Docker image for Git tag: ${gitTag}`);
39
- await $`docker tag ${IMAGE_NAME} ${dockerTag}`;
40
- await $`docker push ${dockerTag}`;
41
- }
42
- } else {
43
- console.log('No Git tags found pointing to the current HEAD.');
44
- }
45
-
46
- // Docker logout
47
- await $`docker logout ${process.env.JF_REGISTRY_URL}`;
48
- }
1
+ import { $ } from 'zx';
2
+
3
+ export async function publish(GIT_SHA) {
4
+ const BITBUCKET_REPO_SLUG = process.env.BITBUCKET_REPO_SLUG;
5
+ const BUILD_IMAGE_NAME = `${BITBUCKET_REPO_SLUG}:build-${process.env.BITBUCKET_BUILD_NUMBER}`;
6
+ const IMAGE_NAME = `${BITBUCKET_REPO_SLUG}:sha-${GIT_SHA}`;
7
+ const JF_REGISTRY_FULL_URL = `${process.env.JF_REGISTRY_URL}/${process.env.JF_REGISTRY_REPO_NAME}`;
8
+
9
+ console.log(`Publishing Docker image: ${IMAGE_NAME}`);
10
+
11
+ // Docker login
12
+ await $`echo ${process.env.JF_REGISTRY_PASSWORD_DEV} | docker login --username ${process.env.JF_REGISTRY_USER_DEV} --password-stdin ${process.env.JF_REGISTRY_URL}`;
13
+
14
+ // Check if the image already exists
15
+ try {
16
+ await $`docker manifest inspect ${JF_REGISTRY_FULL_URL}/${IMAGE_NAME}`;
17
+ console.log(
18
+ `Tag sha-${GIT_SHA} already exists in the remote repository. Skipping push.`,
19
+ );
20
+ } catch {
21
+ await $`docker tag ${IMAGE_NAME} ${JF_REGISTRY_FULL_URL}/${IMAGE_NAME}`;
22
+ await $`docker push ${JF_REGISTRY_FULL_URL}/${IMAGE_NAME}`;
23
+ }
24
+
25
+ // Tag and push build image
26
+ await $`docker tag ${IMAGE_NAME} ${JF_REGISTRY_FULL_URL}/${BUILD_IMAGE_NAME}`;
27
+ await $`docker push ${JF_REGISTRY_FULL_URL}/${BUILD_IMAGE_NAME}`;
28
+
29
+ // Fetch Git tags pointing to the current HEAD
30
+ const gitTagsOutput = (await $`git tag --points-at HEAD`).stdout.trim();
31
+ const gitTags = gitTagsOutput.split('\n').filter((tag) => tag);
32
+
33
+ // Tag and push each Git tag as a Docker tag
34
+ if (gitTags.length > 0) {
35
+ console.log(`Found Git tags pointing to HEAD: ${gitTags.join(', ')}`);
36
+ for (const gitTag of gitTags) {
37
+ const dockerTag = `${JF_REGISTRY_FULL_URL}/${BITBUCKET_REPO_SLUG}:${gitTag}`;
38
+ console.log(`Tagging and pushing Docker image for Git tag: ${gitTag}`);
39
+ await $`docker tag ${IMAGE_NAME} ${dockerTag}`;
40
+ await $`docker push ${dockerTag}`;
41
+ }
42
+ } else {
43
+ console.log('No Git tags found pointing to the current HEAD.');
44
+ }
45
+
46
+ // Docker logout
47
+ await $`docker logout ${process.env.JF_REGISTRY_URL}`;
48
+ }