-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathJenkinsfile.scripted
More file actions
201 lines (186 loc) · 11 KB
/
Copy pathJenkinsfile.scripted
File metadata and controls
201 lines (186 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
properties([
parameters([
choice(name: 'BUILD_RUNTIME', choices: ['auto', 'jenkins-maven', 'docker-maven'], description: 'Use Jenkins Maven when a full JDK 17+ is available, or Docker Maven when Jenkins only has a JRE.'),
string(name: 'MAVEN_TOOL', defaultValue: 'maven3.9.16', description: 'Jenkins Maven tool name used by the successful library pipeline.'),
string(name: 'MAVEN_DOCKER_IMAGE', defaultValue: 'maven:3.9.9-eclipse-temurin-21', description: 'Maven image used when BUILD_RUNTIME is auto/docker-maven.'),
booleanParam(name: 'RUN_SONAR', defaultValue: true, description: 'Run SonarQube analysis and quality gate.'),
string(name: 'SONAR_HOST_URL', defaultValue: 'http://52.91.204.64:9000', description: 'SonarQube server URL.'),
string(name: 'SONAR_TOKEN_CREDENTIALS_ID', defaultValue: 'sonarqube-token', description: 'Secret text credential for SonarQube.'),
booleanParam(name: 'PUBLISH_TO_NEXUS', defaultValue: true, description: 'Publish the WAR artifact to Nexus with Maven deploy.'),
string(name: 'NEXUS_CREDENTIALS_ID', defaultValue: 'nexus-credentials', description: 'Username/password credential for Nexus.'),
string(name: 'NEXUS_URL', defaultValue: 'http://nexus.example.com:8081/', description: 'Base Nexus URL.'),
string(name: 'NEXUS_RELEASES_URL', defaultValue: 'http://nexus.example.com:8081/repository/maven-releases/', description: 'Nexus Maven releases repository URL.'),
string(name: 'NEXUS_SNAPSHOTS_URL', defaultValue: 'http://nexus.example.com:8081/repository/maven-snapshots/', description: 'Nexus Maven snapshots repository URL.'),
booleanParam(name: 'DEPLOY_TO_TOMCAT', defaultValue: false, description: 'Deploy the generated WAR to Tomcat.'),
string(name: 'TOMCAT_URL', defaultValue: 'http://tomcat.example.com:8080', description: 'Base Tomcat URL.'),
string(name: 'TOMCAT_CREDENTIALS_ID', defaultValue: 'tomcat-manager', description: 'Username/password credential for Tomcat Manager.')
])
])
node {
env.APP_NAME = 'liontech-resorts'
env.WAR_FILE = 'target/liontech-resorts.war'
env.MAVEN_OPTS = '-Dmaven.repo.local=.m2/repository'
env.BUILD_RUNTIME = params.BUILD_RUNTIME
env.MAVEN_DOCKER_IMAGE = params.MAVEN_DOCKER_IMAGE
try {
stage('Checkout') {
checkout scm
}
stage('Configure Maven') {
if (params.BUILD_RUNTIME != 'docker-maven') {
try {
def mavenHome = tool name: params.MAVEN_TOOL, type: 'hudson.tasks.Maven$MavenInstallation'
env.MAVEN_HOME = mavenHome
env.M2_HOME = mavenHome
env.PATH = "${mavenHome}/bin:${env.PATH}"
} catch (Exception toolError) {
if (params.BUILD_RUNTIME == 'jenkins-maven') {
error "Jenkins Maven tool '${params.MAVEN_TOOL}' was not found."
}
echo "Jenkins Maven tool '${params.MAVEN_TOOL}' was not found; auto mode can still use Docker Maven."
}
}
sh 'sh ./ci/maven-ci.sh --version'
}
stage('Unit Tests and Jacoco Coverage') {
sh 'sh ./ci/maven-ci.sh clean verify'
junit allowEmptyResults: true, testResults: 'target/surefire-reports/*.xml'
archiveArtifacts artifacts: 'target/site/jacoco/**/*', allowEmptyArchive: true, fingerprint: true
}
if (params.RUN_SONAR) {
stage('SonarQube Analysis') {
def sonarHostUrl = params.SONAR_HOST_URL?.trim()?.replaceAll('/+$', '')
if (!sonarHostUrl) {
error 'Set SONAR_HOST_URL to the real SonarQube URL.'
}
withCredentials([string(credentialsId: "${params.SONAR_TOKEN_CREDENTIALS_ID}", variable: 'SONAR_TOKEN')]) {
withEnv(["SONAR_HOST_URL=${sonarHostUrl}"]) {
sh '''
set -eu
echo "Running SonarQube analysis against $SONAR_HOST_URL"
sh ./ci/maven-ci.sh sonar:sonar \
-Dsonar.host.url="$SONAR_HOST_URL" \
-Dsonar.token="$SONAR_TOKEN"
'''
}
}
}
stage('SonarQube Quality Gate') {
def sonarHostUrl = params.SONAR_HOST_URL?.trim()?.replaceAll('/+$', '')
withCredentials([string(credentialsId: "${params.SONAR_TOKEN_CREDENTIALS_ID}", variable: 'SONAR_TOKEN')]) {
withEnv(["SONAR_HOST_URL=${sonarHostUrl}"]) {
timeout(time: 5, unit: 'MINUTES') {
sh '''
set -eu
if ! command -v curl >/dev/null 2>&1; then
echo "ERROR: curl is required on the Jenkins agent for SonarQube quality gate checks."
exit 1
fi
report_file="target/sonar/report-task.txt"
if [ ! -f "$report_file" ]; then
echo "ERROR: SonarQube task report was not found at $report_file."
exit 1
fi
ce_task_url="$(sed -n 's/^ceTaskUrl=//p' "$report_file")"
dashboard_url="$(sed -n 's/^dashboardUrl=//p' "$report_file")"
if [ -z "$ce_task_url" ]; then
echo "ERROR: SonarQube ceTaskUrl was not found in $report_file."
cat "$report_file"
exit 1
fi
echo "SonarQube dashboard: ${dashboard_url:-unknown}"
for attempt in $(seq 1 30); do
response="$(curl --fail --silent --show-error --user "$SONAR_TOKEN:" "$ce_task_url")"
task_status="$(printf '%s' "$response" | grep -o '"status":"[^"]*"' | head -n 1 | cut -d: -f2 | tr -d '"')"
echo "SonarQube background task status: ${task_status:-unknown} (attempt $attempt)"
if [ "$task_status" = "SUCCESS" ]; then
analysis_id="$(printf '%s' "$response" | grep -o '"analysisId":"[^"]*"' | head -n 1 | cut -d: -f2 | tr -d '"')"
if [ -z "$analysis_id" ]; then
echo "ERROR: SonarQube analysisId was not present in CE task response."
echo "$response"
exit 1
fi
quality_response="$(curl --fail --silent --show-error --user "$SONAR_TOKEN:" "$SONAR_HOST_URL/api/qualitygates/project_status?analysisId=$analysis_id")"
gate_status="$(printf '%s' "$quality_response" | grep -o '"status":"[^"]*"' | head -n 1 | cut -d: -f2 | tr -d '"')"
echo "SonarQube quality gate status: ${gate_status:-unknown}"
if [ "$gate_status" = "OK" ]; then
exit 0
fi
echo "$quality_response"
exit 1
fi
if [ "$task_status" = "FAILED" ] || [ "$task_status" = "CANCELED" ]; then
echo "$response"
exit 1
fi
sleep 10
done
echo "ERROR: Timed out waiting for SonarQube quality gate."
exit 1
'''
}
}
}
}
}
stage('Package WAR') {
sh 'sh ./ci/maven-ci.sh -DskipTests package'
archiveArtifacts artifacts: env.WAR_FILE, fingerprint: true
}
if (params.PUBLISH_TO_NEXUS) {
stage('Publish WAR to Nexus') {
withEnv([
"NEXUS_RELEASES_URL=${params.NEXUS_RELEASES_URL}",
"NEXUS_SNAPSHOTS_URL=${params.NEXUS_SNAPSHOTS_URL}",
"NEXUS_URL=${params.NEXUS_URL}"
]) {
withCredentials([usernamePassword(credentialsId: "${params.NEXUS_CREDENTIALS_ID}", usernameVariable: 'NEXUS_USERNAME', passwordVariable: 'NEXUS_PASSWORD')]) {
sh 'sh ./ci/maven-ci.sh -s maven-settings.example.xml -DskipTests deploy'
}
}
}
}
if (params.DEPLOY_TO_TOMCAT) {
stage('Deploy to Tomcat') {
withCredentials([usernamePassword(credentialsId: "${params.TOMCAT_CREDENTIALS_ID}", usernameVariable: 'TOMCAT_USER', passwordVariable: 'TOMCAT_PASSWORD')]) {
withEnv(["TOMCAT_URL=${params.TOMCAT_URL}"]) {
sh '''
set -eu
TOMCAT_BASE="${TOMCAT_URL%/}"
curl --fail --show-error --silent \
--user "$TOMCAT_USER:$TOMCAT_PASSWORD" \
--upload-file "$WAR_FILE" \
"$TOMCAT_BASE/manager/text/deploy?path=/$APP_NAME&update=true"
for attempt in $(seq 1 30); do
if curl --fail --silent "$TOMCAT_BASE/$APP_NAME/actuator/health" >/tmp/liontech-resorts-health.json; then
cat /tmp/liontech-resorts-health.json
exit 0
fi
sleep 5
done
echo "Tomcat deployment did not become healthy in time."
exit 1
'''
}
}
}
}
} finally {
stage('Publish Reports') {
junit allowEmptyResults: true, testResults: 'target/surefire-reports/*.xml'
archiveArtifacts artifacts: 'target/*.war,target/site/jacoco/**/*', allowEmptyArchive: true, fingerprint: true
try {
publishHTML(target: [
allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'target/site/jacoco',
reportFiles: 'index.html',
reportName: 'Jacoco Coverage'
])
} catch (ignored) {
echo 'HTML Publisher plugin is not installed; Jacoco HTML report was archived instead.'
}
}
}
}