乐趣区

关于golang:利用-GitHub-Action-自动发布-Docker

前言

最近公司外部我的项目的公布流程接入了 GitHub Actions,整个体验过程还是比拟美妙的;本文次要目标是对于没有还接触过 GitHub Actions 的老手,可能利用它疾速构建自动测试及打包推送 Docker 镜像等自动化流程。

创立我的项目

本文次要以 Go 语言为例,当然其余语言也是相似的,与语言自身关系不大。

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

var version = "0.0.1"

func GetVersion() string {return version}

func main() {fmt.Println(GetVersion())
}

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

func TestGetVersion1(t *testing.T) {tests := []struct {
        name string
        want string
    }{{name: "test1", want: "0.0.1"},
    }
    for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {if got := GetVersion(); got != tt.want {t.Errorf("GetVersion() = %v, want %v", got, tt.want)
            }
        })
    }
}

咱们能够执行 go test 运行该单元测试。

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

自动测试

当然以上流程齐全能够利用 Actions 自动化搞定。

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

name: go-docker
on: push
jobs:
  test:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags')
    steps:
      - uses: actions/checkout@v2
      - name: Run Unit Tests
        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

FROM golang:1.15 AS builder
ARG VERSION=0.0.10
WORKDIR /go/src/app
COPY main.go .
RUN go build -o main -ldflags="-X'main.version=${VERSION}'" main.go

FROM debian:stable-slim
COPY --from=builder /go/src/app/main /go/bin/main
ENV PATH="/go/bin:${PATH}"
CMD ["main"]

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

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

docker build -t go-docker:last .
docker run --rm go-docker:0.0.10
0.0.10

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

deploy:
    runs-on: ubuntu-latest
    needs: test
    if: startsWith(github.ref, 'refs/tags')
    steps:
      - name: Extract Version
        id: version_step
        run: |
          echo "##[set-output name=version;]VERSION=${GITHUB_REF#$"refs/tags/v"}"
          echo "##[set-output name=version_tag;]$GITHUB_REPOSITORY:${GITHUB_REF#$"refs/tags/v"}"
          echo "##[set-output name=latest_tag;]$GITHUB_REPOSITORY:latest"

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{secrets.DOCKER_USER_NAME}}
          password: ${{secrets.DOCKER_ACCESS_TOKEN}}

      - name: PrepareReg Names
        id: read-docker-image-identifiers
        run: |
          echo VERSION_TAG=$(echo ${{ steps.version_step.outputs.version_tag}} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
          echo LASTEST_TAG=$(echo ${{ steps.version_step.outputs.latest_tag}} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV

      - name: Build and push Docker images
        id: docker_build
        uses: docker/build-push-action@v2.3.0
        with:
          push: true
          tags: |
            ${{env.VERSION_TAG}}
            ${{env.LASTEST_TAG}}
          build-args: |
            ${{steps.version_step.outputs.version}}

新增了一个 deploy 的 job。

    needs: test
    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

退出移动版