前言

最近公司内部项目的发布流程接入了 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

Github Actions 还能做这些事的更多相关文章

  1. Redis还可以做哪些事?

    在上一篇文章中,讲到了redis五大基本数据类型的使用场景,除了string,hash,list,set,zset之外,redis还提供了一些其他的数据结构(当然,严格意义上也不算数据结构),一起来看 ...

  2. Git 还没push 前可以做的事(转)

    Git 版本控制系統(3) 還沒 push 前可以做的事 转载:http://ihower.tw/blog/archives/2622   這一集要講的是:還沒 push 前可以做的壞事,也就是 re ...

  3. Hexo+GitHub Actions 完美打造个人博客

    Hexo简介 Hexo是一款基于Node.js的静态博客框架,依赖少易于安装使用,可以方便的生成静态网页托管在GitHub和Coding上,是搭建博客的首选框架.大家可以进入hexo官网进行详细查看, ...

  4. 使用.NET 6开发TodoList应用(31)——实现基于Github Actions和ACI的CI/CD

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求和目标 在这个系列的最后一节中,我们将使用GitHub Actions将TodoList应用部署到Azure Container ...

  5. 开发完iOS应用,接下去你该做的事

    iOS专项总结 关于 analyze Clang 静态分析器 Slender Faux Pas Warning Leaks Time Profiler 加载时间 iOS App启动过程 帧率等 如何优 ...

  6. 开发完 iOS 应用,接下去你该做的事

    iOS专项总结 一个应用经过多次迭代后告一段落,接下去我们在技术上还可以做些什么呢?答案是提高代码的整体质量.关于这方面,除了我们常喊的 重构,测试也非常重要. 博主近期给我们的 iOS客户端代码来了 ...

  7. Github原生CI/CD,初尝Github Actions

    Github 原生 CI/CD,初尝 Github Actions Intro Github 目前已经推出了自己的 CICD 服务 -- Github Actions,而且比微软的 Azure Dev ...

  8. 利用 Github Actions 自动更新 docfx 文档

    利用 Github Actions 自动更新 docfx 文档 Intro docfx 是微软出品一个 .NET API 文档框架,有一个理念是代码即文档,会根据项目代码自动生成 API 文档,即使没 ...

  9. Github Packages和Github Actions实践之CI/CD

    概述 Github在被微软收购后,不忘初心,且更大力度的造福开发者们,推出了免费私有仓库等大更新.近期又开放了packages和actions两个大招,经笔者试用后感觉这两个功能配合起来简直无敌. G ...

随机推荐

  1. Google PageSpeed Insights : 网站性能优化检测工具

    1 1 https://developers.google.com/speed/pagespeed/insights/ PageSpeed Insights 使您的网页在所有设备上都能快速加载. 分析 ...

  2. 使用 js 实现一个简易版的模版引擎

    使用 js 实现一个简易版的模版引擎 regex (function test() { this.str = str; })( window.Test = ...; format() { let ar ...

  3. React.createClass vs. ES6 Class Components

    1 1 1 https://www.fullstackreact.com/articles/react-create-class-vs-es6-class-components/ React.crea ...

  4. OLAP

    OLAP Online Analytical Processing https://en.wikipedia.org/wiki/Online_analytical_processing 在线分析处理 ...

  5. npm install 原理

    npm install 原理 https://docs.npmjs.com/about-npm/ npm consists of three distinct components: the webs ...

  6. js currying function All In One

    js currying function All In One js 实现 (5).add(3).minus(2) 功能 例: 5 + 3 - 2,结果为 6 https://stackoverflo ...

  7. js 如何取消promise

    1: 使用reject function hello() { let _res, _rej: any; const promise = new Promise((res, rej) => { _ ...

  8. 人物传记Kyle Tedford:数据环境生变,银行大数据风控怎么办?

    数据是金融业务的基石,监管集中清查大数据公司,很多东西在发生根本性改变,资金方做"甩手掌柜"的好日子不会重现.那些缺乏自主风控能力的金融机构,在未来的行业竞争中,恐无以立足了.近日 ...

  9. 09、IO流—File类与IO流

    目录 一.File类 基本认识 实用方法 获取功能 重命名功能(包含剪切) 判断功能 创建.删除文件 实际小案例 二.IO流 1.认识IO流 2.IO流基类介绍 字节流基类介绍 字符流基类介绍 三.节 ...

  10. Java自学第2期——注释、数据类型、运算符、方法

    2.1.注释 注释用于说明某段代码的作用,某个类的用途,某个方法的功能,参数和返回值数据类型的意义等等: 注释非常非常非常重要,回顾代码时通过注释找回思路:团队沟通需要,让别人读懂你的代码,增加效率: ...