feat: optimize backend build with conditional martial-tool install
This commit is contained in:
@@ -44,3 +44,10 @@ nul
|
||||
minio_data/
|
||||
minio_data/
|
||||
.m2-repo/
|
||||
|
||||
# Keep deploy scripts tracked
|
||||
!scripts/ensure-martial-tool-installed.sh
|
||||
!scripts/deploy-backend.sh
|
||||
|
||||
# Local build cache
|
||||
.build-cache/
|
||||
|
||||
@@ -62,10 +62,20 @@ docker compose ps
|
||||
### 快速构建(开发迭代)
|
||||
|
||||
```bash
|
||||
# 本地编译后构建镜像
|
||||
mvn clean package -DskipTests && docker-compose up --build
|
||||
# 只做后端打包(不会重建容器)
|
||||
./scripts/deploy-backend.sh --skip-docker
|
||||
|
||||
# 打包 + 重建并重启 martial-api 容器
|
||||
./scripts/deploy-backend.sh
|
||||
```
|
||||
|
||||
说明:
|
||||
- `./scripts/ensure-martial-tool-installed.sh` 会自动检测 `martial-tool` 是否已安装到本地 Maven 仓库。
|
||||
- 只有在以下情况才会重新执行 `martial-tool` 的 `mvn install`:
|
||||
- 本地 Maven 仓库缺少 BladeX 依赖产物。
|
||||
- `martial-tool` 代码发生变化(基于 git 状态检测)。
|
||||
- 日常迭代只改后端业务代码时,会跳过 `martial-tool` 编译,减少构建时间。
|
||||
|
||||
> 详细的 Docker 部署说明请参考 [Docker 部署指南](docs/guides/docker-deployment.md)
|
||||
|
||||
## 项目结构
|
||||
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: ./scripts/deploy-backend.sh [--skip-docker]
|
||||
|
||||
Options:
|
||||
--skip-docker Build jar only, skip docker compose build/up
|
||||
USAGE
|
||||
}
|
||||
|
||||
log() {
|
||||
printf '[deploy] %s\n' "$*"
|
||||
}
|
||||
|
||||
SKIP_DOCKER=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--skip-docker)
|
||||
SKIP_DOCKER=1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$SCRIPT_DIR/ensure-martial-tool-installed.sh"
|
||||
|
||||
log "Packaging backend jar ..."
|
||||
(
|
||||
cd "$PROJECT_DIR"
|
||||
mvn clean package -DskipTests
|
||||
)
|
||||
|
||||
if [[ "$SKIP_DOCKER" -eq 1 ]]; then
|
||||
log "--skip-docker enabled, jar build finished."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "Building and restarting martial-api ..."
|
||||
(
|
||||
cd "$PROJECT_DIR"
|
||||
docker compose build martial-api
|
||||
docker compose up -d --no-deps martial-api
|
||||
)
|
||||
|
||||
log "Waiting for martial-api health ..."
|
||||
for _ in $(seq 1 60); do
|
||||
json="$(cd "$PROJECT_DIR" && docker compose ps --format json martial-api 2>/dev/null || true)"
|
||||
health="$(printf '%s\n' "$json" | sed -n 's/.*"Health":"\([^"]*\)".*/\1/p' | head -n 1)"
|
||||
status="$(printf '%s\n' "$json" | sed -n 's/.*"Status":"\([^"]*\)".*/\1/p' | head -n 1)"
|
||||
|
||||
if [[ "$health" == "healthy" ]]; then
|
||||
log "martial-api is healthy."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if printf '%s' "$status" | grep -Eiq 'unhealthy|exited|dead'; then
|
||||
echo "[deploy] ERROR: martial-api status=$status" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 3
|
||||
done
|
||||
|
||||
echo "[deploy] ERROR: timed out waiting for martial-api health" >&2
|
||||
(cd "$PROJECT_DIR" && docker compose ps martial-api)
|
||||
exit 1
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
TOOL_DIR="${TOOL_DIR:-$PROJECT_DIR/../martial-tool}"
|
||||
CACHE_DIR="$PROJECT_DIR/.build-cache"
|
||||
STATE_FILE="$CACHE_DIR/martial-tool.state"
|
||||
|
||||
log() {
|
||||
printf '[martial-tool] %s\n' "$*"
|
||||
}
|
||||
|
||||
fail() {
|
||||
printf '[martial-tool] ERROR: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ -d "$TOOL_DIR" ]] || fail "martial-tool directory not found: $TOOL_DIR"
|
||||
[[ -f "$TOOL_DIR/pom.xml" ]] || fail "pom.xml not found in $TOOL_DIR"
|
||||
command -v mvn >/dev/null 2>&1 || fail "mvn command not found"
|
||||
|
||||
revision="$(sed -n 's:.*<revision>\([^<]*\)</revision>.*:\1:p' "$TOOL_DIR/pom.xml" | head -n 1)"
|
||||
[[ -n "$revision" ]] || fail "Unable to parse <revision> from $TOOL_DIR/pom.xml"
|
||||
|
||||
mapfile -t modules < <(sed -n 's:.*<module>\([^<]*\)</module>.*:\1:p' "$TOOL_DIR/pom.xml")
|
||||
(( ${#modules[@]} > 0 )) || fail "No modules found in $TOOL_DIR/pom.xml"
|
||||
|
||||
missing=()
|
||||
for artifact in "${modules[@]}"; do
|
||||
if [[ "$artifact" == "blade-bom" ]]; then
|
||||
group_path="org/springblade/platform"
|
||||
else
|
||||
group_path="org/springblade"
|
||||
fi
|
||||
|
||||
version_dir="$HOME/.m2/repository/$group_path/$artifact/$revision"
|
||||
if [[ ! -d "$version_dir" ]]; then
|
||||
missing+=("$artifact")
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! find "$version_dir" -maxdepth 1 -type f \( -name "$artifact-$revision.jar" -o -name "$artifact-$revision.pom" \) | grep -q .; then
|
||||
missing+=("$artifact")
|
||||
fi
|
||||
done
|
||||
|
||||
if git -C "$TOOL_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
git_head="$(git -C "$TOOL_DIR" rev-parse HEAD)"
|
||||
git_status="$(git -C "$TOOL_DIR" status --porcelain)"
|
||||
|
||||
if [[ -n "$git_status" ]]; then
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
dirty_hash="$(printf '%s' "$git_status" | sha256sum | awk '{print $1}')"
|
||||
else
|
||||
dirty_hash="$(printf '%s' "$git_status" | shasum -a 256 | awk '{print $1}')"
|
||||
fi
|
||||
tool_state="${git_head}-dirty-${dirty_hash}"
|
||||
else
|
||||
tool_state="$git_head"
|
||||
fi
|
||||
else
|
||||
pom_hash="$(find "$TOOL_DIR" -name pom.xml -type f -print0 | sort -z | xargs -0 cat | sha256sum | awk '{print $1}')"
|
||||
tool_state="nogit-${pom_hash}"
|
||||
fi
|
||||
|
||||
mkdir -p "$CACHE_DIR"
|
||||
previous_state=""
|
||||
if [[ -f "$STATE_FILE" ]]; then
|
||||
previous_state="$(cat "$STATE_FILE")"
|
||||
fi
|
||||
|
||||
if [[ ${#missing[@]} -eq 0 && "$tool_state" == "$previous_state" ]]; then
|
||||
log "Artifacts already installed for revision $revision and source state unchanged, skip install."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ${#missing[@]} -gt 0 ]]; then
|
||||
log "Missing artifacts detected (${#missing[@]}): ${missing[*]}"
|
||||
else
|
||||
log "martial-tool source changed, reinstall required."
|
||||
log "cached state: ${previous_state:-<none>}"
|
||||
log "current state: $tool_state"
|
||||
fi
|
||||
|
||||
log "Installing martial-tool from $TOOL_DIR ..."
|
||||
(
|
||||
cd "$TOOL_DIR"
|
||||
mvn -T 1C -DskipTests install
|
||||
)
|
||||
|
||||
printf '%s\n' "$tool_state" > "$STATE_FILE"
|
||||
log "Install complete. State cache updated: $STATE_FILE"
|
||||
Reference in New Issue
Block a user