介绍

GoReleaser是Go项目的发布自动化工具,目标是简化构建,release和发布步骤,同时为所有步骤提供适当的自定义选项.

GoReleaser是为CI工具而构建的;你只需要在您的构建脚本中下载并执行它。您可以通过定制一个关于你的发布过程的.goreleaser.yml文件.

这个想法始于一个简单的shell脚本,但它很快变得更加复杂,我也希望通过Homebrew taps发布二进制文件,这会使脚本变得更加hacky,所以我放弃了它,并在Go中重写了整个内容.

安装Goreleaser

有三种方法可以安装GoReleaser:

使用homebrew

brew install goreleaser/tap/goreleaser

使用snapcraft

snap install goreleaser

使用Scoop

scoop bucket add goreleaser https://github.com/goreleaser/scoop-bucket.git
scoop install goreleaser

查看tap源,了解更多细节.

使用Docker

您可以使用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 get

注意:此方法需要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

Semantic 版本化

GoReleaser强制为,执行Semantic版本控制,并在非兼容标签上出错.

你的标签应该是有效的语义版本。如果不是,GoReleaser将会出错.

v前缀不是强制性的.你可以查看一下模板文档,以了解如何在名称模板中,使用tag或Semantic版本的方方面面.

CGO

不幸的是,GoReleaser不支持CGO.

您可以在这个Issue中查看有关此内容的讨论.

您可以在上面,找到有关解决方法的问题注释.

变量

GitHub令牌

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企业版

要使用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.

dist文件夹

默认情况下,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通过提供多种自定义的.goreleaser.yml文件.

您可以通过运行goreleaser init生成它,或者从头开始。默认值都是合理的,适合大多数项目.

持续集成

GoReleaser的第一次commit的构建思想,是作为CI集成的一部分运行.

让我们看看如何让它在流行的CI软件上运行.

Travis 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

这是如何与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

默认情况下,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

Google CloudBuild

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

创建两个构建触发器:

  • 常规CI的”推送到任何分支”触发器(不调用goreleaser)
  • 一个”push to tag”触发器,它调用goreleaser

推送到任何分支触发器可以使用Dockerfilecloudbuild.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=

Semaphore

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"

查看管理密钥的更详细文档.

赞助商

贵公司是否使用goreleaser?帮助保持项目无错误,和功能丰富 !赞助该项目吧.

支持者

热爱我们的工作和社区?成为支持者.

教程

社区制作的教程.

想在这里添加你的教程吗? 去做吧! 编辑这个文件并打开拉动请求! 谢谢 !

贡献

此页面最终,将为那些想要为项目做出贡献的人提供信息.

还请看看我们的存储库根目录下的CONTRIBUTING.md文件.

关联

该项目遵守贡献者公约行为守则。通过参与,您应该支持此代码.