mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-05-15 07:25:21 +08:00
313 lines
9.2 KiB
Bash
Executable File
313 lines
9.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
#==============================================
|
|
# Mayfly-Go Release Build Tool
|
|
# 前后端打包编译至指定目录,快速制作发行版
|
|
#==============================================
|
|
|
|
set -e # 遇到错误立即退出
|
|
|
|
#----------------------------------------------
|
|
# 全局配置
|
|
#----------------------------------------------
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
SERVER_DIR="${PROJECT_ROOT}/server"
|
|
FRONTEND_DIR="${PROJECT_ROOT}/frontend"
|
|
BINARY_NAME="mayfly-go"
|
|
|
|
# 构建目标配置:名称|操作系统|架构
|
|
BUILD_TARGETS=(
|
|
"linux-amd64|linux|amd64"
|
|
"linux-arm64|linux|arm64"
|
|
"windows|windows|amd64"
|
|
"mac|darwin|amd64"
|
|
)
|
|
|
|
#----------------------------------------------
|
|
# 工具函数
|
|
#----------------------------------------------
|
|
print_header() {
|
|
echo -e "\033[1;33m$1\033[0m"
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "\033[1;32m$1\033[0m"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "\033[1;31m$1\033[0m" >&2
|
|
}
|
|
|
|
print_info() {
|
|
echo -e "\033[1;34m$1\033[0m"
|
|
}
|
|
|
|
to_lower() {
|
|
echo "$1" | tr '[:upper:]' '[:lower:]'
|
|
}
|
|
|
|
#----------------------------------------------
|
|
# 构建函数
|
|
#----------------------------------------------
|
|
build_frontend() {
|
|
print_header "\n>>> Building frontend..."
|
|
|
|
cd "${FRONTEND_DIR}"
|
|
npm run build
|
|
|
|
# 拷贝到 server 静态目录
|
|
print_success ">>> Copying frontend assets to server/static/static"
|
|
rm -rf "${SERVER_DIR}/static/static"
|
|
mkdir -p "${SERVER_DIR}/static/static"
|
|
cp -r "${FRONTEND_DIR}/dist/"* "${SERVER_DIR}/static/static/"
|
|
|
|
cd "${PROJECT_ROOT}"
|
|
}
|
|
|
|
build_backend() {
|
|
local output_dir="$1"
|
|
local os_name="$2"
|
|
local arch="$3"
|
|
local copy_resources="$4"
|
|
|
|
local binary_file="${BINARY_NAME}"
|
|
local target_name="${os_name}-${arch}"
|
|
|
|
print_header "\n>>> Building backend: ${target_name}"
|
|
|
|
# Windows 需要 .exe 后缀
|
|
if [ "${os_name}" = "windows" ]; then
|
|
binary_file="${BINARY_NAME}.exe"
|
|
fi
|
|
|
|
# 编译
|
|
cd "${SERVER_DIR}"
|
|
go mod tidy
|
|
CGO_ENABLED=0 GOOS="${os_name}" GOARCH="${arch}" \
|
|
go build -trimpath -ldflags="-w" -o "${binary_file}" main.go
|
|
|
|
# 准备输出目录
|
|
local bin_dir="${output_dir}/bin"
|
|
if [ -d "${output_dir}" ]; then
|
|
print_info " Output directory exists, cleaning..."
|
|
rm -rf "${output_dir}"
|
|
fi
|
|
mkdir -p "${bin_dir}"
|
|
|
|
# 移动二进制文件到 bin 目录
|
|
mv "${SERVER_DIR}/${binary_file}" "${bin_dir}/"
|
|
|
|
# 拷贝资源文件
|
|
if [ "${copy_resources}" = "1" ]; then
|
|
print_info " Copying config and scripts..."
|
|
cp "${SERVER_DIR}/config.yml.example" "${output_dir}/config.yml"
|
|
cp "${SERVER_DIR}/readme.txt" "${output_dir}/"
|
|
cp "${SERVER_DIR}/readme_en.txt" "${output_dir}/"
|
|
cp "${SERVER_DIR}/resources/script/mayfly-go.sh" "${output_dir}/"
|
|
chmod +x "${output_dir}/mayfly-go.sh"
|
|
fi
|
|
|
|
print_success ">>> Build complete: ${target_name}"
|
|
cd "${PROJECT_ROOT}"
|
|
}
|
|
|
|
build_docker() {
|
|
local version="$1"
|
|
local use_buildx="$2"
|
|
local image_name
|
|
local build_cmd
|
|
|
|
if [ "${use_buildx}" = "1" ]; then
|
|
image_name="ccr.ccs.tencentyun.com/mayfly/mayfly-go:${version}"
|
|
build_cmd="docker buildx build --no-cache --push --platform linux/amd64,linux/arm64"
|
|
print_header "\n>>> Building Docker image (multi-arch): ${image_name}"
|
|
else
|
|
image_name="mayfly/mayfly-go:${version}"
|
|
build_cmd="docker build --no-cache --platform linux/amd64"
|
|
print_header "\n>>> Building Docker image: ${image_name}"
|
|
fi
|
|
|
|
${build_cmd} --build-arg MAYFLY_GO_VERSION="${version}" -t "${image_name}" "${PROJECT_ROOT}"
|
|
print_success ">>> Docker image built: ${image_name}"
|
|
}
|
|
|
|
cleanup_frontend() {
|
|
print_info "\n>>> Cleaning up temporary frontend assets..."
|
|
rm -rf "${SERVER_DIR}/static/static/"{assets,config.js,index.html}
|
|
print_success ">>> Cleanup complete"
|
|
}
|
|
|
|
compress_package() {
|
|
local source_dir="$1"
|
|
local output_dir="$2"
|
|
local package_name
|
|
|
|
package_name="$(basename "${source_dir}")"
|
|
|
|
print_header "\n>>> Compressing package: ${package_name}"
|
|
|
|
cd "${output_dir}"
|
|
|
|
# 统一使用 zip 格式,跨平台兼容性最好
|
|
zip -r "${package_name}.zip" "${package_name}"/
|
|
rm -rf "${package_name}"
|
|
print_success ">>> Compressed: ${package_name}.zip"
|
|
|
|
cd "${PROJECT_ROOT}"
|
|
}
|
|
|
|
#----------------------------------------------
|
|
# 主流程
|
|
#----------------------------------------------
|
|
main() {
|
|
# 显示菜单
|
|
print_header "========================================"
|
|
print_header " Mayfly-Go Release Build Tool"
|
|
print_header "========================================"
|
|
echo ""
|
|
echo "Build Options:"
|
|
echo " [0] All Platforms (linux-amd64, linux-arm64, windows, mac)"
|
|
echo " [1] Linux AMD64"
|
|
echo " [2] Linux ARM64"
|
|
echo " [3] Windows"
|
|
echo " [4] macOS"
|
|
echo " [5] Docker Image"
|
|
echo " [6] Docker Multi-arch (buildx)"
|
|
echo ""
|
|
|
|
read -p "Select build option [0-6] (default: 0): " build_type
|
|
build_type=${build_type:-0}
|
|
|
|
# 验证输入
|
|
if ! [[ "${build_type}" =~ ^[0-6]$ ]]; then
|
|
print_error "Error: Invalid option. Please enter a number between 0 and 6."
|
|
exit 1
|
|
fi
|
|
|
|
# 初始化配置
|
|
local output_dir="."
|
|
local docker_version="latest"
|
|
local copy_resources="1"
|
|
local compress_output="0"
|
|
local is_docker=0
|
|
|
|
# Docker 构建
|
|
if [[ "${build_type}" == "5" || "${build_type}" == "6" ]]; then
|
|
is_docker=1
|
|
echo ""
|
|
read -p "Enter Docker image version (default: latest): " docker_version
|
|
docker_version=${docker_version:-latest}
|
|
else
|
|
# 二进制构建
|
|
echo ""
|
|
read -p "Enter output directory (default: current): " output_dir
|
|
output_dir=${output_dir:-.}
|
|
|
|
# 验证并获取绝对路径
|
|
if [ "${output_dir}" != "." ] && [ ! -d "${output_dir}" ]; then
|
|
print_error "Error: Directory '${output_dir}' does not exist."
|
|
exit 1
|
|
fi
|
|
output_dir="$(cd "${output_dir}" && pwd)"
|
|
|
|
echo ""
|
|
read -p "Copy config & scripts? [Y/n] (default: Y): " copy_input
|
|
if [ "$(to_lower "${copy_input}")" = "n" ]; then
|
|
copy_resources="0"
|
|
fi
|
|
|
|
echo ""
|
|
read -p "Compress package? [y/N] (default: N): " compress_input
|
|
if [ "$(to_lower "${compress_input}")" = "y" ]; then
|
|
compress_output="1"
|
|
fi
|
|
|
|
# 构建前端
|
|
echo ""
|
|
build_frontend
|
|
fi
|
|
|
|
# 显示配置摘要
|
|
echo ""
|
|
print_header "Build Configuration:"
|
|
|
|
# 获取构建类型名称
|
|
local type_names=("All Platforms" "Linux AMD64" "Linux ARM64" "Windows" "macOS" "Docker Image" "Docker Multi-arch")
|
|
echo " Type: ${type_names[${build_type}]}"
|
|
|
|
if [ "${is_docker}" = "1" ]; then
|
|
echo " Version: ${docker_version}"
|
|
else
|
|
echo " Output: ${output_dir}"
|
|
echo " Resources: $([ "${copy_resources}" = "1" ] && echo "Yes" || echo "No")"
|
|
echo " Compress: $([ "${compress_output}" = "1" ] && echo "Yes" || echo "No")"
|
|
fi
|
|
echo ""
|
|
|
|
# 确认构建
|
|
read -p "Continue? [Y/n] (default: Y): " confirm
|
|
if [ "$(to_lower "${confirm}")" = "n" ]; then
|
|
print_info "Build cancelled."
|
|
exit 0
|
|
fi
|
|
|
|
# 执行构建
|
|
echo ""
|
|
print_header "Starting build..."
|
|
|
|
case "${build_type}" in
|
|
"1"|"2"|"3"|"4")
|
|
# 单个平台构建
|
|
local target="${BUILD_TARGETS[$((build_type-1))]}"
|
|
IFS='|' read -r name os arch <<< "${target}"
|
|
build_backend "${output_dir}/mayfly-go-${name}" "${os}" "${arch}" "${copy_resources}"
|
|
;;
|
|
"5")
|
|
build_docker "${docker_version}" "0"
|
|
;;
|
|
"6")
|
|
build_docker "${docker_version}" "1"
|
|
;;
|
|
*)
|
|
# 构建所有平台
|
|
print_info "Building all platforms..."
|
|
for target in "${BUILD_TARGETS[@]}"; do
|
|
IFS='|' read -r name os arch <<< "${target}"
|
|
build_backend "${output_dir}/mayfly-go-${name}" "${os}" "${arch}" "${copy_resources}"
|
|
done
|
|
;;
|
|
esac
|
|
|
|
# 清理临时文件
|
|
if [ "${is_docker}" = "0" ]; then
|
|
cleanup_frontend
|
|
fi
|
|
|
|
# 压缩输出
|
|
if [ "${compress_output}" = "1" ] && [ "${is_docker}" = "0" ]; then
|
|
case "${build_type}" in
|
|
"1"|"2"|"3"|"4")
|
|
local target="${BUILD_TARGETS[$((build_type-1))]}"
|
|
IFS='|' read -r name os arch <<< "${target}"
|
|
compress_package "${output_dir}/mayfly-go-${name}" "${output_dir}"
|
|
;;
|
|
*)
|
|
print_info "Compressing all packages..."
|
|
for target in "${BUILD_TARGETS[@]}"; do
|
|
IFS='|' read -r name os arch <<< "${target}"
|
|
compress_package "${output_dir}/mayfly-go-${name}" "${output_dir}"
|
|
done
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# 完成
|
|
echo ""
|
|
print_success "========================================"
|
|
print_success " Build Completed Successfully!"
|
|
print_success "========================================"
|
|
}
|
|
|
|
# 执行主函数
|
|
main
|