02.GoReleaser配置-通用
GoReleaser配置 - 通用
GoReleaser 配置
配置文件
goreleaser init 会在当前目录生成一个示例配置,在日常的维护过程中,可以通过修改 .goreleaser.yaml 文件来自定义 GoReleaser 的行为。
出于简便起见,大多数文档都提到了
.goreleaser.yaml这个文件名,但实际上还支持几种不同的变体。按优先级排序如下:
.config/goreleaser.yml.config/goreleaser.yaml.goreleaser.yml.goreleaser.yamlgoreleaser.ymlgoreleaser.yaml
配置检查
运行 goreleaser check 来检查配置是否有效,该命令会提示是否使用了已弃用或无效的选项。
JSON Schema
https://goreleaser.com/static/schema.json
可以在 .goreleaser.yml 配置文件中通过添加如下所示的注释来指定JSON Schema
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
指定版本
# yaml-language-server: $schema=https://raw.githubusercontent.com/goreleaser/goreleaser/v2.17.1/www/docs/static/schema.json
通用
带有 (Pro) 的部分表示只有 GoReleaser Pro 版本可以使用
项目名称
项目名称将用于Brew formula和归档等的命名。如果未指定,则会根据 GitHub、GitLab 或 Gitea 发布版本的名称推断出来。
project_name: project-name
元信息(Metadata)
metadata:
# 文件的修改时间
# 模板: 支持
mod_timestamp: "{{ .CommitTimestamp }}"
# 维护者 (Pro)
# 模板: 支持
maintainers:
- "Foo Bar <foo@bar.com>"
# license SPDX 标识 (Pro)
# https://spdx.org/licenses/
# 模板: 支持
license: "MIT"
# 主页 (Pro)
# 模板: 支持
homepage: "https://example.com/"
# 简短描述 (Pro)
# 模板: 支持
description: "Software to create fast and easy drum rolls."
# 完整描述 (Pro)
# 可以是字符串,也可以从 `from_url` 或者 `from_file` 加载
# 模板: 支持
full_description:
from_url:
url: https://foo.bar/README.md
headers:
x-api-token: "${MYCOMPANY_TOKEN}"
from_file:
path: ./README.md
# 用于向 AUR、Homebrew、Winget、Nix 等提交代码的默认 Git 作者。 (Pro)
commit_author:
# 提交人
# 模板: 支持
name: goreleaserbot
# 电子邮箱
# 模板: 支持
email: bot@goreleaser.com
# Git 提交签名配置
signing:
# 是否启用签名
enabled: true
# 签名Key 值可以是 GPG keyID, fingerprint, 电子邮箱地址或者 key 文件路径
# 模板: 支持
key: "{{ .Env.GPG_SIGNING_KEY }}"
# 签名用的 GPG 可执行程序
# 模板: 支持
program: gpg2
# 签名格式
# Valid options: openpgp, x509, ssh.
# Default: openpgp.
format: openpgp
目标目录
默认情况下,GoReleaser 会将构建产物生成在 ./dist 文件夹中。如有必要,可以通过在 .goreleaser.yaml 文件中进行设置来更改此路径:
# Default: './dist'.
dist: another-folder-that-is-not-dist
Artifacts
GoReleaser 会在 dist 文件夹中生成一个名为 artifacts.json 的文件,其中包含发布过程中生成的所有构建产物的信息。
artifacts.json 文件中包含一个数组,数组中的每个元素有以下属性。
| Field | Description |
|---|---|
name | artifact 文件名 |
path | artifact 路径 |
goos | 目标操作系统 (e.g., linux, darwin, windows) |
goarch | 目标指令集架构 (e.g., amd64, arm64, 386) |
goamd64 | amd64 微架构级别 (e.g., v1, v2, v3) |
go386 | 386 浮点指令集 |
goarm | ARM 版本 (e.g., 6, 7) |
goarm64 | ARM64 版本 |
gomips | MIPS 浮点指令集 |
goppc64 | PPC64 版本 |
goriscv64 | RISC-V 64 版本 |
target | 完整的构建目标 (e.g., linux_amd64_v1) |
type | artifact 类型 (see below) |
extra | 附加元数据 (see below) |
Artifact 类型
| Type | Description |
|---|---|
Archive | 压缩文件(tar.gz、zip 等) |
Binary | 已编译的二进制文件 |
File | 通用可上传文件 |
Linux Package | 由 nfpm 生成的软件包(deb、rpm 等) |
Snap | Snapcraft 软件包 |
Docker Image | Docker 镜像 |
Published Docker Image | 已发布的 Docker 镜像 |
Docker Manifest | Docker 清单文件 |
Checksum | 校验和文件 |
Signature | 签名文件 |
Certificate | 签名证书 |
Source | 源代码归档 |
Homebrew Formula | Homebrew 配方文件 |
Homebrew Cask | Homebrew cask 文件 |
Krew Plugin Manifest | Krew 插件清单文件 |
Scoop Manifest | Scoop 清单文件 |
SBOM | 软件物料清单 |
PKGBUILD | Arch Linux 的 PKGBUILD 文件 |
SRCINFO | Arch Linux 的 .SRCINFO 文件 |
Chocolatey | Chocolatey 软件包 |
C Header | C 头文件 |
C Archive Library | C 静态库 |
C Shared Library | C 共享库 |
Winget Manifest | Winget 清单文件 |
Nixpkg | Nix 软件包 |
Wheel | Python wheel 软件包 |
Source Dist | Python 源代码发行版 |
Makeself Package | Makeself 自解压归档文件 |
App Bundle | macOS .app 软件包 |
DMG | macOS 磁盘映像 |
MacOS Package | macOS 安装程序包 |
MSI | Windows MSI 安装程序 |
NPM Package | NPM 软件包 |
Extra fields
extra 字段包含根据构建产物类型而异的附加元数据。根据工件类型和配置的不同,extra中可能还包含其他字段。最常见的字段如下。
| Field | Type | Description |
|---|---|---|
ID | string | 配置中的 Artifacts ID |
Binary | string | 二进制文件名称(适用于仅包含一个二进制文件的归档文件) |
Binaries | []string | 二进制文件名称列表(适用于包含多个二进制文件的归档文件) |
Ext | string | 文件扩展名(包括前缀 .) |
Format | string | 归档格式(例如,tar.gz、zip) |
WrappedIn | string | 文件所在的目录名称 |
Checksum | string | 以 algorithm:hash 格式表示的校验和 |
Size | int | 文件大小(以字节为单位,当 report_sizes 启用时) |
Digest | string | Docker 镜像摘要 |
Platforms | []string | Docker (v2) 镜像所针对的架构 |
Replaces | bool | 通用二进制文件是否取代了单架构二进制文件 |
Files | []string | 归档文件中可能包含的任何额外文件 |
DynamicallyLinked | bool | 二进制文件是否为动态链接 |
include (Pro)
GoReleaser 允许通过从 URL 或文件路径引入配置文件以复用一些通用的配置文件。
includes:
- from_file:
path: ./config/goreleaser.yaml
- from_url:
url: https://raw.githubusercontent.com/goreleaser/goreleaser/main/.goreleaser.yaml
- from_url:
url: caarlos0/goreleaserfiles/main/packages.yml # the https://raw.githubusercontent.com/ prefix may be omitted
- from_url:
url: https://api.mycompany.com/configs/goreleaser.yaml
headers:
# header values are expanded in case they are environment variables
x-api-token: "${MYCOMPANY_TOKEN}"
模板
GoReleaser 的配置文件中有几个字段支持模板功能。这些字段通常以 _template 结尾,但有时可能没有。
常用字段
| Key | Description |
|---|---|
.ProjectName | 项目名称 |
.Version | 即将发布的版本,前缀“v”已被移除,且在 snapshot 和 nightly 中可能会发生变化。 |
.Branch | 当前的 Git 分支 |
.Tag | 当前的 Git 标签 |
.PreviousTag | 上一个 Git 标签(如果没有上一个标签,则为空) |
.ShortCommit | Git 提交的短哈希值 |
.FullCommit | Git 提交的完整哈希值 |
.Commit | Git 提交的哈希值 (已弃用) |
.CommitDate | RFC 3339 格式的 UTC 提交日期 |
.CommitTimestamp | Unix 格式的 UTC 提交日期 |
.GitURL | Git 远程 URL |
.GitTreeState | “clean” 或 “dirty” |
.IsGitClean | 当前 Git 状态是否为干净状态 |
.IsGitDirty | 当前 Git 状态是否为脏状态 |
.Major | 版本号的主版本号,假设 Tag 是有效的 SemVer,否则为空或清零。 |
.Minor | 版本号的次版本部分,假设 Tag 是有效的 SemVer,否则为空或清零。 |
.Patch | 版本号的补丁部分,假设 Tag 是有效的 SemVer,否则为空或清零。 |
.Prerelease | 版本的预发布部分,例如 beta.1,假设 Tag 是有效的 SemVer,否则为空或清零。 |
.RawVersion | 由 {Major}.{Minor}.{Patch} 组成 ,假设 Tag 是有效的 SemVer,否则为空或清零。 |
.ReleaseNotes | 生成的发布说明,在执行完变更日志步骤后可用 |
.IsDraft | 如果配置中设置了 release.draft,则为 true,否则为 false |
.IsSnapshot | 若设置了 --snapshot 则为 true,否则为 false |
.IsNightly | 若设置了 --nightly 则为 true,否则为 false |
.IsSingleTarget | 若设置了 --single-target 则为 true,否则为 false |
.Env | 包含系统环境变量的映射 |
.Date | 当前 UTC 日期(RFC 3339 格式) |
.Now | 当前 UTC 日期(time.Time 结构体形式),支持所有 time.Time 函数(例如 {{ .Now.Format “2006” }}) |
.Timestamp | 当前 UTC 时间(Unix 格式) |
.ModulePath | Go 模块路径,由 go list -m 报告 |
.ReleaseURL | 当前版本的下载网址 |
.Summary | Git 摘要,例如 v1.0.0-10-g34f56g3 该信息由 git describe --dirty --always --tags 命令生成 |
.TagSubject | 注释标签的消息主题,或其所指向的提交的消息主题 git tag -l --format='%(contents:subject)' |
.TagContents | 注释标签的消息正文,或其所指向的提交的消息正文 git tag -l --format='%(contents)' |
.TagBody | 注释标签的消息正文,或其所指向的提交的消息正文 git tag -l --format='%(contents)' |
.Runtime.Goos | 等同于 runtime.GOOS |
.Runtime.Goarch | 等同于 runtime.GOARCH |
.Outputs | 自定义输出 |
.Dist | 已配置的 dist 目录的绝对路径 |
常用字段 (Pro)
| Key | Description |
|---|---|
.PrefixedTag | 当前 Git 标签,前缀为单仓库配置中的标签前缀(如有) |
.PrefixedPreviousTag | 上一个 Git 标签,前缀为单仓库配置中的标签前缀(如有) |
.PrefixedSummary | Git 摘要,前缀为单仓库配置中的标签前缀(如有) |
.IsRelease | 如果是常规发布(非夜间构建或快照),则为 true |
.IsMerging | 若使用 --merge 运行,则返回 true |
.Artifacts | 参见 Artifacts |
.Metadata | 参见 Metadata |
Metadata (Pro)
如果使用 .Metadata 字段,其结果为项目元数据配置。
| Key | Description |
|---|---|
.Metadata.Description | 项目描述 |
.Metadata.Homepage | 项目主页网址 |
.Metadata.License | 项目许可协议 |
.Metadata.Maintainers | 项目维护者列表 |
.Metadata.ModTimestamp | 修改时间戳模板 |
Artifacts (Pro)
如果使用 .Artifacts 字段,其计算结果为
artifact.Artifact列表
。
.Name.Path.Goos.Goarch.Goarm.Gomips.Goamd64.Goarm64.Gomips64.Goppc64.Goriscv64.Go386.Target.Type.Extra
Single-artifact 扩展字段
在与单个 artifact 相关的字段(例如二进制名称)中,可能会包含一些扩展字段:
| Key | Description |
|---|---|
.Os | GOOS |
.Arch | GOARCH |
.Arm | GOARM |
.Mips | GOMIPS |
.Amd64 | GOAMD64 |
.Arm64 | GOARM64 |
.Mips64 | GOMIPS64 |
.Ppc64 | GOPPC64 |
.Riscv64 | GORISCV64 |
.I386 | GO386 |
.Target | 整个目标 |
.Binary | Artifact 名称(不包含扩展名) |
.ArtifactID | Artifact ID (Pro) |
.ArtifactName | Artifact 名称 |
.ArtifactPath | Artifact 的绝对路径 |
.ArtifactExt | Artifact 扩展名(例如 .exe、.dmg 等) |
nFPM 扩展字段
在 nFPM 的名称模板字段中,可以使用以下扩展字段:
| Key | Description |
|---|---|
.Release | 来自 nFPM 配置的发布版本 |
.Epoch | 来自 nFPM 配置的epoch |
.PackageName | 包名。如果未被覆盖,则与 ProjectName 相同。 |
.ConventionalFileName | 由 nFPM 提供的标准包文件名。 |
.ConventionalExtension | 由 nFPM 提供的标准包扩展名 |
.Format | 包格式 |
Release body 扩展字段
在 release.body 字段中, 可以使用以下扩展字段:
| Key | Description |
|---|---|
.Checksums | 当前校验和文件的内容,或者如果设置了 checksum.split,则为文件名与校验和内容的映射关系。仅在发布正文中可用 |
函数
在所有字段中,您可以使用以下功能:
| Usage | Description |
|---|---|
replace "v1.2" "v" "" | 替换所有匹配项。参见 ReplaceAll |
split "1.2" "." | 按分隔符拆分字符串。参见 Split |
time "01/02/2006" | 以指定格式返回当前 UTC 时间(此结果非确定性,每次调用返回的时间均不同) |
contains "foobar" "foo" | 检查第一个字符串是否包含第二个字符串。参见 Contains |
tolower "V1.2" | 将输入字符串转换为小写。参见 ToLower |
toupper "v1.2" | 将输入字符串转换为大写。参见 ToUpper |
trim " v1.2 " | 移除所有开头和结尾的空格。参见 TrimSpace |
trimprefix "v1.2" "v" | 移除指定的开头前缀字符串(如果存在)。参见 TrimPrefix |
trimsuffix "1.2v" "v" | 移除指定的结尾后缀字符串(如果存在)。参见 TrimSuffix |
dir .Path | 返回 path 中除最后一个元素以外的所有元素,通常是路径中的目录。参见 Dir |
base .Path | 返回 path 的最后一个元素。参见 Base |
abs .ArtifactPath | 返回 path 的绝对表示形式。参见 Abs |
filter "text" "regex" | 仅保留匹配给定正则表达式的行,类似于 grep -E |
reverseFilter "text" "regex" | 仅保留不匹配给定正则表达式的行,类似于 grep -vE |
title "foo" | 使用英语作为语言对字符串进行“标题化”。参见 Title |
mdv2escape "foo" | 根据 MarkdownV2 进行转义,在 Telegram 集成中尤为有用 |
envOrDefault "NAME" "value" | 获取给定环境变量的值,或给定的默认值 |
isEnvSet "NAME" | 如果环境变量已设置且不为空,则返回 true,否则返回 false |
$m := map "KEY" "VALUE" | 根据键值对列表创建一个映射。键和值都必须是 string 类型 |
indexOrDefault $m "KEY" "value" | 从给定的映射中获取指定键的值或给定的默认值 |
incpatch "v1.2.4" | 递增给定版本的补丁号[^panic-if-not-semver] |
incminor "v1.2.4" | 递增给定版本的次版本号[^panic-if-not-semver] |
incmajor "v1.2.4" | 递增给定版本的主版本号[^panic-if-not-semver] |
urlPathEscape "foo/bar" | 对 URL 路径进行转义。参见 PathEscape |
blake2b .ArtifactPath | 构建产物的 blake2b 校验和。参见
Blake2b |
blake2s .ArtifactPath | 构建产物的 blake2s 校验和。参见
Blake2s |
blake3 .ArtifactPath | 构建产物的 blake3 校验和。参见
Blake3 |
crc32 .ArtifactPath | 构建产物的 crc32 校验和。参见
CRC32 |
md5 .ArtifactPath | 构建产物的 md5 校验和。参见
MD5 |
sha224 .ArtifactPath | 构建产物的 sha224 校验和。参见
SHA224 |
sha384 .ArtifactPath | 构建产物的 sha384 校验和。参见
SHA384 |
sha256 .ArtifactPath | 构建产物的 sha256 校验和。参见
SHA256 |
sha1 .ArtifactPath | 构建产物的 sha1 校验和。参见
SHA1 |
sha512 .ArtifactPath | 构建产物的 sha512 校验和。参见
SHA512 |
sha3_224 .ArtifactPath | 构建产物的 sha3_224 校验和。参见
SHA3-224 |
sha3_384 .ArtifactPath | 构建产物的 sha3_384 校验和。参见
SHA3-384 |
sha3_256 .ArtifactPath | 构建产物的 sha3_256 校验和。参见
SHA3-256 |
sha3_512 .ArtifactPath | 构建产物的 sha3_512 校验和。参见
SHA3-512 |
mustReadFile "/foo/bar.txt" | 读取文件内容;若无法读取则返回失败 |
readFile "/foo/bar.txt" | 若能读取文件内容则读取,否则返回空字符串 |
englishJoin | 将多个项目用空格分隔 |
list "a" "b" "c" | 创建一个字符串列表 |
函数 (Pro)
| Usage | Description |
|---|---|
in (list "a" "b" "c") "b" | 检查一个切片是否包含某个值 |
reReplaceAll "(.*)" "foo" "bar-$1" | 使用
regexp.Compile
编译第一个参数,然后使用 [ReplaceAllString](
https://pkg.go.dev/regexp#Regexp
. ReplaceAllStringFunc) 并传入以下参数 |
list "a" "b" "c" | listExclude "^a$" | 从列表中移除与给定正则表达式匹配的项 |
有了这些字段,基本上可以按照自己的意愿来组合工件的名称:
example_template: '{{ tolower .ProjectName }}_{{ .Env.USER }}_{{ time "2006" }}'
例如:如果想在某个构建产物中添加 Go 版本信息
foo_template: "foo_{{ .Env.GOVERSION }}"
运行:
GOVERSION=$(go version | awk '{print $3;}') goreleaser
请注意,这些只是假设性的示例,字段
foo_template和example_template并非有效的 GoReleaser 配置。
自定义变量 (Pro)
您还可以声明自定义变量。此功能在处理 [include] 时特别有用,可以编写拥有更通用的配置文件。
variables:
description: my project description
somethingElse: yada yada yada
empty: ""
然后,就可以将这些字段作为 {{ .Var.description }} 来使用,例如。
环境变量
将传递给所有钩子和构建的全局环境变量。
如果你有一个名为 FOOBAR 的环境变量,其值为 on,那么你的 .goreleaser.yaml 文件可以像这样使用它:
env:
- FOO={{ .Env.FOOBAR }}
- ENV_WITH_DEFAULT={{ if index .Env "ENV_WITH_DEFAULT" }}{{ .Env.ENV_WITH_DEFAULT }}{{ else }}default_value{{ end }}
before:
hooks:
- go mod tidy
builds:
- binary: program
这样一来,无论是预处理钩子(在本例中为 go mod tidy),还是底层的构建操作(使用 go build),FOO 都会被设置为 on。
根级别的 env 部分也支持模板。
全局钩子
某些发布周期可能需要在其他所有操作之前或之后执行某些操作。GoReleaser 通过全局钩子功能支持这一需求。
before 部分支持全局钩子,这些钩子将在发布开始前执行。
before:
# Templates for the commands to be ran.
hooks:
- make clean
- go generate ./...
- go mod tidy
- touch {{ .Env.FILE_TO_TOUCH }}
注意
如果任何一个钩子执行失败,Release将被立刻中止。
如果需要执行更复杂的操作,建议编写一个 shell 脚本并调用它
Git
git 的配置可以更改某些 git 命令的行为。
git:
# 如果同一个提交中包含多个标签,在收集当前标签和上一个标签时,应使用什么标准对标签进行排序?
#
# See: https://git-scm.com/docs/git-tag#Documentation/git-tag.txt---sortltkeygt
#
# Default: '-version:refname'.
tag_sort: -version:creatordate
# 当同一提交中包含多个标签时,在收集当前和上一个标签并按标签排序时,应使用什么来指定预发布后缀?
prerelease_suffix: "-"
# GoReleaser 将忽略的标签。
# 这意味着 GoReleaser 不会将与所提供值中的任何一个匹配的标签作为先前标签或当前标签进行识别。
#
# 支持通配符模式。 (Pro)
#
# 模板: 支持
ignore_tags:
- nightly
- "*-nightly"
- "{{.Env.IGNORE_TAG}}"
# 以这些前缀开头的标签将被忽略。 (Pro)
#
# 模板: 支持
ignore_tag_prefixes:
- foo/
- "{{.Env.IGNORE_TAG_PREFIX}}/bar"
重试
大多数外部服务调用都会经过重试机制,对于被判定为可重试的失败情况,将采用指数退避策略。
这包括:
- Git 服务提供商 — GitHub、GitLab 和 Gitea 的 API 调用(发布、上传、里程碑、拉取请求等)
- 公告渠道 — Discord、Telegram、Slack、Mastodon、Teams、Reddit、Twitter、Bluesky、LinkedIn、Discourse、Mattermost、Webhook、OpenCollective 和 MCP
- HTTP 上传 — Artifactory、自定义 HTTP 上传及类似操作
- Docker — 镜像构建和推送(包括 dockers 和 dockers_v2),其中包含临时基础镜像拉取以及 RUN 步骤中的包安装
临时性失败(网络错误、HTTP 5xx 错误和 429 请求过多)会自动重试。永久性失败(4xx 错误、文件未找到等)则不会重试。
配置如下:
retry:
# Set max retry count.
# Setting to 1 disables retries (single attempt).
#
# Default: 10
attempts: 15
# Set delay between retry
#
# Default: 10s
delay: 10s
# Default: 5m
max_delay: 3m