Files
mdrs-client-rust/scripts/build-release-macos.sh
T
Yoshihiro OKUMURA c24a285cf5 fix(selfupdate): verify the archive before replacing the binary
`mdrs selfupdate` replaced the running binary with whatever the release
endpoint returned, checking only that the transport succeeded. Nothing
proved the archive was the one the release publishes.

- Compare the downloaded archive against the release's `.sha256` asset
  and abort the update on a mismatch.
- Report a release that publishes no checksum as unverified, rather
  than letting its absence pass for a verified download.
- Exclude `.sha256` assets when matching the archive for the build
  target: those assets carry the target name too.
- Write and upload a checksum beside every archive, from the Gitea
  release workflow and the three local build scripts.
2026-09-04 16:31:02 +09:00

96 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build release archives for macOS (x86_64 and aarch64).
#
# Usage:
# ./scripts/build-release-macos.sh [VERSION]
#
# If VERSION is not provided, it is read from Cargo.toml.
# Set GITEA_TOKEN (and optionally GITEA_SERVER_URL / GITEA_REPOSITORY)
# to upload the archives to a Gitea release automatically.
# These can be provided via scripts/.env.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
# Load .env if present (existing env vars take precedence)
if [[ -f "${SCRIPT_DIR}/.env" ]]; then
while IFS='=' read -r key value; do
[[ "${key}" =~ ^#.*$ || -z "${key}" ]] && continue
key="${key%%[[:space:]]}"
value="${value##[[:space:]]}"
[[ -z "${!key+x}" ]] && export "${key}=${value}"
done < "${SCRIPT_DIR}/.env"
fi
# Determine version
if [[ $# -ge 1 ]]; then
VERSION="$1"
else
VERSION="$(grep -m1 '^version' "${REPO_ROOT}/Cargo.toml" | sed 's/.*= *"\(.*\)"/\1/')"
fi
TAG="v${VERSION}"
TARGETS=(x86_64-apple-darwin aarch64-apple-darwin)
cd "${REPO_ROOT}"
echo "==> Building mdrs ${VERSION} for macOS"
ARCHIVES=()
for TARGET in "${TARGETS[@]}"; do
echo "--- Target: ${TARGET}"
rustup target add "${TARGET}"
cargo build --release --target "${TARGET}"
ARCHIVE="mdrs-${VERSION}-${TARGET}.tar.gz"
tar -czf "${ARCHIVE}" -C "target/${TARGET}/release" mdrs
# Uploaded alongside the archive so `mdrs selfupdate` can check what it fetched.
sha256sum "${ARCHIVE}" > "${ARCHIVE}.sha256" 2>/dev/null \
|| shasum -a 256 "${ARCHIVE}" > "${ARCHIVE}.sha256"
ARCHIVES+=("${ARCHIVE}" "${ARCHIVE}.sha256")
echo " Created: ${ARCHIVE}"
done
echo ""
echo "==> Archives ready:"
for A in "${ARCHIVES[@]}"; do echo " ${A}"; done
# Upload to Gitea if token is provided
if [[ -z "${GITEA_TOKEN:-}" ]]; then
echo ""
echo "GITEA_TOKEN not set — skipping upload."
echo "Set GITEA_TOKEN (and GITEA_SERVER_URL, GITEA_REPOSITORY) in scripts/.env to enable upload."
exit 0
fi
: "${GITEA_SERVER_URL:?GITEA_SERVER_URL is required for upload}"
: "${GITEA_REPOSITORY:?GITEA_REPOSITORY is required for upload}"
echo ""
echo "==> Creating Gitea release ${TAG} ..."
curl -sf -X POST \
-H "Authorization: Bearer ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${GITEA_SERVER_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases" \
-d "{\"tag_name\": \"${TAG}\", \"name\": \"${TAG}\"}" > /dev/null || true
RELEASE_ID="$(curl -sf \
-H "Authorization: Bearer ${GITEA_TOKEN}" \
"${GITEA_SERVER_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases/tags/${TAG}" \
| python3 -c 'import sys,json; print(json.load(sys.stdin)["id"])')"
echo "==> Uploading assets (release id: ${RELEASE_ID}) ..."
for ARCHIVE in "${ARCHIVES[@]}"; do
echo " Uploading ${ARCHIVE} ..."
curl -sf -X POST \
-H "Authorization: Bearer ${GITEA_TOKEN}" \
-F "attachment=@${ARCHIVE}" \
"${GITEA_SERVER_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases/${RELEASE_ID}/assets" > /dev/null
echo " Done."
done
echo ""
echo "==> Upload complete: ${GITEA_SERVER_URL}/${GITEA_REPOSITORY}/releases/tag/${TAG}"