多分支流水线方式的pre build

触发原理
多分支流水线是一种Jenkins Job 类型。
新建一个多分支流水线时,会配置 代码仓库、Scan时间、Jenkinsfile路径等信息
如果配置Scan时间为1min,那么每1min会扫描所配置的代码仓库的分支,如果在该分支上搜索到了配置的Jenkinsfile,就会在Jenkins 创建一个以分支命名的Job并编译,如下图dev,当分支上有新的提交也会触发编译

因多分支流水线 job 以分支为命名,ph rule不能直接触发,所以会创建一个中转的jump job来根据分支下发编译需求

模板Jenkinsfile详解
多分支流水线Jenkinsfile
pipeline {
    agent { //2~33 使用docker images 初始化编译环境
        kubernetes {
            label "${UUID.randomUUID().toString()}"
            yaml """
                metadata:
                  labels:
                    some-label: some-label-value
                    class: KubernetesDeclarativeAgentTest
                  namespace: scm
                spec:               
                  nodeSelector:
                    jenkins-ci: "true"
                  containers:
                    - name: prepare
                      image: hub.hobot.cc/builder/cicd-common-tool:v9
                      command:
                      - cat
                      tty: true
                      env:
                        - name: CONTAINER_ENV_VAR
                          value: prepare
                    - name: build
                      image: hub.hobot.cc/builder/ubuntu16.04:20220402
                      command:
                      - cat
                      tty: true
                      env:
                        - name: CONTAINER_ENV_VAR
                          value: build
            """
        }
    }
    environment {
        LANG = 'en_US.UTF-8'
    }
    parameters { //环境变量,用于接收来自Ph的Post请求
        string defaultValue: '', description: 'Enter PH DIFF_ID', name: 'DIFF_ID', trim: true
        string defaultValue: '', description: 'Enter PH PHID', name: 'PHID', trim: true
        string defaultValue: '', description: 'Enter PH REVISION ID', name: 'REVISION_ID', trim: true
    }

    stages{
        stage('prepare') {
            environment { 
                LANG = 'en_US.UTF-8'
                SSH_KEY_FILE = credentials('725axxxxxx')
                //这里需要使用项目账号的credentials. 这是配置编译时下载代码的密钥,密钥配置方法参考:CICD流程获取代码权限管理方案 中的  10. 如何在Jenkins内创建账号认证信息
                
            }
            steps {
                container('prepare') {
                    script {
                        println Jenkins.instance.getNode("${env.NODE_NAME}").toComputer().getLog() //打印机器信息
                        if (!env.DIFF_ID) { //判断是否是来自Ph的触发
                            updateGitlabCommitStatus name: "${env.JOB_NAME}", state: 'running'
                        }//如果DIFF_ID为空,则更新gitlab commit Status
                        else {
                            process_ph()
                        }//否则运行process_ph()函数
                    }
                }
            }
        }
        stage('building') {
            steps {
                container('build') {//括号里填写的是docker名,第23行配置的name
                    script {
                        sh 'sleep 10s'  //此处运行编译脚本
                    }
                }
            }
        }
    }
    options {
      gitLabConnection('Gitlab connector by hobot.ci')
    }
    post { // 76~144行 根据构建结果执行不同的后续步骤,没有特殊需求不用修改
        failure {
            container('prepare') {
                script {
                    if (!env.DIFF_ID) {
                        updateGitlabCommitStatus name: "${env.JOB_NAME}", state: 'failed'
                        send_mail()
                    }
                }
            }
        }
        success {
            container('prepare') {
                script {
                    if (!env.DIFF_ID) {
                        updateGitlabCommitStatus name: "${env.JOB_NAME}", state: 'success'
                    }
                    else {
                        change_ph_status()
                    }
                }
            }
        }
        unstable {
            container('prepare') {
                script {
                    if (!env.DIFF_ID) {
                        updateGitlabCommitStatus name: "${env.JOB_NAME}", state: 'success'
                    }
                    else {
                        change_ph_status()
                    }
                    send_mail()
                }
            }
        }
        aborted {
            container('prepare') {
                script {
                    if (!env.DIFF_ID) {
                        updateGitlabCommitStatus name: "${env.JOB_NAME}", state: 'canceled'
                        send_mail()
                    }
                }
            }
        }
        always {
            container('prepare') {
                script {
                    if (env.DIFF_ID) {
                        try {
                            timeout(time: 10, unit: 'SECONDS') {
                                step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true, customComment: true, commentFile: '.phabricator-comment', commentSize: '999999999'])
                            }
                        }
                        catch (Exception e) {
                            try {
                                timeout(time: 10, unit: 'SECONDS') {
                                    step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true])
                                }
                            }
                            catch (Exception f) {
                                echo "finish"
                            }
                        }
                    }
                }
            }
        }
    }
}
//147~215 函数

def process_ph() {
    sh '''
        curl https://cr.hobot.cc/api/differential.revision.edit \
            -d api.token= \
            -d transactions[0][type]=comment \
            -d transactions[0][value]="build job is running \n click this link then redirect to build job: \n ${BUILD_URL}" \
            -d objectIdentifier=$REVISION_ID
    '''
    addShortText(text: "Link to PH D${env.REVISION_ID}", padding: "1", border: "0", margin: "0px", background: "transparent", color: "blue", link: "https://cr.hobot.cc/D${env.REVISION_ID}")
    title = get_ph_title()
    title = title.replaceAll("\\[Build Not Finish Or FAIL DO NOT ACCEPT\\]", "")
    title = "[Build Not Finish Or FAIL DO NOT ACCEPT]" + title
    change_ph_title(title,"${env.REVISION_ID}")
}

def get_ph_title() {
    title = sh (script: 'curl -s https://cr.hobot.cc/api/differential.query -d api.token= -d ids[0]=$REVISION_ID | python3 -c "import sys, json; print(json.load(sys.stdin)[\'result\'][0][\'title\'])"',returnStdout: true)
    return title
}

def change_ph_title(title_message,revision_id) {
    title_message = java.net.URLEncoder.encode(title_message, "UTF-8")
    sh """
        curl https://cr.hobot.cc/api/differential.revision.edit \
            -d api.token= \
            -d transactions[0][type]=title \
            -d transactions[0][value]=${title_message} \
            -d objectIdentifier=${revision_id}
    """
}

def change_ph_status() {
    title = get_ph_title()
    title = title.replaceAll("\\[Build Not Finish Or FAIL DO NOT ACCEPT\\]", "")
    change_ph_title(title,"${env.REVISION_ID}")
}
def get_code() {
    echo "push process"
    checkout([
        $class: 'GitSCM', 
        branches: [[name: "origin/${PH_BRANCH_NAME}"]], 
        doGenerateSubmoduleConfigurations: false, 
        extensions: [
            [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false], 
            [$class: 'SubmoduleOption', disableSubmodules: false, parentCredentials: true, recursiveSubmodules: true, reference: '', trackingSubmodules: true], 
            [$class: 'AuthorInChangelog'],
            [$class: 'UserIdentity', email: 'xxxx@horizon.ai', name: 'xxxx'],
        ], 
        submoduleCfg: [], 
        userRemoteConfigs: [[credentialsId: 'e486xxxx', url: "${env.gitlabSourceRepoSshUrl}"]]
    ])
    if (env.REVISION_ID) {
        echo "apply patch from ph"
        try{
            PH_BRANCH_NAME = sh (script: 'curl -s https://cr.hobot.cc/api/differential.diff.search -d api.token= -d constraints[ids][0]=$DIFF_ID | python3 -c "import sys, json; print(json.load(sys.stdin)[\'result\'][\'data\'][0][\'fields\'][\'refs\'][1][\'name\'])"',returnStdout: true).trim().replaceAll("/", "%2F")
        }catch (Exception err){
            PH_BRANCH_NAME = sh (script: 'curl -s https://cr.hobot.cc/api/differential.diff.search -d api.token= -d constraints[ids][0]=$DIFF_ID | python3 -c "import sys, json; print(json.load(sys.stdin)[\'result\'][\'data\'][0][\'fields\'][\'refs\'][0][\'name\'])"',returnStdout: true).trim().replaceAll("/", "%2F")
        } 
        sh """
            echo "PH_BRANCH_NAME: ${PH_BRANCH_NAME}"
            git config --global user.name xxxx
            git config --global user.email xxx@horizon.ai
            git reset --hard origin/"${PH_BRANCH_NAME}"
            git clean -fd -f
            arc patch --diff "$DIFF_ID" --nobranch --force --conduit-uri=https://cr.hobot.cc/ --conduit-token=
        """
    }
}

Jump Jenkinsfile

//change to current build jenkins job
def build_jenkins_project = "xxx/XXX" //""里配置需要触发编译的Jenkins job
//Ex: def build_jenkins_project = "CICD-Demo/Demo_Pre_build_Jump/"

pipeline {
    agent {//6~29 行 初始化环境,因为不涉及编译,所以不用修改
        kubernetes {
            label "${UUID.randomUUID().toString()}"
            yaml """
                metadata:
                  labels:
                    some-label: some-label-value
                    class: KubernetesDeclarativeAgentTest
                  namespace: scm
                spec:
                  nodeSelector:
                    jenkins-ci: "true"
                  containers:
                    - name: build
                      image: hub.hobot.cc/builder/cicd-common-tool:v8
                      command:
                      - cat
                      tty: true
                      env:
                        - name: CONTAINER_ENV_VAR
                          value: build
            """
        }
    }
    options { 
        skipDefaultCheckout() 
    }
    parameters { //参数,用来接收来自Ph的post 请求
        string defaultValue: '', description: 'Enter PH DIFF_ID', name: 'DIFF_ID', trim: true
        string defaultValue: '', description: 'Enter PH PHID', name: 'PHID', trim: true
        string defaultValue: '', description: 'Enter PH REVISION ID', name: 'REVISION_ID', trim: true
    }
    stages{ //38~62配置jump触发编译任务
        stage('jump') {
            steps {
                container('build') {
                    script {
                        branch = sh (script: 'curl -s https://cr.hobot.cc/api/differential.query -d api.token= -d ids[0]=$REVISION_ID | python3 -c "import sys, json; print(json.load(sys.stdin)[\'result\'][0][\'branch\'])"',returnStdout: true).trim().replaceAll("/", "%2F")      
                        remote_job = build job: build_jenkins_project + '/' + branch, 
                            wait: false, 
                            parameters: [
                                [$class: 'StringParameterValue', name: 'DIFF_ID', value: "${env.DIFF_ID}"], 
                                [$class: 'StringParameterValue', name: 'PHID', value: "${env.PHID}"], 
                                [$class: 'StringParameterValue', name: 'REVISION_ID', value: "${env.REVISION_ID}"], 
                            ]
                        
                        sh '''
                            curl https://cr.hobot.cc/api/differential.revision.edit \
                               -d api.token= \
                               -d transactions[0][type]=comment \
                               -d transactions[0][value]="Jump job success \n click this link then redirect to build job: \n ${BUILD_URL}" \
                               -d objectIdentifier=$REVISION_ID
                        '''
                    }
                }
            }
        }
    }
    post {
        success {
            container('build') {
                sh 'echo continue'
                script {
                    branch = sh (script: 'curl -s https://cr.hobot.cc/api/differential.query -d api.token= -d ids[0]=$REVISION_ID | python3 -c "import sys, json; print(json.load(sys.stdin)[\'result\'][0][\'branch\'])"',returnStdout: true).trim().replaceAll("/", "%2F")
                    if (!job_branch_list.contains(branch)) {
                        step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true])
                    }
                }
            }
        }
        failure {
            script {
                step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true])
            }
        }
        aborted {
            script {
                step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true])
            }
        }
    }
}

怎么使用模板
编写多分支流水线Jenkinsfile

  • 拷贝Jenkinsfile_Pre_build_branch模板,根据项目情况修改docker image、编译步骤等
  • 将修改完的Jenkinsfile_Pre_build_branch命名为Jenkinsfile ,提交到项目代码仓库的scm/project/目录下
  • 如果需要编译的是多个分支,这些分支的scm/project/ 下都要有Jenkinsfile
    编写Jump Jenkinsfile
  • 拷贝Jenkinsfile_Pre_build_Jump模板,根据项目情况修改docker image、编译步骤等
  • 将修改完的Jenkinsfile_Pre_build_Jump命名为Jenkinsfile_Jump ,提交到项目代码仓库的目录下
    创建并配置多分支流水线Jenkins Job
    在需要创建 Jenkins job的文件夹下新建多分支流水线。

输入Jenkins job名,选择多分支流水线,点击OK完成创建

配置多分支流水线
1.对Branch Sources进行配置

  • Branch Sources点击add source,选择git
  • Project Repository:输入仓库地址
  • Credentials:输入认证凭据(凭据选择git)

Behaviours:

  • add 选择Discover Tags

  • add 选择Advanced clone behaviours

  • 勾选下Shallow clone,Shallow clone depth为1

  • Build strategies选择named branches

  • add添加wildcard include/excludes

  • include默认为*,表示所有分支,也可以在include中添加所需触发的分支名

配置完成后点击保存
创建Jump job
参考 创建Jenkins job 创建Jump job ,命名可以加上Jump 字符
配置Jenkins job ,调用代码仓库中的Jump Jenkinsfile Jenkins job调用代码仓库中的Jenkinsfile

当你遇到 "certificate has expired" 的错误提示时,意味着你的证书已过期。证书是用于验证网站身份和加密通信的一种安全机制。过期的证书会导致浏览器或其他应用程序无法信任该网站,从而阻止你访问或与该网站进行安全通信。 要解决这个问题,你可以尝试以下几个步骤: 1. 检查系统时间和日期:确保你的设备上的时间和日期设置正确。过期的证书通常是由于设备时间不准确导致的。 2. 清除浏览器缓存:如果你在浏览器中遇到这个问题,尝试清除浏览器缓存和Cookie。有时候旧的证书缓存可能导致问题。 3. 更新操作系统和应用程序:确保你的操作系统和相关应用程序都是最新版本。更新可能包含修复过期证书的补丁。 4. 检查证书颁发机构(CA):如果你是网站管理员或开发人员,需要检查你的证书是否由可信任的证书颁发机构(CA)签发。如果证书由不受信任的CA签发,可能会导致浏览器或其他应用程序拒绝信任该证书。 至于 "gifsicle pre-build test failed" 的错误提示,这通常是在构建或安装gifsicle软件包时出现的问题。gifsicle是一个用于处理GIF图像的工具。 要解决这个问题,你可以尝试以下几个步骤: 1. 检查依赖项:确保你的系统上已安装了gifsicle所需的所有依赖项。这可能包括其他库或软件包。你可以查看gifsicle的文档或官方网站获取详细的依赖项信息。 2. 更新软件包:确保你正在使用最新版本的gifsicle和相关软件包。更新可能包含修复已知问题或错误的修补程序。 3. 检查编译环境:如果你是从源代码编译gifsicle,确保你的编译环境设置正确,并且你具备构建所需的所有工具和库。 如果以上步骤都没有解决问题,你可以尝试在相关的开发者社区或论坛上寻求帮助,以获取更具体的指导和支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值