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