#!/usr/bin/env bash set -euo pipefail version="" output_dir="dist" target="all" rust_image="${RUST_IMAGE:-docker.m.daocloud.io/library/rust:1-bookworm}" cargo_registry="${CARGO_REGISTRY:-sparse+https://rsproxy.cn/index/}" apt_mirror="${APT_MIRROR:-https://mirrors.ustc.edu.cn/debian}" clean=0 usage() { cat <<'EOF' Usage: scripts/build.sh [options] Build release binaries with Docker buildx. Options: --version VERSION Version used in output filenames. --output-dir DIR Output directory. Default: dist --target TARGET all, win, linux-x64, linux-arm64. Default: all --rust-image IMAGE Rust Docker image. --cargo-registry URL Cargo registry mirror. --apt-mirror URL Debian apt mirror. --clean Remove output directory before building. -h, --help Show this help. EOF } while [[ $# -gt 0 ]]; do case "$1" in --version) version="${2:?missing value for --version}" shift 2 ;; --output-dir) output_dir="${2:?missing value for --output-dir}" shift 2 ;; --target) target="${2:?missing value for --target}" shift 2 ;; --rust-image) rust_image="${2:?missing value for --rust-image}" shift 2 ;; --cargo-registry) cargo_registry="${2:?missing value for --cargo-registry}" shift 2 ;; --apt-mirror) apt_mirror="${2:?missing value for --apt-mirror}" shift 2 ;; --clean) clean=1 shift ;; -h|--help) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage >&2 exit 2 ;; esac done case "${target}" in all|win|linux-x64|linux-arm64) ;; *) echo "Invalid --target: ${target}" >&2 exit 2 ;; esac repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${repo_root}" if [[ -z "${version}" ]]; then version="$(sed -n 's/^version[[:space:]]*=[[:space:]]*"\([^"]*\)"/\1/p' Cargo.toml | head -n 1)" if [[ -z "${version}" ]]; then echo "Cannot read package version from Cargo.toml" >&2 exit 1 fi fi if [[ "${clean}" -eq 1 ]]; then rm -rf "${output_dir}" fi mkdir -p "${output_dir}" build_asset() { local target_name="$1" local rust_target="$2" local platform="$3" local container_binary="$4" local output_name="$5" local run_id="${GITHUB_RUN_ID:-$(date +%s)-$$}" local image_tag="cdxs-build:${target_name}-${run_id}" local container_name="cdxs-build-${target_name}-${run_id}" echo "Building ${target_name} with Docker platform ${platform}" local proxy_build_args=() local proxy_var for proxy_var in HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY http_proxy https_proxy all_proxy no_proxy; do if [[ -n "${!proxy_var:-}" ]]; then proxy_build_args+=(--build-arg "${proxy_var}=${!proxy_var}") fi done docker buildx build \ --platform "${platform}" \ --target builder \ --build-arg "RUST_TARGET=${rust_target}" \ --build-arg "RUST_IMAGE=${rust_image}" \ --build-arg "CARGO_REGISTRY=${cargo_registry}" \ --build-arg "APT_MIRROR=${apt_mirror}" \ "${proxy_build_args[@]}" \ --load \ -t "${image_tag}" \ -f scripts/docker/Dockerfile.release \ . local container_id container_id="$(docker create --name "${container_name}" "${image_tag}")" trap 'docker rm -f "${container_name}" >/dev/null 2>&1 || true' RETURN docker cp "${container_id}:/out/${container_binary}" "${output_dir}/${output_name}" docker rm -f "${container_name}" >/dev/null trap - RETURN echo "Wrote ${output_dir}/${output_name}" } if [[ "${target}" == "all" || "${target}" == "win" ]]; then build_asset windows-x64 x86_64-pc-windows-gnu linux/amd64 cdxs.exe "cdxs-${version}-windows-x64.exe" fi if [[ "${target}" == "all" || "${target}" == "linux-x64" ]]; then build_asset linux-x64 x86_64-unknown-linux-gnu linux/amd64 cdxs "cdxs-${version}-linux-x64" fi if [[ "${target}" == "all" || "${target}" == "linux-arm64" ]]; then build_asset linux-arm64 aarch64-unknown-linux-gnu linux/arm64 cdxs "cdxs-${version}-linux-arm64" fi echo "Release artifacts are in ${output_dir}"