Skip to content

Release process

metacore-kernel is distributed as a Go module, not as a binary. There are no executable artifacts; releases exist as Git tags indexed by proxy.golang.org, with GitHub Releases providing a categorized changelog on top.

This document is the source of truth for cutting a release and for recovering from a botched one.


Table of contents

  1. Choose the version (SemVer)
  2. Cut and publish the tag
  3. What runs automatically
  4. Verify the release
  5. Consume from a host application
  6. Renovate in consumer repositories
  7. Pre-releases
  8. Rollback / retract
  9. Troubleshooting
  10. References

1. Choose the version (SemVer)

The kernel follows SemVer 2.0 strictly because the Go module graph requires it.

BumpTriggered by
Patchfix: commits, internal refactors, optimisations, doc-only
Minorfeat: commits, new exported symbols, deprecations marked // Deprecated:
Majorfeat!: / BREAKING CHANGE: body, removed/renamed exports, interface changes

Major bumps require the /v2 (or higher) module-path suffix: github.com/asteby/metacore-kernel/v2. Plan for the import-path migration in consumers ahead of time — Renovate cannot rewrite the suffix on its own.

While the kernel is in v0.x, minor bumps may technically include breaking changes. We still mark them as such in the changelog so consumers can tell the difference.

How to decide

bash
# What landed since the last tag?
git log $(git describe --tags --abbrev=0)..HEAD --oneline
  • Any feat!: / BREAKING CHANGE: lines → major.
  • Any feat: lines → minor.
  • Only fix: / chore: / docs: / test: → patch.

The first commit message that introduces a breaking change wins, regardless of how many fixes ship alongside it.

2. Cut and publish the tag

bash
# From a clean main branch:
git checkout main
git pull --ff-only
git status                          # must be clean
go test -race ./...                 # match CI

# Annotated tag — required for GoReleaser to pick up the message:
git tag -a v0.2.0 -m "Release v0.2.0"
git push origin v0.2.0

To push every pending tag at once:

bash
git push --tags

3. What runs automatically

.github/workflows/release.yml triggers on every v* tag and runs:

  1. Checkout + Go 1.25 with module cache.
  2. Tests with the race detector (go test -race ./...). Failure aborts the release.
  3. Go proxy pingcurl https://proxy.golang.org/.../@v/<tag>.info to force immediate indexing. Without it, go get may report unknown revision for several minutes.
  4. GoReleaser (release --clean) creates the GitHub Release with:
    • Categorized changelog (features / fixes / other).
    • Source archive (.tar.gz).
    • Checksums.
    • Automatic prerelease: true when the tag carries a SemVer suffix (-alpha, -beta, -rc).
  5. Consumer dispatchPOST /repos/{owner}/{repo}/dispatches to every consumer host repo with event_type=metacore-kernel-released. Each consumer can subscribe via on: repository_dispatch to run Renovate immediately.

The dispatch token (CROSSREPO_DISPATCH_TOKEN) needs repo scope on every consumer organisation. The step uses continue-on-error: true so a failed dispatch never blocks the release itself.

4. Verify the release

bash
# 1. GitHub Release exists
gh release view v0.2.0 --repo asteby/metacore-kernel

# 2. Go proxy indexed the tag
curl -s https://proxy.golang.org/github.com/asteby/metacore-kernel/@v/list
curl -s https://proxy.golang.org/github.com/asteby/metacore-kernel/@v/v0.2.0.info | jq

# 3. pkg.go.dev (5–30 minutes after release)
open https://pkg.go.dev/github.com/asteby/metacore-kernel@v0.2.0

5. Consume from a host application

In any consumer host repository:

bash
go env -w GOPRIVATE="github.com/asteby/*"   # one time per machine
go get github.com/asteby/metacore-kernel@v0.2.0
go mod tidy

Renovate, configured per consumer-guide.md, opens the PR automatically on the next schedule tick — or immediately when the repository_dispatch event arrives.

6. Renovate in consumer repositories

Every consumer ships a renovate.json derived from docs/consumer-renovate-template.json. Default policy:

  • patch + minor → auto-merge (GitHub platformAutomerge).
  • major → PR opened with breaking and review-required labels.

Auto-merge proceeds only when the consumer's CI is green. A failing test suite leaves the PR open for human intervention.

7. Pre-releases

Pre-releases let consumers exercise upcoming changes before a stable tag.

bash
git tag -a v0.3.0-alpha.1 -m "Pre-release v0.3.0-alpha.1"
git push origin v0.3.0-alpha.1

GoReleaser flags the GitHub Release as prerelease: true automatically. Renovate ignores prereleases by default — to opt a consumer into testing one, run go get github.com/asteby/metacore-kernel@v0.3.0-alpha.1 manually in that repository.

8. Rollback / retract

Go modules are immutable — once a version is on proxy.golang.org, it stays there forever. To mark a release as defective, use retract in go.mod:

bash
# 1. Add a retract directive with a rationale comment.
go mod edit -retract=v0.2.0

Resulting go.mod:

go
module github.com/asteby/metacore-kernel

go 1.25

retract (
    v0.2.0 // leaked credentials in logs; use v0.2.1+
)

Steps:

  1. Land the retract directive (and the actual fix) on main.
  2. Tag a new patch version that includes both (v0.2.1).
  3. Push the tag — the release workflow indexes it and dispatches consumers.
  4. Consumers running go get -u will see a warning and resolve to the next non-retracted version.

To retract a contiguous range:

go
retract [v0.2.0, v0.2.4]

9. Troubleshooting

SymptomLikely causeFix
go get reports unknown revisionProxy not indexed yetGOPROXY=direct go get … or wait 5 minutes
Release workflow fails on testsRecent race conditionFix on main, re-tag with the next patch version
pkg.go.dev does not show the new versionIndex lagOpen https://pkg.go.dev/github.com/asteby/metacore-kernel@vX.Y.Z to force the fetch
Consumer dispatch step failsToken missing scopeRegenerate CROSSREPO_DISPATCH_TOKEN with repo
Consumer never receives a Renovate PRRenovate disabled or GOPRIVATE mis-configuredInspect renovate.json and hostRules.token

10. References

Metacore is open-source. Apache-2.0.