Some checks failed
构建并部署 Spring Boot 应用 / build-and-deploy (push) Failing after 9s
187 lines
6.3 KiB
YAML
187 lines
6.3 KiB
YAML
name: 构建并部署 Spring Boot 应用
|
||
|
||
on:
|
||
push:
|
||
branches: [master, develop]
|
||
pull_request:
|
||
branches: [master, develop]
|
||
|
||
jobs:
|
||
build-and-deploy:
|
||
runs-on: ubuntu-latest # 使用自托管 Runner
|
||
|
||
steps:
|
||
- name: 检出代码
|
||
uses: actions/checkout@v4.1.1
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- name: 设置 Maven
|
||
uses: actions/setup-java@v4.2.1
|
||
with:
|
||
distribution: 'maven'
|
||
java-version: '17'
|
||
cache: 'maven'
|
||
|
||
- name: 从本地文件安装 JDK 17
|
||
run: |
|
||
echo "=== 详细文件检查 ==="
|
||
echo "当前目录: $(pwd)"
|
||
echo "用户: $(whoami)"
|
||
|
||
# 详细检查文件系统
|
||
echo "检查 /opt/ 目录:"
|
||
ls -la /opt/ 2>/dev/null || echo "/opt/ 目录不存在"
|
||
|
||
echo "检查 /opt/jdk-dist/ 目录:"
|
||
ls -la /opt/jdk-dist/ 2>/dev/null || echo "/opt/jdk-dist/ 目录不存在"
|
||
|
||
echo "检查具体文件:"
|
||
if [ -f "/opt/jdk-dist/openjdk-17.0.2_linux-x64_bin.tar.gz" ]; then
|
||
echo " 文件存在!"
|
||
ls -la "/opt/jdk-dist/openjdk-17.0.2_linux-x64_bin.tar.gz"
|
||
file_size=$(stat -c%s "/opt/jdk-dist/openjdk-17.0.2_linux-x64_bin.tar.gz")
|
||
echo "文件大小: $file_size 字节"
|
||
|
||
echo "复制文件..."
|
||
cp "/opt/jdk-dist/openjdk-17.0.2_linux-x64_bin.tar.gz" jdk.tar.gz
|
||
else
|
||
echo " 文件不存在!"
|
||
echo " 本地文件不存在,回退到下载"
|
||
wget http://192.168.171.223:8082/openjdk-17.0.2_linux-x64_bin.tar.gz -O jdk.tar.gz
|
||
fi
|
||
|
||
echo "安装 JDK..."
|
||
sudo mkdir -p /opt/java
|
||
sudo tar -xzf jdk.tar.gz -C /opt/java --strip-components=1
|
||
|
||
echo "JAVA_HOME=/opt/java" >> $GITHUB_ENV
|
||
echo "/opt/java/bin" >> $GITHUB_PATH
|
||
rm -f jdk.tar.gz
|
||
echo " JDK 安装完成"
|
||
|
||
- name: 验证 Java 安装
|
||
run: |
|
||
echo "验证 Java 安装:"
|
||
java -version
|
||
javac -version
|
||
echo "JAVA_HOME: $JAVA_HOME"
|
||
echo "PATH: $PATH"
|
||
|
||
- name: 验证环境
|
||
run: |
|
||
echo "Runner 工作目录: $(pwd)"
|
||
echo "Docker 信息:"
|
||
docker --version
|
||
if ! docker info >/dev/null 2>&1; then
|
||
echo "❌ Docker 守护进程不可访问"
|
||
exit 1
|
||
else
|
||
echo "✅ Docker 守护进程可访问"
|
||
docker info
|
||
fi
|
||
echo "Maven 信息:"
|
||
mvn --version
|
||
|
||
- name: 缓存 Maven 依赖
|
||
uses: actions/cache@v3
|
||
with:
|
||
path: ~/.m2/repository
|
||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-maven-
|
||
|
||
- name: 编译和打包项目
|
||
run: |
|
||
mvn clean package -DskipTests
|
||
ls -la target/
|
||
|
||
- name: 运行测试
|
||
run: mvn test
|
||
|
||
- name: 构建 Docker 镜像
|
||
run: |
|
||
# 使用 Dockerfile 构建镜像
|
||
docker build -t light-delivery-app:latest .
|
||
|
||
- name: 验证镜像构建
|
||
run: |
|
||
echo "构建的 Docker 镜像:"
|
||
docker images | grep light-delivery-app
|
||
echo "镜像详情:"
|
||
docker inspect light-delivery-app:latest --format='Size: {{.Size}} bytes, Created: {{.Created}}'
|
||
|
||
- name: 停止旧容器
|
||
run: |
|
||
# 优雅停止旧容器
|
||
docker stop light-delivery-container 2>/dev/null || echo "没有运行中的容器"
|
||
docker rm light-delivery-container 2>/dev/null || echo "没有可删除的容器"
|
||
|
||
- name: 备份当前镜像(可选)
|
||
run: |
|
||
# 为当前运行中的镜像创建备份标签
|
||
if docker images light-delivery-app:latest --quiet | grep -q .; then
|
||
BACKUP_TAG="backup-$(date +%Y%m%d-%H%M%S)"
|
||
docker tag light-delivery-app:latest light-delivery-app:$BACKUP_TAG
|
||
echo "已创建备份: light-delivery-app:$BACKUP_TAG"
|
||
fi
|
||
|
||
- name: 运行新容器
|
||
run: |
|
||
# 创建必要的目录
|
||
sudo mkdir -p /app/logs
|
||
sudo mkdir -p /etc/ssl/certs
|
||
sudo chown $USER:$USER /app/logs 2>/dev/null || true
|
||
|
||
echo "使用统一的部署配置启动新容器..."
|
||
docker compose -f deploy.yml up -d
|
||
|
||
- name: 等待应用启动并健康检查
|
||
run: |
|
||
echo "等待应用启动..."
|
||
# 最大重试次数
|
||
MAX_RETRIES=12
|
||
RETRY_COUNT=0
|
||
|
||
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||
# 使用正确的端口 (8443) 和协议 (HTTPS),不跳过SSL验证
|
||
if curl -f -s https://localhost:8443/actuator/health > /dev/null 2>&1; then
|
||
echo "✅ 应用健康检查通过"
|
||
|
||
# 获取详细的健康信息
|
||
HEALTH_INFO=$(curl -s https://localhost:8443/actuator/health)
|
||
echo "健康状态: $HEALTH_INFO"
|
||
break
|
||
fi
|
||
|
||
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||
echo "健康检查失败 ($RETRY_COUNT/$MAX_RETRIES),10秒后重试..."
|
||
sleep 10
|
||
done
|
||
|
||
if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
|
||
echo "❌ 应用启动超时,查看日志:"
|
||
docker logs light-delivery-container --tail 50
|
||
exit 1
|
||
fi
|
||
|
||
- name: 清理资源
|
||
run: |
|
||
# 清理旧的备份镜像(保留最近5个)
|
||
echo "清理旧的备份镜像..."
|
||
docker images light-delivery-app --filter "reference=light-delivery-app:backup-*" \
|
||
--format "{{.Tag}}\t{{.CreatedAt}}" | \
|
||
sort -k2 -r | \
|
||
tail -n +6 | \
|
||
awk '{print $1}' | \
|
||
xargs -r -I {} docker rmi light-delivery-app:{} || echo "无需清理"
|
||
|
||
# 清理无用镜像和容器
|
||
docker system prune -f
|
||
|
||
- name: 部署完成通知
|
||
run: |
|
||
echo "🎉 部署完成!"
|
||
echo "应用运行在: http://localhost:8080"
|
||
echo "容器状态: $(docker inspect light-delivery-container --format='{{.State.Status}}')"
|
||
echo "启动时间: $(docker inspect light-delivery-container --format='{{.State.StartedAt}}')" |