ci: 添加 Gitea Actions workflow(推送自动构建/部署)
- .gitea/workflows/deploy.yaml - 支持 master/production 和 beta/development 分支 - 自动构建→测试→备份→部署→迁移→重启→健康检查
This commit is contained in:
95
.gitea/workflows/deploy.yaml
Normal file
95
.gitea/workflows/deploy.yaml
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
name: Deploy Backend
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- beta
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build (release)
|
||||||
|
run: cargo build --release
|
||||||
|
env:
|
||||||
|
APP_ENV: ${{ github.ref_name == 'master' && 'production' || 'development' }}
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: cargo test
|
||||||
|
|
||||||
|
- name: Determine target directories
|
||||||
|
id: target
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.ref_name }}" = "master" ]; then
|
||||||
|
echo "REMOTE_DIR=/root/rust/rust_backend" >> $GITHUB_OUTPUT
|
||||||
|
echo "SERVICE=rust-backend.service" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "REMOTE_DIR=/root/rust/rust_backend_dev" >> $GITHUB_OUTPUT
|
||||||
|
echo "SERVICE=rust-backend-dev.service" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Backup old binary
|
||||||
|
run: |
|
||||||
|
REMOTE_DIR="${{ steps.target.outputs.REMOTE_DIR }}"
|
||||||
|
if [ -f "$REMOTE_DIR/rust-backend" ]; then
|
||||||
|
BACKUP="$REMOTE_DIR/rust-backend.backup.$(date +%Y%m%d_%H%M%S)"
|
||||||
|
cp "$REMOTE_DIR/rust-backend" "$BACKUP"
|
||||||
|
echo "$BACKUP" > "$REMOTE_DIR/.last_deployed"
|
||||||
|
echo "备份已创建: $BACKUP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Backup database
|
||||||
|
run: |
|
||||||
|
source /root/rust/rust_backend/.env 2>/dev/null || true
|
||||||
|
DB_NAME="${DATABASE_URL##*/}"
|
||||||
|
BACKUP_DIR="${{ steps.target.outputs.REMOTE_DIR }}/backups"
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
pg_dump -Fc "$DATABASE_URL" -f "$BACKUP_DIR/${DB_NAME}_$(date +%Y%m%d_%H%M%S).dump" 2>/dev/null || \
|
||||||
|
echo "数据库备份跳过(pg_dump 不可用)"
|
||||||
|
|
||||||
|
- name: Deploy binary
|
||||||
|
run: |
|
||||||
|
REMOTE_DIR="${{ steps.target.outputs.REMOTE_DIR }}"
|
||||||
|
cp ./target/release/rust-backend "$REMOTE_DIR/rust-backend"
|
||||||
|
chmod +x "$REMOTE_DIR/rust-backend"
|
||||||
|
echo "二进制部署完成"
|
||||||
|
|
||||||
|
- name: Run database migrations
|
||||||
|
run: |
|
||||||
|
REMOTE_DIR="${{ steps.target.outputs.REMOTE_DIR }}"
|
||||||
|
mkdir -p "$REMOTE_DIR/migrations"
|
||||||
|
cp ./migrations/*.sql "$REMOTE_DIR/migrations/"
|
||||||
|
source /root/rust/rust_backend/.env 2>/dev/null || true
|
||||||
|
for f in ./migrations/*.sql; do
|
||||||
|
NAME=$(basename "$f")
|
||||||
|
echo "检查迁移: $NAME"
|
||||||
|
# 使用迁移标记表,避免重复执行
|
||||||
|
psql "$DATABASE_URL" -c \
|
||||||
|
"CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at TIMESTAMPTZ DEFAULT NOW())" 2>/dev/null
|
||||||
|
COUNT=$(psql "$DATABASE_URL" -t -A -c "SELECT COUNT(*) FROM _migrations WHERE name='$NAME'" 2>/dev/null || echo "0")
|
||||||
|
if [ "$COUNT" = "0" ]; then
|
||||||
|
echo "执行迁移: $NAME"
|
||||||
|
psql "$DATABASE_URL" -f "$f" && \
|
||||||
|
psql "$DATABASE_URL" -c "INSERT INTO _migrations (name) VALUES ('$NAME')" && \
|
||||||
|
echo "完成: $NAME"
|
||||||
|
else
|
||||||
|
echo "跳过(已执行): $NAME"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Restart service
|
||||||
|
run: |
|
||||||
|
SERVICE="${{ steps.target.outputs.SERVICE }}"
|
||||||
|
systemctl restart "$SERVICE"
|
||||||
|
sleep 2
|
||||||
|
systemctl is-active "$SERVICE" && echo "$SERVICE 重启成功" || echo "⚠️ $SERVICE 重启失败"
|
||||||
|
|
||||||
|
- name: Health check
|
||||||
|
run: |
|
||||||
|
for i in $(seq 1 5); do
|
||||||
|
curl -sf http://127.0.0.1:8080/health && echo "健康检查通过" && exit 0
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
echo "健康检查超时" && exit 1
|
||||||
Reference in New Issue
Block a user