mirror of
https://github.com/zhu1090093659/dsh-web.git
synced 2026-09-28 14:24:03 +08:00
Closes #1704. Deploy Market and Update contributors run on push and schedule in forks, where their production and PAT secrets are intentionally absent, so they failed after doing real work: an empty TURNSTILE_SECRET, and an actions/checkout with no token. Both jobs now carry a `github.repository == 'zhu1090093659/dsh-web'` guard and finish skipped before checkout, instead of copying credentials or weakening the gates. The release workflow is tag-triggered, so a fork push cannot reach it. Verified: both files parse with zero YAML errors and keep their existing trigger and permission blocks.
112 lines
4.5 KiB
YAML
112 lines
4.5 KiB
YAML
name: Deploy Market
|
||
|
||
# Push 到 dev 且市场相关文件变化时,把已提交的 market/dist 产物部署到
|
||
# Cloudflare Workers(Worker dsh-market,自定义域名 dsh-market.com),
|
||
# 同时幂等应用 D1 migration。
|
||
#
|
||
# 以 dev 为唯一自动部署来源:新皮肤 / 宠物 / 社区插件合并进 dev 即上架
|
||
# 创意工坊,不等发版集成;main 只通过维护者集成接收 dev 内容,不再触发
|
||
# 部署(避免集成瞬间用较旧产物回滚商店)。workflow_dispatch 保留手动兜底。
|
||
#
|
||
# 只部署「已提交」的产物,不在 CI 里重建(market-build --check 校验一致性):
|
||
# 与本仓库产物部署纪律一致,避免构建机绝对路径/不确定性进入产物。
|
||
#
|
||
# 部署后不在这里做整站资产校验:从 GitHub runner 出口发出的请求会被该 zone 的
|
||
# 托管质询(cf-mitigated: challenge)挡在 Worker 之前,车道从该出口证明不了任何
|
||
# 资产。整站走查由维护者在策略允许的网络上按需执行:
|
||
# node scripts/market-verify-assets.mjs --attest https://dsh-market.com
|
||
#
|
||
# 需要的仓库 secrets:
|
||
# CLOUDFLARE_API_TOKEN — Workers Scripts / D1 / Zone · Edit
|
||
# CLOUDFLARE_ACCOUNT_ID — Cloudflare 账号 ID
|
||
|
||
on:
|
||
push:
|
||
branches:
|
||
- dev
|
||
paths:
|
||
- 'market/**'
|
||
# A submodule gitlink is the skin / pet / community pin; moving one is
|
||
# what makes an upstream content change reach the site.
|
||
- 'satellites/**'
|
||
- 'market-inputs.lock.json'
|
||
- 'scripts/market-build'
|
||
- 'scripts/market-fetch-inputs.mjs'
|
||
- 'scripts/market-verify-assets.mjs'
|
||
- 'scripts/deploy-market'
|
||
- 'scripts/market-layout.test.mjs'
|
||
- 'package.json'
|
||
- '.github/workflows/deploy-market.yml'
|
||
workflow_dispatch:
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
concurrency:
|
||
group: deploy-market-${{ github.ref }}
|
||
cancel-in-progress: false
|
||
|
||
jobs:
|
||
deploy:
|
||
name: Deploy market to Workers
|
||
# Canonical-repository guard: the production Cloudflare, Turnstile and
|
||
# attestation secrets exist only here. A fork that enables Actions still
|
||
# fires this workflow on push and schedule, burns the gates above and then
|
||
# fails on the empty TURNSTILE_SECRET - noise for the fork, and a
|
||
# suggestion that the workflow is broken. Skip before checkout instead of
|
||
# copying credentials or weakening the gates.
|
||
if: github.repository == 'zhu1090093659/dsh-web'
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 15
|
||
|
||
# Step-level if cannot reference the secrets context (actionlint); gate on
|
||
# the job-level env mirror instead.
|
||
env:
|
||
TURNSTILE_SECRET: ${{ secrets.TURNSTILE_SECRET }}
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v5
|
||
|
||
- name: Setup pnpm
|
||
uses: pnpm/action-setup@v5
|
||
|
||
- name: Setup Node.js
|
||
uses: actions/setup-node@v5
|
||
with:
|
||
node-version: 22
|
||
cache: pnpm
|
||
|
||
- name: Install dependencies
|
||
run: pnpm install --frozen-lockfile --ignore-scripts
|
||
|
||
# The build reads the skin and pet content from the satellite repositories
|
||
# at the commits pinned in market-inputs.lock.json.
|
||
- name: Fetch market content inputs
|
||
run: node scripts/market-fetch-inputs.mjs
|
||
|
||
# The community index is validated in its own repository and consumed here
|
||
# at the commit pinned in market-inputs.lock.json, so this lane runs only
|
||
# the gates that belong to this repository.
|
||
- name: Market consistency
|
||
run: pnpm market:check && pnpm test:scripts
|
||
|
||
- name: Install wrangler
|
||
run: npm install -g wrangler@4
|
||
|
||
# The worker fails closed without TURNSTILE_SECRET (likes/installs reject
|
||
# every write), so deploying without the secret must fail loudly here
|
||
# instead of shipping a write-dead production API.
|
||
- name: Assert Turnstile secret is configured
|
||
run: test -n "$TURNSTILE_SECRET" || { echo "::error::TURNSTILE_SECRET repository secret is not configured; the market worker fails closed without it"; exit 1; }
|
||
|
||
- name: Deploy market
|
||
run: node scripts/deploy-market
|
||
env:
|
||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||
# Refreshes the worker's ASSET_ATTEST_SECRET binding; the deploy fails
|
||
# loudly when the binding is missing, because the deployed-asset sweep
|
||
# measures the deployed version through that binding.
|
||
MARKET_ATTEST_SECRET: ${{ secrets.MARKET_ATTEST_SECRET }}
|