Skip to content

Commit b672340

Browse files
OneeMeclaude
andcommitted
chore(deploy): add Cloudflare Pages deployment workflow
- Add GitHub Actions workflow for auto-deploy to Cloudflare Pages - Update astro.config.mjs with production site URL - Update web/README.md with deployment docs - Make relatedSessions optional in content schema (default []) - Fix missing relatedSessions in 3 article files - Add test to ensure all articles have relatedSessions field Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 5f3410d commit b672340

8 files changed

Lines changed: 135 additions & 30 deletions

File tree

.github/workflows/deploy-web.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Deploy Web to Cloudflare Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'web/**'
8+
- '.github/workflows/deploy-web.yml'
9+
workflow_dispatch:
10+
11+
concurrency:
12+
group: deploy-web
13+
cancel-in-progress: false
14+
15+
jobs:
16+
deploy:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
deployments: write
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- uses: actions/setup-node@v4
25+
with:
26+
node-version: '22'
27+
cache: 'npm'
28+
cache-dependency-path: 'web/package-lock.json'
29+
30+
- name: Install dependencies
31+
working-directory: web
32+
run: npm ci
33+
34+
- name: Build
35+
working-directory: web
36+
run: npm run build
37+
38+
- name: Deploy to Cloudflare Pages
39+
uses: cloudflare/wrangler-action@v3
40+
with:
41+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
42+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
43+
command: pages deploy web/dist --project-name=wwdc-quick-look
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import assert from 'node:assert/strict';
2+
import fs from 'node:fs';
3+
import path from 'node:path';
4+
import { describe, it } from 'node:test';
5+
import { fileURLToPath } from 'node:url';
6+
7+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
8+
const PROJECT_ROOT = path.resolve(__dirname, '../..');
9+
const ARTICLES_DIR = path.join(PROJECT_ROOT, 'web/src/content/articles');
10+
11+
function hasRelatedSessions(filePath) {
12+
const content = fs.readFileSync(filePath, 'utf8');
13+
14+
const frontMatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
15+
if (!frontMatterMatch) {
16+
return { ok: false, reason: 'no-frontmatter' };
17+
}
18+
19+
const frontMatter = frontMatterMatch[1];
20+
if (!frontMatter.includes('relatedSessions')) {
21+
return { ok: false, reason: 'missing-relatedSessions' };
22+
}
23+
24+
return { ok: true };
25+
}
26+
27+
describe('article relatedSessions field', () => {
28+
const files = fs.readdirSync(ARTICLES_DIR).filter((f) => f.endsWith('.mdx'));
29+
const missing = [];
30+
31+
for (const f of files) {
32+
const filePath = path.join(ARTICLES_DIR, f);
33+
const result = hasRelatedSessions(filePath);
34+
if (!result.ok) {
35+
missing.push({ file: f, reason: result.reason });
36+
}
37+
}
38+
39+
it('every MDX article has a relatedSessions field in frontmatter', () => {
40+
const msg = missing.length > 0
41+
? `${missing.length} file(s) missing relatedSessions field:\n` +
42+
missing.map(m => ` - ${m.file} (${m.reason})`).join('\n')
43+
: undefined;
44+
assert.strictEqual(missing.length, 0, msg);
45+
});
46+
});

web/README.md

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,55 @@
1-
# Astro Starter Kit: Minimal
1+
# :globe_with_meridians: wwdc-quick-look Web
22

3-
```sh
4-
npm create astro@latest -- --template minimal
3+
Astro 构建的 wwdc-quick-look 静态站点,部署在 Cloudflare Pages。
4+
5+
## 开发
6+
7+
```bash
8+
cd web
9+
npm install
10+
npm run dev # localhost:4321
11+
npm run build # 输出到 web/dist/
12+
npm run preview # 本地预览构建结果
513
```
614

7-
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
15+
## 部署
816

9-
## 🚀 Project Structure
17+
推送至 `main` 分支且变更涉及 `web/**` 路径时,GitHub Actions 会自动构建并部署到 Cloudflare Pages。
1018

11-
Inside of your Astro project, you'll see the following folders and files:
19+
也可手动触发:在 GitHub 仓库 → Actions → "Deploy Web to Cloudflare Pages" → Run workflow。
1220

13-
```text
14-
/
15-
├── public/
16-
├── src/
17-
│ └── pages/
18-
│ └── index.astro
19-
└── package.json
20-
```
21+
### 必需的 Secrets
2122

22-
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
23+
在仓库 Settings → Secrets and variables → Actions 中配置:
2324

24-
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
25+
| Secret | 说明 |
26+
|--------|------|
27+
| `CLOUDFLARE_API_TOKEN` | Cloudflare API Token(需包含 `Cloudflare Pages:Edit` 权限) |
28+
| `CLOUDFLARE_ACCOUNT_ID` | Cloudflare Account ID |
2529

26-
Any static assets, like images, can be placed in the `public/` directory.
30+
获取方式:
31+
- **API Token**: Cloudflare Dashboard → My Profile → API Tokens → Create Token → 使用 "Custom token" 模板,权限添加 `Zone:Read``Cloudflare Pages:Edit`
32+
- **Account ID**: Cloudflare Dashboard 右侧边栏可见
2733

28-
## 🧞 Commands
34+
### 首次创建 Pages 项目
2935

30-
All commands are run from the root of the project, from a terminal:
36+
若 Cloudflare Pages 上尚未创建 `wwdc-quick-look` 项目,可通过 Wrangler CLI 创建:
3137

32-
| Command | Action |
33-
| :------------------------ | :----------------------------------------------- |
34-
| `npm install` | Installs dependencies |
35-
| `npm run dev` | Starts local dev server at `localhost:4321` |
36-
| `npm run build` | Build your production site to `./dist/` |
37-
| `npm run preview` | Preview your build locally, before deploying |
38-
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
39-
| `npm run astro -- --help` | Get help using the Astro CLI |
38+
```bash
39+
npx wrangler pages project create wwdc-quick-look --production-branch=main
40+
```
4041

41-
## 👀 Want to learn more?
42+
## 项目结构
4243

43-
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
44+
```
45+
web/
46+
├── public/ # 静态资源(favicon、图片等)
47+
├── src/
48+
│ ├── components/ # Astro 组件
49+
│ ├── layouts/ # 页面布局
50+
│ ├── pages/ # 路由页面
51+
│ ├── content/ # MDX 文章集合
52+
│ └── i18n/ # 文案配置
53+
├── astro.config.mjs # Astro 配置
54+
└── package.json
55+
```

web/astro.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ import mdx from '@astrojs/mdx';
33

44
export default defineConfig({
55
integrations: [mdx()],
6+
site: 'https://wwdc-quick-look.swiftgg.team',
67
});

web/src/content.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const articles = defineCollection({
2424
code: z.string(),
2525
description: z.string(),
2626
})
27-
),
27+
).optional().default([]),
2828
}),
2929
});
3030

web/src/content/articles/wwdc2026-111.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ thumbnail: "/images/sessions/2026/111.jpg"
77
videoUrl: "https://developer.apple.com/videos/play/wwdc2026/111/"
88
sessionId: "wwdc2026-111"
99
year: "2026"
10+
relatedSessions: []
1011
---
1112

1213
## Highlight

web/src/content/articles/wwdc2026-112.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ thumbnail: "/images/sessions/2026/112.jpg"
77
videoUrl: "https://developer.apple.com/videos/play/wwdc2026/112/"
88
sessionId: "wwdc2026-112"
99
year: "2026"
10+
relatedSessions: []
1011
---
1112

1213
## Highlight

web/src/content/articles/wwdc2026-394.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ thumbnail: "/images/sessions/2026/394.jpg"
77
videoUrl: "https://developer.apple.com/videos/play/wwdc2026/394/"
88
sessionId: "wwdc2026-394"
99
year: "2026"
10+
relatedSessions: []
1011
---
1112

1213
## Highlight

0 commit comments

Comments
 (0)