126 lines
4.0 KiB
Bash
Executable File
126 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
|
||
set -Eeuo pipefail
|
||
|
||
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||
readonly WORKSPACE_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
|
||
readonly MODULE_ROOT="${WORKSPACE_ROOT}/module"
|
||
# 聚合宿主(全量 / 电商)同样需要构建与生产配置,两者都不在 module/ 下。
|
||
readonly PKGS_ROOT="${WORKSPACE_ROOT}/pkgs"
|
||
readonly BUILD_ROOT="${WORKSPACE_ROOT}/.builds"
|
||
readonly ENTRY_ROOT="${BUILD_ROOT}/.entries"
|
||
readonly CONFIG_ROOT="${BUILD_ROOT}/etc"
|
||
|
||
if ! command -v go >/dev/null 2>&1; then
|
||
echo "error: Go is not installed or is not available in PATH" >&2
|
||
exit 1
|
||
fi
|
||
|
||
if [[ ! -f "${WORKSPACE_ROOT}/go.work" ]]; then
|
||
echo "error: go.work was not found in ${WORKSPACE_ROOT}" >&2
|
||
exit 1
|
||
fi
|
||
|
||
export GOWORK="${WORKSPACE_ROOT}/go.work"
|
||
export GOOS=linux
|
||
export GOARCH=amd64
|
||
export CGO_ENABLED=0
|
||
|
||
modules=()
|
||
for source_root in "${MODULE_ROOT}" "${PKGS_ROOT}"; do
|
||
[[ -d "${source_root}" ]] || continue
|
||
while IFS= read -r -d '' go_mod; do
|
||
modules+=("$(dirname -- "${go_mod}")")
|
||
done < <(find "${source_root}" -type f -name go.mod -print0 | sort -z)
|
||
done
|
||
|
||
if (( ${#modules[@]} == 0 )); then
|
||
echo "error: no service modules were found under ${MODULE_ROOT} or ${PKGS_ROOT}" >&2
|
||
exit 1
|
||
fi
|
||
|
||
mkdir -p "${BUILD_ROOT}"
|
||
mkdir -p "${ENTRY_ROOT}"
|
||
|
||
cleanup() {
|
||
rm -rf -- "${ENTRY_ROOT}"
|
||
}
|
||
trap cleanup EXIT
|
||
|
||
echo "Building ${#modules[@]} service modules..."
|
||
|
||
for module_dir in "${modules[@]}"; do
|
||
# 去掉工作区一级目录(module/ 或 pkgs/),产物名保持原样:base-ads、all、ecmall。
|
||
relative_path="${module_dir#"${WORKSPACE_ROOT}/"}"
|
||
relative_path="${relative_path#module/}"
|
||
relative_path="${relative_path#pkgs/}"
|
||
artifact_name="${relative_path//\//-}"
|
||
output="${BUILD_ROOT}/${artifact_name}"
|
||
|
||
if [[ -f "${module_dir}/cmd/main/main.go" ]]; then
|
||
entry_file="${module_dir}/cmd/main/main.go"
|
||
entry_package="./cmd/main"
|
||
elif [[ -f "${module_dir}/cmd/main.go" ]]; then
|
||
entry_file="${module_dir}/cmd/main.go"
|
||
entry_package="./cmd"
|
||
else
|
||
echo "error: service entry not found under ${module_dir}/cmd" >&2
|
||
exit 1
|
||
fi
|
||
|
||
mkdir -p "$(dirname -- "${output}")"
|
||
echo "==> ${relative_path} -> ${output#"${WORKSPACE_ROOT}/"}"
|
||
|
||
(
|
||
cd -- "${module_dir}"
|
||
package_name="$(awk '$1 == "package" { print $2; exit }' "${entry_file}")"
|
||
|
||
if [[ "${package_name}" == "main" ]]; then
|
||
go build -trimpath -o "${output}" "${entry_package}"
|
||
else
|
||
module_name="$(awk '$1 == "module" { print $2; exit }' go.mod)"
|
||
module_name="${module_name//$'\r'/}"
|
||
wrapper_dir="${ENTRY_ROOT}/${relative_path}"
|
||
wrapper_file="${wrapper_dir}/main.go"
|
||
mkdir -p "${wrapper_dir}"
|
||
printf '%s\n' \
|
||
'package main' \
|
||
'' \
|
||
"import service \"${module_name}/${entry_package#./}\"" \
|
||
'' \
|
||
'func main() {' \
|
||
$'\tservice.Run()' \
|
||
'}' >"${wrapper_file}"
|
||
go build -trimpath -o "${output}" "${wrapper_file}"
|
||
fi
|
||
)
|
||
done
|
||
|
||
# Copy production configuration only after every service has compiled successfully.
|
||
mkdir -p "${CONFIG_ROOT}"
|
||
config_count=0
|
||
|
||
for module_dir in "${modules[@]}"; do
|
||
if [[ "${module_dir}" == "${PKGS_ROOT}/"* ]]; then
|
||
# 聚合入口按 --workspace 选配置,默认工作区为 default,生产配置文件名固定为 default_prod.yaml。
|
||
# 两个入口同名,按入口名分目录存放,避免相互覆盖。
|
||
entry_name="$(basename -- "${module_dir}")"
|
||
config_file="${module_dir}/etc/default_prod.yaml"
|
||
[[ -f "${config_file}" ]] || continue
|
||
mkdir -p "${CONFIG_ROOT}/${entry_name}"
|
||
cp -- "${config_file}" "${CONFIG_ROOT}/${entry_name}/default_prod.yaml"
|
||
((config_count += 1))
|
||
continue
|
||
fi
|
||
|
||
module_name="$(basename -- "${module_dir}")"
|
||
config_name="${module_name}_prod.yaml"
|
||
config_file="${module_dir}/etc/${config_name}"
|
||
[[ -f "${config_file}" ]] || continue
|
||
cp -- "${config_file}" "${CONFIG_ROOT}/${config_name}"
|
||
((config_count += 1))
|
||
done
|
||
|
||
echo "Copied ${config_count} production configs to ${CONFIG_ROOT}"
|
||
echo "Build completed successfully: ${BUILD_ROOT}"
|