Files
cozsweet-frontend-nextjs/.githooks/post-receive
T

169 lines
4.9 KiB
Bash
Executable File

#!/bin/sh
# Post-receive hook: push 后自动构建 Docker 镜像并重启容器
REPO_TOPLEVEL=""
LOG_FILE=""
CURRENT_BRANCH=""
DEPLOY_ENV=""
ENV_FILE=""
START_PORT=""
IMAGE_TAG=""
CONTAINER_NAME=""
COMPOSE_PROJECT_NAME=""
COMPOSE_EXIT=0
resolve_repo_context() {
GIT_DIR_ABS="$(git rev-parse --absolute-git-dir 2>/dev/null)"
if [ -n "$GIT_DIR_ABS" ] && [ -d "$GIT_DIR_ABS" ]; then
REPO_TOPLEVEL="$(cd "$GIT_DIR_ABS/.." && pwd)"
export GIT_DIR="$GIT_DIR_ABS"
else
REPO_TOPLEVEL="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
fi
unset GIT_WORK_TREE
cd "$REPO_TOPLEVEL" || { echo "FATAL: cannot cd to $REPO_TOPLEVEL" >&2; exit 1; }
echo "=== REPO_TOPLEVEL=$REPO_TOPLEVEL (GIT_DIR=$GIT_DIR) ===" >&2
}
init_log_file() {
LOG_FILE="$REPO_TOPLEVEL/logs/post-receive.log"
mkdir -p "$(dirname "$LOG_FILE")"
}
write_metadata_header() {
{
echo "=== post-receive @ $(date +%Y-%m-%dT%H:%M:%S%z) ==="
echo "branch: $(git rev-parse --abbrev-ref HEAD)"
echo "commit: $(git rev-parse --short HEAD)"
echo "cwd: $(pwd)"
echo ""
} > "$LOG_FILE"
}
sync_worktree() {
echo "=== sync_worktree: git reset --hard HEAD @ $(date +%Y-%m-%dT%H:%M:%S%z) ===" >> "$LOG_FILE"
git reset --hard HEAD >> "$LOG_FILE" 2>&1
}
copy_env_by_branch() {
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "=== branch: $CURRENT_BRANCH ===" >> "$LOG_FILE"
case "$CURRENT_BRANCH" in
main)
cp -f env-example/.env.production.example .env.production
ENV_FILE=".env.production"
DEPLOY_ENV="prod"
START_PORT=9185
echo "=== env: copied .env.production (main → prod) ===" >> "$LOG_FILE"
;;
test)
cp -f env-example/.env.local.example .env.local
ENV_FILE=".env.local"
DEPLOY_ENV="test"
START_PORT=9135
echo "=== env: copied .env.local (test → test) ===" >> "$LOG_FILE"
;;
dev)
cp -f env-example/.env.development.example .env.local
ENV_FILE=".env.local"
DEPLOY_ENV="dev"
START_PORT=9135
echo "=== env: copied .env.local (dev → dev) ===" >> "$LOG_FILE"
;;
*)
ENV_FILE=".env.local"
DEPLOY_ENV="$CURRENT_BRANCH"
START_PORT=9135
echo "=== env: UNKNOWN branch '$CURRENT_BRANCH', use defaults ===" >> "$LOG_FILE"
;;
esac
}
prepare_compose_env() {
SHORT_SHA="$(git rev-parse --short HEAD)"
IMAGE_TAG="cozsweet-web:${DEPLOY_ENV}-${SHORT_SHA}"
CONTAINER_NAME="cozsweet-web-${DEPLOY_ENV}"
COMPOSE_PROJECT_NAME="cozsweet-web-${DEPLOY_ENV}"
export COZSWEET_IMAGE="$IMAGE_TAG"
export COZSWEET_CONTAINER_NAME="$CONTAINER_NAME"
export COZSWEET_ENV_FILE="$ENV_FILE"
export COZSWEET_HOST_PORT="$START_PORT"
export COMPOSE_PROJECT_NAME
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
{
echo "=== deploy env: $DEPLOY_ENV ==="
echo "=== env file: $COZSWEET_ENV_FILE ==="
echo "=== image: $COZSWEET_IMAGE ==="
echo "=== container: $COZSWEET_CONTAINER_NAME ==="
echo "=== host port: $COZSWEET_HOST_PORT ==="
echo "=== compose project: $COMPOSE_PROJECT_NAME ==="
echo ""
} >> "$LOG_FILE"
}
docker_compose() {
if docker compose version >/dev/null 2>&1; then
docker compose "$@"
return $?
fi
if command -v docker-compose >/dev/null 2>&1; then
docker-compose "$@"
return $?
fi
echo "=== docker compose command not found ===" >> "$LOG_FILE"
return 127
}
run_container_build() {
echo "=== docker build START @ $(date +%Y-%m-%dT%H:%M:%S%z) ===" >> "$LOG_FILE"
docker_compose build web >> "$LOG_FILE" 2>&1
COMPOSE_EXIT=$?
echo "=== docker build EXIT_CODE=$COMPOSE_EXIT @ $(date +%Y-%m-%dT%H:%M:%S%z) ===" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
return $COMPOSE_EXIT
}
launch_container() {
echo "=== docker compose up START @ $(date +%Y-%m-%dT%H:%M:%S%z) ===" >> "$LOG_FILE"
docker_compose up -d --remove-orphans web >> "$LOG_FILE" 2>&1
COMPOSE_EXIT=$?
echo "=== docker compose up EXIT_CODE=$COMPOSE_EXIT @ $(date +%Y-%m-%dT%H:%M:%S%z) ===" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
return $COMPOSE_EXIT
}
log_abort() {
echo "=== ABORTED @ $(date +%Y-%m-%dT%H:%M:%S%z) ($1) ===" >> "$LOG_FILE"
}
main() {
resolve_repo_context
init_log_file
write_metadata_header
sync_worktree
copy_env_by_branch
prepare_compose_env
if ! run_container_build; then
log_abort "docker build failed, old container kept running"
exit $COMPOSE_EXIT
fi
if ! launch_container; then
log_abort "docker compose up failed"
exit $COMPOSE_EXIT
fi
echo "=== DEPLOY DONE @ $(date +%Y-%m-%dT%H:%M:%S%z) ===" >> "$LOG_FILE"
}
main "$@"
exit 0