Skip to content

Deploy to Cloudflare #50

Deploy to Cloudflare

Deploy to Cloudflare #50

Workflow file for this run

name: Deploy to Cloudflare
on:
push:
branches:
- multi-tenant
paths-ignore:
- 'README.md'
- 'LICENSE'
- '.gitignore'
- 'docs/**'
- '*.md'
schedule:
# 每 3 天检查一次更新并部署
- cron: '0 0 */3 * *'
workflow_dispatch:
inputs:
force_deploy:
description: '强制部署(忽略版本检查)'
required: false
type: boolean
default: false
deploy_frontend:
description: '是否部署前端(auto=仅版本变化时,deploy=强制部署,skip=跳过)'
required: false
type: choice
default: auto
options:
- auto
- deploy
- skip
env:
SUBSTORE_REPO: sub-store-org/Sub-Store
FRONTEND_REPO: sub-store-org/Sub-Store-Front-End
jobs:
check-updates:
runs-on: ubuntu-latest
outputs:
deploy_backend: ${{ steps.check.outputs.deploy_backend }}
deploy_frontend_needed: ${{ steps.check.outputs.deploy_frontend_needed }}
backend_version: ${{ steps.check.outputs.backend_version }}
frontend_version: ${{ steps.check.outputs.frontend_version }}
deploy_frontend: ${{ steps.frontend-check.outputs.deploy_frontend }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup jq
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Restore Last Version Cache
uses: actions/cache/restore@v4
with:
path: |
.last-backend-version
.last-frontend-version
key: version-cache-${{ github.ref_name }}-${{ github.run_id }}
restore-keys: |
version-cache-${{ github.ref_name }}-
- name: Check for New Releases
id: check
run: |
# 获取最新版本
BACKEND_VERSION=$(curl -m 10 -s https://api.github.com/repos/${{ env.SUBSTORE_REPO }}/releases/latest | jq -r '.tag_name' || echo "fetch-failed")
FRONTEND_VERSION=$(curl -m 10 -s https://api.github.com/repos/${{ env.FRONTEND_REPO }}/releases/latest | jq -r '.tag_name' || echo "fetch-failed")
if [[ "$BACKEND_VERSION" == "fetch-failed" || "$FRONTEND_VERSION" == "fetch-failed" ]]; then
echo "::error::获取上游 releases 版本失败(可能是网络/限流),停止部署"
exit 1
fi
echo "backend_version=$BACKEND_VERSION" >> $GITHUB_OUTPUT
echo "frontend_version=$FRONTEND_VERSION" >> $GITHUB_OUTPUT
# 获取上次部署的版本
LAST_BACKEND=$(cat .last-backend-version 2>/dev/null || echo "none")
LAST_FRONTEND=$(cat .last-frontend-version 2>/dev/null || echo "none")
echo "Current backend: $BACKEND_VERSION (last: $LAST_BACKEND)"
echo "Current frontend: $FRONTEND_VERSION (last: $LAST_FRONTEND)"
# 使用动态令牌避免 if 条件/日志被意外处理(不要用纯 true/false)
DEPLOY_TOKEN="ACTION_START_${{ github.run_id }}"
# 后端:push / force / 版本变化 都触发
if [[ "${{ github.event.inputs.force_deploy }}" == "true" ]] || \
[[ "${{ github.event_name }}" == "push" ]] || \
[[ "$BACKEND_VERSION" != "$LAST_BACKEND" ]]; then
echo "deploy_backend=$DEPLOY_TOKEN" >> $GITHUB_OUTPUT
echo "Backend deploy: YES"
else
echo "deploy_backend=ACTION_HOLD" >> $GITHUB_OUTPUT
echo "Backend deploy: NO"
fi
# 前端:支持 workflow_dispatch 手动控制(auto/deploy/skip)
MODE="${{ github.event.inputs.deploy_frontend }}"
if [[ -z "$MODE" ]]; then MODE="auto"; fi
if [[ "$MODE" == "deploy" ]]; then
echo "deploy_frontend_needed=$DEPLOY_TOKEN" >> $GITHUB_OUTPUT
echo "Frontend deploy: YES (manual deploy)"
elif [[ "$MODE" == "skip" ]]; then
echo "deploy_frontend_needed=ACTION_HOLD" >> $GITHUB_OUTPUT
echo "Frontend deploy: NO (manual skip)"
elif [[ "$FRONTEND_VERSION" != "$LAST_FRONTEND" ]]; then
echo "deploy_frontend_needed=$DEPLOY_TOKEN" >> $GITHUB_OUTPUT
echo "Frontend deploy: YES (version changed)"
else
echo "deploy_frontend_needed=ACTION_HOLD" >> $GITHUB_OUTPUT
echo "Frontend deploy: NO"
fi
- name: Check If Frontend Deploy Is Enabled
id: frontend-check
env:
DEPLOY_FRONTEND_SECRET: ${{ secrets.DEPLOY_SUB_STORE_FRONTEND }}
run: |
if [ -n "$DEPLOY_FRONTEND_SECRET" ]; then
echo "deploy_frontend=true" >> $GITHUB_OUTPUT
else
echo "deploy_frontend=false" >> $GITHUB_OUTPUT
fi
deploy-backend:
needs: check-updates
if: contains(needs.check-updates.outputs.deploy_backend, 'ACTION_START')
runs-on: ubuntu-latest
name: Deploy Backend
steps:
- name: Validate JWT_SECRET
run: |
if [ -z "${{ secrets.JWT_SECRET }}" ]; then
echo "::error::JWT_SECRET 未设置!"
exit 1
fi
- name: Checkout Workers Adapter Code
uses: actions/checkout@v4
- name: Download Sub-Store Source Code
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
VERSION=${{ needs.check-updates.outputs.backend_version }}
echo "Downloading Sub-Store source $VERSION..."
# 使用仓库内脚本拉取后端源码(支持 GITHUB_TOKEN 降低限流概率)
SUBSTORE_REPO='${{ env.SUBSTORE_REPO }}' \
SUBSTORE_VERSION="$VERSION" \
bash scripts/fetch-substore.sh
# 复制整个项目到构建目录(包含 sub-store/backend)
mkdir -p build
rsync -av --exclude='.git' --exclude='build' --exclude='node_modules' . build/
- name: Configure wrangler.toml
run: |
cd build
cp wrangler.toml.example wrangler.toml
JWT_SECRET='${{ secrets.JWT_SECRET }}'
ESCAPED_JWT_SECRET=$(printf '%s' "$JWT_SECRET" | sed -e 's/[\\/&]/\\\\&/g')
sed -i "s|__JWT_SECRET__|$ESCAPED_JWT_SECRET|g" wrangler.toml
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Install backend dependencies
working-directory: build/sub-store/backend
run: pnpm install
- name: Install dependencies
working-directory: build
run: bun install
- name: Build with Vite
working-directory: build
run: bun run build
- name: Deploy to Cloudflare Workers
working-directory: build
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
run: |
bun run deploy:action
echo "Deploy completed"
deploy-frontend:
needs: check-updates
if: contains(needs.check-updates.outputs.deploy_frontend_needed, 'ACTION_START') && needs.check-updates.outputs.deploy_frontend == 'true'
runs-on: ubuntu-latest
name: Deploy Frontend
steps:
- name: Download Sub-Store Frontend dist
run: |
VERSION=${{ needs.check-updates.outputs.frontend_version }}
echo "Downloading Sub-Store Frontend $VERSION..."
# 直接下载 release 中的 dist.zip(已构建好)
curl -L "https://github.com/${{ env.FRONTEND_REPO }}/releases/download/${VERSION}/dist.zip" -o dist.zip
unzip dist.zip -d frontend-dist
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}
command: pages deploy frontend-dist/dist --project-name=sub-store-frontend
update-version-cache:
needs: [check-updates, deploy-backend, deploy-frontend]
if: always() && (needs.deploy-backend.result == 'success' || needs.deploy-frontend.result == 'success')
runs-on: ubuntu-latest
steps:
- name: Restore Last Version Cache
uses: actions/cache/restore@v4
with:
path: |
.last-backend-version
.last-frontend-version
key: version-cache-${{ github.ref_name }}-${{ github.run_id }}
restore-keys: |
version-cache-${{ github.ref_name }}-
- name: Update version files
run: |
# 只在对应组件部署成功后,才推进它的“上次部署版本”
if [[ "${{ needs.deploy-backend.result }}" == "success" ]]; then
echo "${{ needs.check-updates.outputs.backend_version }}" > .last-backend-version
else
test -f .last-backend-version || echo "none" > .last-backend-version
fi
if [[ "${{ needs.deploy-frontend.result }}" == "success" ]]; then
echo "${{ needs.check-updates.outputs.frontend_version }}" > .last-frontend-version
else
test -f .last-frontend-version || echo "none" > .last-frontend-version
fi
- name: Save version cache
uses: actions/cache/save@v4
with:
path: |
.last-backend-version
.last-frontend-version
key: version-cache-${{ github.ref_name }}-${{ github.run_id }}
summary:
needs: [check-updates, deploy-backend, deploy-frontend]
if: always()
runs-on: ubuntu-latest
steps:
- name: Deploy Summary
run: |
echo "## 部署摘要报告" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**触发方式**: \`${{ github.event_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 组件 | 版本 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 后端 | \`${{ needs.check-updates.outputs.backend_version }}\` | \`${{ needs.deploy-backend.result }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| 前端 | \`${{ needs.check-updates.outputs.frontend_version }}\` | \`${{ needs.deploy-frontend.result }}\` |" >> $GITHUB_STEP_SUMMARY