Giter Site home page Giter Site logo

hugoreleaser's Introduction

Tests on Linux, MacOS and Windows Go Report Card codecov GoDoc

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.

Archive Aliases

See Hugo's use here.

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 (uses strings.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:

  1. Flags (e.g. -tag)
  2. OS environment variables.
  3. 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:

  1. Set a filename
  2. Set generate_on_host=true and let GitHub do it.
  3. 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.

hugoreleaser's People

Contributors

bep avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

seanpm2001

hugoreleaser's Issues

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.

A question about manylinux compliance for Hugo binaries

@bep

Hi! Thanks for setting this tool up. I am trying to build a Python (pip-installable) binary distribution for Hugo at https://github.com/agriyakhetarpal/hugo-python-distributions/ that embeds binaries for the extended version of Hugo for various platforms and architectures, which will be a subset of Hugo's own platform set owing to the lack of tooling for platform tags for BSD-like platforms for Python.

I am using cibuildwheel to build and package these wheels in CI and plan to upload these to PyPI (edit: have done so for Hugo 0.121.1 and 0.121.2), so that one can run the command pip install python-hugo and run commands like hugo version and hugo server --disableFastRender just like they would normally. I know that Python is not the first choice for most packagers and users of Hugo, but with this distribution I wanted to learn if it's possible to embed Go binaries in Python packages, and I have succeeded so far :)

While building Linux amd64 wheels (and arm64/aarch64 wheels under QEMU emulation), I am able to obtain the correct specification for the wheel, but the ABI tags for the wheel are constrained due to manylinux policies (see below). I was wondering if some information can be shared w.r.t the version of GLIBC being used to build Hugo from source, e.g., GLIBC has backward compatibility but not forward compatibility, so I can explore using an older manylinux2014 base Docker image with an older GCC to compile, or I'm not sure if this is coming from the Go toolchain (I am using 1.21.5 since the minimum version was bumped to 1.20 recently).

This is what I get when I run auditwheel, a tool for Linux wheel repair for Python wheels, locally:

Output

python_hugo-0.120.4-cp310-cp310-linux_x86_64.whl is consistent with
the following platform tag: "linux_aarch64".

The wheel references external versioned symbols in these
system-provided shared libraries: libgcc_s.so.1 with versions
{'GCC_3.0'}, libresolv.so.2 with versions {'GLIBC_2.2.5'}, libdl.so.2
with versions {'GLIBC_2.2.5'}, libm.so.6 with versions
{'GLIBC_2.2.5'}, libc.so.6 with versions {'GLIBC_2.4', 'GLIBC_2.2.5',
'GLIBC_2.14'}, libpthread.so.0 with versions {'GLIBC_2.2.5',
'GLIBC_2.3.2'}, libstdc++.so.6 with versions {'CXXABI_1.3',
'GLIBCXX_3.4.18', 'CXXABI_1.3.5', 'GLIBCXX_3.4.11', 'GLIBCXX_3.4.9',
'GLIBCXX_3.4'}

This constrains the platform tag to "linux_aarch64". In order to
achieve a more compatible tag, you would need to recompile a new wheel
from source on a system with earlier versions of these libraries, such
as a recent manylinux image.

(This is coming from the Hugo unix executable file in the wheel).

On a macOS arm64 machine, this is what I get from otool when I run it on the executable:

Output

otool -L hugo-0.120.4-darwin-arm64
hugo-0.120.4-darwin-arm64:
        /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)
        /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 2048.1.255)
        /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 61040.1.3)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.151.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.0.0)

which doesn't help a lot (note that I am mangling the executable name to conform to the platform and architecture rather than lipo-ing it). I tried on a Docker image and received these symbols:

Output from ldd

``` ldd hugo-0.120.4-linux-arm64 linux-vdso.so.1 (0x0000ffff84bc2000) libresolv.so.2 => /lib/aarch64-linux-gnu/libresolv.so.2 (0x0000ffff84b6b000) libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff84b3a000) libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000ffff84962000) libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff848b7000) libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffff848a3000) libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000ffff8487f000) libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff8470b000) /lib/ld-linux-aarch64.so.1 (0x0000ffff84b92000) ```

I can manually modify the platform tag in the filename(s) to adhere to such compliance, given that the Hugo binary and its commands are working without any issues, but there are risks to this approach and make wheels non-reproducible and non-compliant on older Linux platforms, due to issues such as old system-provided libraries, missing or unresolved symbols, and the like. If the newer versions of the Hugo binaries are supposed to work just on modern systems, then there shouldn't be a problem with manually overwriting these tags – but I thought I should ask around first. Another option I am considering is to use a very old Docker image that comes with a very old GLIBC for this purpose, but building Hugo from source might break in that case. I'm not as familiar with Golang and building packages with it, which is diametrically on the other end in comparison to my experience with Python tooling, and therefore this is a new area for me – I would appreciate a response :))


(P.S. This is a problem on just the Linux wheels I have been trying to compile. I have packaging infrastructure for Windows amd64 wheels and macOS arm64 + amd64 wheels set up—with universal2 wheels too for the latter—I tested the Hugo binary for 0.120.4 manually and it works on Intel MacBooks as old as those released in 2015!)

Be smarter about config merges

This relates to #19 and is in the make a note of it category.

[[archives]]
    paths = ["builds/**/regular/linux/{arm64,amd64}"]
    [archives.archive_settings]
        [archives.archive_settings.type]
            format    = "_plugin"
            extension = ".deb"
        [archives.archive_settings.plugin]
            id      = "deb"
            type    = "gorun"
            command = "github.com/gohugoio/hugoreleaser-archive-plugins/deb@latest"
        [archives.archive_settings.custom_settings]
            vendor      = "gohugo.io"
            homepage    = "https://github.com/gohugoio/hugoreleaser"
            maintainer  = "Bjørn Erik Pedersen <[email protected]>"
            description = "Build, archive and release Go programs."
            license     = "Apache-2.0"
[[archives]]
    paths = ["builds/**/extended/linux/{arm64,amd64}"]
    [archives.archive_settings]
        name_template = "{{ .Project }}_extended_{{ .Tag | trimPrefix `v` }}_{{ .Goos }}-{{ .Goarch }}"
        [archives.archive_settings.type]
            format    = "_plugin"
            extension = ".deb"
        [archives.archive_settings.plugin]
            id      = "deb"
            type    = "gorun"
            command = "github.com/gohugoio/hugoreleaser-archive-plugins/deb@latest"
        [archives.archive_settings.custom_settings]
            vendor      = "gohugo.io"
            homepage    = "https://github.com/gohugoio/hugoreleaser"
            maintainer  = "Bjørn Erik Pedersen <[email protected]>"
            description = "Build, archive and release Go programs."
            license     = "Apache-2.0"

In the above I had to duplicate most parts to apply a different name_template. This is unfortunate, but maybe not a big deal.

Windows archives outputted as msi

hey @bep

Thank you for this code. I got it running and it’s elegant how the apple notarisation works.

i was hoping that for windows windows archive like msi or similar for windows .
Instead it outputs a zip.

is there a reason why it’s a zip file or is it just that you did not have time to get it outputting msi ?

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?

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

TODO(bep)

This is just a short term list to get it ready for Hugo, and does not set any scope for the future (which will be very narrow ...).

  • Move the plugins module to a new hugoreleaser-plugins-api.
  • Move the deb plugin to a new hugoreleaser-archive-plugins.
  • Collapse into one --paths flag (a slice), see below.
  • Remove the goarm setting, that can be set in env.
  • Add a optional "!" (not) prefix to the Glob patterns.
  • Only start archive plugins on the archive step.
  • Add more context (e.g. number of workers to first info statement.
  • Make sure the simple typed flags (strings, bool etc.) are available as HUGORELEASER_TAG etc. in config replacements (also when they're just set as -tag)
  • Add short_title, short_threshold for release notes with a low number of changes.
  • Add option for a custom release notes template.

Two minor changelog issues

I've been using this with Hugo lately, and it works great. Two issues with the changelog:

  1. For short releases, when the "collapse" is set, it doesn't seem to respect ignored groups.
  2. For patch releases, it seem to include changes since the last minor release.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.