name: Build and Publish Server on: push: branches: - main paths: - "server/**" - ".gitea/workflows/server-deploy.yml" jobs: build: # 标准标签:hk / bt-runner 均带 ubuntu-latest,任一空闲 runner 接单 runs-on: ubuntu-latest steps: # hk 等精简 runner(Alpine)无 node,无法跑 action-checkout;直接用 git 浅克隆 - name: Checkout run: | git init -q . git remote add origin "$GITEA_SERVER_URL/$GITEA_REPOSITORY" git fetch -q --depth 20 origin "$GITEA_REF_NAME" git checkout -q FETCH_HEAD git log --oneline -3 - 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: | export HOME="$RUNNER_WORKSPACE" "$LUNAR_GO" mod download - name: Run tests working-directory: server 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" # ldflags 注入版本信息;目标平台为 doc79(linux/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 <> "$GITEA_ENV" - name: Create deployment package working-directory: server run: | mkdir -p deploy cp -r bin/ deploy/ cp -r migrations/ deploy/ cp -r scripts/ deploy/ # 管理后台静态资源必须随包发布(服务以相对路径 ./web 提供) if [ -d "web" ]; then cp -r web/ deploy/web/ fi tar -czf deploy.tar.gz deploy/ sha256sum deploy.tar.gz - name: Publish release with deployment package env: GITEA_SHA: ${{ gitea.sha }} GITEA_RUN_NUMBER: ${{ gitea.run_number }} run: | 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 已存在则先删除(重跑场景);不依赖 python3,纯 grep/sed 解析 EXISTING=$(curl -sS -H "$AUTH" "$API/releases/tags/$TAG" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2 || true) if [ -n "$EXISTING" ]; 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" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) test -n "$RELEASE_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: TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} GITEA_RUN_NUMBER: ${{ gitea.run_number }} run: | VERSION="1.0.${GITEA_RUN_NUMBER}" bash .gitea/scripts/notify.sh success \ "后端构建发布成功" \ "版本: v${VERSION}\n产物: releases/tag/server-v${VERSION}\ndoc79 将自动拉取部署" || echo "通知发送失败,不影响主流程" - name: Send failure notification if: failure() env: TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} run: | bash .gitea/scripts/notify.sh failure \ "后端构建失败" \ "请检查 Actions 日志了解失败原因" || echo "通知发送失败" - name: Cleanup if: always() run: | rm -rf server/deploy/ rm -f server/deploy.tar.gz