Skip to content

Release the .deb and the Homebrew cask with GoReleaser, cut v0.1.0 #2

Closed

Description

@Ilyes512

Wire up GoReleaser and cut v0.1.0, so the specsdeployd Ansible role
(specsops-ansible-collection#12)
has a real artifact to install and can be finished without waiting on the webhook
implementation.

Blocked by #1.

The repository is public, and has to stay that way

The role installs the .deb with an unauthenticated ansible.builtin.get_url running
on an app VM, and brew install reads the cask's release URL the same way. Release
assets of a private repository are not anonymously downloadable, so flipping this repo
back to private breaks both the role and the tap — not at release time, where it would
be noticed, but on the next VM that tries to install.

The binary holds no secrets. The alternative to a public repo is a PAT that can read
specsnl private repos, sitting on every app VM, which is a strictly worse thing to leak.

.goreleaser.yml

Copy labelsync's and
change the names. Everything below is GoReleaser OSS — only nfpm's templated
contents/scripts and the if field are Pro, and none of those are needed.

  • builds — -trimpath, CGO_ENABLED=0, goos: [linux, darwin],
    goarch: [amd64, arm64], ldflags
    -X github.com/specsnl/specsdeployd/internal/cmd.Version={{ .Version }}
  • archives — tar.gz
  • checksum — checksums.txt. Not optional: the role verifies the .deb
    against it via get_url's checksum:, which takes the URL of a sha256sum-format
    file. Without it the role has no integrity check at all, because apt: deb: has
    none
  • nfpms — formats: [deb], both arches
  • homebrew_casks — the specsdeployd@rc / specsdeployd anchor pair labelsync
    uses, with skip_upload: auto on the stable one, pushing to
    specsnl/homebrew-tap. Needs the
    HOMEBREW_TAP_GITHUB_TOKEN secret on this repo
  • .github/workflows/release.yml — on push tags v*, goreleaser-action with
    contents: write

No dockers block for now; nothing consumes a specsdeployd image.

The package ships only the binary

nfpms must not carry the systemd unit, the sudoers drop-in, the specsdeployd user
or /etc/specsdeployd/, and must have no scripts: hooks.

The Ansible role owns every one of those. If the package shipped them too, the two would
write the same paths, and dpkg would quietly win on the next apt upgrade — the unit on
disk would stop matching the role's template and nothing would report the drift. The
split is what lets the golden image bake the scaffolding while leaving the binary out
(architecture.md §9).

bindir is /usr/bin — decided

Leave nfpm's default alone. /usr/local is reserved for content the package manager
does not manage (FHS 4.9, Debian Policy 9.1.2), so a .deb must not write there.

Do not "fix" this to /usr/local/bin later to match something else. The unit's
ConditionPathExists names this exact path: if the guard and the package drift apart,
the install succeeds, the condition never fires, and the unit sits dormant — which is
indistinguishable from the intended behaviour when no version is pinned. Nothing fails
loudly.

The other two repos already name /usr/bin:

  • specsops-ansible-collection — specsdeployd_binary_path default, in issue #12 and
    to be carried into defaults/main.yml, argument_specs.yml and the README table
    when the role is written
  • specsops-golden-images — docs/architecture.md §9 and plans/app-image.md, on the
    plan-next-steps branch

Cut v0.1.0

  • Tag v0.1.0 and let the workflow publish it

Verify

The point of the release is that the role's install path works against it, so check that
rather than checking that files exist:

  • The release carries specsdeployd_0.1.0_linux_amd64.deb, the arm64 .deb, the
    tar.gz archives and checksums.txt
  • dpkg -c specsdeployd_0.1.0_linux_amd64.deb lists the binary and nothing else —
    no unit, no sudoers, no config dir
  • dpkg -I shows no maintainer scripts
  • The built binary reports the tag, not dev:
    dpkg -x it and run ./usr/bin/specsdeployd version → specsdeployd version 0.1.0
  • On an Ubuntu 26.04 box, the exact two tasks from
    collection#12
    install it — get_url with checksum: sha256:<the checksums.txt URL>, then
    apt: deb: — and a second run reports no change
  • brew install specsnl/tap/specsdeployd && specsdeployd version

Activity

  1. Ilyes512 commented on Sep 13, 2026

    @Ilyes512
    MemberAuthor

    Closed with #4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions