Releasing#

This repository holds several Go modules. Each is tagged and released on its own, which is what lets a project depend on adapter/gin without pulling in fasthttp, and on core without pulling in anything at all.

Tags#

Go derives a module’s version from a tag whose prefix is the module’s path relative to the repository root:

Module Tag
core v1.2.3
adapter/gin adapter/gin/v1.2.3
storage/redis storage/redis/v1.2.3
websubtest websubtest/v1.2.3

The core module is the repository root: its go.mod declares github.com/Jazzmoon/websub, the bare repo import path, so its files live directly at the repo root rather than in a named subdirectory (Go requires the two to match), and its tags carry no prefix as a result. Every other module’s go.mod lives in a subdirectory matching its own path suffix.

Changelogs#

The root CHANGELOG.md is core’s changelog, not the whole repository’s. Each other module gets its own CHANGELOG.md in its own directory, written the first time that module ships. They version independently: an adapter/fiber patch that doesn’t touch core has nothing to say in the root file, and someone depending on just storage/redis shouldn’t have to read core’s history to find out what changed in theirs.

Order#

core is tagged first, always. Every other module depends on it, and a module cannot require a version that does not exist yet. Not every module has to ship in the same round: core can be released on its own, with adapters and storage backends following whenever they’re ready, as long as they always come after the core version they require.

  1. Update core’s CHANGELOG.md (or the changelog of whichever other module you’re releasing).
  2. Confirm every module you’re releasing is green: go vet, gofmt -l ., and go test ./... -race -shuffle=on.
  3. Tag and push core, if this round includes it.
  4. For every other module in this round: update the require github.com/Jazzmoon/websub line in its go.mod to the core version it needs, then tag and push it.

During development#

go.work is what makes an edit to core show up immediately in the adapters and in websubtest, and what lets go test ./... see one consistent build list across all of them.

Versioning#

Semantic versioning, starting from v1.0.0. The public API is frozen as of that tag; the CHANGELOG says when something changes.

Two things need a major version bump:

  • Any change to the exported API of core, including adding a method to SubscriptionStore, which breaks every third party backend.
  • Any change to behavior a caller could reasonably have depended on, even where the signature is unchanged.

Adding a case to the conformance suite is not a breaking change to core, but it can break an adapter or a backend that was quietly non-conformant. That is the point of it.

Module paths and v2#

If core ever reaches v2, its module path becomes github.com/Jazzmoon/websub/v2 and every dependent module’s import path and requirement changes with it. Semantic import versioning is not optional and the tooling will not paper over it.