Files
prop-ai-hr/scripts/release-preflight.sh
T

120 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
fail() {
echo "release-preflight: $*" >&2
exit 1
}
require_file() {
[[ -f "$1" ]] || fail "missing artifact: $1; build it before release"
}
sha256() {
if command -v shasum >/dev/null 2>&1; then
shasum -a 256 "$1" | awk '{print $1}'
else
sha256sum "$1" | awk '{print $1}'
fi
}
sha256_stream() {
if command -v shasum >/dev/null 2>&1; then
shasum -a 256 | awk '{print $1}'
else
sha256sum | awk '{print $1}'
fi
}
frontend_index="frontend/dist/index.html"
mobile_index="mobile-uni/dist/build/h5/index.html"
backend_jar="backend/ruoyi-admin/target/ruoyi-admin.jar"
require_file "$frontend_index"
require_file "$mobile_index"
require_file "$backend_jar"
frontend_asset="$(sed -nE 's/.*src="([^"]+\.js)".*/\1/p' "$frontend_index" | head -1)"
mobile_asset="$(sed -nE 's/.*src="([^"]+\.js)".*/\1/p' "$mobile_index" | head -1)"
[[ -n "$frontend_asset" ]] || fail "frontend index does not reference a JavaScript entry"
[[ -n "$mobile_asset" ]] || fail "mobile H5 index does not reference a JavaScript entry"
frontend_asset_path="frontend/dist/${frontend_asset#/}"
mobile_asset_rel="${mobile_asset#/}"
mobile_asset_rel="${mobile_asset_rel#h5/}"
mobile_asset_path="mobile-uni/dist/build/h5/$mobile_asset_rel"
require_file "$frontend_asset_path"
require_file "$mobile_asset_path"
grep -q '/h5/' "$mobile_index" || fail "mobile H5 index does not contain the /h5/ base path"
head_epoch="$(git show -s --format=%ct HEAD)"
file_epoch() {
if stat -f %m "$1" >/dev/null 2>&1; then
stat -f %m "$1"
else
stat -c %Y "$1"
fi
}
require_fresh_artifact() {
local artifact="$1"
local artifact_epoch
artifact_epoch="$(file_epoch "$artifact")" || fail "cannot read artifact timestamp: $artifact"
[[ "$artifact_epoch" -ge "$head_epoch" ]] || fail "artifact is older than HEAD; rebuild before release: $artifact"
}
require_fresh_artifact "$frontend_index"
require_fresh_artifact "$frontend_asset_path"
require_fresh_artifact "$mobile_index"
require_fresh_artifact "$mobile_asset_path"
require_fresh_artifact "$backend_jar"
changed_files="$(git status --porcelain)"
[[ -z "$changed_files" ]] || fail "worktree has uncommitted changes; commit the release batch before publishing"
echo "commit=$(git rev-parse HEAD)"
echo "head_epoch=$head_epoch"
echo "worktree=clean"
echo "frontend_index_sha256=$(sha256 "$frontend_index")"
echo "frontend_asset=$frontend_asset"
echo "frontend_asset_sha256=$(sha256 "$frontend_asset_path")"
echo "mobile_index_sha256=$(sha256 "$mobile_index")"
echo "mobile_asset=$mobile_asset"
echo "mobile_asset_sha256=$(sha256 "$mobile_asset_path")"
echo "backend_jar_sha256=$(sha256 "$backend_jar")"
if [[ -n "${RELEASE_REMOTE_URL:-}" ]]; then
remote="${RELEASE_REMOTE_URL%/}"
curl -fsS --max-time 15 "$remote/" >/dev/null || fail "remote root check failed: $remote/"
echo "remote_root=200 $remote/"
if curl -fsS --max-time 15 "$remote/prod-api/auth/tenant/list" >/dev/null; then
echo "remote_tenant_list=200 $remote/prod-api/auth/tenant/list"
else
fail "remote tenant list check failed: $remote/prod-api/auth/tenant/list"
fi
if [[ "${RELEASE_VERIFY_REMOTE_MATCH:-false}" == "true" ]]; then
remote_frontend_asset="$(curl -fsS --max-time 15 "$remote/" | sed -nE 's/.*src="(\/assets\/[^" ]+\.js)".*/\1/p' | head -n 1)"
remote_mobile_asset="$(curl -fsS --max-time 15 "$remote/h5/" | sed -nE 's/.*src="(\/h5\/assets\/[^" ]+\.js)".*/\1/p' | head -n 1)"
[[ "$remote_frontend_asset" == /assets/*.js ]] || fail "remote frontend entry asset not found"
[[ "$remote_mobile_asset" == /h5/assets/*.js ]] || fail "remote mobile H5 entry asset not found"
remote_frontend_sha256="$(curl -fsS --max-time 15 "$remote$remote_frontend_asset" | sha256_stream)"
remote_mobile_sha256="$(curl -fsS --max-time 15 "$remote$remote_mobile_asset" | sha256_stream)"
local_frontend_sha256="$(sha256 "$frontend_asset_path")"
local_mobile_sha256="$(sha256 "$mobile_asset_path")"
echo "remote_frontend_asset=$remote_frontend_asset"
echo "remote_frontend_asset_sha256=$remote_frontend_sha256"
echo "remote_mobile_asset=$remote_mobile_asset"
echo "remote_mobile_asset_sha256=$remote_mobile_sha256"
[[ "$remote_frontend_sha256" == "$local_frontend_sha256" ]] || fail "remote frontend asset does not match local build"
[[ "$remote_mobile_sha256" == "$local_mobile_sha256" ]] || fail "remote mobile H5 asset does not match local build"
echo "remote_asset_match=true"
fi
fi
echo "release-preflight: read-only checks passed"