| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | set -euo pipefail |
| 37 | |
| 38 | |
| 39 | |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 | |
| 45 | |
| 46 | |
| 47 | |
| 48 | |
| 49 | TARGET="${STEID_RELEASE_TARGET:-x86_64-unknown-linux-gnu}" |
| 50 | |
| 51 | |
| 52 | |
| 53 | |
| 54 | |
| 55 | |
| 56 | |
| 57 | |
| 58 | |
| 59 | RUST_IMAGE="${STEID_RUST_IMAGE:-rust:1.97-slim-bullseye}" |
| 60 | TOPCOAT_CLI_VERSION="${STEID_TOPCOAT_CLI_VERSION:-0.5.0}" |
| 61 | |
| 62 | VERSION="" |
| 63 | OUT_DIR="dist" |
| 64 | NATIVE=0 |
| 65 | |
| 66 | usage() { |
| 67 | sed -n '2,32p' "$0" | sed 's/^#\{1,2\} \{0,1\}//' |
| 68 | exit "${1:-0}" |
| 69 | } |
| 70 | |
| 71 | while [ $# -gt 0 ]; do |
| 72 | case "$1" in |
| 73 | --target) TARGET="${2:?--target needs a triple}"; shift 2 ;; |
| 74 | --version) VERSION="${2:?--version needs a value}"; shift 2 ;; |
| 75 | --out) OUT_DIR="${2:?--out needs a directory}"; shift 2 ;; |
| 76 | --native) NATIVE=1; shift ;; |
| 77 | -h|--help) usage 0 ;; |
| 78 | *) echo "release.sh: unknown argument: $1" >&2; usage 1 ;; |
| 79 | esac |
| 80 | done |
| 81 | |
| 82 | REPO_ROOT="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)" |
| 83 | cd "$REPO_ROOT" |
| 84 | |
| 85 | |
| 86 | |
| 87 | if [ -z "$VERSION" ]; then |
| 88 | VERSION="$(grep -m1 '^version *= *"' Cargo.toml | sed 's/.*"\(.*\)".*/\1/')" |
| 89 | fi |
| 90 | [ -n "$VERSION" ] || { echo "release.sh: could not determine version" >&2; exit 1; } |
| 91 | |
| 92 | if [ "$NATIVE" = 1 ]; then |
| 93 | TARGET="$(rustc -vV | sed -n 's/^host: //p')" |
| 94 | fi |
| 95 | |
| 96 | NAME="steid-${VERSION}-${TARGET}" |
| 97 | STAGE="${OUT_DIR}/${NAME}" |
| 98 | |
| 99 | echo "release.sh: building ${NAME}" |
| 100 | |
| 101 | |
| 102 | |
| 103 | rm -rf "$STAGE" |
| 104 | mkdir -p "$STAGE" |
| 105 | |
| 106 | if [ "$NATIVE" = 1 ]; then |
| 107 | command -v topcoat >/dev/null 2>&1 || { |
| 108 | echo "release.sh: topcoat CLI not found." >&2 |
| 109 | echo " cargo install topcoat-cli --version ${TOPCOAT_CLI_VERSION} --locked" >&2 |
| 110 | exit 1 |
| 111 | } |
| 112 | echo "release.sh: local build (host toolchain) — NOT a release artefact" |
| 113 | topcoat asset bundle --release |
| 114 | cp target/release/steid "$STAGE/steid" |
| 115 | cp -R target/assets "$STAGE/assets" |
| 116 | else |
| 117 | command -v docker >/dev/null 2>&1 || { |
| 118 | echo "release.sh: docker not found, and a Linux artefact cannot be built" >&2 |
| 119 | echo " with the host toolchain. Install Docker, or run on Linux with" >&2 |
| 120 | echo " --native, or use a cross toolchain." >&2 |
| 121 | exit 1 |
| 122 | } |
| 123 | |
| 124 | case "$TARGET" in |
| 125 | x86_64-*) PLATFORM="linux/amd64" ;; |
| 126 | aarch64-*) PLATFORM="linux/arm64" ;; |
| 127 | *) echo "release.sh: don't know the Docker platform for ${TARGET}" >&2; exit 1 ;; |
| 128 | esac |
| 129 | |
| 130 | |
| 131 | |
| 132 | |
| 133 | EXTRA_SETUP="" |
| 134 | BIN_PATH="target/release/steid" |
| 135 | case "$TARGET" in |
| 136 | *-musl) |
| 137 | EXTRA_SETUP="apt-get update && apt-get install -y --no-install-recommends musl-tools && rm -rf /var/lib/apt/lists/* && rustup target add ${TARGET} && export CARGO_BUILD_TARGET=${TARGET}" |
| 138 | BIN_PATH="target/${TARGET}/release/steid" |
| 139 | ;; |
| 140 | esac |
| 141 | |
| 142 | echo "release.sh: building in ${RUST_IMAGE} on ${PLATFORM}" |
| 143 | |
| 144 | |
| 145 | |
| 146 | |
| 147 | IMAGE_TAG="steid-release-build:${VERSION}-${TARGET}" |
| 148 | docker buildx build \ |
| 149 | --platform "$PLATFORM" \ |
| 150 | --load \ |
| 151 | --tag "$IMAGE_TAG" \ |
| 152 | --build-arg "TARGET=${TARGET}" \ |
| 153 | --file - . <<EOF |
| 154 | FROM ${RUST_IMAGE} |
| 155 | ARG TARGET |
| 156 | RUN cargo install topcoat-cli --version ${TOPCOAT_CLI_VERSION} --locked |
| 157 | WORKDIR /src |
| 158 | COPY . . |
| 159 | RUN set -eux; ${EXTRA_SETUP:-true}; \\ |
| 160 | topcoat asset bundle --release; \\ |
| 161 | mkdir -p /out; \\ |
| 162 | cp ${BIN_PATH} /out/steid; \\ |
| 163 | cp -r target/assets /out/assets |
| 164 | EOF |
| 165 | |
| 166 | |
| 167 | |
| 168 | CONTAINER="$(docker create --platform "$PLATFORM" "$IMAGE_TAG" /bin/true)" |
| 169 | trap 'docker rm -f "$CONTAINER" >/dev/null 2>&1 || true' EXIT |
| 170 | docker cp "${CONTAINER}:/out/steid" "$STAGE/steid" |
| 171 | docker cp "${CONTAINER}:/out/assets" "$STAGE/assets" |
| 172 | docker rm -f "$CONTAINER" >/dev/null |
| 173 | trap - EXIT |
| 174 | fi |
| 175 | |
| 176 | chmod 755 "$STAGE/steid" |
| 177 | |
| 178 | |
| 179 | |
| 180 | cp README.md "$STAGE/README.md" |
| 181 | |
| 182 | |
| 183 | |
| 184 | |
| 185 | |
| 186 | [ -f "$STAGE/assets/manifest.toml" ] || { |
| 187 | echo "release.sh: assets/manifest.toml is missing — was this built with" >&2 |
| 188 | echo " 'topcoat asset bundle' and not a bare 'cargo build'?" >&2 |
| 189 | exit 1 |
| 190 | } |
| 191 | |
| 192 | |
| 193 | |
| 194 | TARBALL="${OUT_DIR}/${NAME}.tar.gz" |
| 195 | |
| 196 | |
| 197 | |
| 198 | |
| 199 | |
| 200 | COPYFILE_DISABLE=1 tar --no-xattrs -czf "$TARBALL" -C "$OUT_DIR" "$NAME" 2>/dev/null \ |
| 201 | || COPYFILE_DISABLE=1 tar -czf "$TARBALL" -C "$OUT_DIR" "$NAME" |
| 202 | |
| 203 | |
| 204 | |
| 205 | |
| 206 | ( |
| 207 | cd "$OUT_DIR" |
| 208 | if command -v sha256sum >/dev/null 2>&1; then |
| 209 | sha256sum "${NAME}.tar.gz" > "${NAME}.tar.gz.sha256" |
| 210 | else |
| 211 | |
| 212 | shasum -a 256 "${NAME}.tar.gz" > "${NAME}.tar.gz.sha256" |
| 213 | fi |
| 214 | ) |
| 215 | |
| 216 | echo |
| 217 | echo "release.sh: wrote" |
| 218 | echo " ${TARBALL}" |
| 219 | echo " ${TARBALL}.sha256" |
| 220 | echo |
| 221 | echo "Upload both to the release named v${VERSION}. install.sh expects exactly" |
| 222 | echo "these filenames." |