Jenkins工作流pipeline(groovy)常用操作记录
//主要用于记录工作流中操作,如从git仓库拉取代码、编译其他项目的job任务、编译docker镜像、推送镜像到仓库、操作json数组、从接口中读取数据等操作。
pipeline{
agent {
label "${NODE_LABELS}" //jenkins服务器节点,不同操作系统使用
}
environment {
//该步骤的变量下面操作无法进行修改
PROJECT_API_URL = "..." //获取项目列表api接口地址
UPDATE_DOCKER_API_URL = "..." //更新镜像api接口地址
DOWNLOAD_URL_BASE = "..." //下载程序代码url地址
OPS_GIT_URL = "..." //下载dockerfile的git地址
DOCKER_IMAGE_BASE_URL = '...' //docker镜像仓库地址
DOCKER_CREDENTIALS_ID = '...' //docker授权ID,需在jenkins凭证中进行添加
NEXUS_URL = "..." //制品库地址
NEXUS_CREDENTIALS_ID = '...' //制品库授权ID,需在jenkins凭证中进行添加
}
stages{
stage('清空当前工作目录') {
steps {
script {
// 移除当前工作的目录中的所有文件和子目录
sh 'rm -rf ./*'
// 输出一个确认信息
echo "当前工作目录已清空"
}
}
}
stage('初始化变量') {
steps {
script {
// 声明全局变量,此处变量后续可修改
def frontendProjects = []
def backendProjects = []
env.DOCKERFILE_NAME = 'Dockerfile'
env.BUILD_PROJECTS = '[]'
env.buildCount = 0
env.buildStaticCount = 0
//使用非凭证方式下载代码,可修改为使用凭证方式
def GIT_CONFIG_USER_NAME = 'git_user'
def GIT_CONFIG_USER_PASSWORD = 'git_password'
env.STATIC_CONTIG_GIT_URL = "http://$GIT_CONFIG_USER_NAME:$GIT_CONFIG_USER_PASSWORD@服务器ip:端口号/config.git"
}
}
}
stage('登录Docker镜像仓库') {
steps {
script {
//使用凭证ID登录docker
withCredentials([usernamePassword(credentialsId: env.DOCKER_CREDENTIALS_ID, usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) {
sh """
docker login $DOCKER_IMAGE_BASE_URL -u "$env.DOCKER_USERNAME" -p "$env.DOCKER_PASSWORD"
"""
}
}
}
}
stage('获取项目列表'){
steps {
script {
// 从接口获取项目json项目列表,结构为{"project_name":"aa","build_tag":"test_aa_...."}
def response = httpRequest url: "${env.PROJECT_API_URL}?id=${upgradeListId}", validResponseCodes: '200:499'
// 转换为json数组
def jsonData = readJSON text: response.content
// 提取项目列表
frontendProjects = jsonData.data.frontends ?: []
backendProjects = jsonData.data.backends ?: []
}
}
}
stage('从git仓库中获取Dockerfile'){
steps {
git url: "${env.OPS_GIT_URL}", branch: "master"
}
}
stage('编译关联的其他job任务') {
when {
expression { backendProjects.any { it['project_name'] == 'extra_project' } }
}
steps {
script {
#从项目列表读取关联job的tag
def extraBuildTag = findTagValueFromVariable(backendProjects,'extra_project')
// 编译extra_project项目
build job: 'extra_project',
parameters: [
string(name: 'Tag', value: extraBuildTag),
string(name: 'NODE_LABELS', value: NODE_LABELS)
]
}
}
}
stage('处理后端程序包'){
when {
expression { backendProjects != null && !backendProjects.isEmpty() && buildBackend == 'true' }
}
steps {
script {
backendProjects.each{ project ->
script {
handleBackendProject(project)
env.buildCount = env.buildCount.toInteger() + 1
}
}
}
}
}
stage('下载前端程序包'){
when {
expression { frontendProjects != null && !frontendProjects.isEmpty() && buildFrontend == 'true' }
}
steps {
script {
frontendProjects.each{ project ->
script {
handleFrontendProject(project)
env.buildStaticCount = env.buildStaticCount.toInteger() + 1
}
}
//判断项目是否少于15个,否则返回错误
if( env.buildStaticCount.toInteger() <=15 ){
error "项目不完整,请检查升级方案。"
}
}
}
}
stage('生成metadata.json文件'){
when {
expression { frontendProjects != null && !frontendProjects.isEmpty() && buildFrontend == 'true' }
}
steps {
script {
//将前端项目列表输出到文件,用于后续进行查看
def formatFrontProject = groovy.json.JsonOutput.prettyPrint(frontendProjects.toString())
def metadataFile = "frontend_metadata.json"
//写入文件
writeFile file: metadataFile, text: formatFrontProject
}
}
}
stage('从git获取配置文件'){
when {
expression { frontendProjects != null && !frontendProjects.isEmpty() && buildFrontend == 'true' }
}
steps {
sh """
git clone --branch master --depth 1 ${env.STATIC_CONTIG_GIT_URL}
"""
}
}
stage('编译前端程序包'){
when {
expression { frontendProjects != null && !frontendProjects.isEmpty() && buildFrontend == 'true' }
}
steps {
script {
projectName = 'frontend'
print("--------------开始编译前端项目: ${projectName}--------------")
def now = new Date()
def dockerBuildDir = "${WORKSPACE}/dockerfile/app/${projectName}/"
def dockerPushImageVersion = "${env.IMAGE_PREFIX}_${now.format('yyyyMMdd')}_V0.0.0_${now.format('HHmm')}"
def dockerPackagePushUrl = "${env.DOCKER_IMAGE_BASE_URL}/${projectName}:${dockerPushImageVersion}"
sh """
#编译镜像
docker build -f ${env.DOCKERFILE_NAME} -t ${dockerPackagePushUrl} . && docker push ${dockerPackagePushUrl}
"""
print("--------------编译前端完成项目--------------")
appendToList("${dockerPackagePushUrl}")
}
}
}
stage('打包离线镜像归档并上传到制品库'){
when {
expression { env.BUILD_PROJECTS != null && !env.BUILD_PROJECTS.isEmpty() && saveOfflineImage == 'true' }
}
steps {
script {
print("--------------开始打包离线镜像--------------")
def buildProjectArray = []
def buildProjects = new groovy.json.JsonSlurper().parseText(env.BUILD_PROJECTS)
buildProjects.each{ project ->
buildProjectArray = buildProjectArray + project
}
def buiildProjectString = buildProjectArray.join(' ')
def buildImageOfflineName = "test-app-${upgradeListId}.jar"
sh """
docker save -o $buildImageOfflineName ${buiildProjectString}
"""
//归档镜像,可在点击项目进行下载
archiveArtifacts artifacts: buildImageOfflineName, fingerprint: true
//上传到nexus
withCredentials([usernamePassword(credentialsId: env.NEXUS_CREDENTIALS_ID, usernameVariable: 'NEXUS_USER', passwordVariable: 'NEXUS_PASSWORD')]) {
sh """
curl -X POST "${env.NEXUS_URL}/service/rest/v1/components?repository=buildpackage" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-F "raw.directory=/build_packages/dockerImages/" \
-F "raw.asset1=@${buildImageOfflineName};type=application/java-archive" \
-F "raw.asset1.filename=${buildImageOfflineName}" \
-u ${NEXUS_USER}:${NEXUS_PASSWORD}
"""
}
print("--------------打包离线镜像完成--------------")
def downloadImageLink = "${env.NEXUS_URL}/repository/buildpackage/build_packages/dockerImages/${buildImageOfflineName}"
echo "--------------下载离线镜像URL: ${downloadImageLink} ----------"
}
}
}
stage('删除本地镜像'){
when {
expression { env.BUILD_PROJECTS != null && !env.BUILD_PROJECTS.isEmpty() }
}
steps {
script {
def buildProjects = new groovy.json.JsonSlurper().parseText(env.BUILD_PROJECTS)
buildProjects.each{ project ->
print("--------------开始删除本地镜像: ${project}--------------")
sh """
docker rmi "${project}"
"""
}
print("--------------删除本地镜像完成--------------")
}
}
}
stage('更新记录'){
when {
expression { env.BUILD_PROJECTS != null && !env.BUILD_PROJECTS.isEmpty() && updateListDockerImage == 'true' }
}
steps {
script {
def dokcerImageUrls = java.net.URLEncoder.encode(env.BUILD_PROJECTS, "UTF-8")
// 调用接口更新镜像
def response = httpRequest url: "${env.UPDATE_DOCKER_API_URL}?id=${upgradeListId}&image_urls=${dokcerImageUrls}", validResponseCodes: '200:499'
def jsonData = readJSON text: response.content
}
}
}
}
post {
always {
outputBuildProjects()
}
}
}
// 追加元素到全局列表
def appendToList(String element) {
def list = new groovy.json.JsonSlurper().parseText(env.BUILD_PROJECTS)
list.add(element)
env.BUILD_PROJECTS = new groovy.json.JsonBuilder(list).toString()
}
//输出编译项目列表
def outputBuildProjects() {
stage('输出编译的镜像列表'){
def buildProjectString = ""
def buildProjects = new groovy.json.JsonSlurper().parseText(env.BUILD_PROJECTS)
buildProjects.each{ project ->
buildProjectString = buildProjectString + "\r\n" + project
}
print("docker image push list【${buildProjects.size()}个】:")
print("${buildProjectString}")
}
}
// 处理前端项目
def handleFrontendProject(project) {
def projectName = project.project_name
print("--------------开始复制前端项目: ${projectName}--------------")
dir(projectName) {
// 下载构建包
def downloadUrl = "..."
try {
sh """
//下载项目
mkdir -p ${WORKSPACE}/static && wget -q -O ${WORKSPACE}/static/${projectName}.zip ${downloadUrl}
"""
} catch (Exception e) {
// 捕获异常并在控制台输出错误信息
error "下载项目${projectName}失败: ${e.message}"
}
}
}
// 处理后端项目
def handleBackendProject(project) {
def projectName = project.project_name
print("--------------开始后端处理项目: ${projectName}--------------")
dir(projectName) {
// 下载构建包
def downloadUrl = "..."
def dockerBuildDir = "..."
// 跳过
if (skipCount.toInteger() > 0 && env.buildCount.toInteger() <= skipCount.toInteger() ){
print("${projectName} skipped")
return
}
try {
//
dockerPackagePushUrl = "..."
sh """
mkdir -p ${dockerBuildDir}
wget -q -O "${dockerBuildDir}/app/${buildFilename}" ${downloadUrl}
"""
} catch (Exception e) {
// 捕获异常并在控制台输出错误信息
error "下载项目${projectName}失败: ${e.message}"
}
print("--------------开始编译项目: ${projectName}--------------")
sh """
cd ${dockerBuildDir}
docker build -f ${env.DOCKERFILE_NAME} -t ${dockerPackagePushUrl} . && docker push ${dockerPackagePushUrl}
"""
print("--------------项目编译完成--------------")
appendToList("${dockerPackagePushUrl}")
}
}
//从变量中获取项目对应的tag
def findTagValueFromVariable(projectVariable, key) {
for (def item in projectVariable) {
if (item['project_name'] == key) {
return item['build_tag']
}
}
return null // 如果没有找到匹配的值,返回 null
}
此博客已不再更新,如需查看最新文章请访问雪洁之家
浙公网安备 33010602011771号