Github Actions 还能做这些事

前言
最近公司内部项目的发布流程接入了 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时触发,更多事件定义可以参考官方文档:
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 还能做这些事的更多相关文章
- Redis还可以做哪些事?
在上一篇文章中,讲到了redis五大基本数据类型的使用场景,除了string,hash,list,set,zset之外,redis还提供了一些其他的数据结构(当然,严格意义上也不算数据结构),一起来看 ...
- Git 还没push 前可以做的事(转)
Git 版本控制系統(3) 還沒 push 前可以做的事 转载:http://ihower.tw/blog/archives/2622 這一集要講的是:還沒 push 前可以做的壞事,也就是 re ...
- Hexo+GitHub Actions 完美打造个人博客
Hexo简介 Hexo是一款基于Node.js的静态博客框架,依赖少易于安装使用,可以方便的生成静态网页托管在GitHub和Coding上,是搭建博客的首选框架.大家可以进入hexo官网进行详细查看, ...
- 使用.NET 6开发TodoList应用(31)——实现基于Github Actions和ACI的CI/CD
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求和目标 在这个系列的最后一节中,我们将使用GitHub Actions将TodoList应用部署到Azure Container ...
- 开发完iOS应用,接下去你该做的事
iOS专项总结 关于 analyze Clang 静态分析器 Slender Faux Pas Warning Leaks Time Profiler 加载时间 iOS App启动过程 帧率等 如何优 ...
- 开发完 iOS 应用,接下去你该做的事
iOS专项总结 一个应用经过多次迭代后告一段落,接下去我们在技术上还可以做些什么呢?答案是提高代码的整体质量.关于这方面,除了我们常喊的 重构,测试也非常重要. 博主近期给我们的 iOS客户端代码来了 ...
- Github原生CI/CD,初尝Github Actions
Github 原生 CI/CD,初尝 Github Actions Intro Github 目前已经推出了自己的 CICD 服务 -- Github Actions,而且比微软的 Azure Dev ...
- 利用 Github Actions 自动更新 docfx 文档
利用 Github Actions 自动更新 docfx 文档 Intro docfx 是微软出品一个 .NET API 文档框架,有一个理念是代码即文档,会根据项目代码自动生成 API 文档,即使没 ...
- Github Packages和Github Actions实践之CI/CD
概述 Github在被微软收购后,不忘初心,且更大力度的造福开发者们,推出了免费私有仓库等大更新.近期又开放了packages和actions两个大招,经笔者试用后感觉这两个功能配合起来简直无敌. G ...
随机推荐
- 手把手搭建一套基于 Sentry 的异常监控系统
手把手搭建一套基于 Sentry 的异常监控系统 Sentry 开源版 DevOps refs https://github.com/getsentry/sentry sentry-anomaly-m ...
- React Refs All In One
React Refs All In One https://reactjs.org/docs/react-api.html#refs Ref https://reactjs.org/docs/refs ...
- 同城速递 & 同城跑腿 & 竞品分析
同城速递 & 同城跑腿 & 竞品分析 toC / toB 闪送 https://www.ishansong.com/ https://www.tianyancha.com/compan ...
- Chrome 80 & SameSite & cookie
Chrome 80 & SameSite & cookie chrome://settings/help https://developers.google.com/web/updat ...
- 关于TCP的Total Length
TCP/IP传输层 文档 随便找了个发送的TCP: 70 89 cc ee 84 2c 3c 2c 30 a6 a2 d0 08 00 45 00 00 4c c7 a8 40 00 80 06 00 ...
- 阿里云linux安装nginx,亲测有效
系统平台:CentOS release 6.6 (Final) 64位. 一.安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtoo ...
- oracle 查锁
reference:https://www.cnblogs.com/XQiu/p/5212787.html--以下几个为相关表SELECT * FROM v$lock;SELECT * FROM v$ ...
- 用 Hugo 快速搭建博客
用 Hugo 搭建博客 Hugo 是一个用 Go 编写的静态站点生成器,生成速度很快 下面是具体操作: 1.安装 Hugo Windows 用户 使用 Chocolatey 或者 Scoop 快速安装 ...
- 面试必备——Java多线程与并发(一)
1.进程和线程的 (1)由来 1)串行 最初的计算机只能接受一些特定的指令,用户输入一个指令,计算机就做出一个操作.当用户在思考或者输入时,计算机就在等待.显然这样效率低下,在很多时候,计算机都处在等 ...
- Python插入排序
升序 import random l = [] for i in range(8): l.append(random.randint(0,9)) print(l) for cur in range(1 ...