.gitlab-ci.yml
流水线入口:阶段
stages:
- lint
- test
- build
- deploy
流水线以job为单位运行,每个job就是自己想通过流水线做的事情,例如单元测试的job,核心是运行脚本:
go test -short go list ./...
每个阶段下可以定义多个job。
同一阶段的job会并行执行。
阶段是串行执行。
全局变量
variables:
IMAGE_GROUP: xxx
NAME_SPACE: xxx
GOPATH: ${CI_PROJECT_DIR}/.go
GOMODCACHE: ${CI_PROJECT_DIR}/.go/pkg/mod
GOCACHE: ${CI_PROJECT_DIR}/.go/.cache/go-build
GOLANGCI_LINT_CACHE: ${CI_PROJECT_DIR}/.go/.cache/golangci-lint
GOPATH.goGOMODCACHEGOCACHEGOLANGCI_LINT_CACHE
公共模板
job公共模板
.template:
image: 172.30.3.150/xxx/go-tools:latest
tags:
- 172.30.3.219-runner
interruptible: true
go-tools
- Dockerfile
FROM golang:1.17.9
USER root
ENV GOPATH /go
ENV PATH ${GOPATH}/bin:$PATH
# 设置私服
RUN go env -w GOPRIVATE=xxx.com
# 设置忽略私服的https证书校验
RUN go env -w GOINSECURE=xxx.com
RUN git config --global http.sslverify false
RUN git config --global https.sslverify false
RUN go env -w GOPROXY="https://goproxy.cn,direct"
RUN go env -w GO111MODULE=on
# install docker
RUN curl -O https://get.docker.com/builds/Linux/x86_64/docker-latest.tgz
&& tar zxvf docker-latest.tgz
&& cp docker/docker /usr/local/bin/
&& rm -rf docker docker-latest.tgz
tags
.template.
interruptible
缓存模板
.go_cache:
cache:
key: go-cache-${CI_PROJECT_PATH_SLUG}
paths:
- .go
.go
lint阶段
代码检测job
golangci_lint:
stage: lint
only:
- merge_requests
- /^release/.*$/
extends:
- .go_cache
- .template
script:
- make golangci_lint
stageextendsscript
test阶段
单元测试、检查数据竞争job
unit_test:
stage: test
only:
- merge_requests
- /^release/.*$/
extends:
- .go_cache
- .template
cache:
policy: pull
script:
- make unit_test
cache.policy
build阶段
打包镜像的job模板
.build_image:
stage: build
only:
- tags
- /^release/.*$/
extends:
- .go_cache
- .template
打包镜像job
build_xxx_admin_image:
extends:
- .build_image
script:
- make build_admin_app
- make build_admin_image
- make push_admin_image
build_xxx_interface_image:
extends:
- .build_image
script:
- make build_interface_app
- make build_interface_image
- make push_interface_image
build_xxx_job_image:
extends:
- .build_image
script:
- make build_job_app
- make build_job_image
- make push_job_image
build_xxx_task_image:
extends:
- .build_image
script:
- make build_task_app
- make build_task_image
- make push_task_image
- 一个阶段多个job。
deploy阶段
部署到测试环境的job模板
.deploy_to_test_k8s:
stage: deploy
only:
- tags
- /^release/.*$/
extends:
- .template
image:
name: 172.30.3.150/xxx/kubectl:latest
entrypoint: [ "" ]
image
172.30.3.150/xxx/kubectlkubectl
- Dockerfile
FROM bitnami/kubectl
USER root
RUN apt-get update && apt-get install -y --no-install-recommends
make git
部署到测试环境job
deploy_admin_to_test_k8s:
extends:
- .deploy_to_test_k8s
needs: [ build_xxx_admin_image ]
script:
- make deploy_admin_to_test_k8s
deploy_interface_to_test_k8s:
extends:
- .deploy_to_test_k8s
needs: [ build_xxx_interface_image ]
script:
- make deploy_interface_to_test_k8s
deploy_job_to_test_k8s:
extends:
- .deploy_to_test_k8s
needs: [ build_xxx_job_image ]
script:
- make deploy_job_to_test_k8s
.deploy_task_to_test_k8s:
extends:
- .deploy_to_test_k8s
needs: [ build_xxx_task_image ]
script:
- make deploy_task_to_test_k8s
needs
完整的.gitlab-ci.yml
stages:
- lint
- test
- build
- deploy
#定义全局变量
variables:
IMAGE_GROUP: xxx
NAME_SPACE: xxx
GOPATH: ${CI_PROJECT_DIR}/.go
GOMODCACHE: ${CI_PROJECT_DIR}/.go/pkg/mod
GOCACHE: ${CI_PROJECT_DIR}/.go/.cache/go-build
GOLANGCI_LINT_CACHE: ${CI_PROJECT_DIR}/.go/.cache/golangci-lint
########################### 公共模板 ###########################
#job公共模板
.template:
image: 172.30.3.150/xxx/go-tools:latest
tags:
- 172.30.3.219-runner
interruptible: true
#缓存模板
.go_cache:
cache:
key: go-cache-${CI_PROJECT_PATH_SLUG}
paths:
- .go
########################### lint阶段 ###########################
#代码检测job
golangci_lint:
stage: lint
only:
- merge_requests
- /^release/.*$/
extends:
- .go_cache
- .template
script:
- make golangci_lint
########################### test阶段 ###########################
#单元测试、检查数据竞争job
unit_test:
stage: test
only:
- merge_requests
- /^release/.*$/
extends:
- .go_cache
- .template
cache:
policy: pull
script:
- make unit_test
########################### build阶段 ###########################
#打包镜像的job模板
.build_image:
stage: build
only:
- tags
- /^release/.*$/
extends:
- .go_cache
- .template
#打包镜像job
build_xxx_admin_image:
extends:
- .build_image
script:
- make build_admin_app
- make build_admin_image
- make push_admin_image
build_xxx_interface_image:
extends:
- .build_image
script:
- make build_interface_app
- make build_interface_image
- make push_interface_image
build_xxx_job_image:
extends:
- .build_image
script:
- make build_job_app
- make build_job_image
- make push_job_image
build_xxx_task_image:
extends:
- .build_image
script:
- make build_task_app
- make build_task_image
- make push_task_image
########################### deploy阶段 ###########################
#部署到测试环境的job模板
.deploy_to_test_k8s:
stage: deploy
only:
- tags
- /^release/.*$/
extends:
- .template
image:
name: 172.30.3.150/xxx/kubectl:latest
entrypoint: [ "" ]
#部署到测试环境job
deploy_admin_to_test_k8s:
extends:
- .deploy_to_test_k8s
needs: [ build_xxx_admin_image ]
script:
- make deploy_admin_to_test_k8s
deploy_interface_to_test_k8s:
extends:
- .deploy_to_test_k8s
needs: [ build_xxx_interface_image ]
script:
- make deploy_interface_to_test_k8s
deploy_job_to_test_k8s:
extends:
- .deploy_to_test_k8s
needs: [ build_xxx_job_image ]
script:
- make deploy_job_to_test_k8s
.deploy_task_to_test_k8s:
extends:
- .deploy_to_test_k8s
needs: [ build_xxx_task_image ]
script:
- make deploy_task_to_test_k8s
Makefile
.gitlab-ci.yml
VERSION=$(shell git describe --tags --always)
#################################### 代码检查 ####################################
.PHONY: golangci_lint
golangci_lint:
go mod tidy # 必须先下载依赖,否则golangci-lint会报:could not load export data: no export data for
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.45.0
golangci-lint run -v --timeout=5m --color always --out-format colored-line-number
#################################### 单元测试 ####################################
.PHONY: unit_test
unit_test:
go test -short `go list ./...`
#################################### 构建应用二进制执行文件 ####################################
.PHONY: build_all_app
build_all_app: build_admin_app build_interface_app build_job_app build_task_app
.PHONY: build_admin_app
build_admin_app:
make build_app SUB_MODULE=admin
.PHONY: build_interface_app
build_interface_app:
make build_app SUB_MODULE=interface
.PHONY: build_job_app
build_job_app:
make build_app SUB_MODULE=job
.PHONY: build_task_app
build_task_app:
make build_app SUB_MODULE=task
.PHONY: build_app
build_app:
mkdir -p bin
cd cmd/$(SUB_MODULE) && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X main.version=$(VERSION)" -o ../../bin/ && cd -
#################################### 打镜像 ####################################
.PHONY: build_all_image
build_all_image: build_admin_image build_interface_image build_job_image build_task_image
.PHONY: build_admin_image
build_admin_image:
make build_image SUB_MODULE=admin
.PHONY: build_interface_image
build_interface_image:
make build_image SUB_MODULE=interface
.PHONY: build_job_image
build_job_image:
make build_image SUB_MODULE=job
.PHONY: build_task_image
build_task_image:
make build_image SUB_MODULE=task
.PHONY: build_image
build_image:
docker build --build-arg SUB_MODULE=$(SUB_MODULE) -t xxx-$(SUB_MODULE):$(VERSION) .
#################################### 推镜像到私仓 ####################################
.PHONY: push_all_image
build_all_image: push_admin_image push_interface_image push_job_image push_task_image
.PHONY: push_admin_image
push_admin_image:
make push_image SUB_MODULE=admin
.PHONY: push_interface_image
push_interface_image:
make push_image SUB_MODULE=interface
.PHONY: push_job_image
push_job_image:
make push_image SUB_MODULE=job
.PHONY: push_task_image
push_task_image:
make push_image SUB_MODULE=task
.PHONY: push_image
push_image:
docker login "${DOCKER_REGISTRY_SERVER}" --username "${DOCKER_REGISTRY_USER}" --password "${DOCKER_REGISTRY_PASSWORD}"
docker tag "xxx-$(SUB_MODULE):$(VERSION)" "${DOCKER_REGISTRY_ADDR}/${IMAGE_GROUP}/xxx-$(SUB_MODULE):$(VERSION)"
docker push "${DOCKER_REGISTRY_ADDR}/${IMAGE_GROUP}/xxx-$(SUB_MODULE):$(VERSION)"
docker rmi -f "${DOCKER_REGISTRY_ADDR}/${IMAGE_GROUP}/xxx-$(SUB_MODULE):$(VERSION)"
docker tag "xxx-$(SUB_MODULE):$(VERSION)" "${DOCKER_REGISTRY_ADDR}/${IMAGE_GROUP}/xxx-$(SUB_MODULE):latest"
docker push "${DOCKER_REGISTRY_ADDR}/${IMAGE_GROUP}/xxx-$(SUB_MODULE):latest"
docker rmi -f "${DOCKER_REGISTRY_ADDR}/${IMAGE_GROUP}/xxx-$(SUB_MODULE):latest"
docker rmi -f "xxx-$(SUB_MODULE):$(VERSION)"
#################################### 部署到k8s ####################################
.PHONY: deploy_all_to_test_k8s
deploy_all_to_test_k8s: deploy_admin_to_test_k8s deploy_interface_to_test_k8s deploy_job_to_test_k8s deploy_task_to_test_k8s
.PHONY: deploy_admin_to_test_k8s
deploy_admin_to_test_k8s:
make deploy_to_test_k8s SUB_MODULE=admin
.PHONY: deploy_interface_to_test_k8s
deploy_interface_to_test_k8s:
make deploy_to_test_k8s SUB_MODULE=interface
.PHONY: deploy_job_to_test_k8s
deploy_job_to_test_k8s:
make deploy_to_test_k8s SUB_MODULE=job
.PHONY: deploy_task_to_test_k8s
deploy_task_to_test_k8s:
make deploy_to_test_k8s SUB_MODULE=task
.PHONY: deploy_to_test_k8s
deploy_to_test_k8s:
echo ${K8S_CONFIG_192} | base64 -id > /.kube/config
sed -i "s/IMAGE_VERSION/$(VERSION)/g" deploy/$(SUB_MODULE)/test/*.yaml
sed -i "s/NAME_SPACE/${NAME_SPACE}/g" deploy/$(SUB_MODULE)/test/*.yaml
sed -i "s/DOCKER_REGISTRY_ADDR/${DOCKER_REGISTRY_ADDR}/g" deploy/$(SUB_MODULE)/test/*.yaml
sed -i "s/IMAGE_GROUP/${IMAGE_GROUP}/g" deploy/$(SUB_MODULE)/test/*.yaml
kubectl apply -f deploy/$(SUB_MODULE)/test
VERSION.PHONYDOCKER_REGISTRY_SERVER