feat(ci): 迁移到 hk runner + Release 产物分发,解除对 doc79 runner 的依赖
Publish Mini Program Dev Version / publish (push) Canceled after 0s
Build and Publish Server / build (push) Canceled after 0s

- 两个工作流 runs-on 改为 hk(在线);Go/Node 工具链自包含下载+工作区缓存
- 后端产物改为发布 Gitea Release 附件(server-v<版本>),与 runner 位置解耦
- deploy-watch.sh 重写为从 Release 拉取:匿名/令牌 HTTPS 下载、包结构预检、
  按 release id 幂等、失败下轮重试
- 移除对 /ci-artifacts 本机目录的依赖(原设计要求 runner 与生产同机)
- PULL_DEPLOY.md 架构图同步更新
This commit is contained in:
gouki
2026-08-09 17:17:23 +00:00
parent fc7a30ad9d
commit b507d6c154
4 changed files with 191 additions and 75 deletions
+34 -16
View File
@@ -11,21 +11,45 @@ on:
jobs:
publish:
# 专属运行器 lunar-node: docker://node:22-bookworm(注册于 doc79
runs-on: lunar-node
# hk runner(海外,宿主机直接执行;可直连微信与 Telegram/Discord
runs-on: hk
steps:
- uses: https://gitea.neatcn.com/gouki/action-checkout@v4
with:
# Need recent commit subjects for the WeChat upload remark.
fetch-depth: 20
- name: Prepare Node toolchain
run: |
# 优先复用 runner 宿主机缓存的工具链(工作目录持久化)
TOOLDIR="$RUNNER_WORKSPACE/.lunar-toolchain"
mkdir -p "$TOOLDIR"
if [ -x "$TOOLDIR/node/bin/node" ]; then
echo "复用缓存 Node 工具链"
else
wget -q --tries=2 --timeout=60 -O "$TOOLDIR/node.tgz" \
"https://nodejs.org/dist/v22.12.0/node-v22.12.0-linux-x64.tar.xz" \
|| wget -q --tries=2 --timeout=60 -O "$TOOLDIR/node.tgz" \
"https://mirrors.aliyun.com/nodejs-release/v22.12.0/node-v22.12.0-linux-x64.tar.xz"
rm -rf "$TOOLDIR/node-v22.12.0-linux-x64"
tar -C "$TOOLDIR" -xJf "$TOOLDIR/node.tgz"
mv "$TOOLDIR/node-v22.12.0-linux-x64" "$TOOLDIR/node"
rm -f "$TOOLDIR/node.tgz"
fi
"$TOOLDIR/node/bin/node" --version
echo "PATH=$TOOLDIR/node/bin:$PATH" >> "$GITEA_ENV"
- name: Verify Node runtime
run: node --version
- name: Install dependencies
working-directory: mini
run: npm ci
- name: Run tests
working-directory: mini
run: npm test
- name: Configure production API and app version
working-directory: mini
env:
@@ -39,7 +63,7 @@ jobs:
mkdir -p ci-artifacts
printf '%s\n' "$VERSION" > ci-artifacts/resolved-version.txt
echo "Resolved Mini Program version for build+upload: $VERSION"
# 注入版本号到 utils/version.js
BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
COMMIT_SHORT="${GITEA_SHA:0:7}"
@@ -48,7 +72,7 @@ jobs:
* 版本号配置文件
* 此文件由 CI 构建时自动生成,请勿手动修改
*/
module.exports = {
version: "$VERSION",
buildNumber: "$MINIAPP_BUILD_NUMBER",
@@ -58,6 +82,7 @@ jobs:
EOF
echo "Version info injected into utils/version.js:"
cat utils/version.js
- name: Materialize the upload key
env:
WECHAT_CI_PRIVATE_KEY: ${{ secrets.WECHAT_CI_PRIVATE_KEY }}
@@ -65,6 +90,7 @@ jobs:
test -n "$WECHAT_CI_PRIVATE_KEY"
umask 077
printf '%s' "$WECHAT_CI_PRIVATE_KEY" > "$RUNNER_TEMP/wechat-ci.key"
- name: Upload WeChat development version
working-directory: mini
env:
@@ -106,15 +132,7 @@ jobs:
node ci/upload-ci.cjs
test -s ci-artifacts/upload-result.json
cat ci-artifacts/upload-result.json
- name: Persist upload result on runner host
run: |
test -s mini/ci-artifacts/upload-result.json
test -d /ci-artifacts
cp mini/ci-artifacts/upload-result.json "/ci-artifacts/miniapp-upload-${{ gitea.sha }}.json"
cp mini/ci-artifacts/upload-result.json /ci-artifacts/miniapp-upload-latest.json
ls -la /ci-artifacts/miniapp-upload-latest.json
echo "Upload result saved on runner host: /opt/lunar/ci-artifacts/miniapp-upload-latest.json"
- name: Send success notification
if: success()
env:
@@ -123,8 +141,8 @@ jobs:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
run: |
VERSION="$(tr -d '\n' < mini/ci-artifacts/resolved-version.txt)"
bash .gitea/scripts/notify.sh success "小程序开发版上传成功" "版本: ${VERSION} 上传结果已保存到: /opt/lunar/ci-artifacts/miniapp-upload-latest.json"
bash .gitea/scripts/notify.sh success "小程序开发版上传成功" "版本: ${VERSION}"
- name: Send failure notification
if: failure()
env:
@@ -135,7 +153,7 @@ jobs:
bash .gitea/scripts/notify.sh failure \
"小程序开发版上传失败" \
"请检查 Actions 日志了解失败原因"
- name: Remove temporary credentials
if: always()
run: rm -f "$RUNNER_TEMP/wechat-ci.key"
+76 -36
View File
@@ -1,4 +1,4 @@
name: Build and Deploy Server
name: Build and Publish Server
on:
push:
@@ -10,58 +10,77 @@ on:
jobs:
build:
# 专属运行器:docker://golang:1.22-bookworm(注册于 doc79
runs-on: lunar-ci
# hk runner(海外,宿主机直接执行,无容器标签映射
runs-on: hk
steps:
- uses: https://gitea.neatcn.com/gouki/action-checkout@v4
with:
fetch-depth: 20
- name: Verify Go runtime
run: go version
- name: Prepare Go toolchain
run: |
# 优先复用 runner 宿主机缓存的工具链(工作目录持久化)
TOOLDIR="$RUNNER_WORKSPACE/.lunar-toolchain"
mkdir -p "$TOOLDIR"
if [ -x "$TOOLDIR/go/bin/go" ]; then
echo "复用缓存 Go 工具链"
else
# 官方源与阿里云镜像双通道,先到先用
wget -q --tries=2 --timeout=60 -O "$TOOLDIR/go.tgz" \
"https://go.dev/dl/go1.22.10.linux-amd64.tar.gz" \
|| wget -q --tries=2 --timeout=60 -O "$TOOLDIR/go.tgz" \
"https://mirrors.aliyun.com/golang/go1.22.10.linux-amd64.tar.gz"
rm -rf "$TOOLDIR/go"
tar -C "$TOOLDIR" -xzf "$TOOLDIR/go.tgz"
rm -f "$TOOLDIR/go.tgz"
fi
"$TOOLDIR/go/bin/go" version
echo "LUNAR_GO=$TOOLDIR/go/bin/go" >> "$GITEA_ENV"
- name: Install dependencies
working-directory: server
run: go mod download
run: |
export HOME="$RUNNER_WORKSPACE"
"$LUNAR_GO" mod download
- name: Run tests
working-directory: server
run: go test ./...
run: |
export HOME="$RUNNER_WORKSPACE"
"$LUNAR_GO" test ./...
- name: Build application
working-directory: server
env:
GITEA_SHA: ${{ gitea.sha }}
GITEA_RUN_NUMBER: ${{ gitea.run_number }}
run: |
export HOME="$RUNNER_WORKSPACE"
mkdir -p bin
# 生成版本号(使用构建编号)
VERSION="1.0.${GITEA_RUN_NUMBER}"
BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
COMMIT_SHORT="${GITEA_SHA:0:7}"
echo "Building server version: $VERSION"
echo "Build time: $BUILD_TIME"
echo "Commit SHA: $COMMIT_SHORT"
# 使用 ldflags 注入版本信息
go build -ldflags "\
# ldflags 注入版本信息;目标平台为 doc79linux/amd64
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 "$LUNAR_GO" build -ldflags "\
-X main.Version=$VERSION \
-X main.BuildTime=$BUILD_TIME \
-X main.CommitSha=$COMMIT_SHORT" \
-o bin/server cmd/main.go
# 同时保存版本信息到文件(用于部署时读取)
# 版本元数据随包分发,便于服务器侧追溯
cat > bin/version.env <<EOF
APP_VERSION=$VERSION
APP_BUILD_TIME=$BUILD_TIME
APP_COMMIT_SHA=$COMMIT_SHORT
EOF
echo "Version info saved to bin/version.env:"
cat bin/version.env
echo "SERVER_VERSION=$VERSION" >> "$GITEA_ENV"
- name: Create deployment package
working-directory: server
run: |
@@ -74,16 +93,37 @@ jobs:
cp -r web/ deploy/web/
fi
tar -czf deploy.tar.gz deploy/
- name: Persist deployment package on runner host
sha256sum deploy.tar.gz
- name: Publish release with deployment package
env:
GITEA_SHA: ${{ gitea.sha }}
GITEA_RUN_NUMBER: ${{ gitea.run_number }}
run: |
test -f server/deploy.tar.gz
test -d /ci-artifacts
cp server/deploy.tar.gz "/ci-artifacts/server-deploy-${{ gitea.sha }}.tar.gz"
cp server/deploy.tar.gz /ci-artifacts/server-deploy-latest.tar.gz
ls -la /ci-artifacts/server-deploy-latest.tar.gz
echo "Deployment package saved on runner host: /opt/lunar/ci-artifacts/server-deploy-latest.tar.gz"
set -e
VERSION="1.0.${GITEA_RUN_NUMBER}"
TAG="server-v${VERSION}"
API="https://gitea.neatcn.com/api/v1/repos/gouki/lunar-mini"
# Gitea Actions 内建的 job 令牌(仓库写权限)
AUTH="Authorization: token ${GITEA_TOKEN}"
# 幂等:同 tag 已存在则先删除(重跑场景)
EXISTING=$(curl -sS -H "$AUTH" "$API/releases/tags/$TAG" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('id',''))" 2>/dev/null || true)
if [ -n "$EXISTING" ] && [ "$EXISTING" != "None" ]; then
curl -sS -X DELETE -H "$AUTH" "$API/releases/$EXISTING" -o /dev/null -w "删除旧 release: HTTP %{http_code}\n"
fi
RELEASE_ID=$(curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"server $VERSION\",\"target_commitish\":\"main\",\"body\":\"CI 自动构建,commit ${GITEA_SHA:0:7}。doc79 由 deploy-watch.sh 拉取本附件完成部署。\"}" \
"$API/releases" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
echo "Release created: id=$RELEASE_ID tag=$TAG"
curl -sS -X POST -H "$AUTH" \
-F "attachment=@server/deploy.tar.gz" \
"$API/releases/$RELEASE_ID/assets" \
-o /dev/null -w "附件上传: HTTP %{http_code}\n"
echo "发布地址: https://gitea.neatcn.com/gouki/lunar-mini/releases/tag/$TAG"
- name: Send success notification
if: success()
env:
@@ -94,9 +134,9 @@ jobs:
run: |
VERSION="1.0.${GITEA_RUN_NUMBER}"
bash .gitea/scripts/notify.sh success \
"后端构建成功" \
"版本: v${VERSION}\n产物: /opt/lunar/ci-artifacts/server-deploy-latest.tar.gz\n部署由服务器侧 watcher 自动拉取完成"
"后端构建发布成功" \
"版本: v${VERSION}\n产物: releases/tag/server-v${VERSION}\ndoc79 将自动拉取部署"
- name: Send failure notification
if: failure()
env:
@@ -107,7 +147,7 @@ jobs:
bash .gitea/scripts/notify.sh failure \
"后端构建失败" \
"请检查 Actions 日志了解失败原因"
- name: Cleanup
if: always()
run: |