Skip to content

Commit dca4d6c

Browse files
STRY56640560: Synced code.devsnc with github.com (#4)
1 parent 261717d commit dca4d6c

File tree

8 files changed

+221
-107
lines changed

8 files changed

+221
-107
lines changed

README.md

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ sndevopscli create package --help
6060
npm unlink .
6161
```
6262

63-
## Creating Docker image
63+
## Creating Docker Image
6464

65-
### Building docker image
65+
### Building Docker Image
6666

6767
```sh
6868
docker build -t servicenowdocker/sndevops-cli:0.01 .
@@ -72,75 +72,104 @@ docker build -t servicenowdocker/sndevops-cli:0.01 .
7272
docker push servicenowdocker/sndevops-cli:0.01
7373
```
7474

75-
## Integrating with gitlab
75+
## Integrating with GitLab
7676

77-
[Example gitlab project](https://gitlab.xxxx.xxxxx.xyz/devops-admin/helloworld/-/blob/main/.gitlab-ci.yml?ref_type=heads)
77+
[Example gitlab project](/gitlab-ci.yml)
7878

7979

80-
**Example with passing all ServiceNow info via commandline**
80+
### Env variables
8181

82+
```
83+
SNOW_URL = <servicenow-instance-url>
84+
SNOW_TOKEN = <servicenow-tool-token>
85+
SNOW_TOOLID = <servicenow-tool-id>
86+
```
87+
88+
**Example with passing all ServiceNow information via commandline**
8289
```yaml
8390

91+
This custom step needs to be added at job level to create artifact or package in ServiceNow instance.
92+
8493
stages:
8594
- package
8695

8796
package:
8897
stage: package
89-
image: servicenowdocker/sndevops-cli:0.35
98+
image: servicenowdocker/sndevops-cli:0.01
9099
script:
91100
- sndevopscli create artifact -a '[{"name":"artifact-name-$CI_JOB_ID","repositoryName":"artifact-repo-name" ,"version":"1.3.0"}]'
92101
- sndevopscli create package -n "package-name" -a '[{"name":"artifact-name-$CI_JOB_ID","repositoryName":"artifact-repo-name" ,"version":"1.3.0"}]
93102

94-
```
95-
96-
### Env variables
97-
98-
```
99-
SNOW_URL = <servicenow-instance-url>
100-
SNOW_TOKEN = <servicenow-tool-token>
101-
SNOW_TOOLID = <servicenow-tool-id>
102-
```
103-
104-
**Example with passing all ServiceNow info via commandline**
105-
```yaml
103+
OR
106104

107105
stages:
108106
- package
109107

110108
package:
111109
stage: package
112-
image: servicenowdocker/sndevops-cli:0.35
110+
image: servicenowdocker/sndevops-cli:0.01
113111
script:
114112
- sndevopscli create artifact -u <serviceno-url> -t <tool-id> --token <tool-token> -a '[{"name":"artifact-name-$CI_JOB_ID","repositoryName":"artifact-repo-name" ,"version":"1.3.0"}]'
115113
- sndevopscli create package -u <serviceno-url> -t <tool-id> --token <tool-token> -n "package-mame" -a '[{"name":"artifact-name-$CI_JOB_ID","repositoryName":"artifact-repo-name" ,"version":"1.3.0"}]
116114

115+
-a : [mandatory]
116+
This specifies artifact details.
117+
118+
-n : [mandatory]
119+
This specifies package details.
120+
117121
```
118122

123+
119124
**Example of change creation for ServiceNow via commandline**
120125
```yaml
121126

127+
This custom step needs to be added at job level to create change in ServiceNow instance.
128+
122129
stages:
123130
- DevOpsChangeApproval
124131

125132
ServiceNow DevOps Change:
126133
stage: DevOpsChangeApproval
127-
image: servicenowdocker/sndevops-cli:0.35
134+
image: servicenowdocker/sndevops-cli:0.01
128135
script:
129136
- sndevopscli create change -p '{"changeStepDetails":{"timeout":3600,"interval":100},"attributes":{"short_description":"Automated Software Deployment","description":"Automated Software Deployment.","assignment_group":"XXXXXXX","implementation_plan":"Software update is tested and results can be found in Test Summaries Tab.","backout_plan":"When software fails in production, the previous software release will be re-deployed.","test_plan":"Testing if the software was successfully deployed or not"}}'
130137

138+
changeStepDetails: [optional]
139+
It holds the timeout and interval details.
140+
141+
interval: [optional]
142+
The time in seconds to wait between trying the API. The default value is 100 seconds.
143+
144+
timeout: [optional]
145+
The maximum time in seconds to wait until the action should fails. The default value is 3600 seconds.
146+
147+
attributes: [optional]
148+
The change request attribute details are to be used while creating change in ServiceNow instance. The change request is a JSON object surrounded by curly braces {} containing key-value pairs separated by a comma ,. A key-value pair consists of a key and a value separated by a colon :. The keys supported in key-value pair are short_description, description, assignment_group, implementation_plan, backout_plan, test_plan etc.
149+
150+
151+
131152
```
132153

133154
**Example of sonar summary for ServiceNow via commandline**
134155
```yaml
135156

157+
This custom step needs to be added at job level to create sonar summary in ServiceNow instance.
158+
136159
stages:
137160
- DevOpsSonarStage
138161

139162
ServiceNow DevOps Sonar Scan Results:
140163
stage: DevOpsSonarStage
141-
image: servicenowdocker/sndevops-cli:0.35
164+
image: servicenowdocker/sndevops-cli:0.01
142165
script:
143-
- sndevopscli create sonar -sonarUrl 'https://sonarcloud.io' -sonarProjectKey 'xxxxxxx'
166+
- sndevopscli create sonar -url 'https://sonarcloud.io' -projectKey 'xxxxxxx'
167+
168+
url: [mandatory]
169+
This specifies the sonar url.
170+
171+
projectKey: [mandatory]
172+
This specifies the sonar project key.
144173

145174
```
146175

gitlab-ci.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
image: servicenowdocker/sndevops-cli:0.01
2+
stages:
3+
- pre-build
4+
- build
5+
- sonar
6+
- changeapproval
7+
- deploy
8+
9+
10+
Pre-Build:
11+
stage: pre-build
12+
script:
13+
- echo $CI_JOB_NAME
14+
15+
Artifact and Package:
16+
stage: build
17+
script:
18+
- sndevopscli create artifact -a "[{\"name\":\"Artifact-${CI_JOB_NAME}\",\"repositoryName\":\"TestRepo\",\"version\":\"1.${CI_RUNNER_ID}.0\"}]"
19+
- sndevopscli create package -n "Test_Package" -a "[{\"name\":\"Artifact-${CI_JOB_NAME}\",\"repositoryName\":\"TestRepo\",\"version\":\"1.${CI_RUNNER_ID}.0\"}]"
20+
21+
22+
ServiceNow DevOps SonarScan Results:
23+
stage: sonar
24+
script:
25+
- sndevopscli create sonar -url 'https://sonarcloud.io' -projectKey 'xxxxxxx'
26+
27+
ServiceNow DevOps Change Step:
28+
stage: changeapproval
29+
script:
30+
- sndevopscli create change -p '{"changeStepDetails":{"timeout":3600,"interval":100},"attributes":{"short_description":"Automated Software Deployment","description":"Automated Software Deployment.","assignment_group":"xxxxxx","implementation_plan":"Software update is tested and results can be found in Test Summaries Tab.","backout_plan":"When software fails in production, the previous software release will be re-deployed.","test_plan":"Testing if the software was successfully deployed or not"}}'
31+
32+
Deploy Job:
33+
stage: deploy
34+
script:
35+
- echo $CI_JOB_NAME
36+
Lines changed: 64 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,71 @@
11
const SnDevopsApi = require('../base/sndevopsApi.js')
22

3-
const API_PACKAGE_PATH = 'api/sn_devops/devops/package/registration';
43
const API_ARTIFACT_PATH = 'api/sn_devops/devops/artifact/registration';
5-
const BaseEnv = require('../../common/baseEnv.js')
4+
const BaseEnv = require('../../common/baseEnv.js');
5+
const { default: axios } = require('axios');
66

77

88
class ArtifactManager extends SnDevopsApi {
99

10-
createPackage(packageName, artifacts) {
10+
async createArtifacts(artifacts) {
1111

12-
let url = new URL(API_PACKAGE_PATH, this.url);
13-
url.searchParams.append("orchestrationToolId", this.toolId)
12+
try{
13+
var response;
14+
var payload;
15+
var url;
16+
var artifactJson;
1417

15-
console.log("Computed ServiceNow url " + url.toString())
16-
17-
let artifactJson = JSON.parse(artifacts);
18-
let payload = this._getRequestBodyForPackageRegistration(packageName, artifactJson)
19-
20-
this.post(url.toString(), payload, this._getAuthHeaderWithToken());
18+
url = new URL(API_ARTIFACT_PATH, this.url);
19+
url.searchParams.append("orchestrationToolId", this.toolId)
2120

22-
}
23-
24-
25-
createArtifacts(artifacts) {
26-
27-
let url = new URL(API_ARTIFACT_PATH, this.url);
28-
url.searchParams.append("orchestrationToolId", this.toolId)
29-
console.log("Computed path ServiceNow url " + url.toString())
30-
31-
32-
let artifactJson = JSON.parse(artifacts);
33-
let payload = this._getRequestBodyForArtifactRegistration(artifactJson)
34-
35-
let response = this.post(url.toString(), payload, this._getAuthHeaderWithToken());
36-
console.log("Response for Package Creation" + response);
37-
38-
}
21+
try{
22+
artifactJson = JSON.parse(artifacts);
23+
} catch(exception){
24+
throw new Error("Artifact cannot be registered because Artifact Details were not parsed.");
25+
}
26+
27+
try {
28+
payload = this._getRequestBodyForArtifactRegistration(artifactJson);
29+
let httpHeaders = { headers: this._getAuthHeaderWithToken() };
30+
31+
response = await axios.post(url.toString(), JSON.stringify(payload), httpHeaders);
32+
} catch(e){
33+
if (e.message.includes('ECONNREFUSED') || e.message.includes('ENOTFOUND')) {
34+
throw new Error('Artifact cannot be registered because the ServiceNow Instance URL is invalid. Enter the correct URL and try again.');
35+
}
36+
37+
else if (e.message.includes('401')) {
38+
throw new Error('The SNOW_TOKEN and SNOW_TOOLID are incorrect. Verify that the GitLab project level variables are configured.');
39+
}
40+
41+
else if (e.message.includes('405')) {
42+
throw new Error('Artifact cannot be registered because response Code from ServiceNow is 405. Please check ServiceNow logs for more details.');
43+
}
3944

40-
_getRequestBodyForPackageRegistration(packageName, artifacts) {
41-
let requestPayload = {
42-
"name": packageName,
43-
"pipelineName": BaseEnv.CI_PROJECT_PATH,
44-
"stageName": BaseEnv.CI_JOB_NAME,
45-
"taskExecutionNumber": BaseEnv.CI_JOB_ID,
46-
"orchestrationTask": {
47-
"orchestrationTaskURL": BaseEnv.CI_PIPELINE_URL,
48-
"orchestrationTaskName": BaseEnv.CI_JOB_NAME,
49-
"branchName": BaseEnv.CI_COMMIT_BRANCH,
50-
"toolId": this.toolId,
51-
},
52-
"artifacts": [
53-
{
54-
"name": artifacts[0].name,
55-
"pipelineName": BaseEnv.CI_PROJECT_PATH,
56-
"repositoryName": artifacts[0].repositoryName,
57-
"stageName": BaseEnv.CI_JOB_NAME,
58-
"taskExecutionNumber": BaseEnv.CI_JOB_ID,
59-
"semanticVersion": artifacts[0].semanticVersion,
60-
"version": artifacts[0].version
45+
else if(e.message.includes('400') || e.message.includes('404')){
46+
let errMsg = 'ServiceNow DevOps Artifact Registration is not successful. ';
47+
let responseData = e.response.data;
48+
if (responseData && responseData.result && responseData.result.errorMessage) {
49+
errMsg = errMsg + responseData.result.errorMessage;
50+
throw new Error(errMsg);
51+
}
52+
else if (responseData && responseData.result && responseData.result.details && responseData.result.details.errors) {
53+
let errors = responseData.result.details.errors;
54+
for (var index in errors) {
55+
errMsg = errMsg + errors[index].message;
56+
}
57+
throw new Error(errMsg);
58+
}
6159
}
62-
]
63-
}
64-
return requestPayload;
6560

61+
else {
62+
throw new Error('ServiceNow Artifact Registration cannot be completed. Please check ServiceNow logs for more details.');
63+
}
64+
}
65+
} catch(err) {
66+
console.error('\n \x1b[1m\x1b[31m' + err.message + '\x1b[0m\x1b[0m');
67+
process.exit(1);
68+
}
6669
}
6770

6871
_getRequestBodyForArtifactRegistration(artifacts) {
@@ -71,13 +74,21 @@ class ArtifactManager extends SnDevopsApi {
7174
"taskExecutionNumber": BaseEnv.CI_JOB_ID,
7275
"pipelineName": BaseEnv.CI_PROJECT_PATH,
7376
"stageName": BaseEnv.CI_JOB_NAME,
77+
"gitLabProjectId": BaseEnv.CI_PROJECT_ID,
7478
"artifacts": artifacts
7579
};
80+
this.validateArtifactsPayload(requestPayload);
7681
return requestPayload;
7782

7883
}
7984

80-
85+
validateArtifactsPayload(artifactPayload){
86+
for (var key in artifactPayload) {
87+
if (artifactPayload.hasOwnProperty(key) && !artifactPayload[key]) {
88+
throw new Error(`Artifact cannot be registered as Key: ${key} has a null value.`);
89+
}
90+
}
91+
}
8192
}
8293

8394
module.exports = ArtifactManager;

src/api/base/sndevopsApi.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class SndevopsApi {
5050
_getAuthHeaderWithToken(){
5151
return {
5252
"Authorization": "sn_devops.DevOpsToken " + this.toolId + ":" + this.token,
53+
'Accept': 'application/json',
5354
"Content-Type": "application/json"
5455
}
5556
}

src/api/change/changeRequest.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ class ChangeRequestManager extends SnDevopsApi {
3838
"projectId": BaseEnv.CI_PROJECT_ID,
3939
"jobId": BaseEnv.CI_JOB_ID,
4040
"pipelineName": BaseEnv.CI_PROJECT_TITLE,
41-
"jobName": BaseEnv.CI_JOB_NAME
41+
"jobName": BaseEnv.CI_JOB_NAME,
42+
"projectPath": BaseEnv.CI_PROJECT_PATH
4243
};
4344

4445
//ChangeAttributes are optional
@@ -363,7 +364,8 @@ class ChangeRequestManager extends SnDevopsApi {
363364
"pipelineName": changePayload.pipelineName,
364365
"jobId": changePayload.jobId,
365366
"gitLabProjectId" : changePayload.projectId,
366-
"pipelineId": changePayload.buildNumber
367+
"pipelineId": changePayload.buildNumber,
368+
"projectPath": changePayload.projectPath
367369
}
368370
}
369371

0 commit comments

Comments
 (0)