turbo-editors/turbo-moonbitpublic Fork 0
8c683ec34820eacb48a5069d622bb61461e7abed
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-moonbit.git
git clone ssh://git@rickub.com/turbo-editors/turbo-moonbit.git

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

02-build-releases.sh · 210 lines · 7.3 KBBash Blame HistoryRaw
📦 Turbo MoonBit cc1f595 k33g yesterday1#!/bin/bash
2: <<'COMMENT'
3Build the release binaries and stage them under release/${TAG}/
4
5Usage:
6 ./02-build-releases.sh # TAG and ABOUT come from release.env
7 ./02-build-releases.sh v1.0.0 # override the tag for this run (what CI does)
8
9This is the script the Release workflow runs when ./01-release.tag.sh pushes a
10tag; the workflow then attaches everything staged here to the release page.
11Nothing here publishes anything, so it is also the way to see what a release
12will contain before cutting it, or to build the binaries by hand.
13
14Only the Go toolchain and git are needed. The same command works on a laptop
15and in a Rickub CI job.
16
17What ends up in release/${TAG}/:
18 turbo-moonbit-<version>-<os>-<arch>[.exe] one binary per platform in PLATFORMS
19 SHA256SUMS checksums of every binary
20 README.md the downloads, how to run and verify them
21COMMENT
22
23set -euo pipefail
24
25# release.env carries TAG ("v1.0.0") and ABOUT (the one-line description). It
🛟 Updated. 8c683ec k33g 11h ago26# is committed — the one .env that is — so a CI job has it too and reads ABOUT
27# from it; there the tag still comes from the command line, the tag that was
28# pushed, so the file cannot make a build disagree with the tag it is on. With
29# no ABOUT anywhere it defaults to the tag. A tag given on the command line
30# always wins, so a test build never edits the file.
📦 Turbo MoonBit cc1f595 k33g yesterday31if [ -f release.env ]; then
32 # shellcheck source=/dev/null
33 source release.env
34fi
35TAG="${1:-${TAG:-}}"
36ABOUT="${ABOUT:-Turbo MoonBit ${TAG}}"
37
38# A tag that is not vMAJOR.MINOR.PATCH[-prerelease] is a typo — and for a Go
39# module it is worse than a typo: the proxy will not serve a tag it cannot read
40# as a version, so `go install` would fail on a release that built perfectly.
41if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
42 echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env)"
43 exit 1
44fi
45
46# 01 refuses this too, but CI runs *this* script on a tag that is already
47# pushed, without ever running 01. The proxy serves go.mod as written, so a
48# published editor carrying a replace tells `go install` to look for turbo-core
49# in a directory that does not exist on the installer's machine.
50if grep -qE '^[[:space:]]*replace[[:space:]]' go.mod; then
51 echo "❌ go.mod has a replace directive, which a published module must not"
52 grep -nE '^[[:space:]]*replace[[:space:]]' go.mod
53 exit 1
54fi
55
56# The platforms a release is built for. Add or remove a line and everything
57# below follows: the builds, the checksums and the README.
58PLATFORMS=(
59 "darwin/arm64"
60 "linux/amd64"
61 "linux/arm64"
62 "windows/amd64"
63 "windows/arm64"
64)
65
66echo "🚀 Building Turbo MoonBit ${TAG}${ABOUT}"
67echo "🐹 $(go version)"
68
69RELEASES_DIR="release/${TAG}"
70
71# The tag is "v1.0.0"; the assets carry the bare version, "1.0.0".
72VERSION="${TAG#v}"
73
74# Where the Makefile puts the binary for this machine.
75BUILT="bin/turbo-moonbit"
76
77# The release is ${TAG}, so ${TAG} is what every binary here reports. The
78# Makefile's own default comes from `git describe`, which answers a different
79# question — where HEAD is — and disagrees the moment you commit after tagging.
80# Overriding VERSION keeps the -X paths defined in one place all the same.
81LDFLAGS="$(make --no-print-directory ldflags VERSION="${TAG}")"
82
83# A fresh directory, so a binary left by an earlier run for a platform since
84# removed from PLATFORMS cannot end up on the release page.
85rm -rf "${RELEASES_DIR}"
86mkdir -p "${RELEASES_DIR}"
87
88# The host build comes first: it is the quickest way to find a compile error,
89# before spending five cross-compiles on it.
90make build VERSION="${TAG}"
91
92if [ ! -f "${BUILT}" ]; then
93 echo "❌ make build produced no ${BUILT}"
94 exit 1
95fi
96
97# assetName returns what the binary for a platform is called once staged.
98# Windows executables carry .exe, or Windows will not run them.
99assetName() {
100 local goos=$1 goarch=$2
101 local name="turbo-moonbit-${VERSION}-${goos}-${goarch}"
102
103 if [ "${goos}" = "windows" ]; then
104 name="${name}.exe"
105 fi
106 printf '%s\n' "${name}"
107}
108
109echo ""
110echo "🔨 Cross-compiling for ${#PLATFORMS[@]} platforms..."
111
112for platform in "${PLATFORMS[@]}"; do
113 goos="${platform%/*}"
114 goarch="${platform#*/}"
115 asset="$(assetName "${goos}" "${goarch}")"
116
117 # CGO_ENABLED=0 because there is nothing to link against on the other side
118 # of a cross-compile, and this project needs no C at all: tcell and toml
119 # are both pure Go.
120 #
121 # -trimpath keeps the paths of this machine out of a binary that goes to
122 # strangers.
123 #
124 # -ldflags is what makes a downloaded binary agree with the release it came
125 # from. Without it the Go build system names the build itself, and every
126 # asset here would report "devel" while the release page says ${TAG}.
127 if ! CGO_ENABLED=0 GOOS="${goos}" GOARCH="${goarch}" \
128 go build -trimpath -ldflags "${LDFLAGS}" -o "${RELEASES_DIR}/${asset}" .; then
129 echo "${platform}"
130 exit 1
131 fi
132 echo "${asset}"
133done
134
135# The staged asset for this machine is the only one that can be run here, and
136# running it is the only proof that what ships carries the version rather than
137# that the flags looked right.
138# The number has to *equal* the tag, not merely appear in the output: "0.2.0"
139# is a substring of "10.2.0" and of a commit hash that happens to contain it,
140# and a stamp that is nearly right is the failure worth catching.
141HOST_ASSET="$(assetName "$(go env GOOS)" "$(go env GOARCH)")"
142if [ -x "${RELEASES_DIR}/${HOST_ASSET}" ]; then
143 if ! reported="$(scripts/check-version.sh "${RELEASES_DIR}/${HOST_ASSET}" "${TAG}")"; then
144 exit 1
145 fi
146 echo "${HOST_ASSET} reports ${reported}"
147fi
148
149# checksum runs whichever of the two tools this machine has: sha256sum on
150# Linux, shasum on macOS.
151checksum() {
152 if command -v sha256sum >/dev/null 2>&1; then
153 sha256sum "$@"
154 else
155 shasum -a 256 "$@"
156 fi
157}
158
159# The workflow attaches SHA256SUMS beside the binaries, so it is written here.
160# One file covers every platform, which is what "sha256sum -c" expects to
161# read, and the names carry no directory so it works next to the downloads.
162(cd "${RELEASES_DIR}" && checksum turbo-moonbit-"${VERSION}"-* >SHA256SUMS)
163echo " ✅ SHA256SUMS"
164
165# downloadTable lists the platforms as a Markdown table, so the README grows
166# and shrinks with PLATFORMS rather than repeating it by hand.
167downloadTable() {
168 printf '| Platform | Download |\n|---|---|\n'
169 for platform in "${PLATFORMS[@]}"; do
170 local goos="${platform%/*}" goarch="${platform#*/}"
171 printf '| %s | `%s` |\n' "${platform}" "$(assetName "${goos}" "${goarch}")"
172 done
173}
174
175cat >"${RELEASES_DIR}/README.md" <<EOM
176# Turbo MoonBit ${TAG}
177
178${ABOUT}
179
180Built with $(go env GOVERSION). No runtime dependencies; \`moon-lsp\` is optional and
181only completion and error marks need it.
182
183$(downloadTable)
184
185## Running it
186
187 chmod +x turbo-moonbit-${VERSION}-<platform>
188 ./turbo-moonbit-${VERSION}-<platform> main.mbt
189
190On macOS, an unsigned download is quarantined until you say otherwise:
191
192 xattr -d com.apple.quarantine turbo-moonbit-${VERSION}-darwin-arm64
193
194## Installing from the module proxy instead
195
196 go install $(go list -m)@${TAG}
197
198## Verifying the download
199
200 sha256sum -c SHA256SUMS --ignore-missing # shasum -a 256 -c on macOS
201
202EOM
203echo " ✅ README.md"
204
205echo ""
206echo "✨ Build complete!"
207ls -lh "${RELEASES_DIR}"
208echo ""
209echo "💡 Nothing was published. The Release workflow runs this same script when"
210echo " ./01-release.tag.sh pushes ${TAG}, and attaches release/${TAG}/ to the release page."