我们首先创建一个文件.github/workflows/go.yml,内容如下所示:
name: Release
on:
create:
tags:
- v*
jobs:
release:
name: Release on GitHub
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v1
- name: Get service dependencies
working-directory: ./
run: |
go get -v -u -d ./...
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
- name: Validates GO releaser config
uses: docker://goreleaser/goreleaser:latest
with:
args: check
- name: Create release on GitHub
uses: docker://goreleaser/goreleaser:latest
with:
args: release
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
注意:此版本为 最终版本。Get service dependencies 步骤是后续添加了,初始版本 没有这个步骤,具体原因可见下面的问题描述。
这个 workflow 中我们定义了只有在创建新的 tag 时(tag 首字母为 v
)才触发任务,然后只定义了一个 release 的 Job。
上面我们定义的 Job 任务中先获取项目代码,然后使用 go get
命令获取 Go 工程的依赖包,然后使用 GoReleaser 官方 Docker 镜像来构建任务。当使用 docker 容器的时候,可以定义容器的args和entrypoint,我们这里分别使用args定义了check和release两个参数。
另外还指定了 GoReleaser
所需的 GITHUB_TOKEN
这个环境变量,这样可以在 GitHub 上来发布我们的应用版本,不过需要注意的是,secrets.GITHUB_TOKEN
这个变量的值是由 Actions 平台自动注入的,不需要我们单独手动去设置里添加了,很方便。
然后我们创建一个新的 tag
并推送到远程仓库中去:
$ git tag v0.0.1
$ git push origin --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 536 bytes | 536.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/ThreeTenth/GitHub-Discussions-to-Blog.git
* [new tag] v0.0.1 -> v0.0.1
如果一切正常就会立刻触发任务构建,Job 任务构建完成后会在 GitHub 上面创建一个新的版本,其中包含由 GoReleaser
工具自动生成的应用包和 Changelog
。
以上,就是打包并发布 Goalng 程序的全过程,可以在 这里 查看工作过程,以下讲一下在这个过程中遇到的麻烦。
问题
GitHub Action 有一个很好的功能,就是他会保存历史执行记录,你可以在 Actions 这页看到这个项目过去提交失败的记录。
这是 第一次 提交失败的记录,当时错误的创建了(意外)一个 branch
分支 v0.0.1
,导致这个 workflow 被触发了,我们可以看到他的错误提示:
⨯ release failed after 0s error=git doesn't contain any tags. Either add a tag or use --snapshot
可以在 这里 查看当时的 workflow 代码。
这是因为当前仓库没有任何 tag 可用,所以构建失败了。这是第一次错误,于是删除 branch,创建 tag,就有了 第二次 错误。
⨯ release failed after 0s error=failed to build for linux_arm64: exit status 1: go: github.com/excing/goflag@v1.0.1: missing go.sum entry; to add it:
go mod download github.com/excing/goflag
go: github.com/excing/goflag@v1.0.1: missing go.sum entry; to add it:
go mod download github.com/excing/goflag
提示编译失败,丢失 go.sum
,需要添加一个依赖包 goflag
。
在项目中,go.sum
作为自动生成的文件,我经常把他写入 .gitignore
文件里,所以远程仓库没有这个文件,而我又不想上传这个文件,于是在 wordflow 里添加了以下步骤代码:
解决方法:
- name: Get service dependencies
working-directory: ./
run: |
go get -v -u -d ./...
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
这里要提示一下,workflow 的初始版本里,是没有这个步骤的,初始版本代码:go.yml。
Get service dependencies
步骤的作用前面已经讲过了,是获取 Golang 工程的依赖包,所以我添加了这段代码。为了测试这个代码是否有效,于是有了 第三次 错误。
为了节省时间,我修改了 workflow 的触发条件,使之在 main
分支发生变化时也能被触发,这样我就不用创建分节去测试代码了,可以在 这里 看到原始文件:
⨯ release failed after 0s error=git tag v0.0.1 was not made against commit 7acedebd53edea27e8dcb958309f595f2ad5cd0e
提示 commit 7acede
没有指向 v0.0.1
仓库,这是因为 GoReleaser
仅会在 tags
发生改变时执行打包操作,所以当我们的提交发生了 main
分支上时,就会出现以上错误。
解决办法:
删除推送到 main
分支的触发条件,重新创建分支即可,便是最开始的那个 workflow 和操作过程。
以上就是这次自动化构建过程中踩到的几个坑,如果你也遇到过类似或其他的问题,欢迎在下面评论,谢谢。