Github Actions 还能做这些事

开发 后端
最近公司内部项目的发布流程接入了 GitHub Actions,整个体验过程还是比较美好的;本文主要目的是对于没有还接触过 GitHub Actions的新手,能够利用它快速构建自动测试及打包推送 Docker 镜像等自动化流程。

[[389725]]

本文转载自微信公众号「crossoverJie」,作者crossoverJie。转载本文请联系crossoverJie公众号。

前言

最近公司内部项目的发布流程接入了 GitHub Actions,整个体验过程还是比较美好的;本文主要目的是对于没有还接触过 GitHub Actions的新手,能够利用它快速构建自动测试及打包推送 Docker 镜像等自动化流程。

创建项目

本文主要以 Go 语言为例,当然其他语言也是类似的,与语言本身关系不大。

这里我们首先在 GitHub 上创建一个项目,编写了几段简单的代码 main.go:

  1. var version = "0.0.1" 
  2.  
  3. func GetVersion() string { 
  4.  return version 
  5.  
  6. func main() { 
  7.  fmt.Println(GetVersion()) 

内容非常简单,只是打印了了版本号;同时配套了一个单元测试 main_test.go:

  1. func TestGetVersion1(t *testing.T) { 
  2.  tests := []struct { 
  3.   name string 
  4.   want string 
  5.  }{ 
  6.   {name"test1", want: "0.0.1"}, 
  7.  } 
  8.  for _, tt := range tests { 
  9.   t.Run(tt.name, func(t *testing.T) { 
  10.    if got := GetVersion(); got != tt.want { 
  11.     t.Errorf("GetVersion() = %v, want %v", got, tt.want) 
  12.    } 
  13.   }) 
  14.  } 

我们可以执行 go test 运行该单元测试。

  1. $ go test                           
  2. PASS 
  3. ok      github.com/crossoverJie/go-docker       1.729s 

自动测试

当然以上流程完全可以利用 Actions 自动化搞定。

首选我们需要在项目根路径创建一个 .github/workflows/*.yml 的配置文件,新增如下内容:

  1. name: go-docker 
  2. on: push 
  3. jobs: 
  4.   test: 
  5.     runs-on: ubuntu-latest 
  6.     if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags'
  7.     steps: 
  8.       - uses: actions/checkout@v2 
  9.       - name: Run Unit Tests 
  10.         run: go test 

简单解释下:

  • name 不必多说,是为当前工作流创建一个名词。
  • on 指在什么事件下触发,这里指代码发生 push 时触发,更多事件定义可以参考官方文档:

Events that trigger workflows

  • jobs 则是定义任务,这里只有一个名为 test 的任务。

该任务是运行在 ubuntu-latest 的环境下,只有在 main 分支有推送或是有 tag 推送时运行。

运行时会使用 actions/checkout@v2 这个由他人封装好的 Action,当然这里使用的是由官方提供的拉取代码 Action。

  • 基于这个逻辑,我们可以灵活的分享和使用他人的 Action 来简化流程,这点也是 GitHub Action扩展性非常强的地方。

最后的 run 则是运行自己命令,这里自然就是触发单元测试了。

  • 如果是 Java 便可改为 mvn test.

之后一旦我们在 main 分支上推送代码,或者有其他分支的代码合并过来时都会自动运行单元测试,非常方便。

 

与我们本地运行效果一致。

自动发布

接下来考虑自动打包 Docker 镜像,同时上传到 Docker Hub;为此首先创建 Dockerfile :

  1. FROM golang:1.15 AS builder 
  2. ARG VERSION=0.0.10 
  3. WORKDIR /go/src/app 
  4. COPY main.go . 
  5. RUN go build -o main -ldflags="-X 'main.version=${VERSION}'" main.go 
  6.  
  7. FROM debian:stable-slim 
  8. COPY --from=builder /go/src/app/main /go/bin/main 
  9. ENV PATH="/go/bin:${PATH}" 
  10. CMD ["main"

这里利用 ldflags 可在编译期间将一些参数传递进打包程序中,比如打包时间、go 版本、git 版本等。

这里只是将 VERSION 传入了 main.version 变量中,这样在运行时就便能取到了。

  1. docker build -t go-docker:last . 
  2. docker run --rm go-docker:0.0.10 
  3. 0.0.10 

接着继续编写 docker.yml 新增自动打包 Docker 以及推送到 docker hub 中。

  1. deploy: 
  2.     runs-on: ubuntu-latest 
  3.     needs: test 
  4.     if: startsWith(github.ref, 'refs/tags'
  5.     steps: 
  6.       - name: Extract Version 
  7.         id: version_step 
  8.         run: | 
  9.           echo "##[set-output name=version;]VERSION=${GITHUB_REF#$"refs/tags/v"}" 
  10.           echo "##[set-output name=version_tag;]$GITHUB_REPOSITORY:${GITHUB_REF#$"refs/tags/v"}" 
  11.           echo "##[set-output name=latest_tag;]$GITHUB_REPOSITORY:latest" 
  12.  
  13.       - nameSet up QEMU 
  14.         uses: docker/setup-qemu-action@v1 
  15.  
  16.       - nameSet up Docker Buildx 
  17.         uses: docker/setup-buildx-action@v1 
  18.  
  19.       - name: Login to DockerHub 
  20.         uses: docker/login-action@v1 
  21.         with
  22.           username: ${{ secrets.DOCKER_USER_NAME }} 
  23.           password: ${{ secrets.DOCKER_ACCESS_TOKEN }} 
  24.  
  25.       - name: PrepareReg Names 
  26.         id: read-docker-image-identifiers 
  27.         run: | 
  28.           echo VERSION_TAG=$(echo ${{ steps.version_step.outputs.version_tag }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV 
  29.           echo LASTEST_TAG=$(echo ${{ steps.version_step.outputs.latest_tag  }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV 
  30.  
  31.       - name: Build and push Docker images 
  32.         id: docker_build 
  33.         uses: docker/build-push-action@v2.3.0 
  34.         with
  35.           push: true 
  36.           tags: | 
  37.             ${{env.VERSION_TAG}} 
  38.             ${{env.LASTEST_TAG}} 
  39.           build-args: | 
  40.             ${{steps.version_step.outputs.version}} 

新增了一个 deploy 的 job。

  1. needs: test 
  2.  if: startsWith(github.ref, 'refs/tags'

运行的条件是上一步的单测流程跑通,同时有新的 tag 生成时才会触发后续的 steps。

name: Login to DockerHub

在这一步中我们需要登录到 DockerHub,所以首先需要在 GitHub 项目中配置 hub 的 user_name 以及 access_token.

 

配置好后便能在 action 中使用该变量了。

 

这里使用的是由 docker 官方提供的登录 action(docker/login-action)。

有一点要非常注意,我们需要将镜像名称改为小写,不然会上传失败,比如我的名称中 J 字母是大写的,直接上传时就会报错。

 

所以在上传之前先要执行该步骤转换为小写。

 

最后再用这两个变量上传到 Docker Hub。

 

今后只要我们打上 tag 时,Action 就会自动执行单测、构建、上传的流程。

总结

GitHub Actions 非常灵活,你所需要的大部分功能都能在 marketplace找到现成的直接使用,

比如可以利用 ssh 登录自己的服务器,执行一些命令或脚本,这样想象空间就很大了。

使用起来就像是搭积木一样,可以很灵活的完成自己的需求。

参考链接:

How to Build a CI/CD Pipeline with Go, GitHub Actions and Docker

责任编辑:武晓燕 来源: crossoverJie
相关推荐

2022-12-21 08:20:01

2020-12-04 10:42:54

GithubSSDNode.js

2021-05-13 21:21:50

React应用GitHub

2021-10-15 10:39:43

RabbitMQ队列延迟

2021-01-18 18:30:49

服务器开发工具

2021-10-03 14:47:26

Fedora CoreGitHub Acti运行器

2024-02-20 08:08:43

2021-01-19 05:26:22

Github ActiJenkinsDevOps

2015-11-23 09:50:17

大数据

2021-04-20 09:36:49

黑客网络安全网络攻击

2019-11-26 08:00:00

GitHubGitHub ActiAzure

2024-01-24 18:50:21

WebFTP服务器

2022-05-27 08:55:15

工具自动化软件

2022-11-15 17:07:40

开发自动化前端

2019-05-25 14:58:06

车载微信微信语音交互

2022-08-09 08:00:00

服务网格云原生工具

2017-03-07 11:45:57

DevOps容器

2021-01-15 08:52:09

GitHub GitHubActio博文发布

2020-07-06 14:39:18

知识图谱思维

2015-05-20 17:09:47

云存储数据云端化
点赞
收藏

51CTO技术栈公众号