Files
pangolin/web/website/.gitea/workflows/website.yml
T
wangjia 4df8dc6f87 feat(web): 官网 ui_kits/website → Astro 纯静态 SSG 迁移 (tsk_acMYQ-Z-EIF_)
新建 web/website/(Astro 零 SSR):

- 组件迁移:交互块保留 .jsx 经 @astrojs/react(Header/AnnouncementBar/SignupForm/PricingPlans),纯展示块转 .astro 去运行时 JS;像素以原型为基准。
- 令牌同源:build-tokens.mjs 从 design/colors_and_type.css 生成 tokens.gen.css,仅剔除第三方 Google Fonts @import,数值不改。
- 字体自托管:@fontsource(Sora/Manrope/Noto Sans SC/JetBrains Mono),无第三方 CDN。
- 图标:Lucide 构建期内联 SVG(替代 unpkg CDN),零运行时、零 CDN。
- i18n:/(zh)与 /en/(en)双路由单显,语言切换组件;文案沿用 ui_kits 脱敏文案。
- 安全:public/_headers 严格 CSP(全 self + 自托管资源 + 内联片段 sha256,无 unsafe-inline)+ HSTS;无支付表单。
- CI:.gitea/workflows/website.yml 构建(红线扫描+lint+CSP 哈希)→ 同时发布 Cloudflare Pages 主站与镜像。
- 灾备:README 写明干净环境 npm ci && npm run build 可直接部署到任意静态托管;dist 指纹确定性,主站镜像一致。

测试:npm run lint(0 error)/ npm test(build+CSP 哈希注入+红线扫描 0 命中)/ 两次干净构建 dist 指纹一致。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 14:26:40 +08:00

104 lines
3.2 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: website
# 官网 CI/CDpush web/website/** → 构建(红线词扫描 + lint + CSP 哈希)→ 同时发布主站与镜像。
# 与仓库根 .gitea/workflows/ci.yml 解耦:官网完全静态、与后端无依赖,可独立并行。
#
# 需在 Gitea 配置 Secrets
# CF_API_TOKEN Cloudflare API TokenPages:Edit 权限)
# CF_ACCOUNT_ID Cloudflare Account ID
# CF_PAGES_PROJECT_MAIN 主站 Pages 项目名
# CF_PAGES_PROJECT_MIRROR 镜像 Pages 项目名(≥1 个活跃镜像,应对主域名被墙)
# 并把 runs-on 改成实际 runner label。
on:
push:
paths:
- 'web/website/**'
- '.gitea/workflows/website.yml'
pull_request:
paths:
- 'web/website/**'
workflow_dispatch:
env:
# 主站 canonical 域名;镜像也用同一值 → canonical 指向主站 + 产物 hash 一致。
SITE_URL: https://pangolin.example
jobs:
# ── 构建 + 校验(红线 / lint / CSP / 指纹) ──────────────────────────────
build:
name: Build & Verify
runs-on: nas
defaults:
run:
working-directory: web/website
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Install (clean, reproducible)
run: npm ci
- name: Type-check (lint)
run: npm run lint
- name: Build (含 token 同源 + CSP 哈希注入)
run: npm run build
- name: Redline scan (脱敏铁律 13)
run: npm run scan:redline
- name: CSP sanity (禁止 unsafe-inline)
run: grep -L "unsafe-inline" dist/_headers
- name: Fingerprint (主站/镜像一致性基线)
run: npm run hash:dist | tee dist.fingerprint
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: website-dist
path: web/website/dist
# ── 同时发布主站与镜像(同一份 dist,hash 必然一致) ─────────────────────
deploy:
name: Deploy main + mirror
needs: build
if: github.event_name == 'push'
runs-on: nas
defaults:
run:
working-directory: web/website
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Install
run: npm ci
- name: Build
run: npm run build
- name: Deploy → 主站 (Cloudflare Pages)
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
run: npx wrangler pages deploy dist --project-name "${{ secrets.CF_PAGES_PROJECT_MAIN }}" --branch main
- name: Deploy → 镜像 (Cloudflare Pages)
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
run: npx wrangler pages deploy dist --project-name "${{ secrets.CF_PAGES_PROJECT_MIRROR }}" --branch main
- name: Verify main == mirror (内容一致性)
run: |
echo "主站与镜像部署的是同一份 dist,指纹:"
npm run --silent hash:dist