Jenkins流水线部署+webhook2.0

发布于:2025-07-30 ⋅ 阅读:(31) ⋅ 点赞:(0)

1. 环境

  • Centos7
  • Jenkins2.520
  • JDKopen17
  • 阿里云仓库

注意:这个版本兼容需要特别注意,要不然会很麻烦

2. 用到的插件

  • Generic Webhook Trigger
  • HTTP Request
  • Extra Columns
  • Pipeline: Stage View

3. 流水线部署脚本

  • 兼容钩子部署(webhook)和手动参数化部署
  • 优先取钩子的推送参数,没有的话取手动参数
  • 根据推送的分支进行不同的部署操作
  • 推送结果到钉钉通知
pipeline {
    agent any

    // 定义参数化构建
    parameters {
        string(
            name: 'MANUAL_BRANCH', 
            defaultValue: '', 
            description: '手动指定要部署的分支(如 master, dev, test)'
        )
    }

    triggers {
        GenericTrigger(
            genericVariables: [
                [key: 'ref', value: '$.ref'], // 获取分支信息
                [key: 'repository_name', value: '$.repository.name'] // 获取仓库名称
            ],
            causeString: 'Triggered by push event on branch $ref',
            token: 'AZWSDD2555SSWS', // 自定义的Token
            printContributedVariables: true, // 打印传递的变量
            silentResponse: false,
            regexpFilterText: '$ref', // 匹配分支名
            regexpFilterExpression: '^refs/heads/(dev|test)$' // 只处理特定分支
        )
    }

   stages {
        stage('Determine Branch') {
            steps {
                script {
                    // 优先使用Webhook传递的分支信息
                    if (env.ref) {
                        env.BRANCH_NAME = env.ref.tokenize('/')[-1]
                        echo "Using webhook-triggered branch: ${env.BRANCH_NAME}"
                    } 
                    // 如果没有Webhook信息,检查是否有手动输入的分支
                    else if (params.MANUAL_BRANCH?.trim()) {
                        env.BRANCH_NAME = params.MANUAL_BRANCH.trim()
                        echo "Using manually specified branch: ${env.BRANCH_NAME}"
                    } 
                    // 如果两者都没有,抛出错误
                    else {
                        error "No branch specified! Please provide a branch via manual input or webhook."
                    }
                }
            }
        }

        stage('Checkout Code') {
            steps {
                git branch: env.BRANCH_NAME,
                    url: 'git@codeup.aliyun.com:test.git',
                    credentialsId: 'jenkins密钥ID'
            }
        }

         stage('Build and Deploy') {
            steps {
                echo "Performing actions for branch: ${env.BRANCH_NAME}"
                script {
                    if (env.BRANCH_NAME == 'master') {
                        sh '''
                            ssh 1.11.11.11 "cd /home/test && git pull"
                        '''
                    } else if (env.BRANCH_NAME == 'dev') {
                        sh '''
                            cd /home/dev && git pull
                        '''
                    } else if (env.BRANCH_NAME == 'test') {
                        sh '''
                            cd /home/test && git pull
                        '''
                    } else {
                        error "Unsupported branch: ${env.BRANCH_NAME}. No deployment logic defined."
                    }
                }
            }
        }
    }
    
    post {
        success {
            notifyDingTalk("SUCCESS") // 构建成功时通知
        }

        failure {
            notifyDingTalk("FAILURE") // 构建失败时通知
        }
    }
}

// 定义通用的钉钉通知方法
def notifyDingTalk(String buildStatus) {
    script {
        // 获取构建信息
        def branchName = env.BRANCH_NAME
        def duration = currentBuild.durationString
        def executor = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')?.userId ?: 'webhook'
        def commitHash = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
        def committer = sh(script: 'git log -1 --pretty=format:"%an"', returnStdout: true).trim()
        def commitMessage = sh(script: 'git log -1 --pretty=format:"%s"', returnStdout: true).trim()
        def rawCommitTime = sh(script: 'git log -1 --pretty=format:"%cd" --date=iso', returnStdout: true).trim()
        def formattedCommitTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(
            new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(rawCommitTime)
        )

        // 获取变更内容(修改的文件列表)
        def changedFiles = sh(script: 'git diff --name-only HEAD~1 HEAD', returnStdout: true).trim()

        // 动态生成标题和状态颜色
        def (statusTitle, statusColor) = buildStatus == "SUCCESS" ? ["构建成功", "#00FF00"] : ["构建失败", "#FF0000"]

        // 获取项目名(从环境变量或静态配置中)
        def projectName = env.JOB_NAME ?: "未知项目"

        // 构造钉钉消息内容
        def message = """
        ## Jenkins <font color="${statusColor}">${statusTitle}</font>通知
- **项目**: ${projectName}
- **分支**: ${branchName}
- **状态**: <font color="${statusColor}">${buildStatus}</font>
- **持续时间**: ${duration}
- **执行人**: ${executor}
- **代码推送人**: ${committer}
- **提交哈希**: ${commitHash}
- **提交时间**: ${formattedCommitTime}
- **提交信息**: ${commitMessage}
- **变更内容**: ${changedFiles ?: "无变更内容"}
""".stripIndent()

        // 钉钉机器人配置
        def dingtalkWebhookUrl = 'https://oapi.dingtalk.com/robot/send?access_token=your_token'

           // 使用 JsonOutput 生成 JSON 数据
        def payload = groovy.json.JsonOutput.toJson([
            msgtype: "markdown",
            markdown: [
                title: "[${projectName}] Jenkins ${statusTitle}通知",
                text: message
            ],
            at: [
                isAtAll: true
            ]
        ])
        httpRequest(
            url: dingtalkWebhookUrl,
            httpMode: 'POST',
            contentType: 'APPLICATION_JSON_UTF8',  // 确保 UTF-8 编码
            requestBody: payload,
            validResponseCodes: '200:299'  // 接受 200-299 状态码
        )
    }
}

4.遇到的问题

  • 1.环境兼容问题-linux版本/jenkins版本/java版本三者之间的兼容

  • 2.环境变量作用范围的问题-切换java版本配置环境的生效问题
    通过/etc/profile或/etc/environment配置的环境变量仅对当前终端会话有效,而通过/etc/systemd/system设置的环境变量可确保服务启动时自动加载‌

5.实际效果

在这里插入图片描述

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到