feat(ci): 服务端 server-v* 编译+release+部署(备份/迁移/回滚,复用 lib-ssh/lib-forgejo)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-06 00:24:18 +08:00
parent 91d1355721
commit 4fb3fe3fee
5 changed files with 155 additions and 1 deletions
+4 -1
View File
@@ -50,7 +50,10 @@ jobs:
/mnt/scripts/ci/notify.sh \
/mnt/scripts/ci/lib-ssh.sh \
/mnt/scripts/ci/compile-site.sh \
/mnt/scripts/ci/deploy-site.sh
/mnt/scripts/ci/deploy-site.sh \
/mnt/scripts/ci/compile-backend.sh \
/mnt/scripts/ci/release-server.sh \
/mnt/scripts/ci/deploy-server.sh
# ── Job 2: OpenAPI Sync Check ────────────────────────────────────────────
openapi-check:
+40
View File
@@ -0,0 +1,40 @@
name: Deploy Server
on:
push:
tags:
- 'server-v[0-9]*.[0-9]*.[0-9]*'
workflow_dispatch:
concurrency:
group: deploy-server
cancel-in-progress: false
jobs:
deploy-server:
runs-on: nas
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Compile (Go 控制面, golang:1.25 容器内构建)
run: |
mkdir -p "$HOME/.cache/pangolin-ci/gomod" "$HOME/.cache/pangolin-ci/gobuild"
docker run --rm -v "$PWD:/w" -w /w \
-v "$HOME/.cache/pangolin-ci/gomod:/go/pkg/mod" \
-v "$HOME/.cache/pangolin-ci/gobuild:/root/.cache/go-build" \
golang:1.25 bash scripts/ci/compile-backend.sh
- name: Test (go test)
run: bash scripts/ci/test.sh server
- name: Release → Forgejo
env:
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
FORGEJO_URL: ${{ secrets.FORGEJO_URL }}
run: bash scripts/ci/release-server.sh "${{ gitea.ref_name }}"
- name: Deploy → pangolin1
env:
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
run: bash scripts/ci/deploy-server.sh "${{ gitea.ref_name }}"
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# compile-backend.sh — cross-compile the pangolin Go control-plane binaries
# (server / agent / migrate) for the pangolin1 deploy target. CGO disabled:
# modernc.org/sqlite is pure Go, no cgo toolchain needed on the runner.
# Output: server/out/{pangolin-server,pangolin-agent,pangolin-migrate}.
#
# Run inside a golang:1.25 container by .gitea/workflows/deploy-server.yml;
# this script itself just runs `go build` and assumes it is invoked from the
# repo root.
set -euo pipefail
# shellcheck source=scripts/ci/_env.sh
. scripts/ci/_env.sh
cd server
mkdir -p out
echo "==> compile-backend: building pangolin-server"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o out/pangolin-server ./cmd/server
echo "==> compile-backend: building pangolin-agent"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o out/pangolin-agent ./cmd/agent
echo "==> compile-backend: building pangolin-migrate"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o out/pangolin-migrate ./cmd/migrate
echo "==> compile-backend: done — out/ contents:"
ls -lh out/
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# deploy-server.sh <tag> — deploy the pangolin control-plane binaries
# (pangolin-server / pangolin-agent / pangolin-migrate) to pangolin1, in the
# exact manual sequence used for F3/F4: stop → wal checkpoint → backup db →
# migrate (rollback db + restart old binary on failure) → swap binaries →
# start → healthcheck. Assumes compile-backend.sh has already produced
# server/out/{pangolin-server,pangolin-agent,pangolin-migrate}.
#
# Usage: scripts/ci/deploy-server.sh <tag> (e.g. server-v1.2.3)
# Requires env: DEPLOY_SSH_KEY (see lib-ssh.sh).
set -euo pipefail
# shellcheck source=scripts/ci/lib-ssh.sh
. scripts/ci/lib-ssh.sh
DB=/var/lib/pangolin/pangolin.db
BIN=/usr/local/bin
TAG="${1:?usage: deploy-server.sh <tag>}"
# setup_ssh registers the EXIT cleanup trap itself (before writing the key),
# so a mid-setup failure still cleans up — see lib-ssh.sh. It exports
# SSH_KEY_FILE / DEPLOY_PORT / SSH_KNOWN_HOSTS_FILE / DEPLOY_HOST used below
# to build SCP (mirroring the SSH/RSYNC_SSH command-string convention).
setup_ssh
SCP="scp -i ${SSH_KEY_FILE} -P ${DEPLOY_PORT} -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=${SSH_KNOWN_HOSTS_FILE}"
echo "==> deploy-server: tag=${TAG} host=${DEPLOY_HOST}"
echo "==> deploy-server: uploading binaries to ${DEPLOY_HOST}:/tmp/"
$SCP server/out/pangolin-server server/out/pangolin-agent server/out/pangolin-migrate "root@${DEPLOY_HOST}:/tmp/"
$SSH "root@${DEPLOY_HOST}" "bash -s" <<REMOTE
set -euo pipefail
systemctl stop pangolin-server
runuser -u pangolin -- sqlite3 "$DB" 'PRAGMA wal_checkpoint(TRUNCATE);'
cp -p "$DB" "$DB.bak-pre-$TAG"
if ! runuser -u pangolin -- env DB_DRIVER=sqlite DB_DSN=$DB /tmp/pangolin-migrate up; then
echo "!! migrate 失败,回滚"; cp -p "$DB.bak-pre-$TAG" "$DB"; systemctl start pangolin-server; exit 1
fi
cp -p "$BIN/pangolin-server" "$BIN/pangolin-server.bak-$TAG" || true
install -m755 /tmp/pangolin-server "$BIN/pangolin-server"
install -m755 /tmp/pangolin-agent "$BIN/pangolin-agent"
install -m755 /tmp/pangolin-migrate "$BIN/pangolin-migrate"
systemctl start pangolin-server
systemctl is-active pangolin-server
REMOTE
curl -fsS -m 10 --retry 5 --retry-connrefused "http://${DEPLOY_HOST}:8080/healthz" >/dev/null && echo "healthz OK"
echo "==> deploy-server: done"
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# release-server.sh — ensure the Forgejo release for a server-v* tag exists
# and upload the three compiled binaries as release assets. Assumes
# compile-backend.sh has already produced
# server/out/{pangolin-server,pangolin-agent,pangolin-migrate}.
#
# Usage: scripts/ci/release-server.sh <tag> (e.g. server-v1.2.3)
# Requires env: FORGEJO_URL, FORGEJO_TOKEN (see lib-forgejo.sh).
set -euo pipefail
TAG="${1:?usage: release-server.sh <tag>}"
# shellcheck source=scripts/ci/_env.sh
. scripts/ci/_env.sh
# shellcheck source=scripts/ci/lib-forgejo.sh
. scripts/ci/lib-forgejo.sh
# No command substitution ($()): ver_from_tag prints to stdout, captured via
# a temp file + `read`, same no-substitution pattern as lib-forgejo.sh.
ver_file="/tmp/release_server_ver.$$"
ver_from_tag server "$TAG" > "$ver_file"
VER=""
read -r VER < "$ver_file"
rm -f "$ver_file"
echo "==> release-server: tag=${TAG} ver=${VER}"
forgejo_release_ensure "$TAG" "server ${VER}"
forgejo_upload_asset "$TAG" server/out/pangolin-server
forgejo_upload_asset "$TAG" server/out/pangolin-agent
forgejo_upload_asset "$TAG" server/out/pangolin-migrate
echo "==> release-server: done"