pipeline 是在 Jenkins服务端执行的,所以并不是客户端

pipeline有2种语法,声明式语法、脚本式脚本,这里学习的是声明式语法

Groovy 背景

Jenkins 流水线(Pipeline 是 Jenkins2.X 最核心的特性,帮助 Jenkins 实现从 CI 到 CD 与DevOps 的转变,可支持复杂流程的编排与可视化) 是一套插件

通过 Jenkinsfile 执行,支持脚本式(Script)和声明式(Declarative)两种,其中脚本式可通过 Groovy 语法编写执行过程,声明式需要用 script {} 包裹使用 Groovy 语句。

声明式

  • pipeline :声明其内容为一个声明式的 pipeline 脚本
  • agent:执行节点(支持 any,none,label,docker,dockerfile)
  • stages:阶段集合,包裹所有的阶段(例如:打包,部署等各个阶段)
  • stage:阶段,被 stages 包裹,一个 stages 可以有多个 stage
  • steps:步骤,为每个阶段的最小执行单元,被 stage 包裹
  1. pipeline {
  2. agent any
  3. stages {
  4. stage('Example') {
  5. steps {
  6. echo 'Hello World'
  7. }
  8. }
  9. }
  10. }

脚本式

  1. def TEST_PROJECT_NAME=""
  2. def deployments = ["testing", "staging", "production"]
  3. def run(stepName) {
  4. retry(3){
  5. TEST_PROJECT_NAME = sh(script: "openssl rand -hex 4",returnStdout: true).trim()
  6. sh (
  7. script: "echo ${TEST_PROJECT_NAME}",
  8. label: "开始 ${stepName} 环境API测试"
  9. )
  10. }
  11. }
  12. node {
  13. deployments.each{ param ->
  14. stage("$param") {
  15. run("$param")
  16. }
  17. }
  18. }

简单案例

第一个pipeline

创建项目,类型 pipeline

流水线 - 图1

编辑流水线

流水线 - 图2

  1. pipeline {
  2. agent any
  3. stages {
  4. stage('Stage 1') {
  5. steps {
  6. echo 'Hello world!'
  7. sh "echo 'Hello world!' "
  8. sh "hostname"
  9. sh "uptime"
  10. }
  11. }
  12. }
  13. }
  • agent any:所有jenkins服务端操作,假如你有集群的话可以指定某台,any表示所有,这里是单机
  • echo 在控制台输出中写入简单字符串,这个并不是linux的echo命令,而是jenkins语法的echo
    agent语法
  1. agent any # 所有jenkins服务端操作,any表示所有
  2. agent { label 'master' } #假如你有集群的话可以指定某台,在主机名为master的机器执行

构建

之前有构建过一次,所以有阶段视图

流水线 - 图3

查看构建结果

点击阶段视图的Logs

流水线 - 图4

可以看到构建结果
流水线 - 图5

点击 #1 可以看到 整个构建流程日志

流水线 - 图6

构建流程日志

流水线 - 图7

回放功能,它允许用户实时修改脚本运行,但又不更新Jenkinsfile

第二个pipeline

pipeline是流水线工作

  1. pipeline {
  2. agent any
  3. stages {
  4. stage('Build') {
  5. steps {
  6. echo 'Building..'
  7. }
  8. }
  9. stage('Test') {
  10. steps {
  11. echo 'Testing..'
  12. }
  13. }
  14. stage('Deploy') {
  15. steps {
  16. echo 'Deploying....'
  17. }
  18. }
  19. }
  20. }

点击构建 此时3个阶段会依次进行

流水线 - 图8

在 pipline 块内,为全局变量,对所有阶段和步骤生效
在 stage 阶段内,为局部变量,只对阶段和步骤生效

parameters多版本发布

  1. pipeline {
  2. agent any
  3. parameters {
  4. choice(name:'branchs',choices:"LNMP-1\nLNMP-2\nLNMP-3\n",description:'all branch')
  5. choice(name:'deployProgam',choices:"mysql\nredis\n",description:"deploy")
  6. choice(name:'UpdateOrRollback',choices:"update\nrollback\n",description:'updateroback')
  7. string(name: 'account', defaultValue: '', description: 'chiose account')
  8. }
  9. stages {
  10. stage("input"){
  11. steps{
  12. sh "echo -e deployProgram=${params.deployProgam} >/home/jenkins/scrpit/updatemodule.cfg"
  13. sh "echo -e release=${params.branchs} >>/home/jenkins/scrpit/updatemodule.cfg"
  14. sh "echo -e choice=${params.UpdateOrRollback} >>/home/jenkins/scrpit/updatemodule.cfg"
  15. writeFile file: "updatemodule.cfg", text: "deployProgram=${params.deployProgam}\nrelease=${params.branchs}\nchoice=${params.UpdateOrRollback}\n"
  16. }
  17. }
  18. stage("publish"){
  19. steps{
  20. sh "account=${params.account}"
  21. sh label: '', script: 'rsync -aze ssh --progress /home/jenkins/scrpit/updatemodule.cfg root@server:/root/daily_sync/project_update/new_vpn_release/script'
  22. }
  23. }
  24. }
  25. }

此时构建页面会发生改变,没有改变则刷新

流水线 - 图9

邮件发送

  1. pipeline{
  2. agent any
  3. stages{
  4. stage('mvn test'){
  5. steps{
  6. echo "mvn test"
  7. }
  8. }
  9. }
  10. post{
  11. always{ //always表示不管怎么样都做下面的操作
  12. pmd canComputeNew: false, defaultEncoding: '', healthy: '', pattern: '', unHealthy: ''
  13. }
  14. failure{
  15. step([
  16. $class: 'Mailer',
  17. notifyEveryUnstableBuild: true,
  18. recipients: "738402018@qq.com",
  19. sendToIndividuals: true
  20. ])
  21. echo "failed!Please check pipeline code!"
  22. }
  23. success{
  24. echo "hello!success!"}
  25. }
  26. }

输入型选项

  1. pipeline{
  2. agent any
  3. triggers{
  4. upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS)
  5. }
  6. stages{
  7. stage('pre deploy'){
  8. steps{
  9. script{
  10. BRANCHES = "dev"
  11. dataMap = input message: '准备发布到哪个环境', ok: '确定',
  12. parameters:
  13. [
  14. choice(choices: ['dev', 'sit', 'prod'], description: '部署环境', name: 'ENV'),
  15. choice(choices: "${BRANCHES}", description: '分支', name: 'TAG')
  16. ],
  17. submitterParameter: 'APPROVER'
  18. sh "echo ${dataMap}"
  19. }
  20. }
  21. }
  22. stage("演示一下"){
  23. steps{
  24. echo "${dataMap['APPROVER']}"
  25. echo "${dataMap['ENV']}"
  26. echo "${dataMap['TAG']}"
  27. }
  28. }
  29. }
  30. }

写法2

  1. pipeline {
  2. agent any
  3. stages {
  4. stage('Example') {
  5. input {
  6. message "准备发布到哪个环境?"
  7. ok "确定"
  8. submitter "alice,bob"
  9. parameters {
  10. choice(name:'branchs',choices:"226-beta\n226-release\nAPP_RELEASE\n",description:'all branch')
  11. choice(name:'deployProgam',choices:"stock_publisher_pvo\nredis_publisher\nnew_trademodule\nnew_trademodule_credit\nstrategy_credit\nstrategy_trade_pvo\nstrategy_grab_pvo\nbarbuild\nbarbuild_pvo\nstock_mon\ntest\n",description:"deploy")
  12. choice(name:'UpdateOrRollback',choices:"update\nrollback\n",description:'updateroback')
  13. }
  14. }
  15. steps {
  16. echo "Hello ${branchs} nice to meet you."
  17. }
  18. }
  19. }
  20. }

pipeline脚本

  1. pipeline {
  2. agent {
  3. kubernetes {
  4. label 'jenkins-slave-java'
  5. }
  6. }
  7. parameters {
  8. gitParameter branchFilter: 'origin/(.*)', defaultValue: 'master', name: 'BRANCH', type: 'PT_BRANCH', description:'please switch branch'
  9. choice(name: 'BaseImage', choices: ['openjdk11.0.9'], description: 'base image tag')
  10. choice(name: 'RancherProject', choices: ['dev'],description: 'please switch environment')
  11. string(name: 'BuildParameter', defaultValue: 'none', description: 'default same as RancherProject')
  12. choice(name: 'SyncToRancher', choices: ['Y','N'],description: 'sync to rancher')
  13. string(name: 'DBPassFile', defaultValue:'none', description: 'when value is none,DBPassFile path is ...,you can input special value to cover it')
  14. }
  15. environment {
  16. PRO_NAME = "gateway"
  17. BuildParameter="${params.BuildParameter}"
  18. SyncToRancher = "${params.SyncToRancher}"
  19. NS = "${params.RancherProject}"
  20. RNAME = "476548611639.dkr.ecr.eu-south-1.amazonaws.com/gateway"
  21. S3NAME = "hope-jar-test"
  22. BRANCH = "${params.BRANCH}"
  23. DBPasswd='test-db'
  24. BaseImage="${params.BaseImage}"
  25. }
  26. stages {
  27. stage('Clean workspace') {
  28. steps {
  29. deleteDir()
  30. }
  31. }
  32. stage('Process parameters') {
  33. steps {
  34. script {
  35. if("${params.BuildParameter}"=="none") {
  36. BuildParameter="${RancherProject}"
  37. }
  38. else {
  39. BuildParameter="${params.BuildParameter}"
  40. }
  41. if("${params.DBPassFile}"=="none") {
  42. DBPassFile="${params.DBPassFile}"
  43. }
  44. else {
  45. DBPassFile="${params.DBPassFile}"
  46. }
  47. }
  48. }
  49. }
  50. stage('Pull SourceCode') {
  51. steps {
  52. echo "${BRANCH}"
  53. git branch: "${BRANCH}", credentialsId: 'd560c72c-c2f9-43e0-9cdf-784818071c40', url: 'https://git-codecommit.eu-south-1.amazonaws.com/v1/repos/MyPay_Payment_Gateway'
  54. }
  55. }
  56. stage('Build') {
  57. steps{
  58. sh '''
  59. echo "==============Start Build=========="
  60. cd mypay/pay_common
  61. mvn -DskipTests=true clean install
  62. cd ../mypay-order
  63. mvn -DskipTests=true clean install
  64. cd ../mypayadmin-logging
  65. mvn -DskipTests=true clean install
  66. cd ../mypay-account
  67. mvn -DskipTests=true clean install
  68. cd ../mypayadmin-generator
  69. mvn -DskipTests=true clean install
  70. cd ../pay-gateway
  71. mvn -DskipTests=true clean install
  72. echo "==============End Build=========="
  73. '''
  74. }
  75. }
  76. stage('Collect artifact') {
  77. steps {
  78. script {
  79. if(!fileExists("${PRO_NAME}")) {
  80. sh "mkdir -p ${PRO_NAME}/{classes,lib,webapps}"
  81. }
  82. sh "cp -f /root/mavenlib/com/deepvision/pay/pay-gateway/1.0.0-SNAPSHOT/pay-gateway-1.0.0-SNAPSHOT.jar ${PRO_NAME}/classes/${PRO_NAME}.jar"
  83. }
  84. }
  85. }
  86. stage('Process Dockerfile') {
  87. steps {
  88. script {
  89. sh '''
  90. cp -f /root/bin/DockerfileTemp Dockerfile
  91. sed -i "s/BASEIMAGETAG/${BaseImage}/g" Dockerfile
  92. sed -i "s#deploymentdir#${PRO_NAME}#g" Dockerfile
  93. '''
  94. }
  95. }
  96. }
  97. stage('Build docker image and sync to rancher') {
  98. steps{
  99. sh '''
  100. Tag="${NS}_${BRANCH}_$(date '+%Y%m%d%H%M')"
  101. aws ecr get-login-password | docker login --username AWS --password-stdin 476548611639.dkr.ecr.eu-south-1.amazonaws.com
  102. docker build -t ${RNAME}:${Tag} .
  103. docker push ${RNAME}:${Tag}
  104. docker rmi ${RNAME}:${Tag}
  105. echo "==============start sync ${RNAME}:${Tag} to rancher=========="
  106. if [ "${SyncToRancher}" == "Y" ]
  107. then
  108. python /root/bin/syncRancher.py test ${NS} ${PRO_NAME} ${Tag}
  109. fi
  110. '''
  111. }
  112. }
  113. }
  114. }
  1. pipeline {
  2. agent {
  3. kubernetes {
  4. label 'jenkins-slave-java'
  5. }
  6. }
  7. parameters {
  8. gitParameter branchFilter: 'origin/(.*)', defaultValue: 'master', name: 'BRANCH', type: 'PT_BRANCH', description: '选择需要构建的分支'
  9. choice(name: 'HOSTNAME', choices: ['dev-static-gateway.deepxin.com'], description: '主机名')
  10. string(name: 'BuildCmd', defaultValue: 'npm install && npm run build', description:'编译命令')
  11. }
  12. environment {
  13. HOSTNAME="${params.HOSTNAME}"
  14. S3NAME = "deepxin-fe-all/dev"
  15. BuildCmd="${params.BuildCmd}"
  16. BRANCH="${params.BRANCH}"
  17. }
  18. stages {
  19. stage('Clean workspace') {
  20. steps {
  21. deleteDir()
  22. }
  23. }
  24. stage('Pull SourceCode') {
  25. steps {
  26. dir("${WORKSPACE}") {
  27. git branch: "${params.BRANCH}", credentialsId: 'd560c72c-c2f9-43e0-9cdf-784818071c40', url: 'https://git-codecommit.eu-south-1.amazonaws.com/v1/repos/mypay-backoffice'
  28. }
  29. }
  30. }
  31. stage('Build') {
  32. steps{
  33. dir("${WORKSPACE}") {
  34. sh "${BuildCmd}"
  35. }
  36. }
  37. }
  38. stage('Deploy') {
  39. steps {
  40. dir("${WORKSPACE}") {
  41. sh "aws s3 sync dist/ s3://${S3NAME}/${HOSTNAME}/"
  42. }
  43. }
  44. }
  45. }
  46. }

瓦雀