turbo-editors/turbo-corepublic Fork 0
v1.0.2
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

02-build-releases.sh · 166 lines · 5.9 KBBash Blame HistoryRaw
📦 Turbo Core d662ceb k33g 14h ago1#!/bin/bash
2: <<'COMMENT'
3Stage the release artefacts of turbo-core under release/${TAG}/
4
5Usage:
6 ./02-build-releases.sh # TAG and ABOUT come from release.env
7 ./02-build-releases.sh v0.2.0 # override the tag for this run (what CI does)
8
9turbo-core is a library, so where an editor's build cross-compiles one binary
10per platform this stages the one artefact a Go module has: an archive of the
11source the tag is on. `go get` never downloads it — the module proxy serves the
12module straight from the tag, which is why 01 alone already publishes it. The
13archive is here so a release page has something to verify against, and so the
14library can be had by somebody who does not reach the proxy.
15
16Only the Go toolchain and git are needed. The same command works on a laptop
17and in a Rickub CI job.
18
19What ends up in release/${TAG}/:
20 turbo-core-<version>.tar.gz the tagged source, under turbo-core-<version>/
21 SHA256SUMS checksum of the archive
22 README.md the go get line, the packages, how to verify
23COMMENT
24
25set -euo pipefail
26
27# release.env carries TAG ("v0.2.0") and ABOUT (the one-line description). It
28# is git-ignored (*.env), so a CI job does not have it: there the tag comes
29# from the command line and ABOUT from the environment, or defaults to the
30# tag. A tag given on the command line always wins, so a test build never
31# edits the file.
32if [ -f release.env ]; then
33 # shellcheck source=/dev/null
34 source release.env
35fi
36TAG="${1:-${TAG:-}}"
37ABOUT="${ABOUT:-Turbo Core ${TAG}}"
38
39# A tag that is not vMAJOR.MINOR.PATCH[-prerelease] is a typo — and for a Go
40# module it is worse than a typo: the proxy will not serve a tag it cannot read
41# as a version, so `go get` would fail on a release that staged perfectly.
42if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
43 echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env)"
44 exit 1
45fi
46
47# 01 refuses this too, but CI runs *this* script on a tag that is already
48# pushed, without ever running 01. The proxy serves go.mod as written, so a
49# published library carrying a replace tells every consumer to look for
50# turbo-core in a directory that does not exist on their machine.
51if grep -qE '^[[:space:]]*replace[[:space:]]' go.mod; then
52 echo "❌ go.mod has a replace directive, which a published module must not"
53 grep -nE '^[[:space:]]*replace[[:space:]]' go.mod
54 exit 1
55fi
56
57# The tag is "v0.2.0"; the assets carry the bare version, "0.2.0".
58VERSION="${TAG#v}"
59RELEASES_DIR="release/${TAG}"
60ARCHIVE="turbo-core-${VERSION}.tar.gz"
61MODULE="$(go list -m)"
62
63echo "🚀 Staging turbo-core ${TAG}${ABOUT}"
64echo "🐹 $(go version)"
65
66# The archive comes from HEAD, not from the working directory: git archive
67# writes what is committed. A dirty tree is therefore not an error here, but it
68# does mean the archive is not what you are looking at — worth saying once.
69if ! git diff --quiet HEAD 2>/dev/null; then
70 echo "⚠️ the working tree has uncommitted changes; the archive is HEAD, not what is on disk"
71fi
72
73rm -rf "${RELEASES_DIR}"
74mkdir -p "${RELEASES_DIR}"
75
76echo ""
77echo "🔨 Checking what ships..."
78
79# Every package has to compile and pass vet before it is archived. A library
80# has no binary whose start proves anything, so this is the equivalent: the
81# whole module, built the way a consumer's build will build it.
82if ! go build ./...; then
83 echo " ❌ go build ./..."
84 exit 1
85fi
86echo " ✅ go build ./..."
87
88if ! go vet ./...; then
89 echo " ❌ go vet ./..."
90 exit 1
91fi
92echo " ✅ go vet ./..."
93
94# The prefix is what the archive unpacks into, so extracting it beside other
95# downloads does not scatter a go.mod and eighteen directories into the
96# current one.
97git archive --format=tar.gz --prefix="turbo-core-${VERSION}/" -o "${RELEASES_DIR}/${ARCHIVE}" HEAD
98echo "${ARCHIVE}"
99
100# Extracting the archive and building it is the one proof that what ships
101# builds on its own — that nothing needed was left untracked, gitignored, or
102# only present in this checkout. The dependencies come from the shared module
103# cache, which the build above has just filled.
104extracted="$(mktemp -d)"
105trap 'rm -rf "${extracted}"' EXIT
106tar -xzf "${RELEASES_DIR}/${ARCHIVE}" -C "${extracted}"
107if ! (cd "${extracted}/turbo-core-${VERSION}" && go build ./... >/dev/null); then
108 echo " ❌ the extracted archive does not build on its own"
109 exit 1
110fi
111echo " ✅ the extracted archive builds on its own"
112
113# checksum runs whichever of the two tools this machine has: sha256sum on
114# Linux, shasum on macOS.
115checksum() {
116 if command -v sha256sum >/dev/null 2>&1; then
117 sha256sum "$@"
118 else
119 shasum -a 256 "$@"
120 fi
121}
122
123# Names only (no directory), which is what `sha256sum -c` expects to read next
124# to the downloaded file.
125(cd "${RELEASES_DIR}" && checksum "${ARCHIVE}" >SHA256SUMS)
126echo " ✅ SHA256SUMS"
127
128# packageTable lists the library's packages with the first line of each one's
129# doc comment, so the README grows and shrinks with the module rather than
130# repeating it by hand. Packages with no doc comment — the module root, which
131# holds nothing but this tooling's tests — are left out, and a pipe in a
132# synopsis is escaped so it cannot break the table.
133packageTable() {
134 printf '| Package | What it is |\n|---|---|\n'
135 go list -f '{{.ImportPath}}|{{.Doc}}' ./... | while IFS='|' read -r path doc; do
136 [ -z "${doc}" ] && continue
137 printf '| `%s` | %s |\n' "${path#"${MODULE}"/}" "${doc//|/\\|}"
138 done
139}
140
141cat >"${RELEASES_DIR}/README.md" <<EOM
142# Turbo Core ${TAG}
143
144${ABOUT}
145
146The library the Turbo editors are built from. Built and checked with $(go env GOVERSION).
147
148## Using it
149
150 go get ${MODULE}@${TAG}
151
152The module proxy serves this straight from the tag; the archive beside this file is the same source, for verifying against or for working without the proxy.
153
154## What is in it
155
156$(packageTable)
157
158## Verifying the download
159
160 sha256sum -c SHA256SUMS --ignore-missing # shasum -a 256 -c on macOS
161EOM
162echo " ✅ README.md"
163
164echo ""
165echo "✨ Staging complete!"
166ls -lh "${RELEASES_DIR}"