Jenkins 流水线是一套插件,它支持实现和集成持续交付流水线到 Jenkins。流水线提供了一组可扩展的工具,用于通过流水线 DSL 将简单到复杂的交付流水线建模为“代码”。
对Jenkins 流水线的定义被写在一个文本文件中 (成为 Jenkinsfile),该文件可以被提交到项目的源代码的控制仓库。这是"流水线即代码"的基础; 将CD 流水线作为应用程序的一部分,像其他代码一样进行版本化和审查。 创建 Jenkinsfile
并提交它到源代码控制中提供了一些即时的好处:
自动地为所有分支创建流水线构建过程并拉取请求。
在流水线上代码复查/迭代 (以及剩余的源代码)。
对流水线进行审计跟踪。
该流水线的真正的源代码 [3], 可以被项目的多个成员查看和编辑。
Jenkinsfile 能使用两种语法进行编写 - 声明式和脚本化。
声明式和脚本式流水线都是 DSL 语言,[1]用来描述软件交付流水线的一部分。 脚本式流水线是用一种限制形式的 Groovy 语法编写的。
声明式和脚本化的流水线从根本上是不同的。 声明式流水线的是 Jenkins 流水线更近的特性:
相比脚本化的流水线语法,它提供更丰富的语法特性,
是为了使编写和读取流水线代码更容易而设计的。
然而,写到Jenkinsfile
中的许多单独的语法组件(或者 “步骤”), 通常都是声明式和脚本化相结合的流水线。
在声明式流水线语法中, pipeline 块定义了整个流水线中完成的所有的工作。
pipeline {
agent any
stages {
stage('Build') {
steps {
//
}
}
stage('Test') {
steps {
//
}
}
stage('Deploy') {
steps {
//
}
}
}
}
说明:
在脚本化流水线语法中, 一个或多个 node 块在整个流水线中执行核心工作。 虽然这不是脚本化流水线语法的强制性要求, 但它限制了你的流水线的在node
块内的工作做两件事:
通过在Jenkins队列中添加一个项来调度块中包含的步骤。 节点上的执行器一空闲, 该步骤就会运行。
创建一个工作区(特定为特定流水间建立的目录),其中工作可以在从源代码控制检出的文件上完成。
Caution: 根据你的 Jenkins 配置,在一系列的空闲后,一些工作区可能不会自动清理 。
node {
stage('Build') {
//
}
stage('Test') {
//
}
stage('Deploy') {
//
}
}
说明:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'make'
}
}
stage('Test'){
steps {
sh 'make check'
junit 'reports/**/*.xml'
}
}
stage('Deploy') {
steps {
sh 'make publish'
}
}
}
}
说明:
stage
块的信息。如 above所述, 在脚本化流水线语法中,stage 块是可选的。agent
。pipeline {
agent { docker 'maven:3.3.3' }
stages {
stage('build') {
steps {
sh 'mvn --version'
}
}
}
}
pipeline {
agent { docker 'node:6.3' }
stages {
stage('build') {
steps {
sh 'npm --version'
}
}
}
}
pipeline {
agent { docker 'python:3.5.1' }
stages {
stage('build') {
steps {
sh 'python --version'
}
}
}
}
本示例流水线包括以下八个阶段。
说明:
pipeline {
agent {
node {
label 'maven'
}
}
stages {
stage('clone code') {
steps {
container('maven') {
checkout([$class: 'GitSCM', branches: [[name: '*/$BRANCH_NAME']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/kubesphere/devops-python-sample.git']]])
}
}
}
stage('unit test') {
steps {
container('maven') {
sh 'mvn clean -o -gs `pwd`/configuration/settings.xml test'
}
}
}
stage('build & push') {
steps {
container('maven') {
sh 'mvn -o -Dmaven.test.skip=true -gs `pwd`/configuration/settings.xml clean package'
sh 'docker build -f Dockerfile-online -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER .'
withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,credentialsId : "$DOCKER_CREDENTIAL_ID" ,)]) {
sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
}
}
}
}
stage('push latest') {
when {
branch 'master'
}
steps {
container('maven') {
sh 'docker tag $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
}
}
}
stage('deploy to dev') {
steps {
container('maven') {
input(id: 'deploy-to-dev', message: 'deploy to dev?')
withCredentials([kubeconfigContent(credentialsId : 'KUBECONFIG_CREDENTIAL_ID' ,variable : 'KUBECONFIG_CONFIG' ,)]) {
sh 'mkdir -p ~/.kube/'
sh 'echo "$KUBECONFIG_CONFIG" > ~/.kube/config'
sh 'envsubst < deploy/dev-ol/deploy.yaml | kubectl apply -f -'
}
}
}
}
stage('deploy to production') {
steps {
container('maven') {
input(id: 'deploy-to-production', message: 'deploy to production?')
withCredentials([kubeconfigContent(credentialsId : 'KUBECONFIG_CREDENTIAL_ID' ,variable : 'KUBECONFIG_CONFIG' ,)]) {
sh 'mkdir -p ~/.kube/'
sh 'echo "$KUBECONFIG_CONFIG" > ~/.kube/config'
sh 'envsubst < deploy/prod-ol/deploy.yaml | kubectl apply -f -'
}
}
}
}
}
environment {
DOCKER_CREDENTIAL_ID = 'dockerhub-id'
GITHUB_CREDENTIAL_ID = 'github-id'
KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
REGISTRY = 'docker.io'
DOCKERHUB_NAMESPACE = 'docker_username'
GITHUB_ACCOUNT = 'kubesphere'
APP_NAME = 'devops-java-sample'
}
parameters {
string(name: 'TAG_NAME', defaultValue: '', description: '')
}
}
磨你的心智,是为了以后不管你遇见任何人和事,都能稳如泰山。