Open-source project
goreleaser/goreleaser-action avatar
goreleaser/goreleaser-action

goreleaser-action: running GoReleaser in CI with checksum and cosign verification

GitHub Action for GoReleaser

1,039 stars105 forksTypeScriptMIT

At a glance

What is it?
The goreleaser-action GitHub Action downloads a GoReleaser distribution, verifies it against the published checksums.txt, and additionally verifies the cosign sigstore signature when cosign is on the PATH. It also caches the binary, can install without running, and needs a full git history before the changelog works.
Who is it for?
goreleaser-action suits a Go project that ships binaries through GitHub Releases and wants the release step to be one block of YAML with integrity verification switched on by default rather than remembered.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • goreleaser/goreleaser-action1,039 ★ · +2
Star history
Repository2026-10-212026-11-07
goreleaser/goreleaser-action1k1k

2 Stars in the last 17 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

What the action actually is: an installer and a launcher for GoReleaser

The goreleaser-action repository holds a GitHub Action that runs GoReleaser, and the README is clear that the action itself is not where the release behaviour lives. It says GoReleaser Action runs goreleaser, and to follow the GoReleaser documentation for more information about how to customize what GoReleaser does, linking to the customization page. That separation is the right one, because a release tool's configuration surface is large and versioned independently of the CI wrapper. The action's job is to pick a GoReleaser distribution, put it on the PATH, verify it, and run the arguments you give it. The package.json confirms the scope: the entry point is src/main.ts, and the runtime dependencies are the GitHub Actions toolkit packages for core, exec, http-client and tool-cache, plus js-yaml, semver and yargs. There is no release logic in there at all.

The workflow example, and the one input that silently breaks the changelog

The README's workflow example is a complete GitHub Actions job, and the whole thing is short enough to read as a template. It runs on pull_request and push, on ubuntu-latest, with permissions of contents: write, and three steps: a checkout with actions/checkout@v6 and a fetch-depth of 0, a Go setup with actions/setup-go@v6, and the GoReleaser step with goreleaser/goreleaser-action@v7, a distribution of goreleaser, a version constraint of ~> v2, and args of release --clean. The env block passes GITHUB_TOKEN from the secrets, with a commented line for the GoReleaser Pro key. The important line is the one the README singles out in a callout: the fetch-depth: 0 input in the Checkout step is required for the changelog to work correctly. A shallow clone gives GoReleaser no history to diff, so the changelog is empty or wrong, and the failure is quiet rather than loud.

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:
          distribution: goreleaser
          version: '~> v2'
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Verification: checksums always, cosign when it is available

The action verifies the integrity of the downloaded GoReleaser archive against the published checksums.txt automatically, with no configuration required. On top of that, if cosign is available on the PATH, the action additionally verifies the cosign sigstore signature of the checksums file against the GoReleaser release workflow's OIDC identity, and if cosign is not installed this step is silently skipped. That ordering is deliberate and worth understanding. The checksum verification protects the archive against corruption and against a substituted download, and it is unconditional. The signature verification protects the checksums file itself, which is the thing an attacker would want to replace along with the binary, and it is conditional because cosign is a separate binary that has to be installed. Enabling it is a matter of adding the sigstore installer step before the GoReleaser step.

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 }}

The version floor for signatures, and the nightly channel caveat

The signature verification has a version requirement that is easy to miss, and the README spells it out in a separate 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, so for older versions the cosign step is silently skipped and only the checksums.txt SHA-256 verification runs. There is a second note about the nightly channel. When version: nightly is used, the action resolves the latest immutable vX.Y.Z-sha-nightly release from the GitHub Releases API, and you should pass GITHUB_TOKEN to the action step to avoid unauthenticated API rate limits. Both checksum and signature verification work for tagged releases at or above v2.13.0 and for the nightly channel.

Signing the artifacts themselves, with GPG and a fingerprint from the import step

Verification of the GoReleaser binary is a separate concern from signing the artifacts GoReleaser produces, and the README treats them separately. If signing is enabled in the GoReleaser configuration, you use the Import GPG action along with this one, and the pattern is that the GPG key is imported with an id, and its fingerprint is passed to the GoReleaser step as the GPG_FINGERPRINT environment variable. The GoReleaser configuration then references that environment variable in the signing args, with a --batch flag, a -u flag carrying the fingerprint template, an --output of the signature path and a --detach-sign of the artifact. The artifacts block on the signing entry is the checksum file, so the detached signature covers the checksums. The design here is that the fingerprint is never typed into the configuration, it flows from the import step through the environment, which avoids the class of mistake where the signing key and the signing identity disagree.

yaml
signs:
  - artifacts: checksum
    args: ["--batch", "-u", "{{ .Env.GPG_FINGERPRINT }}", "--output", "${signature}", "--detach-sign", "${artifact}"]

Running on tags only, and uploading artifacts for pull requests

Two workflow patterns cover the two common cases. To run GoReleaser only on a new tag, the trigger is a push on tags with a wildcard pattern. The alternative is to keep the general trigger and put a condition on the GoReleaser step itself, using an if expression that checks whether the ref starts with refs/tags/. The second pattern is usually the better one when you also want the build to run on pull requests, because a single workflow with a conditional step keeps one definition of the release steps. The README then covers the opposite problem, the case where you want the built assets stored rather than released, which applies to pull request or schedule events. The workdir input points GoReleaser at a subdirectory, and actions/upload-artifact then stores the contents of the dist directory under a chosen name.

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 }}

Install only, caching, and how the action is built and tested

The Install Only section covers a case that is easy to miss: using the action to put GoReleaser on the PATH without running a release, which is what you want in a job that then runs your own commands against the installed binary. There is also a "Cache the binary" section, and the inputs, outputs and environment variables are documented in the customizing section. The repository layout shows how the action itself is developed. The source is src/, the compiled output is committed under dist/, which is the convention for a JavaScript action so the marketplace can run it without a build step, and action.yml at the root is the action manifest. The build script is ncc build src/main.ts with minification, the tests are Jest with coverage and run with experimental vm modules enabled, linting is ESLint with a zero warnings threshold, and formatting is Prettier. The pre-checkin script chains format, lint fix, build and test, and the CI workflow badge is named test.

Licence, releases and the practical shape of a release job

The licence is MIT, with the LICENSE file at the root of the repository, and the package manifest records the author as CrazyMax, who also maintains the GPG import action the README recommends. The releases are v7.2.2 on 2026-05-19, v7.2.3 on 2026-06-29 and v7.3.0 on 2026-10-12, and the last push to the repository was on the same day as the newest tag. The action is published on the GitHub Marketplace under the goreleaser-action name, and the README points at the marketplace listing as well as the releases page. Taken together, the shape of the whole thing is that a Go project maintains its release configuration in a.goreleaser.yaml, the action installs and verifies the right GoReleaser build, and the CI job becomes a small block of YAML rather than a set of hand maintained install steps.

Editorial conclusion

goreleaser-action suits a Go project that ships binaries through GitHub Releases and wants the release step to be one block of YAML with integrity verification switched on by default rather than remembered. It is the wrong choice for a project that does not use GoReleaser at all, since the action only installs and invokes it, and a poor fit if you need signature verification on GoReleaser older than v2.13.0, because the cosign step is silently skipped for those releases and only the checksums.txt SHA-256 verification runs. Before adopting it, remember the fetch-depth: 0 requirement in the checkout step, because the changelog is generated from the git history and a shallow clone produces a broken one, and note that if cosign is not installed the signature verification is skipped without an error rather than failing.

Frequently asked questions

What does the goreleaser-action GitHub Action do?

It runs GoReleaser in a workflow. The action downloads a GoReleaser distribution, verifies the downloaded archive against the published checksums.txt automatically with no configuration required, and if cosign is available on the PATH it also verifies the cosign sigstore signature of the checksums file against the GoReleaser release workflow's OIDC identity.

Why does the goreleaser-action workflow need fetch-depth: 0?

The README calls it out in a note: the fetch-depth: 0 input in the Checkout step is required for the changelog to work correctly. A shallow clone leaves GoReleaser without the git history it needs to generate the release notes.

How do I enable cosign signature verification in goreleaser-action?

Install cosign before the GoReleaser step with the sigstore/cosign-installer action. If cosign is not installed the signature step is silently skipped, so without that step only the checksums.txt SHA-256 verification runs.

Which GoReleaser versions support cosign verification in goreleaser-action?

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, so for those versions the cosign step is skipped silently.

How do I sign artifacts with GPG using goreleaser-action?

Use the Import GPG action to import the key and expose its fingerprint, pass that fingerprint to the GoReleaser step as the GPG_FINGERPRINT environment variable, and reference it in the GoReleaser signing configuration, for example with args of --batch, -u, the fingerprint template, --output and --detach-sign.

Official sources

  1. goreleaser/goreleaser-action on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/goreleaser-goreleaser-action.svg)](https://hysenlabs.com/projects/goreleaser-goreleaser-action)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/goreleaser-goreleaser-action.svg)](https://hysenlabs.com/projects/goreleaser-goreleaser-action)

Was this useful?