Configuration
Configuration File
Hugoreleaser reads its main configuration from a file named hugoreleaser.toml
in the working directory. See this project's configuration for an annotated example.
Template Expansion
Hugoreleaser supports Go template syntax in all fields with suffix _template
(e.g. name_template
used to create archive names).
The data received in the template (e.g. the ".") is:
Field | Description |
---|---|
Project | The project name as defined in config. |
Tag | The tag as defined by the -tag flag. |
Goos | The current GOOS. |
Goarch | The current GOARCH. |
In addition to Go's built-ins, we have added a small number of convenient template funcs:
upper
lower
replace
(usesstrings.ReplaceAll
)trimPrefix
trimSuffix
With that, a name template may look like this:
name_template = "{{ .Project }}_{{ .Tag | trimPrefix `v` }}_{{ .Goos }}-{{ .Goarch }}"
Environment Variables
The order of presedence for environment variables/flags:
- Flags (e.g.
-tag
) - OS environment variables.
- Environment variables defined in
hugoreleaser.env
.
A hugoreleaser.env
file will, if found in the current directory, be parsed and loaded into the environment of the running process. The format is simple, a text files of key-value-pairs on the form KEY=value
, empty lines and lines starting with #
is ignored:
Environment variable expressions in hugoreleaser.toml
on the form ${VAR}
will be expanded before it's parsed.
An example hugoreleaser.env
with the enviromnent for the next release may look like this:
HUGORELEASER_TAG=v1.2.3
HUGORELEASER_COMMITISH=main
MYPROJECT_RELEASE_NAME=First Release!
MYPROJECT_RELEASE_DRAFT=false
In the above, the variables prefixed HUGORELEASER_
will be used to set the flags when running the hugoreleaser
commands.
The other custom variables can be used in hugoreleaser.toml
, e.g:
[release_settings]
name = "${MYPROJECT_RELEASE_NAME}"
draft = "${MYPROJECT_RELEASE_DRAFT@U}"
Note the special @U
(Unquoute) syntax. The field draft
is a boolean and cannot be quouted, but this would create ugly validation errors in TOML aware editors. The construct above signals that the quoutes (single or double) should be removed before doing any variable expansion.
Glob Matching
Hugo releaser supports the Glob rules as defined in Gobwas Glob with one additional rule: Glob patterns can be negated with a !
prefix.
The CLI -paths
flag is a slice an, if repeated for a given prefix, will be ANDed together, e.g.:
hugoreleaser build -paths "builds/**" -paths "!builds/**/arm64"
The above will build everything, expect the ARM64 GOARCH
.
Partitions
Manual Partitioning
The configuration file and the (mimics the directory structure inside /dist
) creates a simple tree structure that can be used to partition a build/release. All commands takes one or more -paths
flag values. This is a Glob Path matching builds to cover or releases to release (the latter is only relevant for the last step). Hugo has partitioned its builds using a container name as the first path element. With that, releasing may look something like this:
# Run this in container1
hugoreleaser build --paths "builds/container1/**"
# Run this in container2, using the same /dist as the first step.
hugoreleaser build --paths "builds/container2/**"
hugoreleaser archive
hugoreleaser release
Parallelism
The build command takes the optional -chunks
and -chunk-index
which could be used to automatically split the builds to speed up pipelines., e.g. using Circle CI's Job Splitting.
See Hugo v0.102.0 Release Notes for more information.
Plugins
Hugoreleaser supports Go Module plugins to create archives. See the Deb Plugin for an example.
See the Hugoreleaser Plugins API for API and more information.
Release Notes
The config map release_notes_settings
has 3 options for how to handle release notes:
- Set a
filename
- Set
generate_on_host=true
and let GitHub do it. - Set
generate=true
and let Hugoreleaser do it.
There are more details about change grouping etc. in this this project's configuration.
For the third option, you can set a custom release notes template to use in template_filename
. See the default template in staticfiles/templates/release-notes.gotmpl for an example.
Why another Go release tool?
If you need a Go build/release tool with all the bells and whistles, check out GoReleaser. This project was created because Hugo needed some features not on the road map of that project.
Hugo has used this tool for all of its releases since v0.102.0.
How is hugoreleaser related to goreleaser (if at all)?
I'm currently looking into Goreleaser and was trying to figure out if it supports custom messages in changelogs. Came across this several year old issue from you requesting a related feature. Now I wanted to see how things are setup in Hugo nowadays and discovered Hugoreleaser.
Now I am wondering if and how Hugoreleaser is related to the former?
Detect duplicate archive names within a release
This works great in the simple use cases, but in Hugo's case there seem to be a case where the same archive is uploaded twice, getting some weird 404 errors from GitHub. This may be due to how I configured the build, but that is a common mistake to make that we need to handle better.
Shuffle chunked builds
Testing this feature on Circle CI, it works great, but I'm noticing that reasource heavy builds (e.g. CGO builds and the MacOS universal builds) tend to be configured together and end up in "resource heavy" partitions.
This commit shuffling the builds before the chunk operation, which should improve this.
Throw an error on duplicate archive names in a release
This had me head scratching when testing this with Hugo yesterday, getting some weird 404 errors from GitHub.
Note that this error will be thrown even with the
-try
flag, so you can do:To do a basic verification of your setup.
Two minor changelog issues
I've been using this with Hugo lately, and it works great. Two issues with the changelog:
Replace TOML for the config with ... something
When I started this project, part of the motivation was to see how it would look if I started a new CLI project from scratch.
I chose TOML as the config format because I like its simplicity; it's easy to read (especially when properly indented) and is robust against typing mistakes (YAML errors can be relatively costly when you don't discover them before the CI build is running).
But, looking back (and also after discovering aliases in YAML), especially at the duplication/merge logic added to avoid too much repetition, I want to take a minute to think about better alternatives out there before I set this in stone.
Maybe ...
https://github.com/cue-lang/cue
Be smarter about config merges
This relates to #19 and is in the make a note of it category.
In the above I had to duplicate most parts to apply a different
name_template
. This is unfortunate, but maybe not a big deal.Add -chunks, -chunk-index to the build command
To partition the build step for greater parallelism.
The idea is to use this with Circle CI's
CIRCLE_NODE_INDEX
andCIRCLE_NODE_TOTAL
env vars. How well/if that works out, time will tell.Implement autogenerated release notes
With that there is also a slight change in the release notes config config:
Release notes settings are pulled out in its own map: release_notes_settings.
Fixes #12