GoReleaser是Go项目的发布自动化工具,目标是简化构建,release和发布步骤,同时为所有步骤提供适当的自定义选项.
GoReleaser是为CI工具而构建的;你只需要在您的构建脚本中下载并执行它。您可以通过定制一个关于你的发布过程的.goreleaser.yml
文件.
这个想法始于一个简单的shell脚本,但它很快变得更加复杂,我也希望通过Homebrew taps
发布二进制文件,这会使脚本变得更加hacky,所以我放弃了它,并在Go中重写了整个内容.
有三种方法可以安装GoReleaser:
brew install goreleaser/tap/goreleaser
snap install goreleaser
scoop bucket add goreleaser https://github.com/goreleaser/scoop-bucket.git
scoop install goreleaser
查看tap源,了解更多细节.
您可以使用Docker来执行简单的发布.目前,提供的docker镜像不支持snapcraft.
$ docker run --rm --privileged \
-v $PWD:/go/src/github.com/user/repo \
-v /var/run/docker.sock:/var/run/docker.sock \
-w /go/src/github.com/user/repo \
-e GITHUB_TOKEN \
-e DOCKER_USERNAME \
-e DOCKER_PASSWORD \
goreleaser/goreleaser release
请注意,镜像几乎总是最后一个稳定的Go版本.
如果您需要更多东西,我们鼓励您拥有自己的镜像。你可以使用GoReleaser自身的Dockerfile作为示例.
从发布页面下载您喜欢的味道,并手动安装.
注意:此方法需要Go 1.10+.
$ go get -d github.com/goreleaser/goreleaser
$ cd $GOPATH/src/github.com/goreleaser/goreleaser
$ dep ensure -vendor-only
$ make setup build
建议也运行下dep ensure
,确保依赖项的版本正确.
在这个例子中,我们将构建,存档和发布Go项目.
创建一个GitHub存储库,并添加一个主包:
// main.go
package main
func main() {
println("Ba dum, tss!")
}
运行goreleaser init
创建一个例子,.goreleaser.yaml
文件:
$ goreleaser init
• Generating .goreleaser.yml file
• config created; please edit accordingly to your needs file=.goreleaser.yml
生成的配置文件如下所示:
# This is an example goreleaser.yaml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
builds:
- env:
- CGO_ENABLED=0
archive:
replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
GoReleaser将为您的应用程序构建Windows,Linux和macOS
的二进制文件,包括amd64和i386
系结构.您可以通过更改定义的builds
部分。查看其文档获得更多信息.
构建二进制文件后,GoReleaser将为每个OS/Arch组合
创建一个单独存档文件。您可以自定义archive
部分的多项内容。查看其文档获得更多信息.
你需要导出一个GITHUB_TOKEN
环境变量,它应该包含一个有效的GitHubrepo
的tag范围。它用于将版本部署到您的GitHub存储库.您可以在这里创建令牌.
$ export GITHUB_TOKEN=`YOUR_TOKEN`
GoReleaser会使用您的存储库最新的Git tag。下面创建一个tag,并将其推送到GitHub:
$ git tag -a v0.1.0 -m "First release"
$ git push origin v0.1.0
注意:查看您的tag是否符合语义版本控制.
如果您还不想创建tag,还可以使用,基于最新提交的版本的--snapshot
参数.
现在您可以在存储库的根目录下,运行GoReleaser:
$ goreleaser
就这样! 查看您的GitHub项目的发布页面。该版本应如下所示:
如果你想在发布”真实”版本之前,测试所有内容,你可以使用--skip-publish
参数,只会构建和打包东西:
$ goreleaser release --skip-publish
您可以查看其他选项:
$ goreleaser --help
和
$ goreleaser release --help
GoReleaser强制为,执行Semantic版本控制,并在非兼容标签上出错.
你的标签应该是有效的语义版本。如果不是,GoReleaser将会出错.
该v
前缀不是强制性的.你可以查看一下模板文档,以了解如何在名称模板中,使用tag或Semantic版本的方方面面.
GoReleaser需要一个GitHub API token ,其具有选择repo
范围,具有部署到GitHub的权限。你可以创建一个点-这里.
此token应添加到环境变量中GITHUB_TOKEN
.以下是Travis CI的使用方法:在存储库设置中,定义环境变量.
或者,您可以在文件中提供GitHub令牌。默认情况下,GoReleaser会查看~/.config/goreleaser/github_token
,您可以在.goreleaser.yml
文件中更改它:
# .goreleaser.yml
env_files:
github_token: ~/.path/to/my/token
要使用GitHub Enterprise,你需要提供其URL搭配.goreleaser.yml
配置文件,给予GoReleaser使用:
# .goreleaser.yml
github_urls:
api: https://git.company.com/api/v3/
upload: https://git.company.com/api/uploads/
download: https://git.company.com/
如果没有设置,则默认为GitHub的公共URL.
重要:小心URL,它们可能会从一个安装更改为另一个安装。如果他们错了,goreleaser会在某些时候失败,所以,在开启Issue之前,确保他们是对的。例如,参见#472.
默认情况下,GoReleaser将在./dist
中创建其二进制存档。如有必须,可以通过在.goreleaser.yml
文件的设置,更改它:
# .goreleaser.yml
dist: another-folder-that-is-not-dist
main.version
默认的GoReleaser设置三个ldflags:
main.version
: 当前的Git标签(v
前缀被剥离)或snapshot的名称,若正在使用--snapshot
参数main.commit
: 当前git commit 的 SHA码main.date
: RFC3339规范日期这样,在你的main.go
文件,就能被使用:
package main
import "fmt"
var (
version = "dev"
commit = "none"
date = "unknown"
)
func main() {
fmt.Printf("%v, commit %v, built at %v", version, commit, date)
}
您可以通过更改build
部分的ldflags
选项,来覆盖它.
GoReleaser的第一次commit的构建思想,是作为CI集成的一部分运行.
让我们看看如何让它在流行的CI软件上运行.
您可能希望将项目设置为新tag,就自动Travis部署, 例如:
# .travis.yml
language: go
addons:
apt:
packages:
# needed for the nfpm pipe:
- rpm
# needed for the snap pipe:
- snapcraft
env:
# needed for the snap pipe:
- PATH=/snap/bin:$PATH
install:
# needed for the snap pipe:
- sudo snap install snapcraft --classic
# needed for the docker pipe
services:
- docker
after_success:
# docker login is required if you want to push docker images.
# DOCKER_PASSWORD should be a secret in your .travis.yml configuration.
- test -n "$TRAVIS_TAG" && docker login -u=myuser -p="$DOCKER_PASSWORD"
# snapcraft login is required if you want to push snapcraft packages to the
# store.
# You'll need to run `snapcraft export-login snap.login` and
# `travis encrypt-file snap.login --add` to add the key to the travis
# environment.
- test -n "$TRAVIS_TAG" && snapcraft login --with snap.login
# calls goreleaser
deploy:
- provider: script
skip_cleanup: true
script: curl -sL https://git.io/goreleaser | bash
on:
tags: true
condition: $TRAVIS_OS_NAME = linux
注意最后一行(condition: $TRAVIS_OS_NAME = linux
): 如果您运行具有多个Go版本和/或多个操作系统的构建矩阵,这一点很重要。如果是这种情况,您将需要确保GoReleaser只运行一次。
这是如何与CircleCI 2.0协作:
# .circleci/config.yml
version: 2
jobs:
release:
docker:
- image: circleci/golang:1.10
steps:
- checkout
- run: curl -sL https://git.io/goreleaser | bash
workflows:
version: 2
release:
jobs:
- release:
filters:
branches:
ignore: /.*/
tags:
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
默认情况下,Drone不会获取标签。plugins/git
与默认值一起使用,在大多数情况下,我们需要覆盖clone
步骤,启用标签,以使goreleaser
工作正常.
在这个例子中,我们每次推送新标签时,都会创建一个新版本.请注意,您需在repo settings中启用tags
和添加github_token
密钥.
pipeline:
clone:
image: plugins/git
tags: true
test:
image: golang:1.10
commands:
- go test ./... -race
release:
image: golang:1.10
secrets: [github_token]
commands:
curl -sL https://git.io/goreleaser | bash
when:
event: tag
CloudBuild使用的克隆与你github repo不同: 似乎你的更改被拉取到了像下面source.developers.google.com/p/YourProjectId/r/github-YourGithubUser-YourGithubRepo
类似的repo,和这就是你正在建设的东西.
这个repo具有糟糕的名称,所以为了防止Goreleaser发布到错误的github repo。请输入你的信息,到.goreleaser.yml
文件的release部分:
release:
github:
owner: YourGithubUser
name: YourGithubRepo
创建两个构建触发器:
推送到任何分支触发器可以使用Dockerfile
或cloudbuild.yaml
,您喜欢就好.
你应该有一个专用的cloudbuild.release.yaml,它只能被”push to tag”触发器使用.
在这个例子中,我们每次推送新标签时,都会创建一个新版本.看看使用加密资源文档,其中有如何加密和base64编码你的github令牌.
构建使用的克隆时没有标签,这就是为什么,我们必须明确运行git tag $TAG_NAME
的原因( 请注意,只有当你的构建由”push to tag”触发时,才设置$TAG_NAME。) 这将允许goreleaser使用该版本创建一个版本,但它并不会构建一个适当只包含自先前标记以来提交的消息的changelog,.
steps:
~ # Setup the workspace so we have a viable place to point GOPATH at.
~ - name: gcr.io/cloud-builders/go
~ env: ['PROJECT_ROOT=github.com/YourGithubUser/YourGithubRepo']
~_ args: ['env']
~ # Create github release.
~ - name: goreleaser/goreleaser
~ entrypoint: /bin/sh
~ dir: gopath/src/github.com
~ env: ['GOPATH=/workspace/gopath']
~ args: ['-c', 'cd YourGithubUser/YourGithubRepo && git tag $TAG_NAME && /goreleaser' ]
~_ secretEnv: ['GITHUB_TOKEN']
secrets:
~ - kmsKeyName: projects/YourProjectId/locations/global/keyRings/YourKeyRing/cryptoKeys/YourKey
~ secretEnv:
~ GITHUB_TOKEN: |
~ ICAgICAgICBDaVFBZUhVdUVoRUtBdmZJSGxVWnJDZ0hOU2NtMG1ES0k4WjF3L04zT3pEazhRbDZr
~ QVVTVVFEM3dVYXU3cVJjK0g3T25UVW82YjJaCiAgICAgICAgREtBMWVNS0hOZzcyOUtmSGoyWk1x
~_ ICAgICAgIEgwYndIaGUxR1E9PQo=
在Sempahore 2.0的每个项目,都在.semaphore/semaphore.yml
指定默认管道的开头.
# .semaphore/semaphore.yml.
version: v1.0
name: Build
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
blocks:
- name: "Test"
task:
prologue:
commands:
# set go version
- sem-version go 1.11
- "export GOPATH=~/go"
- "export PATH=/home/semaphore/go/bin:$PATH"
- checkout
jobs:
- name: "Lint"
commands:
- go get ./...
- go test ./...
# On Semaphore 2.0 deployment and delivery is managed with promotions,
# which may be automatic or manual and optionally depend on conditions.
promotions:
- name: Release
pipeline_file: goreleaser.yml
auto_promote_on:
- result: passed
branch:
- "^refs/tags/v*"
.semaphore/goreleaser.yml
中的管道文件:
version: "v1.0"
name: GoReleaser
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
blocks:
- name: "Release"
task:
secrets:
- name: goreleaser
prologue:
commands:
- sem-version go 1.11
- "export GOPATH=~/go"
- "export PATH=/home/semaphore/go/bin:$PATH"
- checkout
jobs:
- name: goreleaser
commands:
- curl -sL https://git.io/goreleaser | bash
下面的YAML文件,createSecret.yml
创建一个名为goreleaser的密钥项,其包含一个名为GITHUB_TOKEN的环境变量:
apiVersion: v1alpha
kind: Secret
metadata:
name: goreleaser
data:
env_vars:
- name: GITHUB_TOKEN
value: "4afk4388304hfhei34950dg43245"
查看管理密钥的更详细文档.