Some checks failed
构建并部署 Spring Boot 应用 / build-and-deploy (push) Failing after 17m1s
160 lines
5.4 KiB
YAML
160 lines
5.4 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: 从本地文件安装 JDK 17
|
||
run: |
|
||
echo "使用本地 JDK 文件..."
|
||
# 强制使用本地文件,不依赖网络
|
||
if [ -f "/opt/jdk-dist/openjdk-17.0.2_linux-x64_bin.tar.gz" ]; then
|
||
echo "复制本地 JDK 文件..."
|
||
cp "/opt/jdk-dist/openjdk-17.0.2_linux-x64_bin.tar.gz" jdk.tar.gz
|
||
else
|
||
echo "本地 JDK 文件不存在,从网络下载..."
|
||
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
|
||
|
||
- name: 安装 Maven
|
||
run: |
|
||
echo "安装 Maven..."
|
||
sudo apt update
|
||
sudo apt install -y maven
|
||
echo "Maven 版本:"
|
||
mvn --version
|
||
|
||
- name: 验证环境
|
||
run: |
|
||
echo "Runner 工作目录: $(pwd)"
|
||
echo "Java 版本:"
|
||
java -version
|
||
echo "Maven 版本:"
|
||
mvn --version
|
||
echo "JAVA_HOME: $JAVA_HOME"
|
||
echo "实际 JAVA_HOME 路径:"
|
||
ls -la $JAVA_HOME
|
||
|
||
- 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://www.doubleyin.cn:8443/actuator/health > /dev/null 2>&1; then
|
||
echo "✅ 应用健康检查通过"
|
||
|
||
# 获取详细的健康信息
|
||
HEALTH_INFO=$(curl -s https://www.doubleyin.cn: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}}')" |