mirror of
https://github.com/euzu/tuliprox.git
synced 2026-09-16 06:02:27 +02:00
156 lines
4.9 KiB
Bash
Executable File
156 lines
4.9 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Required environment variables (set by CI)
|
|
if [ -z "${REPO_OWNER:-}" ] || [ -z "${GITHUB_IO_TOKEN:-}" ]; then
|
|
echo "🧨 Error: REPO_OWNER and GITHUB_IO_TOKEN env vars are required"
|
|
exit 1
|
|
fi
|
|
|
|
# -----------------------------
|
|
# Rust / Cargo Setup (Assuming toolchain is handled by CI)
|
|
# -----------------------------
|
|
export RUSTUP_NO_UPDATE_CHECK=1
|
|
export CARGO_NET_GIT_FETCH_WITH_CLI=true
|
|
export RUSTFLAGS="--remap-path-prefix $HOME=~"
|
|
|
|
# Validate arguments
|
|
if [ $# -ne 1 ]; then
|
|
echo "Usage: $(basename "$0") <branch>"
|
|
exit 1
|
|
fi
|
|
|
|
BRANCH="$1"
|
|
case "$BRANCH" in
|
|
master) TAG_SUFFIX="latest" ;;
|
|
develop) TAG_SUFFIX="dev" ;;
|
|
*) echo "🧨 Error: Branch '$BRANCH' not supported"; exit 1 ;;
|
|
esac
|
|
|
|
echo "🚀 Building for branch: $BRANCH (tag: $TAG_SUFFIX)"
|
|
|
|
# Directories
|
|
WORKING_DIR=$(pwd)
|
|
DOCKER_DIR="${WORKING_DIR}/docker"
|
|
#BACKEND_DIR="${WORKING_DIR}/backend"
|
|
FRONTEND_DIR="${WORKING_DIR}/frontend"
|
|
FRONTEND_BUILD_DIR="${FRONTEND_DIR}/dist"
|
|
ARTIFACT_DIR="${WORKING_DIR}/artifacts"
|
|
|
|
# Config
|
|
declare -A ARCHITECTURES=([LINUX]=x86_64-unknown-linux-musl [AARCH64]=aarch64-unknown-linux-musl)
|
|
declare -A MULTI_PLATFORM_IMAGES=([tuliprox]="scratch-final" [tuliprox-alpine]="alpine-final")
|
|
|
|
# Version detection
|
|
VERSION=$(grep -Po '^version\s*=\s*"\K[0-9\.]+' "${WORKING_DIR}/Cargo.toml")
|
|
echo "📦 Version: ${VERSION}"
|
|
|
|
# Prepare artifact directory (clean per run to avoid stale files)
|
|
rm -rf "${ARTIFACT_DIR}"
|
|
mkdir -p "${ARTIFACT_DIR}"
|
|
|
|
write_checksum() {
|
|
local file_path="$1"
|
|
local file_dir
|
|
local file_name
|
|
file_dir="$(dirname "${file_path}")"
|
|
file_name="$(basename "${file_path}")"
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
(cd "${file_dir}" && sha256sum "${file_name}") > "${file_path}.sha256"
|
|
else
|
|
(cd "${file_dir}" && shasum -a 256 "${file_name}") > "${file_path}.sha256"
|
|
fi
|
|
}
|
|
|
|
create_release_bundle() {
|
|
local architecture="$1"
|
|
local binary_path="$2"
|
|
local bundle_root=""
|
|
local bundle_name
|
|
local bundle_path
|
|
|
|
bundle_root="$(mktemp -d)"
|
|
trap 'if [ -n "${bundle_root:-}" ] && [ -d "${bundle_root}" ]; then rm -rf "${bundle_root}"; fi' RETURN ERR INT
|
|
mkdir -p "${bundle_root}/tuliprox"
|
|
|
|
cp "${binary_path}" "${bundle_root}/tuliprox/tuliprox"
|
|
chmod +x "${bundle_root}/tuliprox/tuliprox"
|
|
cp -r "${FRONTEND_BUILD_DIR}" "${bundle_root}/tuliprox/web"
|
|
cp -r "${WORKING_DIR}/resources" "${bundle_root}/tuliprox/resources"
|
|
|
|
bundle_name="tuliprox-v${VERSION}-${architecture}.tar.gz"
|
|
bundle_path="${ARTIFACT_DIR}/${bundle_name}"
|
|
tar -C "${bundle_root}" -czf "${bundle_path}" tuliprox
|
|
write_checksum "${bundle_path}"
|
|
}
|
|
|
|
# -----------------------------------------
|
|
# 1. Documentation + Frontend Build
|
|
# -----------------------------------------
|
|
echo "🎨 Building frontend..."
|
|
"${WORKING_DIR}/bin/build_fe.sh" release
|
|
|
|
cd "$WORKING_DIR"
|
|
|
|
# -----------------------------------------
|
|
# 2. Binary Compilation (Multi-Arch)
|
|
# -----------------------------------------
|
|
echo "🏗️ Building binaries..."
|
|
mkdir -p "${DOCKER_DIR}/binaries"
|
|
|
|
for PLATFORM in "${!ARCHITECTURES[@]}"; do
|
|
ARCHITECTURE=${ARCHITECTURES[$PLATFORM]}
|
|
echo "🔨 Building for $ARCHITECTURE"
|
|
|
|
# Using cross for compilation
|
|
cross build -p tuliprox --release --target "$ARCHITECTURE" --locked
|
|
|
|
SOURCE_BIN_PATH="target/${ARCHITECTURE}/release/tuliprox"
|
|
cp "${SOURCE_BIN_PATH}" "${DOCKER_DIR}/binaries/tuliprox-${ARCHITECTURE}"
|
|
|
|
create_release_bundle "${ARCHITECTURE}" "${SOURCE_BIN_PATH}"
|
|
done
|
|
|
|
echo "📦 Release bundles prepared in ${ARTIFACT_DIR}"
|
|
|
|
# -----------------------------------------
|
|
# 3. Docker Build & Push (Optimized Caching)
|
|
# -----------------------------------------
|
|
echo "📋 Preparing Docker context..."
|
|
cp -r "${FRONTEND_BUILD_DIR}" "${DOCKER_DIR}/web"
|
|
cp -r "resources" "${DOCKER_DIR}/resources"
|
|
|
|
cd "${DOCKER_DIR}"
|
|
|
|
# Login
|
|
echo "🔑 Logging into GHCR..."
|
|
echo "${GITHUB_IO_TOKEN}" | docker login ghcr.io -u "${REPO_OWNER}" --password-stdin
|
|
|
|
REPO_OWNER_LC="${REPO_OWNER,,}"
|
|
|
|
for IMAGE_NAME in "${!MULTI_PLATFORM_IMAGES[@]}"; do
|
|
BUILD_TARGET="${MULTI_PLATFORM_IMAGES[$IMAGE_NAME]}"
|
|
TAG_VERSION="ghcr.io/${REPO_OWNER_LC}/${IMAGE_NAME}:${VERSION}"
|
|
TAG_BRANCH="ghcr.io/${REPO_OWNER_LC}/${IMAGE_NAME}:${TAG_SUFFIX}"
|
|
|
|
echo "🎯 Building multi-platform image: ${IMAGE_NAME}"
|
|
|
|
# THE FIX: Using type=gha for automatic GitHub Actions cache management.
|
|
# No more local files, no more leftover artifacts.
|
|
docker buildx build -f Dockerfile.manual \
|
|
-t "${TAG_VERSION}" \
|
|
-t "${TAG_BRANCH}" \
|
|
--target "$BUILD_TARGET" \
|
|
--platform "linux/amd64,linux/arm64" \
|
|
--cache-from "type=gha,scope=${IMAGE_NAME}" \
|
|
--cache-to "type=gha,mode=max,scope=${IMAGE_NAME}" \
|
|
--push \
|
|
.
|
|
done
|
|
|
|
# -----------------------------------------
|
|
# Cleanup
|
|
# -----------------------------------------
|
|
echo "🗑️ Final cleanup..."
|
|
rm -rf "${DOCKER_DIR}/binaries" "${DOCKER_DIR}/web" "${DOCKER_DIR}/resources"
|