From 4fb3fe3fee44e3def3460a8502493562486fc691 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Mon, 6 Jul 2026 00:24:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(ci):=20=E6=9C=8D=E5=8A=A1=E7=AB=AF=20serve?= =?UTF-8?q?r-v*=20=E7=BC=96=E8=AF=91+release+=E9=83=A8=E7=BD=B2(=E5=A4=87?= =?UTF-8?q?=E4=BB=BD/=E8=BF=81=E7=A7=BB/=E5=9B=9E=E6=BB=9A,=E5=A4=8D?= =?UTF-8?q?=E7=94=A8=20lib-ssh/lib-forgejo)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .gitea/workflows/ci.yml | 5 ++- .gitea/workflows/deploy-server.yml | 40 ++++++++++++++++++++++++ scripts/ci/compile-backend.sh | 28 +++++++++++++++++ scripts/ci/deploy-server.sh | 49 ++++++++++++++++++++++++++++++ scripts/ci/release-server.sh | 34 +++++++++++++++++++++ 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/deploy-server.yml create mode 100644 scripts/ci/compile-backend.sh create mode 100644 scripts/ci/deploy-server.sh create mode 100644 scripts/ci/release-server.sh diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 2b513cf..93cc05b 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -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: diff --git a/.gitea/workflows/deploy-server.yml b/.gitea/workflows/deploy-server.yml new file mode 100644 index 0000000..ef722ce --- /dev/null +++ b/.gitea/workflows/deploy-server.yml @@ -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 }}" diff --git a/scripts/ci/compile-backend.sh b/scripts/ci/compile-backend.sh new file mode 100644 index 0000000..2a922ea --- /dev/null +++ b/scripts/ci/compile-backend.sh @@ -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/ diff --git a/scripts/ci/deploy-server.sh b/scripts/ci/deploy-server.sh new file mode 100644 index 0000000..5963d6f --- /dev/null +++ b/scripts/ci/deploy-server.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# deploy-server.sh — 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 (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 }" + +# 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" </dev/null && echo "healthz OK" + +echo "==> deploy-server: done" diff --git a/scripts/ci/release-server.sh b/scripts/ci/release-server.sh new file mode 100644 index 0000000..4d22148 --- /dev/null +++ b/scripts/ci/release-server.sh @@ -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 (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 }" + +# 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"