Github Actions与CI/CD
GitHub Actions是GitHub提供的一种自动化工具,可以帮助您在代码仓库中自动执行任务,如构建、测试和部署。CI/CD(持续集成/持续部署)是一种自动化软件开发实践,可以帮助您更快地交付高质量的软件。在本文中,我们将介绍如何使用GitHub Actions为Go项目实现简易CI/CD。
实现目标
将Actions主要分为三个部分
- 在代码提交后进行编译检查,检查是否存在代码错误。
- 在进行git tag操作后,针对tag进行docker镜像的构建与推送。
- 达到版本号发布时,自动构建多平台可执行二进制文件。
前置准备
为Actions开放仓库权限
在仓库主页,选中Settings→Actions→General→Workflow permissions,将权限设置为Read and write permisssions。
获取Docker相关信息
将信息储存在Actions secrets and variables中,分别设置Docker用户名,token与仓库名称。
获取 Docker token 的步骤如下:
- 登录到 Docker Hub 帐户。
- 点击右上角的头像,选择“Account Settings”。
- 在左侧菜单中选择“Security”。
- 滚动到“Access Tokens”部分,然后单击“New Access Token”按钮。
- 输入访问令牌的描述,选择令牌的有效期,并选择要授予令牌的权限。
- 单击“Create”按钮以生成令牌。
- 复制生成的令牌并保存在安全的地方。
仓库名称则为 用户名/仓库名
进行secrets的设置
在Settings→Secrets and variables中点击New repository secret进行新增。
- DOCKER_USERNAME
- DOCKER_ACCESS_TOKEN
- DOCKER_IMAGE_NAME
设置Actions
点击仓库内Actions模块,点击New workflow进行工作流的新增。
代码编译检查工作流
将会在检测到push或pull_request后进行代码编译检查。
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
name: 代码编译测试
on:
push:
branches: ['main']
pull_request:
branches: ['main']
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
- name: Build
run: |
go build -v ./...
pwd
编译构建并推送Docker镜像
此工作流只会在仓库新增tag时进行。
git tag v0.0.1
git push --tags
工作流分为以下几个步骤
- 获取tag作为版本号
- 根据Dockerfile进行Docker镜像的构建
- 针对构建完成镜像进行tag打版本号
- 将镜像推送至Dockerhub
name: Build and push Docker image
on:
push:
tags:
- 'v*'
env:
IMAGE_NAME: ${{ secrets.DOCKER_IMAGE_NAME }}
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Get version
id: get_version
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
- name: Checkout code
uses: actions/checkout@v3
- name: Login to Dockerhub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
- name: Build Docker image
run: docker build -t $IMAGE_NAME:${{ github.sha }} .
- name: Tag Docker image
run: docker tag $IMAGE_NAME:${{ github.sha }} $IMAGE_NAME:${{ steps.get_version.outputs.VERSION }}
- name: Tag Docker image as latest
run: docker tag $IMAGE_NAME:${{ github.sha }} $IMAGE_NAME:latest
- name: Push Docker image
run: |
docker push $IMAGE_NAME:${{ steps.get_version.outputs.VERSION }}
docker push $IMAGE_NAME:latest
这时我们需要针对项目进行Dockerfile的编写,一下是一个针对Goframe项目的示例。
- 设置golang构建环境,有许多版本可以选择,可以参考https://hub.docker.com/_/golang,这里选择golang:1.20-buster。
- 拷贝代码至构建环境,进行构建,在这里将编译完成后将二进制文件命名为service,构建命令也可以指定系统与架构,在命令中加上GOOS=linux GOARCH=amd64。
- 设置镜像环境,设置工作路径,为二进制文件添加权限并增加端口绑定。
- 设置入口命令。
至此一份Dockerfile就编写完成了。
FROM golang:1.20-buster AS builder
ARG VERSION=dev
WORKDIR /go/src/app
COPY . .
RUN CGO_ENABLED=0 go build -o service -ldflags=-X=main.version=${VERSION} main.go
FROM loads/alpine:3.8
LABEL maintainer="Hamster <liaolaixin@gmail.com>"
###############################################################################
# INSTALLATION
###############################################################################
# 设置固定的项目路径
ENV WORKDIR /app/main
COPY --from=builder /go/src/app/service $WORKDIR/service
# 添加应用可执行文件,并设置执行权限
RUN chmod +x $WORKDIR/service
# 增加端口绑定
EXPOSE 10399
###############################################################################
# START
###############################################################################
WORKDIR $WORKDIR
CMD ["./service"]
新增后通过git tag测试工作流,检查Dockerhub是否有最新构建镜像。
编译多平台二进制文件
设置为只在新增release时进行构建,可以设置需要的系统架构或排除的,十分简单易用。
name: build-go-binary
on:
release:
types: [created] # 表示在创建新的 Release 时触发
jobs:
build-go-binary:
runs-on: ubuntu-latest
strategy:
matrix:
goos: [linux, windows, darwin] # 需要打包的系统
goarch: [amd64, arm64] # 需要打包的架构
exclude: # 排除某些平台和架构
- goarch: arm64
goos: windows
steps:
- uses: actions/checkout@v3
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # 一个默认的变量,用来实现往 Release 中添加文件
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
goversion: 1.18 # 可以指定编译使用的 Golang 版本
binary_name: 'push_go' # 可以指定二进制文件的名称
pre_command: export CGO_ENABLED=0 && export GODEBUG=http2client=0
overwrite: true
在仓库中新增release并测试,等待编译完成后即可在release中查看不同系统架构的二进制文件。
消息通知
可针对Actions的进度进行消息通知,在Settings→Webhooks设置推送目标URL,搭配自建的消息推送即可实现在手机上获取Actions进度流程。