Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ tab, run the **Release** workflow from `main`, and choose a bump:

CI runs `script/release`, which regenerates and verifies the tree, runs the
full build, computes the next version from the latest `go/vX.Y.Z` tag, pushes
the tag, cuts a GitHub Release with generated notes, and warms the Go module
proxy. The first release has no prior tag, so it bases off `v0.0.0` — pick
**minor** to land on `v0.1.0`.
the tag, cuts a GitHub Release with generated notes, and confirms the new
version resolves through the Go toolchain. The first release has no prior tag,
so it bases off `v0.0.0` — pick **minor** to land on `v0.1.0`.

This repo is private, so the public module proxy can't see it: the toolchain
resolves it `direct` over git, the same path consumers use with
`GOPRIVATE=github.com/github/*`. The resolution check is best-effort — a green
tag and Release are the real deliverable. Run locally, it also warms your
module cache.

`script/release` is the single source of truth and runs locally too. Preview
without touching anything:
Expand Down
44 changes: 40 additions & 4 deletions script/release
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,39 @@ die() {
exit 1
}

# Smoke-test that a published module version resolves through the Go toolchain.
# The repo is private, so resolution goes "direct" over git (the public proxy
# can't see it) — the same path consumers use with GOPRIVATE=github.com/github/*.
# Run locally this also warms your module cache. In CI, git auth is injected
# from GH_TOKEN via GIT_CONFIG_* env so go's child git can fetch the tag.
# Best-effort by design: callers treat a failure here as a warning, never a
# release-blocker, since the tag and Release are already published.
verify_module_resolves() {
local module_version="$1" dir status
dir="$(mktemp -d)"
(
cd "$dir"
go mod init release-verify >/dev/null 2>&1 || exit 1
local -a go_env=(
GOFLAGS=-mod=mod
GOPROXY=direct
GOPRIVATE="github.com/github/*"
GIT_TERMINAL_PROMPT=0
)
if [ -n "${GH_TOKEN:-}" ]; then
go_env+=(
GIT_CONFIG_COUNT=1
"GIT_CONFIG_KEY_0=url.https://x-access-token:${GH_TOKEN}@github.com/.insteadOf"
"GIT_CONFIG_VALUE_0=https://github.com/"
)
fi
env "${go_env[@]}" go mod download "${MODULE_PATH}@${module_version}"
)
status=$?
rm -rf "$dir"
return $status
}

bump="${1:-}"
case "$bump" in
patch | minor | major) ;;
Expand Down Expand Up @@ -112,9 +145,12 @@ git push origin "refs/tags/${tag}"
# 7. Cut the GitHub Release from the tag we just pushed.
gh release create "$tag" --title "$tag" --verify-tag --generate-notes

# 8. Best-effort: prime the Go module proxy so `go get ...@${version}` resolves
# immediately instead of on first external fetch.
curl -fsSL "https://proxy.golang.org/${MODULE_PATH}/@v/${version}.info" >/dev/null ||
echo "warning: proxy warm failed (non-fatal); the proxy will fetch on first use." >&2
# 8. Best-effort: confirm the published version resolves (and warm the local
# cache). Never fails the release — tag and Release are already live.
if verify_module_resolves "$version"; then
echo "Verified ${version} resolves via the module toolchain."
else
echo "warning: could not verify ${version} via the toolchain (auth?); the tag and Release are published regardless." >&2
fi

echo "Released ${tag}."
Loading