Jenkinsfile 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /**
  2. * 开发环境(deve):Checkout -> Maven(按需模块)-> 拷贝 jar -> docker compose 启停
  3. *
  4. * Jenkins Job 配置:
  5. * - Pipeline script from SCM
  6. * - Repository: http://8.152.195.41:3000/alien/alien_cloud
  7. * - Script Path: docs/devops/dev/java/Jenkinsfile
  8. * - 分支默认 deve(构建参数 GIT_BRANCH 可覆盖)
  9. *
  10. * 宿主机目录:/deve/java(docker-compose.yml 与 gateway/store/... 子目录)
  11. * Jenkins 容器须能访问该路径(建议挂载 /deve/java:/deve/java)及 docker.sock
  12. *
  13. * 容器名:gateway-dev、store-dev…(compose 内 services 键仍为 gateway、store…)
  14. */
  15. def getServiceDefinitions() {
  16. return [
  17. [module: 'alien-gateway', dir: 'gateway', composeService: 'gateway', container: 'gateway-dev', withLib: false],
  18. [module: 'alien-store', dir: 'store', composeService: 'store', container: 'store-dev', withLib: true],
  19. [module: 'alien-second', dir: 'second', composeService: 'second', container: 'second-dev', withLib: false],
  20. [module: 'alien-store-platform', dir: 'store-platform', composeService: 'store-platform', container: 'store-platform-dev', withLib: false],
  21. [module: 'alien-lawyer', dir: 'lawyer', composeService: 'lawyer', container: 'lawyer-dev', withLib: false],
  22. [module: 'alien-job', dir: 'job', composeService: 'job', container: 'job-dev', withLib: false],
  23. [module: 'alien-dining', dir: 'dining', composeService: 'dining', container: 'dining-dev', withLib: true],
  24. ]
  25. }
  26. def deployParamName(String composeService) {
  27. return 'DEPLOY_' + composeService.replace('-', '_')
  28. }
  29. def collectSelectedServices(Map buildParams) {
  30. def selected = []
  31. getServiceDefinitions().each { svc ->
  32. def paramName = deployParamName(svc.composeService)
  33. if (buildParams[paramName]) {
  34. selected.add(svc)
  35. }
  36. }
  37. return selected
  38. }
  39. def deployOneService(String workspace, String deployRoot, Map svc) {
  40. def sourceJar = "${workspace}/${svc.module}/target/${svc.module}-1.0.0.jar"
  41. def sourceLib = "${workspace}/${svc.module}/target/lib"
  42. def targetDir = "${deployRoot}/${svc.dir}"
  43. sh """
  44. set -e
  45. echo ">>> Deploy module: ${svc.module} -> ${targetDir}"
  46. if [ ! -f "${sourceJar}" ]; then
  47. echo ">>> [${svc.dir}] jar missing, skip copy"
  48. exit 0
  49. fi
  50. mkdir -p "${targetDir}"
  51. if [ "${svc.withLib}" = "true" ] && [ -d "${sourceLib}" ]; then
  52. rm -rf "${targetDir}/lib"
  53. cp -rf "${sourceLib}" "${targetDir}/lib"
  54. fi
  55. cp -f "${sourceJar}" "${targetDir}/"
  56. echo ">>> [${svc.dir}] jar copied"
  57. """
  58. }
  59. def composeStop(String deployRoot, List composeServices) {
  60. if (composeServices == null || composeServices.isEmpty()) {
  61. return
  62. }
  63. def svcList = composeServices.join(' ')
  64. sh """
  65. set -e
  66. cd "${deployRoot}"
  67. test -f docker-compose.yml
  68. echo ">>> docker compose stop ${svcList}"
  69. docker compose stop ${svcList}
  70. """
  71. }
  72. def startOrRestartServices(String deployRoot, List composeServices) {
  73. if (composeServices == null || composeServices.isEmpty()) {
  74. return
  75. }
  76. def svcList = composeServices.join(' ')
  77. sh """
  78. set -e
  79. cd "${deployRoot}"
  80. test -f docker-compose.yml
  81. echo ">>> docker compose up -d ${svcList}"
  82. docker compose up -d ${svcList}
  83. echo ">>> docker compose restart ${svcList}"
  84. docker compose restart ${svcList}
  85. """
  86. }
  87. pipeline {
  88. agent any
  89. options {
  90. buildDiscarder(logRotator(numToKeepStr: '2', artifactNumToKeepStr: '2'))
  91. disableConcurrentBuilds()
  92. timestamps()
  93. timeout(time: 60, unit: 'MINUTES')
  94. }
  95. parameters {
  96. string(
  97. name: 'GIT_BRANCH',
  98. defaultValue: 'deve',
  99. trim: true,
  100. description: '构建分支,默认 deve,可在「Build with Parameters」中修改'
  101. )
  102. booleanParam(
  103. name: 'STOP_ALL',
  104. defaultValue: false,
  105. description: '为 true 时:先停止全部 dev 微服务,再按下方勾选部署;此时 gateway 必须勾选'
  106. )
  107. // 多选复选框(Declarative 须逐项声明,不可用 each 动态生成)
  108. booleanParam(name: 'DEPLOY_gateway', defaultValue: true, description: 'alien-gateway -> gateway-dev')
  109. booleanParam(name: 'DEPLOY_store', defaultValue: true, description: 'alien-store -> store-dev')
  110. booleanParam(name: 'DEPLOY_second', defaultValue: true, description: 'alien-second -> second-dev')
  111. booleanParam(name: 'DEPLOY_store_platform', defaultValue: false, description: 'alien-store-platform -> store-platform-dev')
  112. booleanParam(name: 'DEPLOY_lawyer', defaultValue: false, description: 'alien-lawyer -> lawyer-dev')
  113. booleanParam(name: 'DEPLOY_job', defaultValue: false, description: 'alien-job -> job-dev')
  114. booleanParam(name: 'DEPLOY_dining', defaultValue: false, description: 'alien-dining -> dining-dev')
  115. }
  116. environment {
  117. MAVEN_HOME = tool '3.6.3'
  118. PATH = "${MAVEN_HOME}/bin:${env.PATH}"
  119. GIT_URL = 'http://8.152.195.41:3000/alien/alien_cloud'
  120. GIT_CREDENTIALS = '5e058e17-8089-45e0-a802-596d91758b4d'
  121. DEPLOY_ROOT = '/deve/java'
  122. MAVEN_LOCAL_REPO = '/var/jenkins_home/.m2/repository'
  123. }
  124. stages {
  125. stage('Validate') {
  126. steps {
  127. script {
  128. def selected = collectSelectedServices(params)
  129. if (selected.isEmpty()) {
  130. error('请至少勾选一个微服务')
  131. }
  132. if (params.STOP_ALL && !params.DEPLOY_gateway) {
  133. error('STOP_ALL=true 时 gateway 必须勾选')
  134. }
  135. env.SELECTED_COMPOSE_SERVICES = selected.collect { it.composeService }.join(' ')
  136. env.SELECTED_MAVEN_MODULES = selected.collect { it.module }.join(',')
  137. echo ">>> Branch: ${params.GIT_BRANCH}"
  138. echo ">>> STOP_ALL: ${params.STOP_ALL}"
  139. echo ">>> Selected compose services: ${env.SELECTED_COMPOSE_SERVICES}"
  140. }
  141. }
  142. }
  143. stage('Checkout') {
  144. steps {
  145. script {
  146. def branch = (params.GIT_BRANCH ?: 'deve').trim()
  147. if (!branch) {
  148. error('GIT_BRANCH is required')
  149. }
  150. env.GIT_BRANCH = branch
  151. echo ">>> Checkout branch: ${env.GIT_BRANCH}"
  152. git branch: "${env.GIT_BRANCH}",
  153. credentialsId: "${env.GIT_CREDENTIALS}",
  154. url: "${env.GIT_URL}"
  155. sh """
  156. set -e
  157. git fetch origin
  158. git reset --hard origin/${env.GIT_BRANCH}
  159. git log -1 --oneline
  160. """
  161. }
  162. }
  163. }
  164. stage('Stop All Dev Services') {
  165. when {
  166. expression { return params.STOP_ALL }
  167. }
  168. steps {
  169. script {
  170. def allServices = getServiceDefinitions().collect { it.composeService }
  171. composeStop(env.DEPLOY_ROOT, allServices)
  172. }
  173. }
  174. }
  175. stage('Maven Build') {
  176. steps {
  177. sh """
  178. set -e
  179. cat > settings.xml <<'EOF'
  180. <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  181. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  182. xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
  183. <mirrors>
  184. <mirror>
  185. <id>aliyunmaven</id>
  186. <mirrorOf>*</mirrorOf>
  187. <name>Aliyun Maven</name>
  188. <url>https://maven.aliyun.com/repository/public</url>
  189. </mirror>
  190. </mirrors>
  191. </settings>
  192. EOF
  193. echo ">>> Maven modules: ${SELECTED_MAVEN_MODULES}"
  194. mvn clean package -DskipTests -s settings.xml -pl ${SELECTED_MAVEN_MODULES} -am
  195. """
  196. }
  197. }
  198. stage('Deploy Services') {
  199. steps {
  200. script {
  201. def selected = collectSelectedServices(params)
  202. selected.each { svc ->
  203. deployOneService(env.WORKSPACE, env.DEPLOY_ROOT, svc)
  204. }
  205. }
  206. }
  207. }
  208. stage('Start Dev Services') {
  209. steps {
  210. script {
  211. def selected = collectSelectedServices(params)
  212. def composeServices = selected.collect { it.composeService }
  213. startOrRestartServices(env.DEPLOY_ROOT, composeServices)
  214. }
  215. }
  216. }
  217. }
  218. post {
  219. always {
  220. sh 'rm -f settings.xml || true'
  221. echo '>>> 开发环境构建结束'
  222. }
  223. failure {
  224. echo '>>> 构建失败,已部署的 jar 不会自动回滚,请检查日志'
  225. }
  226. }
  227. }