Jenkins Pipeline实现Golang项目的CI/CD
背景
最近新增了一个Golang实现的项目,需要接入到现有的流水线架构中。
流程图
这边流程和之前我写过的一篇《基于Jenkins实现的CI/CD方案》差不多,不一样的是构建现在是手动触发的,没有配置webhook。因为不是业务主干代码,部署的频率比较低。
项目目录结构
Dockerfile文件
FROM alpine:3.19.1
WORKDIR /data
COPY go-pipline /data/go-pipline
# 设置阿里云仓库
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 设置时区和安装bash
RUN apk add -U tzdata && \
apk add -U bash && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone
EXPOSE 8080
ENTRYPOINT ["/data/go-pipline"]
Jenkinsfile文件
import java.text.SimpleDateFormat
import java.util.TimeZone
// 构建版本
def createVersion() {
def simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss")
simpleDateFormat.timeZone = TimeZone.getTimeZone("Asia/Shanghai")
return simpleDateFormat.format(new Date()) + "_${env.branch}"
}
// 获取ssh连接
def GetRemoteServer(ip, username, password) {
def remote = [:]
remote.name = ip
remote.host = ip
remote.user = username
remote.password = password
remote.allowAnyHosts = true
return remote
}
pipeline {
agent none
environment {
_version = createVersion()
}
stages {
stage('Git Checkout') {
agent any
steps {
checkout([
$class: 'GitSCM',
branches: [[name: "${branch}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [],
gitTool: 'Default',
submoduleCfg: [],
userRemoteConfigs: [[url: 'xxx.git',credentialsId: 'xxx',]]
])
}
}
stage('Source Package') {
agent {
docker {
image 'golang:1.21.0'
args '-v go-cache:/go/pkg/mod'
}
}
steps {
sh 'go env -w GO111MODULE=on'
sh 'go env -w GOPROXY=https://goproxy.cn,direct'
sh 'go mod download'
sh 'CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o go-pipeline'
}
}
stage('Image Build') {
agent any
steps {
sh 'docker build -f $WORKSPACE/Dockerfile -t {{harbor}}/common/go-pipeline:${_version} $WORKSPACE'
sh 'rm -f $WORKSPACE/go-pipeline'
sh 'docker push {{harbor}}/common/go-pipeline:${_version}'
sh 'docker rmi {{harbor}}/common/go-pipeline:${_version}'
}
}
stage('Publish To Env') {
agent any
steps {
script {
def remote = GetRemoteServer('127.0.0.1', 'root', 'root')
sshCommand remote: remote, command: "docker stop go-pipeline; docker rm go-pipeline"
sshCommand remote: remote, command: "docker run -it --name go-pipeline -d -p 8080:8080 {{harbor}}/common/go-pipeline:${_version}"
}
}
}
}
}
有一个需要注意的地方,Source Package 源码编译阶段,除了指定构建的容器以外,我还挂载了一个go-cache的volume,这边是为了缓存go的依赖。这边是为了提高构建的速度,或者也可以解决构建机器连接不了外网的情况。具体volume创建命令:
docker volume create go-cache
main方法中只提供了一个接口
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/ping", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
r.Run()
}
流水线配置
新增一个pipeline类型的流水线
新增一个参数branch,将构建的分支参数开出来
选择Pipeline script from SCM,配置如下图
这边需要注意,把最后Lightweight checkout去掉勾选,不然branch参数会不生效
选择构建,结果验证ok
结语
代码地址:https://github.com/yzh19961031/blogDemo/tree/master/go-pipeline