Jenkinsfile小笔记

Jenkinsfile

Jenkins 流水线支持两种语法, 声明式和脚本式流水线. 两种语法都支持持续交付流水线. 两种都可以用来在web UI 或jenkinsfile中定义流水线, 不过通常认为创建一个Jenkinsfile并将其检入源代码控制仓库是最佳实践.

# 声明式流水线
pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}

# 脚本式流水线
node {
    stage('Build') {
        echo 'Building....'
    }
    stage('Test') {
        echo 'Testing....'
    }
    stage('Deploy') {
        echo 'Deploying....'
    }
}

agent是必须的, 指示jenkins为流水线分配一个执行器和工作区, 没有agent指令的话, 声明式流水线不仅无效, 也无法完成任何工作.
一个合法的声明式流水线还需要stages指令和steps指令, 指示jenkins需要执行什么操作, 在哪个阶段执行.

jenkins将一个项目的开发生命周期的多个阶段(构建, 部署, 测试)绑定在一起. jenkins有许多插件可以用于调用几乎所有常用的构建工具, 例如以下的例子用于从shell中调用make, 基于Windows的系统可以使用bat代替

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'make' 
                archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true 
            }
        }
    }
}

sh调用make命令, 只有命令返回的状态码为0时才会继续, 任何非零的返回码都将使流水线失败.

运行自动化测试是任何成功的持续交付过程的重要组成部分, 因此, jenkins有很多测试记录, 报告和可视化的工具, 由各种插件提供. 当测试失败时, jenkins可以记录这些失败以供汇报以及在web UI 中可视化
以下是一个使用Junit的例子

pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                /* `make check` 在测试失败后返回非零的退出码;
                * 使用 `true` 允许流水线继续进行
                */
                sh 'make check || true' 
                junit '**/target/*.xml' 
            }
        }
    }
}

使用内联的shell条件sh make || true确保sh步骤总是看到退出码是0, 是Junit步骤有机会捕获和处理测试报告

部署可以隐含很多步骤, 取决于项目或者组织的要求, 可能是从交付件到artifactory服务器, 或着将代码推送到生产系统的任何东西, 在实例流水线的这个阶段, 构建和测试阶段都已经成功执行.部署阶段只有在之前的阶段都成功完成之后才会进行, 否则流水线会自动退出.

pipeline {
    agent any

    stages {
        stage('Deploy') {
            when {
              expression {
                currentBuild.result == null || currentBuild.result == 'SUCCESS' 
              }
            }
            steps {
                sh 'make publish'
            }
        }
    }
}

流水线访问currentBuild.result变量确定是否有任何测试的失败, 在这种情况下, 值为UNSTABLE

使用jenkinsfile 工作

字符串插值

def username = 'Jenkins'
echo 'hello ${username}'
echo "hello Mr. ${username}"

内置变量

BUILD_ID 当前构建的ID
BUILD_NUMBER 当前构建号
BUILD_TAG 字符串 ``jenkins-${JOB_NAME}-${BUILD_NUMBER}``
BILD_URL 可以定位此次构建结果的 URL(比如 http://buildserver/jenkins/job/MyJobName/17/ )
EXECUTOR_NUMBER 用于识别执行当前构建的执行者的唯一编号(在同一台机器的所有执行者中)。这个就是你在“构建执行状态”中看到的编号,只不过编号从 0 开始,而不是 1。
JAVA_HOME 如果你的任务配置了使用特定的一个 JDK,那么这个变量就被设置为此 JDK 的 JAVA_HOME。当设置了此变量时,PATH 也将包括 JAVA_HOME 的 bin 子目录。
JENKINS_URL Jenkins 服务器的完整 URL,比如 https://example.com:port/jenkins/ (注意:只有在“系统设置”中设置了 Jenkins URL 才可用)。
JOB_NAME 本次构建的项目名称,如 “foo” 或 “foo/bar”。
NODE_NAME 运行本次构建的节点名称。对于 master 节点则为 “master”。
WORKSPACE workspace 的绝对路径。

设置环境变量

声明式流水线支持environment指令, 脚本式流水线必须使用withEnv

# 声明式
pipeline {
    agent any
    environment { 
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment { 
                DEBUG_FLAGS = '-g'
            }
            steps {
                sh 'printenv'
            }
        }
    }
}
# 脚本式
node {
    withEnv(["PATH+MAVEN=${tool 'M3'}/bin"]) {
        sh 'mvn -B verify'
    }
}

定义在最高层的pipeline的environment指令适用于流水线的所有步骤, 定义在stage中的environment指令适用于stage中的步骤

动态环境变量

pipeline {
    agent any 
    environment {
        // 使用 returnStdout
        CC = """${sh(
                returnStdout: true,
                script: 'echo "clang"'
            )}""" 
        // 使用 returnStatus
        EXIT_STATUS = """${sh(
                returnStatus: true,
                script: 'exit 1'
            )}"""
    }
    stages {
        stage('Example') {
            environment {
                DEBUG_FLAGS = '-g'
            }
            steps {
                sh 'printenv'
            }
        }
    }
}

agent 必须设置在流水线的最高级, 如何设置为agent none会失败
使用returnStdout时, 返回的字符串末尾会追加一个空格, 可以使用.trim()将其移除

处理凭据

pipeline {
    agent {
        // 此处定义 agent 的细节
    }
    environment {
        AWS_ACCESS_KEY_ID     = credentials('jenkins-aws-secret-key-id')
        AWS_SECRET_ACCESS_KEY = credentials('jenkins-aws-secret-access-key')
    }
    stages {
        stage('Example stage 1') {
            steps {
                // 
            }
        }
        stage('Example stage 2') {
            steps {
                // 
            }
        }
    }
}

带密码的用户名

environment {
    BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-common-creds')
}

实际设置了三个环境变量
BITBUCKET_COMMON_CREDS - 包含一个以冒号分隔的用户名和密码,格式为 username:password。
BITBUCKET_COMMON_CREDS_USR - 附加的一个仅包含用户名部分的变量。
BITBUCKET_COMMON_CREDS_PSW - 附加的一个仅包含密码部分的变量。

处理参数

pipeline {
    agent any
    parameters {
        string(name: 'Greeting', defaultValue: 'Hello', description: 'How should I greet the world?')
    }
    stages {
        stage('Example') {
            steps {
                echo "${params.Greeting} World!"
            }
        }
    }
}

处理故障

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'make check'
            }
        }
    }
    post {
        always {
            junit '**/target/*.xml'
        }
        failure {
            mail to: team@example.com, subject: 'The Pipeline failed :('
        }
    }
}

使用多个agent

pipeline {
    agent none
    stages {
        stage('Build') {
            agent any
            steps {
                checkout scm
                sh 'make'
                stash includes: '**/target/*.jar', name: 'app' 
            }
        }
        stage('Test on Linux') {
            agent { 
                label 'linux'
            }
            steps {
                unstash 'app' 
                sh 'make check'
            }
            post {
                always {
                    junit '**/target/*.xml'
                }
            }
        }
        stage('Test on Windows') {
            agent {
                label 'windows'
            }
            steps {
                unstash 'app'
                bat 'make check' 
            }
            post {
                always {
                    junit '**/target/*.xml'
                }
            }
        }
    }
}

流水线并行

stage('Build') {
    /* .. snip .. */
}

stage('Test') {
    parallel linux: {
        node('linux') {
            checkout scm
            try {
                unstash 'app'
                sh 'make check'
            }
            finally {
                junit '**/target/*.xml'
            }
        }
    },
    windows: {
        node('windows') {
            /* .. snip .. */
        }
    }
}
posted @ 2023-02-04 10:54  Chinor  阅读(112)  评论(0编辑  收藏  举报