82 lines
3.6 KiB
Bash
Executable File
82 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BACKEND_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
JAR_PATH="${JAR_PATH:-$BACKEND_DIR/target/petstore-backend-1.0.0.jar}"
|
|
JAVA_BIN="${JAVA_BIN:-java}"
|
|
BUILD_FIRST="${BUILD_FIRST:-1}"
|
|
|
|
fail() {
|
|
printf 'PRECHECK FAIL: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
require_env() {
|
|
local name="$1"
|
|
[[ -n "${!name:-}" ]] || fail "missing environment variable: $name"
|
|
}
|
|
|
|
for name in MYSQL_URL MYSQL_USERNAME MYSQL_PASSWORD WECHAT_APPID WECHAT_APPSECRET \
|
|
WECHAT_REDIRECT_URI PETSTORE_SESSION_SECRET APP_BASE_URL UPLOAD_PATH CORS_ALLOWED_ORIGINS; do
|
|
require_env "$name"
|
|
done
|
|
|
|
[[ "$APP_BASE_URL" == https://* ]] || fail "APP_BASE_URL must use https"
|
|
[[ "$APP_BASE_URL" != *localhost* ]] || fail "APP_BASE_URL must not use localhost"
|
|
[[ "$APP_BASE_URL" != *.invalid* ]] || fail "APP_BASE_URL must not use a placeholder domain"
|
|
[[ "$APP_BASE_URL" != *.example* && "$APP_BASE_URL" != *.test* ]] \
|
|
|| fail "APP_BASE_URL must not use a reserved example/test domain"
|
|
[[ "$WECHAT_REDIRECT_URI" == https://* ]] || fail "WECHAT_REDIRECT_URI must use https"
|
|
[[ "$WECHAT_REDIRECT_URI" != *localhost* && "$WECHAT_REDIRECT_URI" != *.invalid* ]] \
|
|
|| fail "WECHAT_REDIRECT_URI must use a production domain"
|
|
[[ "$WECHAT_REDIRECT_URI" != *.example* && "$WECHAT_REDIRECT_URI" != *.test* ]] \
|
|
|| fail "WECHAT_REDIRECT_URI must not use a reserved example/test domain"
|
|
[[ ${#PETSTORE_SESSION_SECRET} -ge 32 ]] || fail "PETSTORE_SESSION_SECRET must be at least 32 characters"
|
|
[[ "$PETSTORE_SESSION_SECRET" != "dev-change-me" ]] || fail "PETSTORE_SESSION_SECRET must not use the default"
|
|
[[ -z "${SMS_UNIVERSAL_CODE:-}" ]] || fail "SMS_UNIVERSAL_CODE must be empty in production"
|
|
[[ "${SPRING_JPA_HIBERNATE_DDL_AUTO:-validate}" == "validate" ]] || fail "production ddl-auto must be validate"
|
|
[[ "${SPRING_JPA_SHOW_SQL:-false}" == "false" ]] || fail "production show-sql must be false"
|
|
[[ "$UPLOAD_PATH" == /* ]] || fail "UPLOAD_PATH must be absolute"
|
|
[[ -d "$UPLOAD_PATH" && -r "$UPLOAD_PATH" && -w "$UPLOAD_PATH" ]] \
|
|
|| fail "UPLOAD_PATH must exist and be readable/writable by the service user"
|
|
|
|
IFS=',' read -r -a cors_origins <<< "$CORS_ALLOWED_ORIGINS"
|
|
[[ ${#cors_origins[@]} -gt 0 ]] || fail "CORS_ALLOWED_ORIGINS must not be empty"
|
|
for origin in "${cors_origins[@]}"; do
|
|
origin="${origin#${origin%%[![:space:]]*}}"
|
|
origin="${origin%${origin##*[![:space:]]}}"
|
|
[[ "$origin" == https://* && "$origin" != *'*'* \
|
|
&& "$origin" != *localhost* && "$origin" != *127.0.0.1* && "$origin" != *.invalid* ]] \
|
|
|| fail "every CORS origin must be an explicit https origin"
|
|
[[ "$origin" != *.example* && "$origin" != *.test* ]] \
|
|
|| fail "CORS origins must not use reserved example/test domains"
|
|
done
|
|
|
|
command_ready() {
|
|
local binary="$1"
|
|
if [[ "$binary" == */* ]]; then
|
|
[[ -x "$binary" ]]
|
|
else
|
|
command -v "$binary" >/dev/null 2>&1
|
|
fi
|
|
}
|
|
|
|
FFMPEG_BINARY="${HIGHLIGHT_FFMPEG:-ffmpeg}"
|
|
FFPROBE_BINARY="${HIGHLIGHT_FFPROBE:-ffprobe}"
|
|
command_ready "$FFMPEG_BINARY" || fail "HIGHLIGHT_FFMPEG is not executable"
|
|
command_ready "$FFPROBE_BINARY" || fail "HIGHLIGHT_FFPROBE is not executable"
|
|
command -v "$JAVA_BIN" >/dev/null 2>&1 || fail "JAVA_BIN is not executable"
|
|
|
|
if [[ "$BUILD_FIRST" == "1" ]]; then
|
|
(cd "$BACKEND_DIR" && mvn -q -DskipTests package)
|
|
fi
|
|
[[ -r "$JAR_PATH" ]] || fail "backend jar not found: $JAR_PATH"
|
|
|
|
printf 'Static production precheck PASS\n'
|
|
printf 'Running read-only Spring/JPA/database invariant preflight...\n'
|
|
exec "$JAVA_BIN" -jar "$JAR_PATH" \
|
|
--spring.profiles.active=production \
|
|
--spring.main.web-application-type=none \
|
|
--app.preflight-only=true
|