GoReleaser 是快速、轻松地发布 Go 项目的首选工具,支持与 github actions 集成
介绍
GoReleaser 功能:
- 交叉编译 Go 项目
- 发布 release 到 GitHub、GitLab 和 Gitea
- 支持夜间构建(nightly builds)
- 创建 Docker 镜像和清单
- 创建 Linux 软件包和 Homebrew taps
- 签署制品(Sign artifacts)、校验(checksums)和及容器镜像(container images)
- 在 Twitter、Slack、Discord 等平台上发布新版本信息
- 为二进制文件和容器镜像生成
SBOMs(Software Bill of Materials)
GoReleaser 有两个版本:
- OSS: 开源免费版本(本文示例使用)
- Pro: 需要 license
安装
# mac
brew install goreleaser/tap/goreleaser
brew install goreleaser
# snapcraft
sudo snap install --classic goreleaser
# apt
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
sudo apt update
sudo apt install goreleaser
# go
go install github.com/goreleaser/goreleaser/v2@latest
# go install github.com/goreleaser/goreleaser@v1.25.1
# bash
curl -sfL https://goreleaser.com/static/run | bash
$ goreleaser -v
____ ____ _
/ ___| ___ | _ \ ___| | ___ __ _ ___ ___ _ __
| | _ / _ \| |_) / _ \ |/ _ \/ _` / __|/ _ \ '__|
| |_| | (_) | _ < __/ | __/ (_| \__ \ __/ |
\____|\___/|_| \_\___|_|\___|\__,_|___/\___|_|
goreleaser: Deliver Go Binaries as fast and easily as possible
https://goreleaser.com
GitVersion: 2.0.1
GitCommit: 684c1805864e5f29acc204e34e1770eb74918d15
GitTreeState: false
BuildDate: 2024-06-11T01:45:52Z
BuiltBy: goreleaser
GoVersion: go1.22.4
Compiler: gc
ModuleSum: h1:Wx2peRnvixEBRKxU6T0Gh+3wlire+Jv2IOW5eNPan3U=
Platform: darwin/amd64
help
$ goreleaser --help
GoReleaser is a release automation tool for Go projects.
Its goal is to simplify the build, release and publish steps while providing variant customization options for all steps.
GoReleaser is built for CI tools, you only need to download and execute it in your build script. Of course, you can also install it locally if you wish.
You can customize your entire release process through a single .goreleaser.yaml file.
Check out our website for more information, examples and documentation: https://goreleaser.com
Usage:
goreleaser [command]
Available Commands:
build Builds the current project
check Checks if configuration is valid
completion Generate the autocompletion script for the specified shell
healthcheck Checks if needed tools are installed
help Help about any command
init Generates a .goreleaser.yaml file
jsonschema outputs goreleaser's JSON schema
release Releases the current project
Flags:
-h, --help help for goreleaser
--verbose Enable verbose mode
-v, --version version for goreleaser
Use "goreleaser [command] --help" for more information about a command.
goreleaser build --help
goreleaser release --help
使用
- 参考
- init 命令初始化
.goreleaser.yaml
文件
$ goreleaser init
• Generating .goreleaser.yaml file
• config created; please edit accordingly to your needs file=.goreleaser.yaml
• thanks for using goreleaser!
$ cat .goreleaser.yaml
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
# The lines below are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of `uname`.
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
format: zip
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
二进制名称字段支持模板化。可显示以下构建细节:
Key |
Description |
.Os |
GOOS |
.Arch |
GOARCH |
.Arm |
GOARM |
.Ext |
Extension, e.g. .exe |
.Target |
Build target, e.g. darwin_amd64 |
goreleaser release --snapshot --clean
goreleaser check
- 使用 GoReleaser 只为指定的 GOOS/GOARCH 生成二进制文件
goreleaser build --single-target
- 发布(release)到 GitHub,需要配置环境变量
GITHUB_TOKEN
export GITHUB_TOKEN="YOUR_GH_TOKEN"
# GoReleaser will use the latest Git tag of your repository.
git tag -a v0.1.0 -m "First release"
git push origin v0.1.0
# it will create a release on GitHub with all the artifacts
goreleaser release
如果还不想创建标签,也可以使用 --snapshot
标记,在不发布最新提交的情况下运行 GoReleaser:
goreleaser release --snapshot
goreleaser release --skip=publish
# .goreleaser.yaml
before:
hooks:
- go mod tidy
# rest of the file...
Linux packages
# .goreleaser.yaml
nfpms:
# note that this is an array of nfpm configs
- #
# ID of the nfpm config, must be unique.
#
# Default: 'default'
id: foo
# Name of the package.
# Default: ProjectName
# Templates: allowed (since v1.18)
package_name: foo
# You can change the file name of the package.
#
# Default: '{{ .PackageName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}'
# Templates: allowed
file_name_template: "{{ .ConventionalFileName }}"
# Build IDs for the builds you want to create NFPM packages for.
# Defaults empty, which means no filtering.
builds:
- foo
- bar
# Your app's vendor.
vendor: Drum Roll Inc.
# Your app's homepage.
homepage: https://example.com/
# Your app's maintainer (probably you).
maintainer: Drummer <drum-roll@example.com>
# Your app's description.
description: |-
Drum rolls installer package.
Software to create fast and easy drum rolls.
# Your app's license.
license: Apache 2.0
# Formats to be generated.
formats:
- apk
- deb
- rpm
- termux.deb # Since: v1.11
- archlinux # Since: v1.13
# Umask to be used on files without explicit mode set. (overridable)
#
# Default: 0o002 (will remove world-writable permissions)
# Since: v1.19
umask: 0o002
# Packages your package depends on. (overridable)
dependencies:
- git
- zsh
# Packages it provides. (overridable)
#
# Since: v1.11
provides:
- bar
# Packages your package recommends installing. (overridable)
recommends:
- bzr
- gtk
# Packages your package suggests installing. (overridable)
suggests:
- cvs
- ksh
# Packages that conflict with your package. (overridable)
conflicts:
- svn
- bash
# Packages it replaces. (overridable)
replaces:
- fish
# Path that the binaries should be installed.
#
# Default: '/usr/bin'
bindir: /usr/bin
# Paths to the directories where to put specific types of libraries that
# GoReleaser built.
#
# This should be used together with `builds.buildmode`
#
# Since: v1.24.
# Templates: allowed
libdirs:
# Default: '/usr/include'
headers: /usr/include/something
# Default: '/usr/lib'
cshared: /usr/lib/foo
# Default: '/usr/lib'
carchive: /usr/lib/foobar
# Version Epoch.
# Default: extracted from `version` if it is semver compatible
epoch: 2
# Version Prerelease.
# Default: extracted from `version` if it is semver compatible
prerelease: beta1
# Version Metadata (previously deb.metadata).
# Setting metadata might interfere with version comparisons depending on the
# packager.
#
# Default: extracted from `version` if it is semver compatible
version_metadata: git
# Version Release.
release: 1
# Section.
section: default
# Priority.
priority: extra
# Makes a meta package - an empty package that contains only supporting
# files and dependencies.
# When set to `true`, the `builds` option is ignored.
meta: true
# Changelog YAML file, see: https://github.com/goreleaser/chglog
#
# You can use goreleaser/chglog to create the changelog for your project,
# pass that changelog yaml file to GoReleaser,
# and it should in turn setup it accordingly for the given available
# formats (deb and rpm at the moment).
#
# Experimental.
# Since: v1.11
changelog: ./foo.yml
# Contents to add to the package.
# GoReleaser will automatically add the binaries.
contents:
# Basic file that applies to all packagers
- src: path/to/foo
dst: /usr/bin/foo
# This will add all files in some/directory or in subdirectories at the
# same level under the directory /etc. This means the tree structure in
# some/directory will not be replicated.
- src: some/directory/
dst: /etc
# This will replicate the directory structure under some/directory at
# /etc, using the "tree" type.
#
# Since: v1.17
# Templates: allowed
- src: some/directory/
dst: /etc
type: tree
# Simple config file
- src: path/to/foo.conf
dst: /etc/foo.conf
type: config
# Simple symlink.
# Corresponds to `ln -s /sbin/foo /usr/local/bin/foo`
- src: /sbin/foo
dst: /usr/bin/foo
type: "symlink"
# Corresponds to `%config(noreplace)` if the packager is rpm, otherwise it
# is just a config file
- src: path/to/local/bar.conf
dst: /etc/bar.conf
type: "config|noreplace"
# The src and dst attributes also supports name templates
- src: path/{{ .Os }}-{{ .Arch }}/bar.conf
dst: /etc/foo/bar-{{ .ProjectName }}.conf
# Additional templated contents to add to the archive.
# Those files will have their contents pass through the template engine,
# and its results will be added to the package.
#
# This feature is only available in GoReleaser Pro.
# Since: v1.17 (pro)
# Templates: allowed
templated_contents:
# a more complete example, check the globbing deep dive below
- src: "LICENSE.md.tpl"
dst: LICENSE.md
# These files are not actually present in the package, but the file names
# are added to the package header. From the RPM directives documentation:
#
# "There are times when a file should be owned by the package but not
# installed - log files and state files are good examples of cases you
# might desire this to happen."
#
# "The way to achieve this, is to use the %ghost directive. By adding this
# directive to the line containing a file, RPM will know about the ghosted
# file, but will not add it to the package."
#
# For non rpm packages ghost files are ignored at this time.
- dst: /etc/casper.conf
type: ghost
- dst: /var/log/boo.log
type: ghost
# You can use the packager field to add files that are unique to a
# specific packager
- src: path/to/rpm/file.conf
dst: /etc/file.conf
type: "config|noreplace"
packager: rpm
- src: path/to/deb/file.conf
dst: /etc/file.conf
type: "config|noreplace"
packager: deb
- src: path/to/apk/file.conf
dst: /etc/file.conf
type: "config|noreplace"
packager: apk
# Sometimes it is important to be able to set the mtime, mode, owner, or
# group for a file that differs from what is on the local build system at
# build time.
- src: path/to/foo
dst: /usr/local/foo
file_info:
mode: 0644
mtime: 2008-01-02T15:04:05Z
owner: notRoot
group: notRoot
# If `dst` ends with a `/`, it'll create the given path and copy the given
# `src` into it, the same way `cp` works with and without trailing `/`.
- src: ./foo/bar/*
dst: /usr/local/myapp/
# Using the type 'dir', empty directories can be created. When building
# RPMs, however, this type has another important purpose: Claiming
# ownership of that directory. This is important because when upgrading or
# removing an RPM package, only the directories for which it has claimed
# ownership are removed. However, you should not claim ownership of a
# directory that is created by the OS or a dependency of your package.
#
# A directory in the build environment can optionally be provided in the
# 'src' field in order copy mtime and mode from that directory without
# having to specify it manually.
- dst: /some/dir
type: dir
file_info:
mode: 0700
# Scripts to execute during the installation of the package. (overridable)
#
# Keys are the possible targets during the installation process
# Values are the paths to the scripts which will be executed.
#
# Templates: allowed (since v1.20)
scripts:
preinstall: "scripts/preinstall.sh"
postinstall: "scripts/postinstall.sh"
preremove: "scripts/preremove.sh"
postremove: "scripts/postremove.sh"
# Templated scripts to execute during the installation of the package. (overridable)
#
# Keys are the possible targets during the installation process
# Values are the paths to the scripts which will be executed.
#
# This feature is only available in GoReleaser Pro.
# Since: v1.20 (pro)
# Templates: allowed
templated_scripts:
preinstall: "scripts/preinstall.sh"
postinstall: "scripts/postinstall.sh"
preremove: "scripts/preremove.sh"
postremove: "scripts/postremove.sh"
# All fields above marked as `overridable` can be overridden for a given
# package format in this section.
overrides:
# The dependencies override can for example be used to provide version
# constraints for dependencies where different package formats use
# different versions or for dependencies that are named differently.
deb:
dependencies:
- baz (>= 1.2.3-0)
- some-lib-dev
# ...
rpm:
dependencies:
- baz >= 1.2.3-0
- some-lib-devel
# ...
apk:
# ...
# Custom configuration applied only to the RPM packager.
rpm:
# RPM specific scripts.
scripts:
# The pretrans script runs before all RPM package transactions / stages.
pretrans: ./scripts/pretrans.sh
# The posttrans script runs after all RPM package transactions / stages.
posttrans: ./scripts/posttrans.sh
# The package summary.
#
# Default: first line of the description
summary: Explicit Summary for Sample Package
# The package group.
# This option is deprecated by most distros but required by old distros
# like CentOS 5 / EL 5 and earlier.
group: Unspecified
# The packager is used to identify the organization that actually packaged
# the software, as opposed to the author of the software.
# `maintainer` will be used as fallback if not specified.
# This will expand any env var you set in the field, eg packager: ${PACKAGER}
packager: GoReleaser <staff@goreleaser.com>
# Compression algorithm (gzip (default), lzma or xz).
compression: lzma
# Prefixes for relocatable packages.
#
# Since: v1.20
prefixes:
- /usr/bin
# The package is signed if a key_file is set
signature:
# PGP secret key file path (can also be ASCII-armored).
#
# See "Signing key passphrases" below for more information.
#
# Templates: allowed
key_file: "{{ .Env.GPG_KEY_PATH }}"
# Custom configuration applied only to the Deb packager.
deb:
# Lintian overrides
lintian_overrides:
- statically-linked-binary
- changelog-file-missing-in-native-package
# Custom deb special files.
scripts:
# Deb rules script.
rules: foo.sh
# Deb templates file, when using debconf.
templates: templates
# Custom deb triggers
triggers:
# register interest on a trigger activated by another package
# (also available: interest_await, interest_noawait)
interest:
- some-trigger-name
# activate a trigger for another package
# (also available: activate_await, activate_noawait)
activate:
- another-trigger-name
# Packages which would break if this package would be installed.
# The installation of this package is blocked if `some-package`
# is already installed.
#
# Since: v1.25.
breaks:
- some-package
# The package is signed if a key_file is set
signature:
# PGP secret key file path (can also be ASCII-armored).
#
# See "Signing key passphrases" below for more information.
#
# Templates: allowed
key_file: "{{ .Env.GPG_KEY_PATH }}"
# The type describes the signers role, possible values are "origin",
# "maint" and "archive".
#
# Default: 'origin'
type: origin
# Additional fields for the control file. Empty fields are ignored.
# This will expand any env vars you set in the field values, e.g. Vcs-Browser: ${CI_PROJECT_URL}
fields:
Bugs: https://github.com/goreleaser/nfpm/issues
# The Debian-specific "predepends" field can be used to ensure the complete installation of a list of
# packages (including unpacking, pre- and post installation scripts) prior to the installation of the
# built package.
predepends:
- baz (>= 1.2.3-0)
apk:
# APK specific scripts.
scripts:
# The preupgrade script runs before APK upgrade.
preupgrade: ./scripts/preupgrade.sh
# The postupgrade script runs after APK.
postupgrade: ./scripts/postupgrade.sh
# The package is signed if a key_file is set
signature:
# PGP secret key file path (can also be ASCII-armored).
#
# See "Signing key passphrases" below for more information.
#
# Templates: allowed
key_file: "{{ .Env.GPG_KEY_PATH }}"
# The name of the signing key. When verifying a package, the signature
# is matched to the public key store in /etc/apk/keys/<key_name>.rsa.pub.
#
# Default: maintainer's email address
# Templates: allowed (since v1.15)
key_name: origin
archlinux:
# Archlinux-specific scripts
scripts:
# The preupgrade script runs before pacman upgrades the package.
preupgrade: ./scripts/preupgrade.sh
# The postupgrade script runs after pacman upgrades the package.
postupgrade: ./scripts/postupgrade.sh
# The pkgbase can be used to explicitly specify the name to be used to refer
# to a group of packages. See: https://wiki.archlinux.org/title/PKGBUILD#pkgbase.
pkgbase: foo
# The packager refers to the organization packaging the software, not to be confused
# with the maintainer, which is the person who maintains the software.
packager: GoReleaser <staff@goreleaser.com>
nfpm 介绍
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
sudo apt update
sudo apt install nfpm
go install github.com/goreleaser/nfpm/v2/cmd/nfpm@latest
# 初始化配置文件,参考https://nfpm.goreleaser.com/configuration/
nfpm init
nfpm pkg --packager deb --target /tmp/
nfpm pkg --packager rpm --target /tmp/
DMG
MSI
Snapcraft Packages (snaps)
Docker Images
配置示例
golang
---
version: 2
project_name: go-actions-demo
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
builds:
- binary: go-actions-demo
main: ./cmd/go-actions-demo/
flags:
- -trimpath
ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.ShortCommit}} -X main.date={{.Date}}
env:
- CGO_ENABLED=0
goos:
- darwin
- windows
- linux
- freebsd
- netbsd
- illumos
goarch:
- amd64
- arm64
- arm
- 386
- ppc64le
- s390x
- mips64
- mips64le
- riscv64
- loong64
goarm:
- 6
- 7
gomips:
- hardfloat
ignore:
- goos: darwin
goarch: 386
- goos: freebsd
goarch: arm64
archives:
- format: tar.gz
wrap_in_directory: true
format_overrides:
- goos: windows
format: zip
name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
files:
- LICENSE
- README.md
snapshot:
name_template: SNAPSHOT-{{ .Commit }}
checksum:
name_template: '{{ .ProjectName }}-{{ .Version }}-checksums.txt'
changelog:
sort: asc
filters:
exclude:
- '(?i)^docs?:'
- '(?i)^docs\([^:]+\):'
- '(?i)^docs\[[^:]+\]:'
- '^tests?:'
- '(?i)^dev:'
- '(?i)^chore:'
- '^build\(deps\): bump .* in /docs \(#\d+\)'
- '^build\(deps\): bump .* in /\.github/peril \(#\d+\)'
- '^build\(deps\): bump .* in /scripts/gen_github_action_config \(#\d+\)'
- Merge pull request
- Merge branch
release:
github:
owner: xiexianbin
name: go-actions-demo
header: |
`go-actions-demo` is a free and open-source project built by volunteers.
If you value it, consider supporting us, the maintainers.
We appreciate it! :heart:
For key updates, see the [changelog](https://github.com/xiexianbin/go-actions-demo/releases/tag/v{{ .Major }}{{ .Minor }}{{ .Patch }}).
source:
enabled: true
name_template: '{{ .ProjectName }}-{{ .Version }}-source'
brews:
- repository:
owner: xiexianbin
name: homebrew-tap
directory: Formula
homepage: https://xiexianbin.cn
description: go actions demo.
install: |
bin.install "go-actions-demo"
output = Utils.popen_read("#{bin}/go-actions-demo completion bash")
(bash_completion/"go-actions-demo").write output
output = Utils.popen_read("#{bin}/go-actions-demo completion zsh")
(zsh_completion/"_go-actions-demo").write output
output = Utils.popen_read("#{bin}/go-actions-demo completion fish")
(fish_completion/"go-actions-demo.fish").write output
prefix.install_metafiles
test: |
system "#{bin}/go-actions-demo --version"
chocolateys:
- name: go-actions-demo
owners: xiexianbin
title: go-actions-demo
authors: xiexianbin
project_url: https://github.com/xiexianbin/go-actions-demo
url_template: "https://github.com/xiexianbin/go-actions-demo/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
icon_url: "https://www.xiexianbin.cn/images/logo/logo.png"
copyright: xiexianbin.cn
license_url: https://github.com/xiexianbin/go-actions-demo/blob/main/LICENSE
require_license_acceptance: false
project_source_url: https://github.com/xiexianbin/go-actions-demo
package_source_url: https://github.com/xiexianbin/go-actions-demo
docs_url: https://github.com/xiexianbin/go-actions-demo
bug_tracker_url: https://github.com/xiexianbin/go-actions-demo/issues
tags: "go golang lint linter"
summary: go actions demo
description: |
{{ .ProjectName }} installer package.
go actions demo .
release_notes: "https://github.com/xiexianbin/go-actions-demo/releases/tag/v{{ .Version }}"
api_key: "{{ .Env.CHOCOLATEY_API_KEY }}"
source_repo: "https://push.chocolatey.org/"
skip_publish: false
goamd64: v1
nfpms:
-
id: go-actions-demo-nfpms
package_name: go-actions-demo
file_name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
homepage: https://github.com/xiexianbin/go-actions-demo/
maintainer: "xiexianbin <me@xiexianbin.cn>"
description: go-actions-demo
license: Apache-2.0 license
section: golang
formats:
- deb
- rpm
- apk
umask: 0o022
overrides:
deb:
contents:
- src: LICENSE
dst: /usr/share/doc/go-actions-demo/copyright
- src: README.md
dst: /usr/share/doc/go-actions-demo/README.md
recommends:
- golang-go
rpm:
contents:
- src: LICENSE
dst: /usr/share/doc/go-actions-demo/LICENSE
type: license
- src: README.md
dst: /usr/share/doc/go-actions-demo/README.md
type: readme
recommends:
- /usr/bin/go
rpm:
group: Development/Tools
docker_manifests:
# basic
- name_template: 'xiexianbin/go-actions-demo:latest'
image_templates:
- 'xiexianbin/go-actions-demo:{{ .Tag }}-amd64'
- 'xiexianbin/go-actions-demo:{{ .Tag }}-arm64'
- name_template: 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}'
image_templates:
- 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-amd64'
- 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-arm64'
- name_template: 'xiexianbin/go-actions-demo:{{ .Tag }}'
image_templates:
- 'xiexianbin/go-actions-demo:{{ .Tag }}-amd64'
- 'xiexianbin/go-actions-demo:{{ .Tag }}-arm64'
# alpine
- name_template: 'xiexianbin/go-actions-demo:latest-alpine'
image_templates:
- 'xiexianbin/go-actions-demo:{{ .Tag }}-alpine-amd64'
- 'xiexianbin/go-actions-demo:{{ .Tag }}-alpine-arm64'
- name_template: 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-alpine'
image_templates:
- 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-alpine-amd64'
- 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-alpine-arm64'
- name_template: 'xiexianbin/go-actions-demo:{{ .Tag }}-alpine'
image_templates:
- 'xiexianbin/go-actions-demo:{{ .Tag }}-alpine-amd64'
- 'xiexianbin/go-actions-demo:{{ .Tag }}-alpine-arm64'
dockers:
- use: buildx
goos: linux
goarch: amd64
dockerfile: build/buildx.Dockerfile
image_templates:
- 'xiexianbin/go-actions-demo:latest-amd64'
- 'xiexianbin/go-actions-demo:{{ .Tag }}-amd64'
- 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-amd64'
build_flag_templates:
- '--pull'
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
- '--label=org.opencontainers.image.title={{.ProjectName}}'
- '--label=org.opencontainers.image.description=go actions demo'
- '--label=org.opencontainers.image.source={{.GitURL}}'
- '--label=org.opencontainers.image.url={{.GitURL}}'
- '--label=org.opencontainers.image.documentation=https://github.com/xiexianbin/go-actions-demo'
- '--label=org.opencontainers.image.created={{.Date}}'
- '--label=org.opencontainers.image.revision={{.FullCommit}}'
- '--label=org.opencontainers.image.version={{.Version}}'
- '--platform=linux/amd64'
- use: buildx
goos: linux
goarch: arm64
dockerfile: build/buildx.Dockerfile
image_templates:
- 'xiexianbin/go-actions-demo:latest-arm64'
- 'xiexianbin/go-actions-demo:{{ .Tag }}-arm64'
- 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-arm64'
build_flag_templates:
- '--pull'
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
- '--label=org.opencontainers.image.title={{.ProjectName}}'
- '--label=org.opencontainers.image.description=go actions demo'
- '--label=org.opencontainers.image.source={{.GitURL}}'
- '--label=org.opencontainers.image.url={{.GitURL}}'
- '--label=org.opencontainers.image.documentation=https://github.com/xiexianbin/go-actions-demo'
- '--label=org.opencontainers.image.created={{.Date}}'
- '--label=org.opencontainers.image.revision={{.FullCommit}}'
- '--label=org.opencontainers.image.version={{.Version}}'
- '--platform=linux/arm64'
- use: buildx
goos: linux
goarch: amd64
dockerfile: build/buildx-alpine.Dockerfile
image_templates:
- 'xiexianbin/go-actions-demo:latest-alpine-amd64'
- 'xiexianbin/go-actions-demo:{{ .Tag }}-alpine-amd64'
- 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-alpine-amd64'
build_flag_templates:
- '--pull'
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
- '--label=org.opencontainers.image.title={{.ProjectName}}'
- '--label=org.opencontainers.image.description=go actions demo'
- '--label=org.opencontainers.image.source={{.GitURL}}'
- '--label=org.opencontainers.image.url={{.GitURL}}'
- '--label=org.opencontainers.image.documentation=https://github.com/xiexianbin/go-actions-demo'
- '--label=org.opencontainers.image.created={{.Date}}'
- '--label=org.opencontainers.image.revision={{.FullCommit}}'
- '--label=org.opencontainers.image.version={{.Version}}'
- '--platform=linux/amd64'
- use: buildx
goos: linux
goarch: arm64
dockerfile: build/buildx-alpine.Dockerfile
image_templates:
- 'xiexianbin/go-actions-demo:latest-alpine-arm64'
- 'xiexianbin/go-actions-demo:{{ .Tag }}-alpine-arm64'
- 'xiexianbin/go-actions-demo:v{{ .Major }}.{{ .Minor }}-alpine-arm64'
build_flag_templates:
- '--pull'
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
- '--label=org.opencontainers.image.title={{.ProjectName}}'
- '--label=org.opencontainers.image.description=go actions demo'
- '--label=org.opencontainers.image.source={{.GitURL}}'
- '--label=org.opencontainers.image.url={{.GitURL}}'
- '--label=org.opencontainers.image.documentation=https://github.com/xiexianbin/go-actions-demo'
- '--label=org.opencontainers.image.created={{.Date}}'
- '--label=org.opencontainers.image.revision={{.FullCommit}}'
- '--label=org.opencontainers.image.version={{.Version}}'
- '--platform=linux/arm64'
与其他工具集成
Makefile
.PHONY: release-dry-run
release-dry-run:
goreleaser release --clean --auto-snapshot --skip-validate --skip-publish --debug
.PHONY: release-build
release-build:
goreleaser build --clean --skip-validate --snapshot --debug
github actions
name: "Release a tag"
on:
push:
tags:
- v*
jobs:
release:
runs-on: ubuntu-latest
env:
# https://github.com/actions/setup-go#supported-version-syntax
# ex:
# - 1.18beta1 -> 1.18.0-beta.1
# - 1.18rc1 -> 1.18.0-rc.1
GO_VERSION: '1.22'
CHOCOLATEY_VERSION: 2.2.0
steps:
- uses: actions/checkout@v4
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Unshallow
run: git fetch --prune --unshallow
- name: Install chocolatey
run: |
mkdir -p /opt/chocolatey
wget -q -O - "https://github.com/chocolatey/choco/releases/download/${CHOCOLATEY_VERSION}/chocolatey.v${CHOCOLATEY_VERSION}.tar.gz" | tar -xz -C "/opt/chocolatey"
echo '#!/bin/bash' >> /usr/local/bin/choco
echo 'mono /opt/chocolatey/choco.exe $@' >> /usr/local/bin/choco
chmod +x /usr/local/bin/choco
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login do docker.io
run: docker login -u golangci -p ${{ secrets.DOCKER_TOKEN }}
- name: Create release
uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --clean --timeout=90m
env:
CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: Release (Dry Run)
on:
push:
branches:
- main
- release-*
pull_request:
branches:
- main
- release-*
merge_group:
branches:
- main
jobs:
goreleaser:
name: Release (Dry Run)
needs: skip-check
if: ${{ needs.skip-check.outputs.should_skip != 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 40
permissions:
contents: read
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-gov4
with:
go-version-file: .go-version
- name: Set up Snapcraft
run: |
sudo snap install snapcraft --channel=7.x/stable --classic
# See https://github.com/goreleaser/goreleaser/issues/1715
mkdir -p "$HOME/.cache/snapcraft/download"
mkdir -p "$HOME/.cache/snapcraft/stage-packages"
- name: Validate
uses: goreleaser/goreleaser-action@v4
with:
distribution: goreleaser
version: ${{ env.GORELEASER_VERSION }}
args: check
- name: Set Tag
run: |
echo "goreleaser_current_tag=`git describe --match 'v*' --tags`" >> $GITHUB_ENV
- name: Dry Run
uses: goreleaser/goreleaser-action@v4
with:
distribution: goreleaser
version: ${{ env.GORELEASER_VERSION }}
args: release --clean --skip-validate --skip-publish --timeout=60m
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GORELEASER_CURRENT_TAG: "${{ env.goreleaser_current_tag }}"
name: Goreleaser
on:
push:
tags:
- v*
env:
# renovate: datasource=go depName=github.com/goreleaser/goreleaser
GORELEASER_VERSION: v2.0.1
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
timeout-minutes: 45
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: .go-version
- uses: pnpm/action-setup@v3
with:
version: ${{ env.PNPM_VERSION }}
- name: Set up Snapcraft
run: |
sudo snap install snapcraft --channel=7.x/stable --classic
# See https://github.com/goreleaser/goreleaser/issues/1715
mkdir -p "$HOME/.cache/snapcraft/download"
mkdir -p "$HOME/.cache/snapcraft/stage-packages"
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
if: startsWith(github.ref, 'refs/tags/')
with:
distribution: goreleaser
version: ${{ env.GORELEASER_VERSION }}
args: release --clean --timeout=60m
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Archive generated artifacts
uses: actions/upload-artifact@v3
with:
name: go-actions-demo-dist-release
if-no-files-found: error
path: |
dist
!dist/*.txt
container:
name: Build and release container images
runs-on: ubuntu-latest
timeout-minutes: 30
needs: release
container:
# https://github.com/containers/podman/tree/main/contrib/podmanimage
image: quay.io/containers/podman:v4.9.4
options: >-
--device /dev/fuse:rw
--privileged
--security-opt label=disable
--security-opt seccomp=unconfined
permissions:
id-token: write
packages: write
contents: read
steps:
- name: Install dependencies
run: dnf install --assumeyes --repo fedora git make jq
- name: Check out code into the Go module directory
uses: actions/checkout@v4
- uses: actions/download-artifact@v3
with:
name: go-actions-demo-dist-release
path: dist
- name: Get branch name
shell: bash
run: echo "GITHUB_BRANCH_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Build container
run: make container
- name: Check images created
run: podman images | grep 'ghcr.io/xiexianbin/go-actions-demo'
- name: Login to registry
run: |
echo "${{ secrets.PERSONAL_ACCESS_TOKEN }}" | podman login -u xiexianbin --password-stdin ghcr.io
- name: Install cosign
uses: sigstore/cosign-installer@v3
- name: Install crane
uses: imjasonh/setup-crane@v0.3
- name: Push container
run: |
make push-container
- name: Sign container
run: |
make sign-container
snap:
runs-on: ubuntu-latest
needs: release
timeout-minutes: 30
steps:
- uses: actions/download-artifact@v3
with:
name: go-actions-demo-dist-release
path: dist
- name: Install snapcraft
run: |
sudo snap install snapcraft --classic --channel=7.x/stable
- name: Release to latest/edge
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
run: |
snapcraft upload dist/*_amd64.snap --release stable
snapcraft upload dist/*_arm64.snap --release stable