Jenkinsfile 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /**
  2. * UAT: Checkout -> Maven -> (optional) push images to Harbor -> deploy jar + docker restart.
  3. *
  4. * Jenkins Job: Pipeline script from SCM
  5. * Script Path: docs/jenkins/uat/Jenkinsfile
  6. *
  7. * Harbor (153.68): when PUSH_TO_HARBOR=true, push e.g.
  8. * 39.105.153.68/alien_cloud/gateway:uat-latest
  9. * Before push: existing uat-latest is archived as uat-build-<BUILD_NUMBER> (Harbor API tag when
  10. * permitted; on 403 falls back to docker pull/tag/push). New image is pushed only as uat-latest.
  11. * Prod promote: SOURCE_TAG=uat-latest.
  12. */
  13. /** Normalize GIT_BRANCH: uat-20260202 (not origin/uat-20260202 or refs/heads/...) */
  14. def normalizeGitBranch(String raw) {
  15. def b = (raw ?: 'uat-20260202').trim()
  16. if (!b) {
  17. return 'uat-20260202'
  18. }
  19. while (b.startsWith('refs/heads/')) {
  20. b = b.substring('refs/heads/'.length())
  21. }
  22. while (b.startsWith('origin/')) {
  23. b = b.substring('origin/'.length())
  24. }
  25. return b ?: 'uat-20260202'
  26. }
  27. /** HARBOR_PUSH_SCOPE: all-java-services | <repo>-only */
  28. def filterHarborPushScope(List allServices, String scope) {
  29. def s = (scope ?: 'all-java-services').trim()
  30. if (s == 'all-java-services') {
  31. return allServices
  32. }
  33. if (s.endsWith('-only')) {
  34. def repo = s.substring(0, s.length() - '-only'.length())
  35. def picked = allServices.findAll { it.repo == repo }
  36. if (picked.isEmpty()) {
  37. error("Unknown HARBOR_PUSH_SCOPE: ${scope}")
  38. }
  39. return picked
  40. }
  41. error("Unknown HARBOR_PUSH_SCOPE: ${scope}")
  42. }
  43. /** Marker file: docker pull/tag/push archive needed when Harbor API tag is forbidden. */
  44. def harborArchiveDockerFallbackMarker(String repo) {
  45. return "/tmp/harbor_archive_docker_fallback_${repo}"
  46. }
  47. /** Archive current uat-latest as uat-build-N via Harbor API (same digest, no layer re-upload). */
  48. def archiveHarborLatestViaApi(def script, String reg, String proj, String repo, String latestTag, String buildTag) {
  49. def fallbackMarker = harborArchiveDockerFallbackMarker(repo)
  50. script.sh """
  51. set -e
  52. REG='${reg}'
  53. PROJ='${proj}'
  54. REPO='${repo}'
  55. LATEST='${latestTag}'
  56. BUILD_TAG='${buildTag}'
  57. FALLBACK_MARKER='${fallbackMarker}'
  58. rm -f "\${FALLBACK_MARKER}"
  59. if ! command -v jq >/dev/null 2>&1; then
  60. echo ">>> WARN: jq missing, will docker-fallback archive for \${REPO}"
  61. touch "\${FALLBACK_MARKER}"
  62. exit 0
  63. fi
  64. enc_repo=\$(printf '%s' "\${REPO}" | jq -sRr @uri)
  65. if ! curl -fsS -u "\${HARBOR_USER}:\${HARBOR_PASS}" \\
  66. "http://\${REG}/api/v2.0/projects/\${PROJ}/repositories/\${enc_repo}/artifacts/\${LATEST}" >/dev/null 2>&1; then
  67. echo ">>> no prior \${LATEST} for \${REPO}, skip archive"
  68. exit 0
  69. fi
  70. echo ">>> archive previous \${LATEST} -> \${BUILD_TAG} (\${REPO}, Harbor API)"
  71. archive_code=\$(curl -sS -o /tmp/harbor_archive_\${REPO}.json -w '%{http_code}' \\
  72. -X POST -u "\${HARBOR_USER}:\${HARBOR_PASS}" \\
  73. "http://\${REG}/api/v2.0/projects/\${PROJ}/repositories/\${enc_repo}/artifacts/\${LATEST}/tags" \\
  74. -H 'Content-Type: application/json' \\
  75. -d "{\\"name\\":\\"\${BUILD_TAG}\\"}")
  76. case "\${archive_code}" in
  77. 201|200)
  78. echo ">>> archived \${REPO}:\${BUILD_TAG} (same digest as prior \${LATEST})"
  79. ;;
  80. 409)
  81. echo ">>> WARN: \${REPO}:\${BUILD_TAG} already exists, continue"
  82. ;;
  83. 403)
  84. echo ">>> WARN: Harbor API archive forbidden (403) for \${REPO}, will docker-fallback"
  85. cat /tmp/harbor_archive_\${REPO}.json 2>/dev/null || true
  86. touch "\${FALLBACK_MARKER}"
  87. ;;
  88. *)
  89. echo ">>> ERROR: Harbor archive \${REPO} HTTP \${archive_code}"
  90. cat /tmp/harbor_archive_\${REPO}.json 2>/dev/null || true
  91. exit 1
  92. ;;
  93. esac
  94. """
  95. }
  96. def pushOneHarborImage(def script, Map svc, String reg, String proj, String latestTag, String buildTag,
  97. String baseImage, String dockerfile, String workspace) {
  98. def jarName = "${svc.module}-1.0.0.jar"
  99. def imageLatest = "${reg}/${proj}/${svc.repo}:${latestTag}"
  100. def imageBuild = "${reg}/${proj}/${svc.repo}:${buildTag}"
  101. def fallbackMarker = harborArchiveDockerFallbackMarker(svc.repo)
  102. def withLibFlag = svc.withLib ? 'true' : 'false'
  103. script.sh """
  104. set -e
  105. test -f ${workspace}/${svc.module}/target/${jarName}
  106. cd ${workspace}/${svc.module}
  107. rm -rf .jenkins_docker_ctx && mkdir -p .jenkins_docker_ctx/lib
  108. cp -f target/${jarName} .jenkins_docker_ctx/${jarName}
  109. if [ "${withLibFlag}" = "true" ] && [ -d target/lib ]; then
  110. cp -rf target/lib/. .jenkins_docker_ctx/lib/
  111. else
  112. touch .jenkins_docker_ctx/lib/.keep
  113. fi
  114. """
  115. // Harbor API archive runs outside flock (HTTP only, safe to parallelize).
  116. archiveHarborLatestViaApi(script, reg, proj, svc.repo, latestTag, buildTag)
  117. // Parallel branches share one Docker daemon; serialize docker build/push to avoid containerd races.
  118. script.sh """
  119. set -e
  120. DOCKER_LOCK=/tmp/jenkins-alien-cloud-docker.lock
  121. flock "\${DOCKER_LOCK}" sh -c '
  122. set -e
  123. FALLBACK_MARKER="${fallbackMarker}"
  124. if [ -f "\${FALLBACK_MARKER}" ]; then
  125. echo ">>> docker-fallback archive ${svc.repo}:${buildTag} from ${latestTag}"
  126. if docker pull ${imageLatest}; then
  127. docker tag ${imageLatest} ${imageBuild}
  128. docker push ${imageBuild}
  129. docker rmi ${imageBuild} 2>/dev/null || true
  130. echo ">>> archived ${imageBuild} via docker"
  131. else
  132. echo ">>> WARN: docker pull ${imageLatest} failed, skip archive"
  133. fi
  134. rm -f "\${FALLBACK_MARKER}"
  135. fi
  136. cd ${workspace}/${svc.module}/.jenkins_docker_ctx
  137. build_ok=0
  138. for attempt in 1 2 3; do
  139. if docker build -f ${workspace}/${dockerfile} \\
  140. --build-arg BASE_IMAGE=${baseImage} \\
  141. --build-arg JAR_FILE=${jarName} \\
  142. --build-arg SERVER_PORT=${svc.port} \\
  143. --build-arg WITH_LIB=${svc.withLib} \\
  144. -t ${imageLatest} .; then
  145. build_ok=1
  146. break
  147. fi
  148. echo ">>> WARN: docker build ${svc.repo} attempt \${attempt} failed, retrying..."
  149. sleep "\$((attempt * 5))"
  150. done
  151. if [ "\${build_ok}" -ne 1 ]; then
  152. echo ">>> ERROR: docker build ${svc.repo} failed after 3 attempts"
  153. exit 1
  154. fi
  155. docker push ${imageLatest}
  156. echo ">>> pushed ${imageLatest} (archived prior latest as ${buildTag} if any)"
  157. docker rmi ${imageLatest} 2>/dev/null || true
  158. '
  159. cd ${workspace}/${svc.module}
  160. rm -rf .jenkins_docker_ctx
  161. """
  162. }
  163. def deployOneUatService(def script, String moduleName, String dirName, String workspace) {
  164. def sourceJar = "${workspace}/${moduleName}/target/${moduleName}-1.0.0.jar"
  165. def sourceLib = "${workspace}/${moduleName}/target/lib"
  166. def targetDir = "/app_deploy_uat/${dirName}"
  167. script.sh """
  168. set -e
  169. echo ">>> Deploy module: ${moduleName}"
  170. if [ -f "${sourceJar}" ]; then
  171. mkdir -p "${targetDir}"
  172. if [ -d "${sourceLib}" ]; then
  173. rm -rf "${targetDir}/lib"
  174. cp -rf "${sourceLib}" "${targetDir}"
  175. fi
  176. cp -f "${sourceJar}" "${targetDir}/"
  177. if docker ps -a --format '{{.Names}}' | grep -wq "${dirName}"; then
  178. docker restart "${dirName}"
  179. echo ">>> [${dirName}] restarted"
  180. else
  181. echo ">>> [${dirName}] container missing, jar copied only"
  182. fi
  183. else
  184. echo ">>> [${dirName}] jar missing, skip"
  185. fi
  186. """
  187. }
  188. /** Delete oldest uat-build-* tags in Harbor, keep newest KEEP. Never deletes uat-latest or current build tag. */
  189. def pruneHarborUatTags(def script, String reg, String proj, List repoNames, int keepCount, String tagPrefix, String currentBuildTag, String latestTag) {
  190. if (repoNames == null || repoNames.isEmpty() || keepCount < 1) {
  191. return
  192. }
  193. def repos = repoNames.join(' ')
  194. // POSIX sh only (Jenkins sh step); no mapfile / process substitution
  195. script.sh """
  196. set -e
  197. REG='${reg}'
  198. PROJ='${proj}'
  199. KEEP=${keepCount}
  200. PREFIX='${tagPrefix}'
  201. CURRENT='${currentBuildTag}'
  202. LATEST='${latestTag}'
  203. if ! command -v jq >/dev/null 2>&1; then
  204. echo '>>> Harbor prune skipped: jq not installed on Jenkins agent'
  205. exit 0
  206. fi
  207. for repo in ${repos}; do
  208. enc_repo=\$(printf '%s' "\${repo}" | jq -sRr @uri)
  209. tags_file=\$(mktemp)
  210. curl -fsS -u "\${HARBOR_USER}:\${HARBOR_PASS}" \\
  211. "http://\${REG}/api/v2.0/projects/\${PROJ}/repositories/\${enc_repo}/artifacts?page_size=100" \\
  212. | jq -r '.[] | .tags[]? | .name' | grep "^\${PREFIX}" | sort -t- -k3 -n > "\${tags_file}" || true
  213. count=\$(wc -l < "\${tags_file}" | tr -d ' ')
  214. echo ">>> prune \${repo}: \${count} tag(s) matching \${PREFIX}*"
  215. if [ "\${count}" -le "\${KEEP}" ]; then
  216. rm -f "\${tags_file}"
  217. continue
  218. fi
  219. del_count=\$((count - KEEP))
  220. deleted=0
  221. while IFS= read -r t; do
  222. if [ -z "\${t}" ]; then
  223. continue
  224. fi
  225. if [ "\${t}" = "\${CURRENT}" ] || [ "\${t}" = "\${LATEST}" ]; then
  226. continue
  227. fi
  228. if [ "\${deleted}" -ge "\${del_count}" ]; then
  229. break
  230. fi
  231. echo ">>> DELETE Harbor tag \${repo}:\${t}"
  232. if ! curl -fsS -X DELETE -u "\${HARBOR_USER}:\${HARBOR_PASS}" \\
  233. "http://\${REG}/api/v2.0/projects/\${PROJ}/repositories/\${enc_repo}/artifacts/\${t}/tags/\${t}"; then
  234. echo ">>> WARN: delete failed \${repo}:\${t} (check robot delete permission)"
  235. fi
  236. deleted=\$((deleted + 1))
  237. done < "\${tags_file}"
  238. rm -f "\${tags_file}"
  239. done
  240. """
  241. }
  242. pipeline {
  243. agent any
  244. options {
  245. buildDiscarder(logRotator(numToKeepStr: '5'))
  246. disableConcurrentBuilds()
  247. timestamps()
  248. timeout(time: 90, unit: 'MINUTES')
  249. }
  250. parameters {
  251. string(
  252. name: 'GIT_BRANCH',
  253. defaultValue: 'uat-20260202',
  254. trim: true,
  255. description: 'Git branch name only (e.g. uat-20260202). Do not prefix origin/'
  256. )
  257. booleanParam(name: 'FORCE_UPDATE', defaultValue: false, description: 'mvn -U (routine builds leave unchecked for speed)')
  258. booleanParam(name: 'ALLOW_SNAPSHOTS', defaultValue: true, description: 'allow SNAPSHOT deps')
  259. booleanParam(
  260. name: 'PUSH_TO_HARBOR',
  261. defaultValue: true,
  262. description: 'After Maven: docker build + push to Harbor (tags uat-latest and uat-build-<N>). Uncheck for jar-only UAT deploy.'
  263. )
  264. choice(
  265. name: 'HARBOR_PUSH_SCOPE',
  266. choices: [
  267. 'all-java-services',
  268. 'gateway-only',
  269. 'store-only',
  270. 'second-only',
  271. 'store-platform-only',
  272. 'lawyer-only',
  273. 'job-only',
  274. 'dining-only',
  275. ],
  276. description: 'Only when PUSH_TO_HARBOR=true; default=all seven; *-only=one service'
  277. )
  278. string(name: 'HARBOR_REGISTRY', defaultValue: '39.105.153.68', trim: true)
  279. string(name: 'HARBOR_PROJECT', defaultValue: 'alien_cloud', trim: true)
  280. booleanParam(
  281. name: 'HARBOR_PRUNE_OLD_TAGS',
  282. defaultValue: true,
  283. description: 'After push: delete old uat-build-* tags in Harbor, keep last N per repo (never deletes uat-latest)'
  284. )
  285. string(name: 'HARBOR_KEEP_TAG_COUNT', defaultValue: '10', trim: true,
  286. description: 'How many uat-build-* tags to keep per repository')
  287. booleanParam(
  288. name: 'HARBOR_PUSH_PARALLEL',
  289. defaultValue: true,
  290. description: 'Parallel per service (context prep + Harbor API archive); docker build/push serialized via flock'
  291. )
  292. }
  293. environment {
  294. MAVEN_HOME = tool '3.6.3'
  295. PATH = "${MAVEN_HOME}/bin:${env.PATH}"
  296. GIT_URL = 'http://8.152.195.41:3000/alien/alien_cloud'
  297. GIT_CREDENTIALS = 'zhanghaomimapingzheng'
  298. HARBOR_CREDENTIALS = 'harbor-robot-alien'
  299. UAT_HARBOR_LATEST_TAG = 'uat-latest'
  300. UAT_HARBOR_BUILD_TAG = "uat-build-${env.BUILD_NUMBER}"
  301. DOCKERFILE_JAVA = 'docs/jenkins/produ/docker/Dockerfile.java-service'
  302. MAVEN_LOCAL_REPO = '/var/jenkins_home/.m2/repository'
  303. }
  304. stages {
  305. stage('Checkout') {
  306. steps {
  307. script {
  308. // Do not use env.GIT_BRANCH - Jenkins SCM plugin injects origin/<branch> and overwrites it.
  309. def branch = normalizeGitBranch(params.GIT_BRANCH)
  310. if (!branch) {
  311. error('GIT_BRANCH is required')
  312. }
  313. env.UAT_GIT_BRANCH = branch
  314. if (params.GIT_BRANCH?.trim() != branch) {
  315. echo ">>> GIT_BRANCH normalized: '${params.GIT_BRANCH}' -> '${branch}'"
  316. }
  317. echo ">>> Checkout branch: ${branch}"
  318. sh """
  319. set -e
  320. git fetch origin
  321. git checkout -B ${branch} origin/${branch}
  322. git log -1 --oneline
  323. """
  324. }
  325. }
  326. }
  327. stage('Prepare Maven Settings') {
  328. steps {
  329. script {
  330. writeFile file: 'settings.xml', text: """<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  331. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  332. xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
  333. <mirrors>
  334. <mirror>
  335. <id>aliyun-central</id>
  336. <mirrorOf>central</mirrorOf>
  337. <name>Aliyun Central</name>
  338. <url>https://maven.aliyun.com/repository/central</url>
  339. </mirror>
  340. </mirrors>
  341. <profiles>
  342. <profile>
  343. <id>repo-mix</id>
  344. <repositories>
  345. <repository>
  346. <id>aliyunmaven</id>
  347. <name>Aliyun Maven</name>
  348. <url>https://maven.aliyun.com/repository/public</url>
  349. <releases><enabled>true</enabled><updatePolicy>daily</updatePolicy></releases>
  350. <snapshots><enabled>false</enabled></snapshots>
  351. </repository>
  352. <repository>
  353. <id>central</id>
  354. <name>Maven Central</name>
  355. <url>https://repo.maven.apache.org/maven2</url>
  356. <releases><enabled>true</enabled><updatePolicy>daily</updatePolicy></releases>
  357. <snapshots><enabled>false</enabled></snapshots>
  358. </repository>
  359. <repository>
  360. <id>spring-milestones</id>
  361. <name>Spring Milestones</name>
  362. <url>https://repo.spring.io/milestone</url>
  363. <releases><enabled>true</enabled><updatePolicy>daily</updatePolicy></releases>
  364. <snapshots><enabled>false</enabled></snapshots>
  365. </repository>
  366. <repository>
  367. <id>spring-snapshots</id>
  368. <name>Spring Snapshots</name>
  369. <url>https://repo.spring.io/snapshot</url>
  370. <releases><enabled>false</enabled></releases>
  371. <snapshots><enabled>true</enabled><updatePolicy>daily</updatePolicy></snapshots>
  372. </repository>
  373. </repositories>
  374. <pluginRepositories>
  375. <pluginRepository>
  376. <id>aliyunmaven</id>
  377. <url>https://maven.aliyun.com/repository/public</url>
  378. <releases><enabled>true</enabled></releases>
  379. <snapshots><enabled>false</enabled></snapshots>
  380. </pluginRepository>
  381. <pluginRepository>
  382. <id>central</id>
  383. <url>https://repo.maven.apache.org/maven2</url>
  384. <releases><enabled>true</enabled></releases>
  385. <snapshots><enabled>false</enabled></snapshots>
  386. </pluginRepository>
  387. <pluginRepository>
  388. <id>spring-milestones</id>
  389. <url>https://repo.spring.io/milestone</url>
  390. <releases><enabled>true</enabled></releases>
  391. <snapshots><enabled>false</enabled></snapshots>
  392. </pluginRepository>
  393. </pluginRepositories>
  394. </profile>
  395. </profiles>
  396. <activeProfiles>
  397. <activeProfile>repo-mix</activeProfile>
  398. </activeProfiles>
  399. </settings>
  400. """
  401. }
  402. }
  403. }
  404. stage('Maven Build') {
  405. steps {
  406. script {
  407. def updateFlag = params.FORCE_UPDATE ? '-U' : ''
  408. retry(2) {
  409. sh """
  410. set -e
  411. mvn -version
  412. unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY all_proxy no_proxy NO_PROXY || true
  413. export MAVEN_OPTS="-Xms512m -Xmx2048m -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true"
  414. mkdir -p ${MAVEN_LOCAL_REPO}
  415. mvn clean package -DskipTests -s settings.xml ${updateFlag} -e \\
  416. -T 1C -Dmaven.artifact.threads=8 \\
  417. -Dmaven.repo.local=${MAVEN_LOCAL_REPO}
  418. """
  419. }
  420. }
  421. }
  422. }
  423. stage('Push images to Harbor') {
  424. when {
  425. expression { return params.PUSH_TO_HARBOR == true }
  426. }
  427. steps {
  428. script {
  429. def reg = params.HARBOR_REGISTRY.trim()
  430. def proj = params.HARBOR_PROJECT.trim()
  431. def latestTag = env.UAT_HARBOR_LATEST_TAG
  432. def buildTag = env.UAT_HARBOR_BUILD_TAG
  433. def baseImage = "${reg}/${proj}/base/openjdk8-ffmpeg:v1"
  434. def dockerfile = env.DOCKERFILE_JAVA
  435. def allHarborServices = [
  436. [module: 'alien-gateway', repo: 'gateway', port: '8000', withLib: false],
  437. [module: 'alien-store', repo: 'store', port: '50014', withLib: true],
  438. [module: 'alien-second', repo: 'second', port: '50015', withLib: false],
  439. [module: 'alien-store-platform', repo: 'store-platform', port: '50016', withLib: false],
  440. [module: 'alien-lawyer', repo: 'lawyer', port: '50017', withLib: true],
  441. [module: 'alien-job', repo: 'job', port: '50108', withLib: false],
  442. [module: 'alien-dining', repo: 'dining', port: '50019', withLib: false],
  443. ]
  444. def harborServices = filterHarborPushScope(allHarborServices, params.HARBOR_PUSH_SCOPE)
  445. echo ">>> HARBOR_PUSH_SCOPE=${params.HARBOR_PUSH_SCOPE} repos=${harborServices*.repo.join(',')}"
  446. withCredentials([usernamePassword(
  447. credentialsId: env.HARBOR_CREDENTIALS,
  448. usernameVariable: 'HARBOR_USER',
  449. passwordVariable: 'HARBOR_PASS',
  450. )]) {
  451. sh """
  452. set -e
  453. echo "\${HARBOR_PASS}" | docker login ${reg} -u "\${HARBOR_USER}" --password-stdin
  454. echo ">>> docker disk before Harbor push:"
  455. df -h /var/lib/docker 2>/dev/null || df -h / || true
  456. docker image prune -f 2>/dev/null || true
  457. """
  458. if (params.HARBOR_PUSH_PARALLEL) {
  459. def pushBranches = [:]
  460. harborServices.each { svc ->
  461. def s = svc
  462. pushBranches[s.repo] = {
  463. pushOneHarborImage(
  464. this, s, reg, proj, latestTag, buildTag,
  465. baseImage, dockerfile, env.WORKSPACE,
  466. )
  467. }
  468. }
  469. parallel pushBranches
  470. } else {
  471. harborServices.each { svc ->
  472. pushOneHarborImage(
  473. this, svc, reg, proj, latestTag, buildTag,
  474. baseImage, dockerfile, env.WORKSPACE,
  475. )
  476. }
  477. }
  478. sh """
  479. echo ">>> docker disk after Harbor push:"
  480. df -h /var/lib/docker 2>/dev/null || df -h / || true
  481. docker image prune -f 2>/dev/null || true
  482. """
  483. if (params.HARBOR_PRUNE_OLD_TAGS == true) {
  484. def keepN = (params.HARBOR_KEEP_TAG_COUNT ?: '10').trim() as int
  485. catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') {
  486. pruneHarborUatTags(
  487. this, reg, proj, harborServices*.repo,
  488. keepN, 'uat-build-', buildTag, latestTag,
  489. )
  490. }
  491. }
  492. }
  493. echo ">>> Harbor latest: ${env.UAT_HARBOR_LATEST_TAG}; archived tag this run: ${env.UAT_HARBOR_BUILD_TAG}"
  494. echo ">>> Prod promote: SOURCE_TAG=${env.UAT_HARBOR_LATEST_TAG}"
  495. }
  496. }
  497. }
  498. stage('Deploy Services') {
  499. steps {
  500. script {
  501. def services = [
  502. 'alien-gateway:gateway-uat',
  503. 'alien-job:job-uat',
  504. 'alien-lawyer:lawyer-uat',
  505. 'alien-second:second-uat',
  506. 'alien-store:store-uat',
  507. 'alien-dining:dining-uat',
  508. 'alien-store-platform:store-platform-uat',
  509. ]
  510. def deployBranches = [:]
  511. services.each { item ->
  512. def parts = item.split(':')
  513. def moduleName = parts[0]
  514. def dirName = parts[1]
  515. deployBranches[dirName] = {
  516. deployOneUatService(this, moduleName, dirName, env.WORKSPACE)
  517. }
  518. }
  519. parallel deployBranches
  520. }
  521. }
  522. }
  523. }
  524. post {
  525. always {
  526. sh 'rm -f settings.xml || true'
  527. script {
  528. if (!params.PUSH_TO_HARBOR) {
  529. echo '>>> Harbor push SKIPPED: PUSH_TO_HARBOR is false. On "Build with Parameters" check PUSH_TO_HARBOR.'
  530. }
  531. }
  532. }
  533. success {
  534. script {
  535. if (params.PUSH_TO_HARBOR) {
  536. echo ">>> Harbor latest: ${env.UAT_HARBOR_LATEST_TAG}"
  537. echo ">>> Prod promote: SOURCE_TAG=${env.UAT_HARBOR_LATEST_TAG}"
  538. }
  539. }
  540. }
  541. }
  542. }