| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- #!/bin/bash
- # 功能:
- # 非交互式用法:
- # ./build.sh <环境编号> [更新Excel] [发布]
- # 示例:
- # ./build.sh 1 1 0 # 使用当前分支,构建dev环境,更新Excel并导表,不发布
- # make build 1 1 0
- # 参数说明:
- # <环境编号> : 1=dev, 2=test, 3=dev&test, 4=prod
- # [更新Excel]: y/Y/1 表示更新并导表,其他值或省略表示跳过
- # [发布] : y/Y/1 表示 push 发布仓库,其他值或省略表示跳过
- # 特点:
- # - 默认使用当前 git 分支
- # - 全程无需交互输入,适合脚本/CI 调用
- #
- # 交互式用法:
- # ./build.sh
- # 交互步骤:
- # 1) 选择代码分支(默认当前分支),如选择其他分支则执行 git 切换
- # 2) 选择是否更新 Excel 仓库及 commit/hash/branch,并在该引用上执行导表
- # 并将生成/输出文件复制到项目的 etc/data 和 etc/data_map 下
- # 3) 选择构建类型(dev/test/prod)
- # 4) 选择是否将 publish 内容推送到发布仓库
- #
- # 注意:
- # - 假定脚本位于 e:\f1\server\etc\script 中,脚本会自动切换到仓库根目录以进行 git 操作
- PUBLISH_GIT_URL="ssh://git@git.chun-pu.com:9022/f1/server-publish.git"
- EXCEL_GIT_URL="ssh://git@git.chun-pu.com:9022/f1/excel.git"
- _tmp_dirs=()
- cleanup() {
- for d in "${_tmp_dirs[@]:-}"; do
- [[ -d "$d" ]] && rm -rf "$d"
- done
- return 0
- }
- trap cleanup EXIT
- # 检查并进入仓库根目录
- repo_root=$(git rev-parse --show-toplevel 2>/dev/null || true)
- if [[ -z "$repo_root" ]]; then
- echo "未检测到 git 仓库,请在项目仓库内运行此脚本。"
- exit 1
- fi
- cd "$repo_root"
- build_arg="${1:-}" #分支id
- update_excel_arg="${2:-}" #是否更新excel
- do_publish_arg="${3:-}" #是否发布到仓库
- noninteractive=false
- if [[ -n "$build_arg" ]]; then
- noninteractive=true
- fi
- # 1) 分支选择与切换(默认当前分支)
- repo_branch_current=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
- if $noninteractive; then
- target_branch="$repo_branch_current"
- echo "非交互模式:使用当前分支 ${target_branch}"
- else
- read -p "请输入要编译的分支(回车使用当前分支 ${repo_branch_current}): " target_branch
- target_branch=${target_branch:-$repo_branch_current}
- fi
- if [[ "$target_branch" != "$repo_branch_current" ]]; then
- echo "切换到分支 ${target_branch} ..."
- git fetch origin || true
- if git rev-parse --verify --quiet "refs/heads/${target_branch}"; then
- git checkout "$target_branch"
- git pull origin "$target_branch" --rebase || true
- repo_branch_current=$(git rev-parse --abbrev-ref HEAD)
- echo "当前分支: ${repo_branch_current}"
- else
- echo "不存在该分支,脚本终止。"
- exit 1
- fi
- fi
- # 获取当前分支的 hash
- repo_hash=$(git rev-parse HEAD 2>/dev/null || true)
- repo_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
- # 2) Excel 导表:询问是否需要更新Excel,回车默认跳过
- if $noninteractive; then
- case "$update_excel_arg" in
- y|Y|1)
- update_excel="y"
- ;;
- *)
- update_excel=""
- ;;
- esac
- echo "非交互模式:Excel 更新选项: ${update_excel:-跳过}"
- else
- read -p "是否需要更新 Excel 仓库?(y/n,回车跳过) " update_excel
- fi
- excel_hash=""
- excel_branch=""
- if [[ "$update_excel" =~ ^[Yy]$ ]]; then
- excel_tmp="$repo_root/_excel/"
-
- if [[ -d "$repo_root/_excel/" ]]; then
- echo "检测到已存在的 Excel 仓库,执行更新..."
- cd "$excel_tmp" || {
- echo "进入 Excel 仓库失败:${excel_tmp}"
- exit 2
- }
- git pull --rebase || true
- else
- git clone "$EXCEL_GIT_URL" "$excel_tmp" || {
- echo "克隆 Excel 仓库失败:${EXCEL_GIT_URL}"
- exit 2
- }
- cd "$excel_tmp" || {
- echo "进入 Excel 仓库失败:${excel_tmp}"
- exit 2
- }
- fi
-
- # 提示输入分支号,回车使用远程默认分支
- if $noninteractive; then
- excel_ref=""
- else
- read -p "请输入 Excel 仓库的 commit/hash/branch(回车使用远程默认分支): " excel_ref
- fi
-
- if [[ -z "${excel_ref}" ]]; then
- # 使用远程默认分支
- default_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
- if [[ -n "$default_branch" ]]; then
- echo "未输入引用,使用默认分支: ${default_branch}"
- else
- echo "默认分支未找到,终止脚本。"
- exit 2
- fi
- else
- # 输入了引用,尝试检出:优先当作本地/commit/short-hash,再尝试远程分支/标签
- echo "尝试检出指定引用: ${excel_ref} ..."
- if git rev-parse --verify --quiet "$excel_ref"; then
- git checkout -f "$excel_ref"
- else
- echo "无法检出指定引用: ${excel_ref},请确认输入是否正确"
- exit 2
- fi
- fi
-
- excel_hash=$(git rev-parse HEAD 2>/dev/null || true)
- excel_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
- echo "当前 Excel 仓库位于: ${excel_branch}"
- else
- echo "跳过 Excel 更新"
- fi
- # 执行导表,输出到output目录
- if [[ -n "$update_excel" ]] && [[ "$update_excel" =~ ^[Yy]$ ]]; then
- if [[ -f "$repo_root/_excel/bin/ee_linux" ]]; then
- echo "检测到 $repo_root/_excel/bin/ee_linux,开始执行导表..."
- cd "$repo_root/_excel/bin/" || true
- if [[ "$(uname -s)" == "MINGW"* ]]; then
- ./ee.exe --path=./server.json
- else
- ./ee_linux --path=./server.json
- fi
- echo "导表完成,复制生成的文件到项目..."
- cp -r "$repo_root/_excel/output/server_go/"* "$repo_root/internal/data/" 2>/dev/null || true
- cp -r "$repo_root/_excel/output/server_json/"* "$repo_root/etc/data/" 2>/dev/null || true
- cp -r "$repo_root/_excel/data_map/"* "$repo_root/etc/data_map/" 2>/dev/null || true
- else
- echo "$repo_root/_excel/bin/ee_linux 未找到,导表失败。"
- exit 2
- fi
- else
- echo "跳过导表步骤"
- fi
- cd "$repo_root" || true
- # 3) 编译源代码
- os_name=$(expr substr $(uname -s) 1 5 || true)
- build_user=$(whoami || true)
- build_time=$(date +"%Y-%m-%d %H:%M:%S" || true)
- publish_dir="$repo_root/publish"
- publish_dir_etc="${publish_dir}/etc/"
- publish_dir_etc_data="${publish_dir_etc}data/"
- publish_dir_etc_data_map="${publish_dir_etc}data_map/"
- publish_dir_etc_lua="${publish_dir_etc}lua/"
- publish_dir_etc_profile="${publish_dir_etc}profile/"
- publish_dir_etc_profile_include="${publish_dir_etc}profile/include/"
- main_file="$repo_root/nodes/main.go"
- # 回到 etc/script 以保持原相对路径引用
- cd "$repo_root/etc/script" || true
- # 构建相关函数(基于原脚本逻辑,使用绝对路径读取数据/文件)
- function clean_publish() {
- rm -rf "$publish_dir" 2>/dev/null || true
- mkdir -p "$publish_dir" "$publish_dir_etc" "$publish_dir_etc_data" "$publish_dir_etc_data_map" "$publish_dir_etc_lua" "$publish_dir_etc_profile"
- }
- function go_build() {
- local outname="$1"
- f_repo_hash="'f1-game/internal/version.RepoHash=${repo_hash}'"
- f_repo_branch="'f1-game/internal/version.RepoBranch=${repo_branch}'"
- f_excel_hash="'f1-game/internal/version.ExcelHash=${excel_hash}'"
- f_excel_branch="'f1-game/internal/version.ExcelBranch=${excel_branch}'"
- f_build_user="'f1-game/internal/version.BuildUser=${build_user}'"
- f_build_time="'f1-game/internal/version.BuildTime=${build_time}'"
- echo "[BUILD-${number}] ${f_repo_hash}"
- echo "[BUILD-${number}] ${f_repo_branch}"
- echo "[BUILD-${number}] ${f_excel_hash}"
- echo "[BUILD-${number}] ${f_excel_branch}"
- echo "[BUILD-${number}] ${f_build_user}"
- echo "[BUILD-${number}] ${f_build_time}"
- # 使用 $repo_root 相对的 main_file
- go build -ldflags "-X ${f_repo_hash} -X ${f_repo_branch} -X ${f_excel_hash} -X ${f_excel_branch} -X ${f_build_user} -X ${f_build_time}" -o "$publish_dir/${outname}" "$repo_root/nodes/main.go"
- echo "[BUILD-${number}] go build complete!"
- echo ""
- }
- function copy_etc_files() {
- echo "[BUILD-${number}] copy etc files."
- mkdir -p "$publish_dir_etc_data" "$publish_dir_etc_data_map" "$publish_dir_etc_lua" || true
- cp -r "$repo_root/etc/data/"* "$publish_dir_etc_data" 2>/dev/null || true
- cp -r "$repo_root/etc/data_embed/"* "$publish_dir_etc_data" 2>/dev/null || true
- cp -r "$repo_root/etc/data_map/"* "$publish_dir_etc_data_map" 2>/dev/null || true
- cp -r "$repo_root/etc/lua/"* "$publish_dir_etc_lua" 2>/dev/null || true
- }
- function build_dev() {
- clean_publish
- echo "[BUILD-${number}] dev profile..."
- export CGO_ENABLED=0
- export GOOS=linux
- export GOARCH=amd64
- go_build "node"
- copy_etc_files
- echo "[BUILD-${number}] copy profile include files."
- cp -r "$repo_root/etc/profile/include" "$publish_dir_etc_profile" 2>/dev/null || true
- echo "[BUILD-${number}] copy linux files."
- cp "$repo_root/etc/profile/dev.json" "$publish_dir_etc_profile" 2>/dev/null || true
- cp "$repo_root/etc/cli/cli.sh" "$publish_dir" 2>/dev/null || true
- cp "$repo_root/etc/cli/docker.sh" "$publish_dir" 2>/dev/null || true
- cp -r "$repo_root/tool/bin/"* "$publish_dir" 2>/dev/null || true
- cp "$repo_root/etc/docker/dev.yaml" "$publish_dir" 2>/dev/null || true
- cp "$repo_root/etc/docker/db.yaml" "$publish_dir" 2>/dev/null || true
- echo "[BUILD-${number}] exit."
- }
- function build_test() {
- clean_publish
- echo "[BUILD-${number}] test profile..."
- export CGO_ENABLED=0
- export GOOS=linux
- export GOARCH=amd64
- go_build "node"
- copy_etc_files
- echo "[BUILD-${number}] copy profile files."
- cp "$repo_root/etc/profile/test.json" "$publish_dir_etc_profile" 2>/dev/null || true
- echo "[BUILD-${number}] copy run script files."
- cp "$repo_root/etc/cli/docker.sh" "$publish_dir" 2>/dev/null || true
- cp -r "$repo_root/tool/bin/"* "$publish_dir" 2>/dev/null || true
- cp -r "$repo_root/etc/docker/test.yaml" "$publish_dir/test.yaml" 2>/dev/null || true
- cp "$repo_root/etc/docker/db.yaml" "$publish_dir" 2>/dev/null || true
- echo "[BUILD-${number}] exit."
- }
- function build_dev_test() {
- clean_publish
- echo "[BUILD-${number}] dev & test profile..."
- export CGO_ENABLED=0
- export GOOS=linux
- export GOARCH=amd64
- go_build "node"
- copy_etc_files
- echo "[BUILD-${number}] copy profile files."
- cp -r "$repo_root/etc/profile/include" "$publish_dir_etc_profile" 2>/dev/null || true
- cp "$repo_root/etc/profile/dev.json" "$publish_dir_etc_profile" 2>/dev/null || true
- cp "$repo_root/etc/profile/test.json" "$publish_dir_etc_profile" 2>/dev/null || true
- echo "[BUILD-${number}] copy run script files."
- cp "$repo_root/etc/cli/docker.sh" "$publish_dir" 2>/dev/null || true
- cp -r "$repo_root/tool/bin/"* "$publish_dir" 2>/dev/null || true
- cp -r "$repo_root/etc/docker/dev.yaml" "$publish_dir/dev.yaml" 2>/dev/null || true
- cp -r "$repo_root/etc/docker/test.yaml" "$publish_dir/test.yaml" 2>/dev/null || true
- cp "$repo_root/etc/docker/db.yaml" "$publish_dir" 2>/dev/null || true
- echo "[BUILD-${number}] exit."
- }
- # 若需,可实现 build_prod
- function build_prod() {
- clean_publish
- echo "[BUILD-${number}] prod profile..."
- export CGO_ENABLED=0
- export GOOS=linux
- export GOARCH=amd64
- go_build "node"
- copy_etc_files
- echo "[BUILD-${number}] copy profile files."
- cp "$repo_root/etc/profile/prod.json" "$publish_dir_etc_profile" 2>/dev/null || true
- cp -r "$repo_root/etc/profile/include" "$publish_dir_etc_profile" 2>/dev/null || true
- cp "$repo_root/etc/cli/cli.sh" "$publish_dir" 2>/dev/null || true
- cp -r "$repo_root/tool/bin/"* "$publish_dir" 2>/dev/null || true
- cp "$repo_root/etc/docker/prod.yaml" "$publish_dir" 2>/dev/null || true
- cp "$repo_root/etc/docker/db.yaml" "$publish_dir" 2>/dev/null || true
- echo "[BUILD-${number}] exit."
- }
- echo "------------------------------------------------------"
- echo "OS Name : ${os_name}"
- echo "Code Path : ${repo_root}"
- echo "Repo Hash : ${repo_hash}"
- echo "Repo Branch : ${repo_branch}"
- echo "Excel Hash : ${excel_hash}"
- echo "Excel Branch : ${excel_branch}"
- echo "Build User : ${build_user}"
- echo "Build Time : ${build_time}"
- echo "------------------------------------------------------"
- echo ""
- if $noninteractive; then
- number="$build_arg"
- echo "非交互模式:构建环境编号: ${number}"
- echo ""
- else
- echo "请选择构建的环境:"
- echo "[1] dev"
- echo "[2] test"
- echo "[3] dev & test"
- echo "[4] prod"
- echo "[9] exit"
- echo ""
- read -p "请输入选项编号: " number
- echo ""
- fi
- case $number in
- 1)
- build_dev
- ;;
- 2)
- build_test
- ;;
- 3)
- build_dev_test
- ;;
- 4)
- build_prod
- ;;
- 9)
- echo "退出"
- exit 0
- ;;
- *)
- echo "输入不正确,退出。"
- exit 1
- ;;
- esac
- # 5) 上传到发布仓库
- echo "准备将 publish 内容推送到发布仓库: ${PUBLISH_GIT_URL}"
- echo ""
- if $noninteractive; then
- case "$do_publish_arg" in
- y|Y|1)
- do_publish="y"
- ;;
- *)
- do_publish="n"
- ;;
- esac
- echo "非交互模式:发布选项: ${do_publish}"
- else
- read -p "是否将本次编译结果push到发布仓库?(y/n,回车跳过)" do_publish
- fi
- if [[ "$do_publish" =~ ^[Yy]$ ]]; then
- echo "开始推送发布内容..."
- pub_tmp=$(mktemp -d -t publish_repo_XXXX)
- _tmp_dirs+=("$pub_tmp")
- git clone "$PUBLISH_GIT_URL" "$pub_tmp"
- rm -rf "$pub_tmp"/*
- cp -r "$publish_dir/"* "$pub_tmp"/ 2>/dev/null || true
- pushd "$pub_tmp" >/dev/null
- git add --all
- git commit -m "auto build from repo:${repo_branch}@${repo_hash}, excel:${excel_branch}@${excel_hash}" || echo "Nothing to commit"
- git push origin master || echo "git push 失败,请检查网络或权限。"
- popd >/dev/null
- else
- echo "取消发布。"
- exit 0
- fi
- echo "exit"
- exit 0
|