背景
最初的 workflow 只有一个 job:SSH 到服务器执行 deploy.sh。
简单直接,但有个问题:代码写错了也会直接部署。
比如手滑把 app.py 改错了,push 上去,Actions 照样 SSH 到服务器、git pull、docker compose up -d –build——服务器上的服务直接挂。
想做到:先检查代码,通过了再部署。
原因
部署前必须先"体检"。
就像寄快递前要检查包裹:东西对不对、包装破没破、地址写没写对。
对应到 CI/CD:
检查清单
| 代码语法 | Python 代码能否通过编译 | python -m py_compile 或 python -m compileall |
| 配置文件语法 | compose 文件有没有写错 | docker compose config 校验 |
| 依赖完整性 | 有没有漏装包 | 对比 requirements.txt 与运行环境 |
这些检查应该跑在"独立的 job"里——检查失败,根本不进部署环节。
解决
把 workflow 拆成两个 job
name: Deploy
on:
push:
branches: [ main ]
jobs:
test:
name: 🔍 代码检查
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v4
– uses: actions/setup-python@v5
with:
python-version: '3.11'
– name: Python 语法检查
run: python -m compileall . -x '(\\.git|__pycache__)'
– name: 校验 compose 语法
run: docker compose config -q
deploy:
name: 🚀 部署
needs: test # 关键:test 通过才跑
runs-on: ubuntu-latest
steps:
– name: SSH 部署
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script: /home/YOUR_USER/app/deploy.sh
关键点:needs: test
deploy:
needs: test
这一行的含义:deploy job 要等 test job 完成且成功才启动。
如果 test 失败:
deploy job 状态显示为 skipped(跳过)
不会 SSH 到服务器
服务器上的服务完全不受影响
验证效果
故意写个语法错误:
# 在 app.py 里加一行无效代码
echo "this is not python syntax !!!" >> app.py
git add app.py
git commit -m "test: 故意写错验证检查"
git push
去 GitHub Actions 看:
🔍 代码检查 ❌ 失败
🚀 部署 ⏭️ 跳过
服务器上:
cd /home/YOUR_USER/app
git log –oneline -1
# 还是上一次的 commit,没有被更新
结论:坏代码被"拦在门外"了。
三个坑
坑 1:忘了加 needs: test
不加的话,两个 job 并行跑——test 还在检查,deploy 已经上服务器了。等于没检查。
记住:要让两个 job 有先后顺序,必须用 needs。
坑 2:test job 里检查的东西太少
只查 Python 语法,查不出配置文件错误。建议至少三条:
python -m compileall . # Python 语法
docker compose config -q # compose 语法
grep -r "YOUR_DB_PASSWORD" . –include="*.py" # 防止密码硬编码
第三条是"防止把明文密码提交上去"——写代码时最常犯的错。
坑 3:test job 用了和生产不一样的 Python 版本
你本地是 Python 3.11,但 workflow 里写 python-version: ‘3.10’——语法检查可能在本地通过、在 CI 里报错,或者反过来。
建议:workflow 里的 Python 版本跟 Dockerfile 里的基础镜像版本保持一致。
生活小插曲:好不容易把博客搭好了,兴冲冲分享给朋友,结果人家打不开。折腾半天才知道是备案卡住了。行,那就先当个“单机博客”玩着,等备案过了再联网。🤡



