-
Notifications
You must be signed in to change notification settings - Fork 1
185 lines (159 loc) · 7.13 KB
/
Copy pathdeploy.yml
File metadata and controls
185 lines (159 loc) · 7.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
name: Deploy to Production
# push 到 dev 分支(或手动触发):构建 → 上传 → 原子切换 → 健康检查
on:
push:
branches: [dev]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: infosphere-production
cancel-in-progress: false
jobs:
build-and-deploy:
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout source
uses: actions/checkout@v6
# ── 前端:类型检查 + lint + SSR 构建,打包为独立 Node 服务 ──
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: pnpm
cache-dependency-path: app/web/pnpm-lock.yaml
- name: Install web dependencies
working-directory: app/web
run: pnpm install --frozen-lockfile
- name: Typecheck, test and lint web
working-directory: app/web
run: |
pnpm exec tsc --noEmit
pnpm test
pnpm exec next lint
- name: Build web (SSR standalone)
working-directory: app/web
env:
NEXT_DIST_DIR: .next-build
run: pnpm build
- name: Package web
run: |
mkdir -p release/web/.next/static release/web/.next-build/static
cp -R app/web/.next-build/standalone/. release/web/
# static 需同时满足:runtime 按 distDir(.next-build) 自取 + nginx 累积目录脚本取 .next
cp -R app/web/.next-build/static/. release/web/.next/static/
cp -R app/web/.next-build/static/. release/web/.next-build/static/
if [ -d app/web/public ]; then cp -R app/web/public release/web/public; fi
tar -czf release/infosphere-web-linux-amd64.tar.gz -C release/web .
rm -rf release/web
test -s release/infosphere-web-linux-amd64.tar.gz
# ── 后端:测试 + 交叉编译 Linux 单文件二进制 ──
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: server/go.mod
cache-dependency-path: server/go.sum
- name: Vet and test backend
working-directory: server
run: |
go vet ./...
go test ./...
- name: Build Linux backend
working-directory: server
env:
CGO_ENABLED: "0"
GOOS: linux
GOARCH: amd64
COMMIT_SHA: ${{ github.sha }}
run: |
go build -trimpath \
-ldflags="-s -w \
-X 'infosphere/server/internal/app.Commit=${COMMIT_SHA::7}' \
-X 'infosphere/server/internal/app.BuildDate=$(date -u +%Y-%m-%dT%H:%M:%SZ)'" \
-o ../release/infosphere-server .
# ── 打包发布:二进制 + 前端包 + systemd unit + env ──
- name: Assemble release
env:
INFO_SPHERE_ENV_FILE: ${{ secrets.INFO_SPHERE_ENV_FILE }}
run: |
test -n "$INFO_SPHERE_ENV_FILE"
cp deploy/infosphere-api.service deploy/infosphere-web.service deploy/infosphere.sudoers release/
printf '%s\n' "$INFO_SPHERE_ENV_FILE" > release/infosphere.env
chmod 600 release/infosphere.env
(cd release && sha256sum infosphere-server infosphere-web-linux-amd64.tar.gz > SHA256SUMS)
ls -la release/
- name: Upload release to server
uses: appleboy/scp-action@v1.0.0
with:
host: ${{ secrets.SSH_PRIVATE_HOST }}
username: ${{ secrets.SSH_PRIVATE_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "release/*"
target: "/tmp/infosphere-release-${{ github.sha }}"
strip_components: 1
- name: Activate release
uses: appleboy/ssh-action@v1.2.5
env:
RELEASE_SHA: ${{ github.sha }}
with:
host: ${{ secrets.SSH_PRIVATE_HOST }}
username: ${{ secrets.SSH_PRIVATE_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
envs: RELEASE_SHA
script: |
set -eu
deploy_root=/var/www/infosphere
staged_dir=/tmp/infosphere-release-$RELEASE_SHA
release_dir=$deploy_root/releases/$RELEASE_SHA
test -f "$staged_dir/infosphere-server"
test -s "$staged_dir/infosphere-web-linux-amd64.tar.gz"
test -s "$staged_dir/infosphere.env"
# 目录骨架
sudo install -d -m 755 "$deploy_root/releases" "$release_dir/web" /etc/infosphere
sudo install -d -m 755 -o www-data -g www-data /var/lib/infosphere /var/lib/infosphere/uploads
# 发布内容
sudo cp -a "$staged_dir/." "$release_dir/"
sudo chmod 755 "$release_dir/infosphere-server"
sudo tar -xzf "$release_dir/infosphere-web-linux-amd64.tar.gz" -C "$release_dir/web"
sudo install -d -m 755 -o www-data -g www-data "$release_dir/web/.next/cache"
sudo chown -R www-data:www-data "$release_dir/web"
# 累积式静态资源目录:chunk 文件名带内容哈希永不冲突,
# 合并而非替换,保证已打开的旧页面引用的旧 chunk 仍然可用
sudo mkdir -p /var/www/infosphere/static
sudo cp -a "$release_dir/web/.next/static/." /var/www/infosphere/static/
# 配置与服务
sudo install -m 600 "$release_dir/infosphere.env" /etc/infosphere/infosphere.env
sudo install -m 644 "$release_dir/infosphere-api.service" /etc/systemd/system/infosphere-api.service
sudo install -m 644 "$release_dir/infosphere-web.service" /etc/systemd/system/infosphere-web.service
sudo install -m 440 "$release_dir/infosphere.sudoers" /etc/sudoers.d/infosphere
sudo visudo -c >/dev/null
# 原子切换 current
sudo ln -sfn "$release_dir" "$deploy_root/current.next"
sudo mv -Tf "$deploy_root/current.next" "$deploy_root/current"
sudo systemctl daemon-reload
sudo systemctl enable infosphere-api.service infosphere-web.service
sudo systemctl restart infosphere-api.service
sudo systemctl restart infosphere-web.service
# 健康检查:API 包含当前 commit,前端可访问
attempt=0
until curl -fsS http://127.0.0.1:6969/api/v1/health | grep -q "\"commit\":\"${RELEASE_SHA::7}\"" \
&& curl -fsS -o /dev/null http://127.0.0.1:6900/; do
attempt=$((attempt + 1))
if [ "$attempt" -ge 15 ]; then
sudo systemctl status infosphere-api.service --no-pager || true
sudo systemctl status infosphere-web.service --no-pager || true
sudo journalctl -u infosphere-api.service -n 30 --no-pager || true
sudo journalctl -u infosphere-web.service -n 30 --no-pager || true
exit 1
fi
sleep 2
done
# 清理:仅保留最近 5 个版本
sudo bash -c "ls -1dt $deploy_root/releases/*/ | tail -n +6 | xargs -r rm -rf"
rm -rf "$staged_dir"
echo "✅ InfoSphere 部署完成: $release_dir"