|
9940
|
7672
|
6
|
5
|
db7f39e63151b9c065646855287b8be73e13649b
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774321883
|
1774321785
|
1774321883
|
|
0
|
|
0
|
Edit
Delete
|
|
9951
|
7674
|
6
|
5
|
db7f39e63151b9c065646855287b8be73e13649b
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
8509
|
4
|
1774321903
|
1774321904
|
1774321883
|
1774321904
|
|
1
|
|
0
|
Edit
Delete
|
|
10006
|
7689
|
6
|
5
|
81e883dfff9283af39b3dd2aa30e25ae2119e8f0
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774325277
|
1774325215
|
1774325277
|
|
0
|
|
0
|
Edit
Delete
|
|
10020
|
7691
|
6
|
5
|
81e883dfff9283af39b3dd2aa30e25ae2119e8f0
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774325282
|
1774325277
|
1774325282
|
|
0
|
|
0
|
Edit
Delete
|
|
10030
|
7692
|
6
|
5
|
81e883dfff9283af39b3dd2aa30e25ae2119e8f0
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774325283
|
1774325282
|
1774325283
|
|
0
|
|
0
|
Edit
Delete
|
|
10040
|
7693
|
6
|
5
|
81e883dfff9283af39b3dd2aa30e25ae2119e8f0
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
8562
|
4
|
1774325300
|
1774325300
|
1774325284
|
1774325300
|
|
1
|
|
0
|
Edit
Delete
|
|
10156
|
7769
|
6
|
5
|
9f09902dce3537d952595fd6d33175b6f0c24c7e
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774346925
|
1774346863
|
1774346925
|
|
0
|
|
0
|
Edit
Delete
|
|
10170
|
7771
|
6
|
5
|
9f09902dce3537d952595fd6d33175b6f0c24c7e
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774346930
|
1774346925
|
1774346930
|
|
0
|
|
0
|
Edit
Delete
|
|
10180
|
7772
|
6
|
5
|
9f09902dce3537d952595fd6d33175b6f0c24c7e
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774346931
|
1774346930
|
1774346931
|
|
0
|
|
0
|
Edit
Delete
|
|
10190
|
7773
|
6
|
5
|
9f09902dce3537d952595fd6d33175b6f0c24c7e
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
8676
|
4
|
1774346950
|
1774346950
|
1774346932
|
1774346950
|
|
1
|
|
0
|
Edit
Delete
|
|
10448
|
7984
|
6
|
5
|
adc3e0209b2ffa4d34c89b638f1f03b36ebfd24f
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774408812
|
1774408752
|
1774408812
|
|
0
|
|
0
|
Edit
Delete
|
|
10462
|
7986
|
6
|
5
|
adc3e0209b2ffa4d34c89b638f1f03b36ebfd24f
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774408814
|
1774408812
|
1774408814
|
|
0
|
|
0
|
Edit
Delete
|
|
10472
|
7987
|
6
|
5
|
adc3e0209b2ffa4d34c89b638f1f03b36ebfd24f
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
8932
|
4
|
1774408833
|
1774408833
|
1774408815
|
1774408833
|
|
1
|
|
0
|
Edit
Delete
|
|
10617
|
8092
|
6
|
5
|
1b2a0b35284edd65cdda0501ced15ca388220ddd
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774439143
|
1774439039
|
1774439143
|
|
0
|
|
0
|
Edit
Delete
|
|
10632
|
8095
|
6
|
5
|
1b2a0b35284edd65cdda0501ced15ca388220ddd
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774439239
|
1774439143
|
1774439239
|
|
0
|
|
0
|
Edit
Delete
|
|
10642
|
8096
|
6
|
5
|
1b2a0b35284edd65cdda0501ced15ca388220ddd
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
9075
|
4
|
1774439256
|
1774439256
|
1774439240
|
1774439256
|
|
1
|
|
0
|
Edit
Delete
|
|
10704
|
8114
|
6
|
5
|
3b540d63f39a66a79b06f096f7b7e9041dd4bc26
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774444077
|
1774443471
|
1774444077
|
|
0
|
|
0
|
Edit
Delete
|
|
10746
|
8119
|
6
|
5
|
83de8108577a8633d0dc3193eb7e19e9e6a668c1
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774444189
|
1774444077
|
1774444189
|
|
0
|
|
0
|
Edit
Delete
|
|
10786
|
8122
|
6
|
5
|
18d5b913e02e9d72301206688cfee01e40b9d2cd
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774451083
|
1774444190
|
1774451083
|
|
0
|
|
0
|
Edit
Delete
|
|
10857
|
8151
|
6
|
5
|
18d5b913e02e9d72301206688cfee01e40b9d2cd
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774451247
|
1774451083
|
1774451247
|
|
0
|
|
0
|
Edit
Delete
|
|
10884
|
8157
|
6
|
5
|
18d5b913e02e9d72301206688cfee01e40b9d2cd
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774451341
|
1774451247
|
1774451341
|
|
0
|
|
0
|
Edit
Delete
|
|
10894
|
8158
|
6
|
5
|
18d5b913e02e9d72301206688cfee01e40b9d2cd
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
9199
|
4
|
1774451358
|
1774451358
|
1774451341
|
1774451358
|
|
1
|
|
0
|
Edit
Delete
|
|
11091
|
8308
|
6
|
5
|
0b85dd84d5debc36f158918b188cde8b6305035f
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774494798
|
1774494731
|
1774494798
|
|
0
|
|
0
|
Edit
Delete
|
|
11105
|
8310
|
6
|
5
|
0b85dd84d5debc36f158918b188cde8b6305035f
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774494803
|
1774494798
|
1774494803
|
|
0
|
|
0
|
Edit
Delete
|
|
11115
|
8311
|
6
|
5
|
0b85dd84d5debc36f158918b188cde8b6305035f
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
9394
|
4
|
1774494819
|
1774494820
|
1774494803
|
1774494820
|
|
1
|
|
0
|
Edit
Delete
|
|
11275
|
8431
|
6
|
5
|
6b8d13c5b29827249da650ed1bd9ace7fc68959c
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774529274
|
1774529191
|
1774529274
|
|
0
|
|
0
|
Edit
Delete
|
|
11289
|
8433
|
6
|
5
|
6b8d13c5b29827249da650ed1bd9ace7fc68959c
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774529279
|
1774529274
|
1774529279
|
|
0
|
|
0
|
Edit
Delete
|
|
11299
|
8434
|
6
|
5
|
6b8d13c5b29827249da650ed1bd9ace7fc68959c
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
9552
|
4
|
1774529296
|
1774529296
|
1774529279
|
1774529296
|
|
1
|
|
0
|
Edit
Delete
|
|
11590
|
8678
|
6
|
5
|
c09d9ff6160d851464fbce2a407409d4e8d2bc95
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774602058
|
1774600925
|
1774602058
|
|
0
|
|
0
|
Edit
Delete
|
|
11608
|
8684
|
6
|
5
|
c09d9ff6160d851464fbce2a407409d4e8d2bc95
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774602062
|
1774602058
|
1774602062
|
|
0
|
|
0
|
Edit
Delete
|
|
11618
|
8685
|
6
|
5
|
c09d9ff6160d851464fbce2a407409d4e8d2bc95
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
9844
|
4
|
1774602079
|
1774602079
|
1774602063
|
1774602080
|
|
1
|
|
0
|
Edit
Delete
|
|
11917
|
8933
|
6
|
5
|
9953914b57055e78c3af10cbf077f41f0580f0da
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774676428
|
1774674959
|
1774676428
|
|
0
|
|
0
|
Edit
Delete
|
|
11962
|
8942
|
6
|
5
|
9953914b57055e78c3af10cbf077f41f0580f0da
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774676705
|
1774676428
|
1774676705
|
|
0
|
|
0
|
Edit
Delete
|
|
11984
|
8946
|
6
|
5
|
9953914b57055e78c3af10cbf077f41f0580f0da
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774676708
|
1774676706
|
1774676708
|
|
0
|
|
0
|
Edit
Delete
|
|
11994
|
8947
|
6
|
5
|
9953914b57055e78c3af10cbf077f41f0580f0da
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
10160
|
4
|
1774676727
|
1774676728
|
1774676709
|
1774676728
|
|
1
|
|
0
|
Edit
Delete
|
|
12061
|
8970
|
6
|
5
|
03181d96b7830a1e1ec141a36a19c7a59c681262
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774682654
|
1774682196
|
1774682654
|
|
0
|
|
0
|
Edit
Delete
|
|
12102
|
8975
|
6
|
5
|
03181d96b7830a1e1ec141a36a19c7a59c681262
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774683475
|
1774682655
|
1774683475
|
|
0
|
|
0
|
Edit
Delete
|
|
12123
|
8981
|
6
|
5
|
03181d96b7830a1e1ec141a36a19c7a59c681262
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774683482
|
1774683475
|
1774683482
|
|
0
|
|
0
|
Edit
Delete
|
|
12133
|
8982
|
6
|
5
|
03181d96b7830a1e1ec141a36a19c7a59c681262
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
10238
|
4
|
1774683499
|
1774683499
|
1774683483
|
1774683500
|
|
1
|
|
0
|
Edit
Delete
|
|
12201
|
9010
|
6
|
5
|
b27f9d478a1cc664b9ca612e54c2ba37bc57b152
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774690760
|
1774690540
|
1774690760
|
|
0
|
|
0
|
Edit
Delete
|
|
12215
|
9012
|
6
|
5
|
b27f9d478a1cc664b9ca612e54c2ba37bc57b152
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774690763
|
1774690761
|
1774690763
|
|
0
|
|
0
|
Edit
Delete
|
|
12225
|
9013
|
6
|
5
|
b27f9d478a1cc664b9ca612e54c2ba37bc57b152
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
10303
|
4
|
1774690782
|
1774690782
|
1774690764
|
1774690783
|
|
1
|
|
0
|
Edit
Delete
|
|
12274
|
9022
|
6
|
5
|
f60415723c7e4450e3f307a54e65df5fbb4d38d2
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774692620
|
1774692272
|
1774692620
|
|
0
|
|
0
|
Edit
Delete
|
|
12290
|
9026
|
6
|
5
|
f60415723c7e4450e3f307a54e65df5fbb4d38d2
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774692656
|
1774692620
|
1774692656
|
|
0
|
|
0
|
Edit
Delete
|
|
12300
|
9027
|
6
|
5
|
f60415723c7e4450e3f307a54e65df5fbb4d38d2
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
10352
|
4
|
1774692675
|
1774692675
|
1774692657
|
1774692676
|
|
1
|
|
0
|
Edit
Delete
|
|
12353
|
9040
|
6
|
5
|
0c8f4a138b823e8d615f93850a64c3365e5aed15
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774695547
|
1774695320
|
1774695547
|
|
0
|
|
0
|
Edit
Delete
|
|
12367
|
9042
|
6
|
5
|
0c8f4a138b823e8d615f93850a64c3365e5aed15
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774695581
|
1774695547
|
1774695581
|
|
0
|
|
0
|
Edit
Delete
|
|
12377
|
9043
|
6
|
5
|
0c8f4a138b823e8d615f93850a64c3365e5aed15
|
0
|
Production 自动回滚
|
1
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
10403
|
4
|
1774695600
|
1774695600
|
1774695582
|
1774695601
|
|
1
|
|
0
|
Edit
Delete
|
|
12624
|
9243
|
6
|
5
|
58e5152a38868b8f3832d9573c340a3eb60051c8
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774754098
|
1774753878
|
1774754098
|
|
0
|
|
0
|
Edit
Delete
|
|
12638
|
9245
|
6
|
5
|
58e5152a38868b8f3832d9573c340a3eb60051c8
|
0
|
Production 自动回滚
|
0
|
name: CI/CD Deploy
"on":
# test-pipeli name: CI/CD Deploy
"on":
# test-pipeline 通过后自动触发(仅 main 分支)
workflow_run:
workflows: ["Test Pipeline"]
types: [completed]
branches: [main]
# 版本标签触发完整部署
push:
tags: ['v*']
# 手动触发
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
- aliyun
- rollback-production
- rollback-aliyun
skip_tests:
description: '跳过测试(紧急修复)'
required: false
default: false
type: boolean
version:
description: '部署版本号(留空使用自动版本)'
required: false
type: string
env:
IMAGE_PREFIX: ${{ github.repository_owner }}/juhi
NODE_VERSION: "20"
PNPM_VERSION: "8"
REGISTRY: ghcr.io
jobs:
auto-rollback-production:
name: Production 自动回滚
runs-on: ubuntu-latest
if: failure() && needs.deploy-production.result == 'failure'
steps:
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.PRODUCTION_SSH_KEY }}
- name: 配置 SSH Known Hosts
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PRODUCTION_SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: 执行回滚
run: |
ssh $USER@$HOST << 'EOF'
cd /opt/juhi
echo "==> Production 自动回滚..."
if [ -f "./scripts/rollback.sh" ]; then
chmod +x ./scripts/rollback.sh
./scripts/rollback.sh --confirm -y
else
PREV_LINE=$(tail -1 .deploy-history 2>/dev/null)
PREV_API=$(echo "$PREV_LINE" | cut -d'|' -f2)
PREV_FE=$(echo "$PREV_LINE" | cut -d'|' -f3)
if [ -n "$PREV_API" ] && [ "$PREV_API" != "none" ]; then
export API_IMAGE="$PREV_API"
export FRONTEND_IMAGE="$PREV_FE"
docker compose -f docker-compose.prod.yml up -d --no-deps api frontend
RETRY=0
until curl -sf http://localhost:3000/health > /dev/null 2>&1; do
RETRY=$((RETRY + 1))
[ $RETRY -ge 12 ] && { echo "回滚后健康检查失败"; exit 1; }
sleep 5
done
echo "==> 回滚成功"
else
echo "无法获取上一版本,需要手动回滚"
exit 1
fi
fi
EOF
env:
HOST: ${{ secrets.PRODUCTION_HOST }}
USER: ${{ secrets.PRODUCTION_USER }}
timeout-minutes: "10"
...
|
auto-rollback-production
|
["deploy-production"]
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1774754136
|
1774754098
|
1774754136
|
|
0
|
|
0
|
Edit
Delete
|