GitHub Actions部署Spring Boot至EC2时测试失败求助
核心问题排查
你的测试失败大概率是部署时生成的.env文件格式错误,或者环境变量未被测试代码正确读取导致的,结合你的Workflow和配置,具体问题点如下:
1. .env文件格式不标准
你本地的.env用空格分隔变量(DB_HOST=localhost DB_PORT=3306 ...),这种写法不符合常规.env文件的规范(标准格式是每行一个变量)。虽然本地可能通过自定义解析逻辑正常工作,但部署时生成的文件可能因shell解析问题,导致变量无法被Spring Boot的.env解析器正确识别。
2. GitHub Secrets输出时的shell解析问题
你用echo ${{ secrets.ENV_VARIABLES }} > src/main/resources/.env生成.env文件时,如果Secrets里的内容包含空格或换行,shell会自动解析空格为参数分隔符,导致生成的文件内容丢失格式(比如换行被压缩、空格被截断),最终测试代码无法读取正确的环境变量。
3. 测试阶段的环境变量加载问题
Gradle执行测试时,可能未正确加载resources目录下的.env文件,或者文件权限不足导致无法读取。
分步解决方法
步骤1:修正.env文件格式(本地+GitHub Secrets)
首先把本地的.env改成标准的每行一个变量格式:
DB_HOST=localhost DB_PORT=3306 DB_USERNAME=root DB_PASSWORD=1234
然后在GitHub Secrets中更新ENV_VARIABLES,直接粘贴上述多行内容(GitHub Secrets支持换行输入)。
步骤2:修正Workflow中生成.env的命令
替换原来的echo命令,用printf或带引号的echo避免shell解析问题,确保生成的文件保留正确格式:
# 推荐用printf,更稳定 printf "%s" '${{ secrets.ENV_VARIABLES }}' > src/main/resources/.env # 或者用带双引号的echo echo "${{ secrets.ENV_VARIABLES }}" > src/main/resources/.env
步骤3:添加文件权限(可选但保险)
生成.env后,赋予可读权限,避免进程无法读取:
chmod 644 src/main/resources/.env
步骤4:优化测试阶段的环境变量注入(可选,更可靠)
如果测试代码支持直接读取系统环境变量,建议跳过生成.env文件,直接在shell中注入变量,避免文件读取的问题:
# 替换生成.env的步骤,直接导出环境变量 export DB_HOST=${{ secrets.DB_HOST }} export DB_PORT=${{ secrets.DB_PORT }} export DB_USERNAME=${{ secrets.DB_USERNAME }} export DB_PASSWORD=${{ secrets.DB_PASSWORD }}
注意:需要把原来的单个ENV_VARIABLES拆分成4个独立的GitHub Secrets(DB_HOST、DB_PORT等)。
步骤5:查看测试失败的具体日志
修改Workflow中的build命令,添加日志参数,方便定位具体错误:
./gradlew clean build --stacktrace --info
这样能看到测试失败的详细堆栈信息,比如是数据库连接超时,还是变量未找到,进一步确认问题。
修正后的完整Workflow示例
name: CD to EC2 on: push: branches: - main jobs: Deploy: runs-on: ubuntu-latest steps: - name: Access EC2 by SSH Key uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.EC2_HOST }} username: ${{ secrets.EC2_USERNAME }} key: ${{ secrets.EC2_PRIVATE_KEY }} script_stop: true script: | cd /home/ubuntu/SignUp git pull origin main # 生成标准格式的.env文件 printf "%s" '${{ secrets.ENV_VARIABLES }}' > src/main/resources/.env chmod 644 src/main/resources/.env # 执行build并输出详细日志 ./gradlew clean build --stacktrace --info sudo fuser -k -n tcp 8080 || true nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &
内容的提问来源于stack exchange,提问作者mintuchel

