unarr/.goreleaser.yml
Deivid Soto 1757bdabf5 feat(release): sign release checksums (ed25519), enforce + bake pubkey
Releases were shipping UNSIGNED: ship.sh never invoked sign-checksums, the
goreleaser pubkey ldflag defaulted to empty, and publish-cli-release.sh did not
upload a .sig — so the self-updater's signature check was silently skipped
(1.0.0-beta had no checksums.txt.sig). Make signing unconditional:

- internal/upgrade/signature.go: bake the canonical release public key as the
  compiled-in default (public, safe to commit; removes the empty-env footgun).
- .goreleaser.yml: drop the pubkey ldflag (committed default is authoritative)
  + add a signs: block that runs scripts/sign-checksums over checksums.txt.
  sign-checksums requires -key, so an unset RELEASE_SIGNING_KEY fails the build
  instead of shipping unsigned.
- scripts/ship.sh: source RELEASE_SIGNING_KEY from ~/.config/unarr-release/signing.key
  (or the env), die if absent, and assert checksums.txt.sig was produced.

Private key lives outside the repo (gitignored keyfile + operator's vault);
public key verified to match (priv[32:] == baked pubkey).
2026-06-03 19:23:19 +02:00

112 lines
3.4 KiB
YAML

version: 2
project_name: unarr
# Pre-build hook: fetch static ffmpeg + ffprobe per platform so each
# release tarball ships them adjacent to the unarr binary. ResolveFFmpeg /
# ResolveFFprobe pick them up via the "adjacent to executable" branch — no
# system install or runtime download needed.
before:
hooks:
- bash scripts/download-ffmpeg-static.sh
builds:
- main: ./cmd/unarr/
binary: unarr
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X github.com/torrentclaw/unarr/internal/cmd.Version={{.Version}}
- -X github.com/torrentclaw/unarr/internal/sentry.dsn={{ .Env.SENTRY_DSN }}
# The release-signing PUBLIC key is compiled in as the canonical default
# in internal/upgrade/signature.go (it's public — committing it removes
# the "empty env var → unsigned binary" footgun). No ldflag override:
# every build bakes the same key and verifies checksums.txt.sig.
archives:
- formats: [tar.gz]
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
format_overrides:
- goos: windows
formats: [zip]
files:
- LICENSE*
- README*
# Bundle the matching ffmpeg + ffprobe (filename includes .exe on Windows
# because download-ffmpeg-static.sh writes ffmpeg.exe / ffprobe.exe there).
- src: "dist-ffbinaries/{{ .Os }}-{{ .Arch }}/*"
dst: .
strip_parent: true
info:
mode: 0o755
checksum:
name_template: "checksums.txt"
# Sign checksums.txt with the release ed25519 private key → checksums.txt.sig,
# verified by the self-updater against the compiled-in public key. Releases are
# signed UNCONDITIONALLY: sign-checksums requires -key, so an unset/empty
# RELEASE_SIGNING_KEY makes this step (and the whole `goreleaser release`) fail
# rather than silently shipping an unsigned release. ship.sh sources the key
# from ~/.config/unarr-release/signing.key (or the RELEASE_SIGNING_KEY env).
signs:
- id: checksums
cmd: go
args:
- run
- ./scripts/sign-checksums
- -key
- "{{ .Env.RELEASE_SIGNING_KEY }}"
- -in
- "${artifact}"
- -out
- "${signature}"
signature: "${artifact}.sig"
artifacts: checksum
output: true
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
- "^chore:"
# Self-hosted Forgejo at git.torrentclaw.com. goreleaser detects GITEA_TOKEN +
# these URLs and publishes the release there instead of GitHub. Reachable via
# `forgejo` hostname inside the dokploy-network (the runner shares it); for
# local goreleaser runs outside the network, override via env GITEA_API_URL.
#
# In goreleaser v2 `gitea_urls` is a top-level key (was nested under `release`
# in v1).
gitea_urls:
api: http://forgejo:3000/api/v1
download: https://git.torrentclaw.com
skip_tls_verify: false
release:
draft: false
prerelease: auto
# Homebrew tap — requires PAT with repo scope (not GITHUB_TOKEN)
# Enable when torrentclaw/homebrew-tap PAT is configured as HOMEBREW_TAP_TOKEN
# brews:
# - repository:
# owner: torrentclaw
# name: homebrew-tap
# token: "{{ .Env.HOMEBREW_TAP_TOKEN }}"
# name: unarr
# homepage: https://github.com/torrentclaw/unarr
# description: "unarr — replaces the entire *arr stack"
# license: MIT
# install: |
# bin.install "unarr"