jenkins流水线

在这里插入图片描述
在这里插入图片描述

最近有一个jenkins发版需求,画一个草图说明下:
在这里插入图片描述
流水线作业直接开干:

pipeline {
    agent any
    environment {
        DINGTALK_SECRET = 'SEC*******************'  // 替换为您的钉钉机器人密钥
        DINGTALK_ACCESS_TOKEN = ''  // 替换为您的钉钉机器人 access token
        DINGTALK_USER = ''  // 钉钉用户的登录账号

        GIT_REPO = '' //仓库地址
        MAVEN_CMD = '' //打包命令
        TARGET_DIR = '' //打包目录 
        TARGET_FILE = '' //jar包
        REMOTE_DIR = '' //远程部署目录
        BACKUP_DIR = "${REMOTE_DIR}/bak" //jar包备份目录
        DEPLOY_SCRIPT = '' //shell脚本执行命令
        PROJECT_NAME = '' //项目名称
    }
    stages {
        stage('准备脚本') {
            steps {
                script {
                    writeFile file: 'generate_signature.py', text: '''\
import hmac
import hashlib
import base64
import time
import urllib.parse
import sys

def generate_dingtalk_signature(secret):
    timestamp = str(round(time.time() * 1000))
    secret_enc = secret.encode('utf-8')
    string_to_sign = '{}\\n{}'.format(timestamp, secret)
    string_to_sign_enc = string_to_sign.encode('utf-8')
    hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
    signature = urllib.parse.quote(base64.b64encode(hmac_code))
    return timestamp, signature

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python generate_signature.py <secret>")
        sys.exit(1)
    secret = sys.argv[1]
    timestamp, signature = generate_dingtalk_signature(secret)
    print(timestamp)
    print(signature)
'''
                }
            }
        }
        stage('生成签名') {
            steps {
                script {
                    def result = sh(script: "python3 generate_signature.py ${env.DINGTALK_SECRET}", returnStdout: true).trim().split('\n')
                    env.TIMESTAMP = result[0]
                    env.SIGNATURE = result[1]
                }
            }
        }
        stage('选择Tag') {
            steps {
                script {
                    // 使用凭证获取tags
                    withCredentials([usernamePassword(credentialsId: '替换成你的服务器凭证ID(jenkins)', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) {
                        def tags = sh(script: "git ls-remote --tags http://${GIT_USERNAME}:${GIT_PASSWORD}@${GIT_REPO.split('http://')[1]} | awk -F'/' '{print \$3}'", returnStdout: true).trim().split("\n")
                        def userInput = input(id: 'userInput', message: '选择Tag', parameters: [choice(name: 'TAG', choices: tags.join('\n'), description: '请选择Tag进行构建')])
                        env.SELECTED_TAG = userInput
                    }
                }
            }
        }
        stage('发送钉钉通知') {
            steps {
                script {
                    def dingTalkWebhook = "https://oapi.dingtalk.com/robot/send?access_token=${env.DINGTALK_ACCESS_TOKEN}&timestamp=${env.TIMESTAMP}&sign=${env.SIGNATURE}"
                    def message = [
                        msgtype: 'text',
                        text: [
                            content: "请审核此构建: ${env.BUILD_URL}\n项目名称: ${env.PROJECT_NAME}\nTag: ${env.SELECTED_TAG}\n@${env.DINGTALK_USER} 请进行审核。"
                        ],
                        at: [
                            atMobiles: ["${env.DINGTALK_USER}"],
                            isAtAll: false
                        ]
                    ]
                    def messageJson = groovy.json.JsonOutput.toJson(message)
                    sh "curl -X POST '${dingTalkWebhook}' -H 'Content-Type: application/json' -d '${messageJson}'"
                }
            }
        }
        
        stage('审批') {
            steps {
                script {
                    def userInput = input(
                        id: 'approval_step',
                        message: '请在钉钉中审核此构建,然后在此输入结果',
                        parameters: [
                            booleanParam(defaultValue: true, description: '通过审核?', name: '审核结果')
                        ]
                    )
                    if (userInput) { 
                        echo '审核通过,继续执行后续步骤'
                    } else {
                        error '审核未通过,流水线终止'
                    }
                }
            }
        }
        stage('拉取代码') {
            steps {
                script {
                    // 使用凭证检出代码和选择的 tag
                    withCredentials([usernamePassword(credentialsId: 'git登录凭证(jenkins)', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) {
                        sh "git clone http://${GIT_USERNAME}:${GIT_PASSWORD}@${GIT_REPO.split('http://')[1]} . || true"
                        sh "git fetch --tags"
                        sh "git checkout tags/${env.SELECTED_TAG}"
                    }
                }
            }
        }
        stage('构建') {
            steps {
                sh "${MAVEN_CMD}"
            }
        }
        stage('备份和部署') {
            steps {
                script {
                    def backupTimestamp = sh(script: 'date +"%Y%m%d%H%M%S"', returnStdout: true).trim()
                    // 备份文件
                    sshPublisher(publishers: [
                        sshPublisherDesc(configName: 'jenkins上配置的ssh服务器名称', transfers: [
                            sshTransfer(
                                sourceFiles: "${REMOTE_DIR}/${TARGET_FILE}",
                                remoteDirectory: "${BACKUP_DIR}",
                                execCommand: "mv ${REMOTE_DIR}/${TARGET_FILE} ${BACKUP_DIR}/${TARGET_FILE}-${backupTimestamp}"
                            ),
                        ], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)
                    ])

                    // 部署文件
                    sshPublisher(publishers: [
                        sshPublisherDesc(configName: 'jenkins上配置的ssh服务器名称', transfers: [
                            sshTransfer(
                                sourceFiles: "${TARGET_DIR}/${TARGET_FILE}",
                                remoteDirectory: "${REMOTE_DIR}",
                                removePrefix: "${TARGET_DIR}",
                                execCommand: "${DEPLOY_SCRIPT}"
                            ),
                        ], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)
                    ])
                }
            }
        }
        stage('发送部署结果通知') {
            steps {
                script {
                    def deployResult = '成功'  // 这里假设部署成功,如果有部署失败的情况需要根据实际情况修改
                    def dingTalkWebhook = "https://oapi.dingtalk.com/robot/send?access_token=${env.DINGTALK_ACCESS_TOKEN}&timestamp=${env.TIMESTAMP}&sign=${env.SIGNATURE}"
                    def message = [
                        msgtype: 'text',
                        text: [
                            content: "项目名称: ${env.PROJECT_NAME}\n发布结果: ${deployResult}\n发布的Tag: ${env.SELECTED_TAG}"
                        ],
                        at: [
                            atMobiles: ["${env.DINGTALK_USER}"],
                            isAtAll: false
                        ]
                    ]
                    def messageJson = groovy.json.JsonOutput.toJson(message)
                    sh "curl -X POST '${dingTalkWebhook}' -H 'Content-Type: application/json' -d '${messageJson}'"
                }
            }
        }
    }
}

上述流水线脚本大致满足需求,点击构建触发后会hold住,等待选择tag,选择完tag后会推送钉钉消息通知审批,等待审批结束后流程才会走下去。
待优化的地方还有很多,欢迎大家指正

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值