Skip to content

Commit 9d92096

Browse files
committed
ci: add production deployment workflow
1 parent 3b14ae2 commit 9d92096

2 files changed

Lines changed: 120 additions & 0 deletions

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: Deploy Production
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
concurrency:
10+
group: agentspace-production
11+
cancel-in-progress: false
12+
13+
permissions:
14+
contents: read
15+
16+
jobs:
17+
deploy:
18+
if: github.repository == 'HKUDS/AgentSpace' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main')
19+
runs-on:
20+
- self-hosted
21+
- Linux
22+
- X64
23+
- agentspace-prod
24+
timeout-minutes: 45
25+
env:
26+
DEPLOY_DIR: /home/AgentSpace
27+
SERVICE_NAME: agentspace
28+
HEALTHCHECK_URL: http://127.0.0.1:1455/api/health
29+
BACKUP_DIR: /home/AgentSpace/data/backups/deployments
30+
steps:
31+
- name: Deploy from main
32+
shell: bash
33+
run: |
34+
set -Eeuo pipefail
35+
36+
cd "$DEPLOY_DIR"
37+
38+
run_systemctl() {
39+
if [ "$(id -u)" -eq 0 ]; then
40+
systemctl "$@"
41+
else
42+
sudo systemctl "$@"
43+
fi
44+
}
45+
46+
healthcheck() {
47+
for attempt in {1..30}; do
48+
if curl -fsS "$HEALTHCHECK_URL" >/dev/null; then
49+
echo "Health check passed."
50+
return 0
51+
fi
52+
echo "Waiting for service health ($attempt/30)..."
53+
sleep 2
54+
done
55+
return 1
56+
}
57+
58+
rollback() {
59+
local target_commit="$1"
60+
61+
echo "Rolling back to $target_commit"
62+
git reset --hard "$target_commit"
63+
npm run setup
64+
npm run build
65+
run_systemctl restart "$SERVICE_NAME"
66+
healthcheck
67+
}
68+
69+
if ! git diff --quiet || ! git diff --cached --quiet; then
70+
echo "Tracked worktree changes detected; refusing to deploy."
71+
git status --short
72+
exit 1
73+
fi
74+
75+
remote="origin"
76+
if git remote get-url hku >/dev/null 2>&1; then
77+
remote="hku"
78+
fi
79+
80+
before="$(git rev-parse HEAD)"
81+
82+
git fetch --prune "$remote" main
83+
after="$(git rev-parse FETCH_HEAD)"
84+
85+
if [ "$before" = "$after" ] && [ "${GITHUB_EVENT_NAME:-}" != "workflow_dispatch" ]; then
86+
echo "Already up to date at $after."
87+
exit 0
88+
fi
89+
90+
if [ "$before" = "$after" ]; then
91+
echo "Manual deployment requested for current commit $after."
92+
fi
93+
94+
mkdir -p "$BACKUP_DIR"
95+
if [ -f data/agent-space.sqlite ]; then
96+
cp -a data/agent-space.sqlite "$BACKUP_DIR/agent-space.sqlite.$(date -u +%Y%m%dT%H%M%SZ)"
97+
fi
98+
99+
git reset --hard "$after"
100+
npm run setup
101+
102+
if ! npm run build; then
103+
rollback "$before"
104+
exit 1
105+
fi
106+
107+
run_systemctl restart "$SERVICE_NAME"
108+
109+
if ! healthcheck; then
110+
rollback "$before"
111+
exit 1
112+
fi
113+
114+
echo "Deployed $after."

apps/web/app/api/health/route.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export function GET(): Response {
2+
return Response.json({
3+
ok: true,
4+
service: "agentspace-web",
5+
});
6+
}

0 commit comments

Comments
 (0)