Establish the release process and cut v0.1.0

Open
#175 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
48/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
github-actions, go

Research direction

Start by reading .goreleaser.yaml and .github/workflows/ci.yml, then run goreleaser release --snapshot --clean locally. Review the release workflow requirements and docs/releasing.md checklist, including the cask decision and pinned actions. Done means v0.1.0 produces the three documented archives, checksums, completions, and version output, with README.md and SECURITY.md updated accurately.

Written by the indexing model from the issue text.

Description

enhancement

Establish the release process, document it, and cut v0.1.0.

.goreleaser.yaml is fully configured and nothing has ever invoked it. There are no tags, no releases, and no release workflow — ci.yml is the only workflow in the repo. So the download path, the checksum file, the archive layout and the Homebrew cask are all things this project has never done once, and every one of them is a guess until a real tag has produced real assets.

This blocks #29 (ship markfluence as a GitHub Action), whose whole premise is fetching markfluence_<version>_<os>_<arch>.tar.gz from a release. It also unblocks the two release-shaped notes already in the tree: #1 (the Homebrew tap) and #95 (SECURITY.md's supported-versions table).

What the release process has to decide

The tag must be vX.Y.Z

Git does not care, but two things here do, and both are hard requirements rather than conventions:

  • Go modules. github.com/mozilla/markfluence is a module and docs/github-actions.md tells people to go install github.com/mozilla/markfluence@latest. The module proxy only recognises semver tags with the v prefix — a 1.2.3 or release-1 tag is invisible to it, so @v1.2.3 does not resolve and @latest degrades to a v0.0.0-2026…-<sha> pseudo-version.
  • goreleaser, which parses the tag and fails with not a valid semantic version otherwise.

A prerelease suffix is fine for both: v0.1.0-rc.1 is valid semver, valid for Go, and goreleaser marks the release a prerelease on its own. Worth knowing for a dry run against a throwaway tag.

Also worth writing down because it bites downstream: .Version strips the v, so tag v1.2.3 produces markfluence_1.2.3_linux_amd64.tar.gz. Anything that constructs an asset name from a tag has to account for it.

The trigger glob is v*.*.*, not v*

The obvious tags: ['v*'] will also match a moving major tag (v1), which #29 needs. That would re-enter the workflow on every release and fail the second run on a tag goreleaser rejects as non-semver. Actions tag filters are globs rather than regex, so v*.*.* is the available way to say "three components".

The Homebrew cask needs two permissions on the release job

Settled in #1: this repository is its own tap. The cask lands in ./Casks here rather than in a separate mozilla/homebrew-markfluence, which is how mozilla/mozcloud does it, and it matters for this issue because it decides the credential. GitHub Actions' automatic GITHUB_TOKEN is scoped to the repository the workflow runs in, so a separate tap repo would have needed a fine-grained PAT someone owns and rotates; a same-repo write needs nothing extra.

What release.yml has to grant is just contents: write — which the GitHub Release itself already needs. The cask is pushed to a goreleaser/cask-<tag> branch and the release stops there; opening the PR is a human step (gh pr create), because a PR opened by the automatic GITHUB_TOKEN never triggers ci and main's ruleset requires that check with nobody able to bypass it. #1 has the measurement.

So: no separate repo to create, no pull-requests: write, and nothing here blocks on it. The one thing this issue should carry is a line in docs/releasing.md saying that the cask PR is opened by hand after the release, or the first person to cut a release will assume it failed.

No changelog file is required

There is no CHANGELOG.md and none is needed: a Release body may be empty, and .goreleaser.yaml already sets changelog: {use: github, sort: asc}, so notes are generated from commit subjects — which Conventional Commits already makes readable here. Worth a deliberate decision rather than a default, since adding one later is cheap and removing one is not.

Which platforms ship

goreleaser builds darwin+linux × arm64+amd64 — four assets as of c03b1ff. darwin/amd64 had been in ignore on the grounds that the macos-13 runner is retiring, and that came back once the repo became its own Homebrew tap: the build matrix is then the install matrix, and the cask had no on_intel block, so brew install failed on an Intel Mac. Windows is still not built and is deliberately out of scope. Recorded here because #29 turns this into a support matrix too, so it is no longer a private goreleaser detail.

Work

  • .github/workflows/release.ymlon: push: tags: ['v*.*.*'], permissions: {contents: write}, goreleaser release --clean. Every action pinned by commit SHA, the way ci.yml already pins them (the repo is under Mozilla's SSDLC zizmor gate).
  • Grant the release job contents: write (that is all the cask needs; #1 settled the shape, and .goreleaser.yaml is configured for it as of 586fbfb).
  • Decide whether release: gets draft: true plus a publish step after the upload. goreleaser creates the GitHub Release and then uploads assets, so a run that dies mid-upload leaves a latest whose archives 404 — which #29's action relies on not happening, since version: latest is its default. Drafting first is the fix; the alternative is telling consumers to pin.
  • Dry-run locally first — goreleaser release --snapshot --clean builds today — then against a real throwaway prerelease tag before v0.1.0.
  • docs/releasing.mddone as a "Cutting a release" section at the end of CONTRIBUTING.md (1f7a037), rather than a file of its own: release steps are maintainer documentation and that is where a maintainer already looks. Covers the tag format and both reasons for it, the snapshot rehearsal, the manual cask PR and why, verification, and how to recover from a failed release. It carries an IMPORTANT admonition saying the process is not usable until this issue lands — remove that admonition as part of closing this issue.
  • Any tooling the above wants — a make target, or a checklist if a target would just wrap two commands.
  • Cut v0.1.0 and verify the assets: all four archives present, checksums.txt verifying, completions/ inside the archive, markfluence --version reporting the tag from the ldflags stamp.
  • README.md: "Homebrew — TBD, published to a tap on the first release" becomes true or accurate.
  • SECURITY.md: "markfluence has not had a release yet" is no longer true. The supported-versions table itself is #95, not this.
  • CLAUDE.md if the release workflow or a new make target belongs in the Commands/architecture notes.

Why v0.1.0 and not 1.0.0

#29 is in the 1.0.0 milestone, so the action cannot wait for the release it is meant to ship with — and the release pipeline has never run, so the first tag should be the cheap one to re-cut while it is being debugged. v0.1.0 gives #29 real assets to build against, and pre-1.0 means re-tagging costs nothing if the first attempt is wrong.

markfluence is unreleased, so there is no backwards-compatibility or migration story to design for here.

Not in scope

  • The supported-versions table in SECURITY.md — #95.
  • The Homebrew tap's own follow-through — #1: the README instructions, verifying brew install end to end after v0.1.0, and whether the cask works under Homebrew on Linux. This issue only has to give the release job the two permissions the cask PR needs.
  • The moving v1 tag, and Marketplace publication. Both belong to #29, which is what needs them; release.yml grows the tag-moving step there.
  • Release provenance / attestation. checksums.txt is the integrity story for now. Worth having, and a separate change.
  • Windows and Intel-macOS builds. Deferred, as above.
Dominant language
Go
Stars
2
Forks
0
Avg merge
2h 8m
Merged PRs (30d)
49

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from mozilla/markfluence

All issues in mozilla/markfluence

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.