Skip to content

Commit 05c38ed

Browse files
committed
添加网站部署自动化工作流
1 parent f4b04d5 commit 05c38ed

2 files changed

Lines changed: 127 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Deploy Website
2+
3+
# 触发:push 到默认分支且改动了 website/ 时;或手动触发
4+
on:
5+
push:
6+
branches: [main]
7+
paths:
8+
- 'website/**'
9+
- '.github/workflows/deploy_website.yml'
10+
workflow_dispatch:
11+
12+
concurrency:
13+
group: deploy-website
14+
cancel-in-progress: true
15+
16+
jobs:
17+
build-and-deploy:
18+
runs-on: ubuntu-latest
19+
# 仅在配置了部署密钥时运行,避免 fork / 未配置环境时报错
20+
if: ${{ github.repository == 'zerx-lab/zap' }}
21+
defaults:
22+
run:
23+
working-directory: website
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Setup Bun
30+
uses: oven-sh/setup-bun@v2
31+
32+
- name: Install dependencies
33+
run: bun install --frozen-lockfile
34+
35+
- name: Build (astro + pagefind)
36+
run: bun run build
37+
38+
- name: Setup SSH
39+
run: |
40+
mkdir -p ~/.ssh
41+
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
42+
chmod 600 ~/.ssh/deploy_key
43+
ssh-keyscan -p "${{ secrets.DEPLOY_PORT || '22' }}" -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null
44+
45+
- name: Rsync dist to server incoming/
46+
env:
47+
PORT: ${{ secrets.DEPLOY_PORT || '22' }}
48+
USER: ${{ secrets.DEPLOY_USER }}
49+
HOST: ${{ secrets.DEPLOY_HOST }}
50+
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
51+
run: |
52+
# 确保远端目录存在
53+
ssh -i ~/.ssh/deploy_key -p "$PORT" "$USER@$HOST" \
54+
"mkdir -p '$DEPLOY_PATH/incoming' '$DEPLOY_PATH/deploy'"
55+
# 推送静态产物(--delete 保证 incoming 与本地 dist 完全一致)
56+
rsync -az --delete \
57+
-e "ssh -i ~/.ssh/deploy_key -p $PORT" \
58+
dist/ "$USER@$HOST:$DEPLOY_PATH/incoming/"
59+
# 推送部署脚本
60+
rsync -az \
61+
-e "ssh -i ~/.ssh/deploy_key -p $PORT" \
62+
deploy/deploy.sh "$USER@$HOST:$DEPLOY_PATH/deploy/deploy.sh"
63+
64+
- name: Run remote deploy script
65+
env:
66+
PORT: ${{ secrets.DEPLOY_PORT || '22' }}
67+
USER: ${{ secrets.DEPLOY_USER }}
68+
HOST: ${{ secrets.DEPLOY_HOST }}
69+
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
70+
run: |
71+
# 远端赋予执行权限并运行,避免 pull/上传后无执行权限的问题
72+
ssh -i ~/.ssh/deploy_key -p "$PORT" "$USER@$HOST" \
73+
"chmod +x '$DEPLOY_PATH/deploy/deploy.sh' && '$DEPLOY_PATH/deploy/deploy.sh'"
74+
75+
- name: Cleanup SSH key
76+
if: always()
77+
run: rm -f ~/.ssh/deploy_key

website/deploy/deploy.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env bash
2+
# Zap 官网部署脚本(在服务器上执行)
3+
#
4+
# 由 GitHub Actions 上传到 $DEPLOY_PATH/deploy/deploy.sh 后,经 chmod +x 远程执行。
5+
# 职责:把上传好的静态产物(dist/)切换为对外服务目录,做原子发布 + 保留回滚。
6+
#
7+
# 约定的目录布局($DEPLOY_PATH 下):
8+
# incoming/ ← Actions 用 rsync 推上来的最新 dist 内容
9+
# releases/<ts>/ ← 每次发布的快照
10+
# current ← symlink,指向当前生效的 releases/<ts>(nginx root 指这里)
11+
#
12+
# nginx 的 root 应配置为 $DEPLOY_PATH/current
13+
set -euo pipefail
14+
15+
# 部署根目录:脚本位于 <root>/deploy/deploy.sh,故根目录是脚本上两级
16+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
17+
INCOMING="$ROOT/incoming"
18+
RELEASES="$ROOT/releases"
19+
CURRENT="$ROOT/current"
20+
KEEP=5 # 保留最近多少份 release 用于回滚
21+
22+
log() { printf '[deploy] %s\n' "$*"; }
23+
24+
if [ ! -d "$INCOMING" ] || [ -z "$(ls -A "$INCOMING" 2>/dev/null)" ]; then
25+
log "错误:$INCOMING 不存在或为空,没有可发布的产物。先由 CI rsync 产物到 incoming/。"
26+
exit 1
27+
fi
28+
29+
TS="$(date +%Y%m%d%H%M%S)"
30+
TARGET="$RELEASES/$TS"
31+
32+
mkdir -p "$RELEASES"
33+
log "创建发布快照:$TARGET"
34+
# 用 cp -a 从 incoming 物化一份不可变快照,保证 current 切换是原子的
35+
cp -a "$INCOMING" "$TARGET"
36+
37+
# 原子切换 current symlink:先建临时 link 再 rename,避免出现短暂无 current 的窗口
38+
log "切换 current -> releases/$TS"
39+
ln -sfn "$TARGET" "$CURRENT.tmp"
40+
mv -Tf "$CURRENT.tmp" "$CURRENT"
41+
42+
# 清理旧 release,保留最近 $KEEP 份
43+
log "清理旧 release,保留最近 $KEEP"
44+
cd "$RELEASES"
45+
ls -1dt */ 2>/dev/null | tail -n +$((KEEP + 1)) | while read -r old; do
46+
log " 删除 $old"
47+
rm -rf "${RELEASES:?}/${old%/}"
48+
done
49+
50+
log "完成。current 现指向:$(readlink -f "$CURRENT")"

0 commit comments

Comments
 (0)