mirror of
https://github.com/goreleaser/goreleaser-action
synced 2026-09-02 19:38:29 +00:00
Review found that the GitHub Actions cache layer cost more than it saved. Measured on ubuntu-latest, same job, same version: cold: download + checksum + cosign + extract 0.93 s cache hit: restore the 24 MB entry 1.28 s first run also pays a save +2.26 s It is slower than a download in every configuration measured, because a GitHub-hosted runner reaches the release CDN in about 0.4 s for a 15 MB archive, and the cached entry is the larger extracted directory. It also skipped the sha256 and cosign verification on a hit, which is the control it was supposed to protect, and the only case where it wins on time is when cosign is installed, which is exactly the case where skipping is wrong. It cost 875 KB (+120%) of dist/index.js for every user and 24 MB of repository cache quota per version and platform. The restore and save wrappers were also dead code: @actions/cache catches everything except ValidationError internally, so the try/catch and the ReserveCacheError classification could never run. What remains is the runner tool cache lookup, which is what #476 asked for, and the distribution-keyed tool name that stops a Pro binary being returned for an OSS install. The tool cache test asserted that two installs return the same path, but that path is a pure function of the tool, version and architecture: it passed even with the tool cache wiped between the calls. It now asserts that the second install reports a tool cache hit and does not download, and it was verified to fail when the lookup is removed. Co-authored-by: timbretimber <105982513+timbretimber@users.noreply.github.com> Co-authored-by: Akkuman <akkumans@qq.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4eaf86fa-a85b-41f6-8763-612acc1ccc39 Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
334 lines
12 KiB
Markdown
334 lines
12 KiB
Markdown
<p align="center">
|
|
<img alt="GoReleaser Logo" src="https://avatars2.githubusercontent.com/u/24697112?v=3&s=200" height="140" />
|
|
<h3 align="center">GoReleaser Action</h3>
|
|
<p align="center"><a href="https://github.com/features/actions">GitHub Action</a> for GoReleaser</p>
|
|
<p align="center">
|
|
<a href="https://github.com/goreleaser/goreleaser-action/releases/latest"><img alt="GitHub release" src="https://img.shields.io/github/release/goreleaser/goreleaser-action.svg?logo=github&style=flat-square"></a>
|
|
<a href="https://github.com/marketplace/actions/goreleaser-action"><img alt="GitHub marketplace" src="https://img.shields.io/badge/marketplace-goreleaser--action-blue?logo=github&style=flat-square"></a>
|
|
<a href="https://github.com/goreleaser/goreleaser-action/actions?workflow=test"><img alt="Test workflow" src="https://img.shields.io/github/actions/workflow/status/goreleaser/goreleaser-action/test.yml?label=test&branch=master&logo=github&style=flat-square"></a>
|
|
<a href="https://codecov.io/gh/goreleaser/goreleaser-action"><img alt="Codecov" src="https://img.shields.io/codecov/c/github/goreleaser/goreleaser-action?logo=codecov&style=flat-square"></a>
|
|
</p>
|
|
</p>
|
|
|
|
___
|
|
|
|

|
|
|
|
* [Usage](#usage)
|
|
* [Workflow](#workflow)
|
|
* [Verification](#verification)
|
|
* [Run on new tag](#run-on-new-tag)
|
|
* [Signing](#signing)
|
|
* [Upload artifacts](#upload-artifacts)
|
|
* [Install Only](#install-only)
|
|
* [Cache the binary](#cache-the-binary)
|
|
* [Customizing](#customizing)
|
|
* [inputs](#inputs)
|
|
* [outputs](#outputs)
|
|
* [environment variables](#environment-variables)
|
|
* [Limitation](#limitation)
|
|
* [Development](#development)
|
|
* [License](#license)
|
|
|
|
## Usage
|
|
|
|
GoReleaser Action runs [goreleaser][], please follow its [docs][gdocs] for
|
|
more information about how to customize what GoReleaser does.
|
|
|
|
[goreleaser]: https://goreleaser.com/
|
|
[gdocs]: https://goreleaser.com/customization
|
|
|
|
### Workflow
|
|
|
|
```yaml
|
|
name: goreleaser
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
goreleaser:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
-
|
|
name: Checkout
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
-
|
|
name: Set up Go
|
|
uses: actions/setup-go@v6
|
|
-
|
|
name: Run GoReleaser
|
|
uses: goreleaser/goreleaser-action@v7
|
|
with:
|
|
# either 'goreleaser' (default) or 'goreleaser-pro'
|
|
distribution: goreleaser
|
|
# 'latest', 'nightly', or a semver
|
|
version: '~> v2'
|
|
args: release --clean
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
|
|
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
|
```
|
|
|
|
> **IMPORTANT**: note the `fetch-depth: 0` input in `Checkout` step. It is required for the changelog to work correctly.
|
|
|
|
### Verification
|
|
|
|
The action verifies the integrity of the downloaded GoReleaser archive
|
|
against the published `checksums.txt` automatically — no configuration
|
|
required.
|
|
|
|
If [`cosign`](https://docs.sigstore.dev/cosign/) is available on `PATH`, the
|
|
action will additionally verify the cosign sigstore signature of the
|
|
checksums file against the GoReleaser release workflow's OIDC identity. If
|
|
`cosign` isn't installed, this step is silently skipped.
|
|
|
|
> **Note**: cosign signature verification requires GoReleaser **v2.13.0 or
|
|
> newer** (and the matching `nightly`). Earlier releases ship a `.sig`
|
|
> detached signature signed with cosign v2, which is not compatible with
|
|
> the cosign v3 sigstore-bundle format the action verifies. For older
|
|
> versions the cosign step is silently skipped — only the `checksums.txt`
|
|
> SHA-256 verification runs.
|
|
|
|
> **Note**: when `version: nightly` is used, the action resolves the
|
|
> latest immutable `vX.Y.Z-<sha>-nightly` release from the GitHub
|
|
> Releases API. Pass `GITHUB_TOKEN` to the action step (as in the example
|
|
> above) to avoid unauthenticated API rate limits.
|
|
|
|
To enable signature verification, install cosign before running the action:
|
|
|
|
```yaml
|
|
-
|
|
name: Install cosign
|
|
uses: sigstore/cosign-installer@v3
|
|
-
|
|
name: Run GoReleaser
|
|
uses: goreleaser/goreleaser-action@v7
|
|
with:
|
|
distribution: goreleaser
|
|
version: '~> v2'
|
|
args: release --clean
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
```
|
|
|
|
Both checksum and signature verification work for tagged releases (≥ v2.13.0)
|
|
and the `nightly` channel.
|
|
|
|
### Run on new tag
|
|
|
|
If you want to run GoReleaser only on new tag, you can use this event:
|
|
|
|
```yaml
|
|
on:
|
|
push:
|
|
tags:
|
|
- '*'
|
|
```
|
|
|
|
Or with a condition on GoReleaser step:
|
|
|
|
```yaml
|
|
-
|
|
name: Run GoReleaser
|
|
uses: goreleaser/goreleaser-action@v7
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
with:
|
|
version: '~> v2'
|
|
args: release --clean
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
```
|
|
|
|
> For detailed instructions please follow GitHub Actions [workflow syntax](https://help.github.com/en/articles/workflow-syntax-for-github-actions#About-yaml-syntax-for-workflows).
|
|
|
|
### Signing
|
|
|
|
If [signing is enabled](https://goreleaser.com/customization/#Signing) in your GoReleaser configuration, you can use
|
|
the [Import GPG](https://github.com/crazy-max/ghaction-import-gpg) GitHub Action along with this one:
|
|
|
|
```yaml
|
|
-
|
|
name: Import GPG key
|
|
id: import_gpg
|
|
uses: crazy-max/ghaction-import-gpg@v7
|
|
with:
|
|
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
|
passphrase: ${{ secrets.PASSPHRASE }}
|
|
-
|
|
name: Run GoReleaser
|
|
uses: goreleaser/goreleaser-action@v7
|
|
with:
|
|
version: '~> v2'
|
|
args: release --clean
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
|
```
|
|
|
|
And reference the fingerprint in your signing configuration using the `GPG_FINGERPRINT` environment variable:
|
|
|
|
```yaml
|
|
signs:
|
|
- artifacts: checksum
|
|
args: ["--batch", "-u", "{{ .Env.GPG_FINGERPRINT }}", "--output", "${signature}", "--detach-sign", "${artifact}"]
|
|
```
|
|
|
|
### Upload artifacts
|
|
|
|
For some events like pull request or schedule you might want to store the artifacts somewhere for testing
|
|
purposes. You can do that with the [actions/upload-artifact](https://github.com/actions/upload-artifact) action:
|
|
|
|
```yaml
|
|
-
|
|
name: Run GoReleaser
|
|
uses: goreleaser/goreleaser-action@v7
|
|
with:
|
|
version: '~> v2'
|
|
args: release --clean
|
|
workdir: myfolder
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
-
|
|
name: Upload assets
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: myapp
|
|
path: myfolder/dist/*
|
|
```
|
|
|
|
### Install Only
|
|
|
|
```yaml
|
|
steps:
|
|
-
|
|
name: Install GoReleaser
|
|
uses: goreleaser/goreleaser-action@v7
|
|
with:
|
|
install-only: true
|
|
-
|
|
name: Show GoReleaser version
|
|
run: goreleaser -v
|
|
```
|
|
|
|
### Cache the binary
|
|
|
|
The action looks for GoReleaser in the [runner tool cache][toolcache] before it
|
|
downloads. A second use of the action in the same job, or any job on a
|
|
self-hosted runner that already has the version, installs immediately.
|
|
|
|
A binary taken from the tool cache is not verified again, because the checksum
|
|
and the cosign signature were verified when it was first written. On a
|
|
self-hosted runner the tool cache is kept between jobs, so it must be trusted
|
|
like the runner itself. GitHub-hosted runners start with an empty tool cache in
|
|
every job, so they always download and verify.
|
|
|
|
The action does not use the [GitHub Actions cache][ghcache]. It was measured and
|
|
it is slower than a download: restoring the 24 MB entry takes about 1.3 s, while
|
|
downloading, verifying the checksum, verifying the cosign signature and
|
|
extracting the release takes about 0.9 s on a GitHub-hosted runner. It would
|
|
also skip the verification it is supposed to protect.
|
|
|
|
[toolcache]: https://github.com/actions/toolkit/tree/main/packages/tool-cache
|
|
[ghcache]: https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/cache-dependencies
|
|
|
|
## Customizing
|
|
|
|
### inputs
|
|
|
|
Following inputs can be used as `step.with` keys
|
|
|
|
| Name | Type | Default | Description |
|
|
|------------------|---------|--------------|------------------------------------------------------------------|
|
|
| `distribution` | String | `goreleaser` | GoReleaser distribution, either `goreleaser` or `goreleaser-pro` |
|
|
| `version`**¹** | String | `~> v2` | GoReleaser version |
|
|
| `version-file`**²** | String | | Read the GoReleaser version from a file (see below) |
|
|
| `args` | String | | Arguments to pass to GoReleaser |
|
|
| `workdir` | String | `.` | Working directory (below repository root) |
|
|
| `install-only` | Bool | `false` | Just install GoReleaser |
|
|
|
|
> **¹** Can be a fixed version like `v0.117.0` or a max satisfying semver one like `~> 0.132`. In this case this will return `v0.132.1`.
|
|
>
|
|
> **²** Path to a file containing the GoReleaser version. Resolved relative
|
|
> to `workdir`. Currently only [`.tool-versions`](https://asdf-vm.com/manage/configuration.html#tool-versions)
|
|
> (asdf/mise) format is supported. When set, this takes precedence over `version`.
|
|
>
|
|
> ```yaml
|
|
> # .tool-versions
|
|
> goreleaser 2.13.0
|
|
> ```
|
|
>
|
|
> ```yaml
|
|
> - uses: goreleaser/goreleaser-action@v7
|
|
> with:
|
|
> version-file: .tool-versions
|
|
> args: release --clean
|
|
> ```
|
|
|
|
### outputs
|
|
|
|
Following outputs are available
|
|
|
|
| Name | Type | Description |
|
|
|-------------|------|------------------------|
|
|
| `artifacts` | JSON | Build result artifacts |
|
|
| `metadata` | JSON | Build result metadata |
|
|
|
|
### environment variables
|
|
|
|
Following environment variables can be used as `step.env` keys
|
|
|
|
| Name | Description |
|
|
|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
| `GITHUB_TOKEN` | [GITHUB_TOKEN](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token) as provided by `secrets` and requires `contents:write` |
|
|
| `GORELEASER_KEY` | Your [GoReleaser Pro](https://goreleaser.com/pro) License Key, in case you are using the `goreleaser-pro` distribution |
|
|
|
|
## Limitation
|
|
|
|
`GITHUB_TOKEN` permissions [are limited to the repository](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#about-the-github_token-secret)
|
|
that contains your workflow.
|
|
|
|
If you need to push the homebrew tap to another repository, you must therefore create a custom [Personal Access Token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)
|
|
with `repo` permissions and [add it as a secret in the repository](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets). If you create a
|
|
secret named `GH_PAT`, the step will look like this:
|
|
|
|
```yaml
|
|
-
|
|
name: Run GoReleaser
|
|
uses: goreleaser/goreleaser-action@v7
|
|
with:
|
|
version: '~> v2'
|
|
args: release --clean
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
|
```
|
|
|
|
## Migrating from v3
|
|
|
|
If you need the auto-snapshot feature, take a look at [this example repository](https://github.com/caarlos0/goreleaser-action-v4-auto-snapshot-example): it's a minimal working example with all you need.
|
|
|
|
## Development
|
|
|
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full development workflow.
|
|
|
|
Quick reference:
|
|
|
|
```
|
|
# install dependencies
|
|
npm ci
|
|
|
|
# format, build dist/, and run tests
|
|
npm run pre-checkin
|
|
```
|
|
|
|
## License
|
|
|
|
MIT. See `LICENSE` for more details.
|