Skip to content

Commit ee27194

Browse files
authored
Merge branch 'dev': 修复 CI 内测包云服务配置缺失并统一更新源
fix(build): 修复 CI 内测安装包云服务配置缺失并统一更新源
2 parents 9cd3085 + c521d3f commit ee27194

7 files changed

Lines changed: 114 additions & 24 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,27 +62,12 @@ jobs:
6262
# --publish never:发布由下方 release job 统一负责,避免 electron-builder
6363
# 因检测到 tag 而自行尝试发布(github provider 无 GH_TOKEN 会报错)
6464
#
65-
# DOWNLOAD_BASE_URL 已配置时,用 -c.publish.0.url 覆盖 generic 更新源为 CDN,
66-
# 使新包内的 app-update.yml 指向 CDN;未配置时沿用 electron-builder.yml
67-
# 中的自建服务器地址。注:存量客户端的更新源已固化在已安装的
68-
# app-update.yml 中,故 ECS 与 GitHub 两侧资产均需继续发布。
65+
# 更新源(CDN)已直接固化在 electron-builder.yml 的 generic provider 中,
66+
# 本地打包与 CI 打包产物的 app-update.yml 完全一致,不再用
67+
# DOWNLOAD_BASE_URL sed 改写(行锚定模式在 yml 变动后会静默失效,已移除)
6968
- name: Build Electron app
7069
shell: bash
71-
env:
72-
DOWNLOAD_BASE_URL: ${{ secrets.DOWNLOAD_BASE_URL }}
73-
run: |
74-
cd client
75-
if [ -n "$DOWNLOAD_BASE_URL" ]; then
76-
# 不能用 -c.publish.0.url 覆盖:electron-builder 会将其解析成
77-
# 对象 {publish:{0:{url}}} 而非数组元素,触发 schema 校验失败。
78-
# 故直接改写配置文件中 generic provider 的 url(行锚定精确匹配)。
79-
sed -i "s|^ url: https://entropydecrease.com/downloads$| url: ${DOWNLOAD_BASE_URL%/}|" electron-builder.yml
80-
echo 'generic provider after rewrite:'
81-
grep -A1 'provider: generic' electron-builder.yml
82-
else
83-
echo "Update feed -> 默认(electron-builder.yml 中的自建服务器)"
84-
fi
85-
npm run electron:build -- --publish never
70+
run: cd client && npm run electron:build -- --publish never
8671
- uses: actions/upload-artifact@v4
8772
with:
8873
name: release-${{ matrix.os }}

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ Thumbs.db
3636
.env.*.local
3737
.env.production
3838
.env.test
39+
# 例外:client/.env.production 全部为公开值(Supabase publishable anon key + 公网 URL,
40+
# 本就随安装包分发)。CI 打包(release.yml)依赖它注入渲染进程 VITE_ 变量,必须入库,
41+
# 否则产物中 Supabase/同步/AI 网关地址全为空(见 docs/knowledge/bugs/ 2026-07 记录)
42+
!client/.env.production
3943

4044
# Brainstorm scratch (personal notes)
4145
brainstorm*.md

‎client/.env.production‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# ============================================
2+
# 熵减 Entropydecrease - 生产环境变量配置
3+
# 用于 Web/PWA 生产构建: vite build --mode production
4+
# ============================================
5+
6+
# ---- Supabase 配置 ----
7+
VITE_SUPABASE_URL=https://oinwxwiqiruxrnsxtkyk.supabase.co
8+
VITE_SUPABASE_ANON_KEY=sb_publishable_bahxLn7MxT59-AfT8aIr7A_yEILvgj9
9+
10+
# ---- API 服务地址(指向生产服务器)----
11+
# 同步服务 — apiClient 在代码中拼接完整路径(如 /api/v1/sync/push)
12+
# Nginx 将 /api/v1/sync/ 反向代理到 sync-service:8080
13+
VITE_API_BASE_URL=https://entropydecrease.com
14+
15+
# 同步服务健康检查端点(Nginx /health 直接返回 200)
16+
VITE_API_HEALTH_URL=https://entropydecrease.com/health
17+
18+
# ---- AI 网关 ----
19+
# aiClient 在代码中拼接完整路径(如 /api/v1/ai/summarize)
20+
# Nginx 将 /api/v1/ai/ 反向代理到 ai-gateway:8000
21+
VITE_AI_GATEWAY_URL=https://entropydecrease.com

‎client/electron-builder.yml‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# Electron Builder 打包配置 - 熵减桌面端
22
appId: com.entropydecrease.app
33
productName: "Entropy decrease"
4-
# 双发布源:第一项(generic = 自建服务器)被写入 app-update.yml 作为
4+
# 双发布源:第一项(generic = CDN,dl 域名,源站 OSS)被写入 app-update.yml 作为
55
# electron-updater 的自动更新源;GitHub 保留为开源分发/灾备源。
6-
# 注意:存量客户端的 app-update.yml 仍指向 GitHub,过渡期内
7-
# GitHub Release 资产(含 latest.yml)不可停发,否则存量用户无法升级到新源。
6+
# 此处即最终值:CI 不再改写(历史上的 DOWNLOAD_BASE_URL sed 改写已移除),
7+
# 本地打包与 CI 打包产物的更新源完全一致;换域名直接改本文件。
8+
# 注意:存量客户端的 app-update.yml 仍指向 GitHub/ECS 旧源,过渡期内
9+
# GitHub Release 资产(含 latest.yml)与 ECS 侧不可停发,否则存量用户无法升级到新源。
810
publish:
911
- provider: generic
10-
url: https://entropydecrease.com/downloads
12+
url: https://dl.entropydecrease.com/downloads
1113
- provider: github
1214
owner: Aparencia
1315
repo: Entropydecrease

‎client/vite.config.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ function electronBuildConfigPlugin(): Plugin {
2222
// 使用 Vite 的 loadEnv 加载 .env 文件(与 Vite 构建行为一致)
2323
// loadEnv 按约定加载:.env → .env.production → 系统环境变量(后者覆盖前者)
2424
const env = loadEnv('production', process.cwd(), '');
25+
// 构建期防护:关键 VITE_ 变量缺失/占位符时立即终止构建,
26+
// 防止产出「云服务尚未配置」的静默残废安装包
27+
//(曾因 .env.production 被 gitignore、CI checkout 缺失而发生)
28+
const required = ['VITE_SUPABASE_URL', 'VITE_SUPABASE_ANON_KEY', 'VITE_API_BASE_URL', 'VITE_AI_GATEWAY_URL'];
29+
const missing = required.filter((key) => !env[key] || env[key].includes('your-'));
30+
if (missing.length > 0) {
31+
throw new Error(
32+
`[electron-build-config] 缺少必需环境变量: ${missing.join(', ')},请检查 client/.env.production 是否存在且完整`,
33+
);
34+
}
2535
const config = {
2636
VITE_AI_GATEWAY_URL: env.VITE_AI_GATEWAY_URL || '',
2737
VITE_API_BASE_URL: env.VITE_API_BASE_URL || '',
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# 知识卡片 · 踩坑记录
2+
3+
## 基本信息
4+
5+
| 字段 | 内容 |
6+
|------|------|
7+
| 标题 | `.env.production` 被 gitignore 致 CI 安装包 Supabase/同步/AI 网关地址全为空,用户见「云服务尚未配置」 |
8+
| 日期 | 2026-07-31 |
9+
| 类型 | 踩坑记录 |
10+
| 标签 | #CI #环境变量 #Vite #Supabase #GitHubActions #发布 #安装包 |
11+
12+
---
13+
14+
## 症状
15+
16+
内测用户使用 CI(GitHub Actions `release.yml`)打包的 Windows 安装包,在注册/登录页提交时报错:
17+
18+
```
19+
云服务尚未配置,请先在 .env 中设置 VITE_SUPABASE_URL 和 VITE_SUPABASE_ANON_KEY
20+
```
21+
22+
关键陷阱:**本地打包的安装包完全正常,只有 CI 产物必现**——本地开发机上存在 `.env.production`,问题只在 CI 环境暴露。且连带影响不止 Supabase:CI 产物中 `VITE_API_BASE_URL`、`VITE_AI_GATEWAY_URL` 同样为空(`build-config.json` 生成空值),意味着**云同步与云端 AI 网关整体失效**,只是 Supabase 报错最先被用户看到。
23+
24+
## 环境
25+
26+
| 项目 | 版本/信息 |
27+
|------|----------|
28+
| CI | GitHub Actions(windows-latest 打包) |
29+
| 构建 | Vite 8 + electron-builder,`npm run electron:build` |
30+
| 相关文件 | `.gitignore`、`client/.env.production`、`client/vite.config.ts`、`client/src/lib/auth/supabaseClient.ts`、`.github/workflows/release.yml` |
31+
32+
## 排查过程(5 Whys)
33+
34+
1. 为什么报错?→ `AuthContext.tsx` 中 `signUp/signIn` 检测到 `isPlaceholder === true`
35+
2. 为什么是占位符?→ `supabaseClient.ts` 在**构建时**读取 `import.meta.env.VITE_SUPABASE_URL`,缺失则回落到 `'https://your-project.supabase.co'`
36+
3. 为什么构建时缺失?→ CI checkout 的工作区里没有 `client/.env.production`
37+
4. 为什么没有?→ `git check-ignore -v` 显示根 `.gitignore:37` 的 `.env.production` 规则将其忽略,该文件**从未入库**
38+
5. 为什么没兜底?→ `release.yml` 的 Build 步骤也未通过 secrets 注入任何 `VITE_*` 变量
39+
40+
→ **根因:渲染进程环境变量的唯一来源(`.env.production`)被 gitignore,CI 打包环境无任何 `VITE_*` 注入渠道,且构建全程静默通过。**
41+
42+
## 根因
43+
44+
- Vite 在构建时将 `import.meta.env.VITE_*` **静态替换**进渲染包;`.env.production` 缺失时不报错,直接替换为 `undefined`,代码回落到占位符默认值
45+
- 主进程侧 `electronBuildConfigPlugin` 生成的 `build-config.json` 同样写入空字符串,同样静默
46+
- 本地正常 / CI 异常的经典「环境差异」问题:gitignore 的文件只存在于开发机
47+
48+
## 解决方案
49+
50+
1. **提交 `client/.env.production` 入库**:根 `.gitignore` 添加 `!client/.env.production` 例外。安全性评估:文件内全部为公开值——Supabase anon key 是 `sb_publishable_` 前缀的前端公开密钥(本就烘焙进每个安装包分发,由 RLS 保护),其余为公网 URL
51+
2. **构建期防护**:`vite.config.ts` 的 `electronBuildConfigPlugin` 中校验 `VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY / VITE_API_BASE_URL / VITE_AI_GATEWAY_URL`,缺失或含占位符时 `throw`,让 CI 构建**红灯失败**而非产出静默残废包
52+
53+
验证:正向构建通过且渲染产物中含真实 Supabase 域名;负向测试(临时移走两个 env 文件)构建以 exit 1 终止并输出 `[electron-build-config] 缺少必需环境变量: ...`。
54+
55+
## 教训
56+
57+
- **下次如何避免**:任何「构建时烘焙」的配置文件若被 gitignore,CI 产物必然缺失。新增 gitignore 规则时检查:这个文件是否被 CI 构建依赖?
58+
- **配置缺失必须显式失败**:Vite 对缺失 env 静默替换 `undefined` 是产出「残废包」的温床。所有关键构建期变量都应有 fail-fast 校验,让问题死在 CI 而非用户手里。
59+
- **「本地能跑、CI 挂/产物坏」的嫌疑清单**(与 Git LFS 卡片互补):LFS 指针未拉取、**gitignore 的配置文件**、平台可选依赖、secrets/环境变量缺失。
60+
- **公开值不必按密钥管理**:Supabase publishable key 设计上就是公开的,为其引入 secrets 流程反而增加维护成本与静默失败面;区分「真密钥」与「公开配置」再选存放位置。
61+
62+
## 参考
63+
64+
- 错误触发点:`client/src/lib/auth/AuthContext.tsx`(`isPlaceholder` 检查)
65+
- 占位符判定:`client/src/lib/auth/supabaseClient.ts`
66+
- 防护实现:`client/vite.config.ts` `electronBuildConfigPlugin`
67+
- 关联卡片:[Git LFS 图标未在 CI 拉取致 electron-builder 打包失败](./2026-07-git-lfs-icon-electron-builder-ci-failure.md)(同为「本地好 / CI 坏」环境差异类)

‎docs/knowledge/index.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
| 日期 | 标题 | 标签 |
88
|------|------|------|
9+
| 2026-07-31 | [`.env.production` 被 gitignore 致 CI 安装包云服务地址全为空(「云服务尚未配置」)](./bugs/2026-07-ci-env-production-gitignore-supabase-placeholder.md) | #CI #环境变量 #Vite #Supabase #GitHubActions #发布 |
910
| 2026-07-31 | [下载慢诊断中的三次误判:对照实验缺失与观测行为污染测量](./bugs/2026-07-download-slow-misdiagnosis.md) | #性能诊断 #CDN #测量方法 #对照实验 #复盘 |
1011
| 2026-07-30 | [Git LFS 图标未在 CI 拉取致 electron-builder 打包报 `ERR_ELECTRON_BUILDER_CANNOT_EXECUTE`](./bugs/2026-07-git-lfs-icon-electron-builder-ci-failure.md) | #CI #GitLFS #electron-builder #GitHubActions #发布 |
1112
| 2026-07-30 | [reduced-motion 用 `animation-play-state: paused` 冻结入场动画致内容不可见](./bugs/2026-07-reduced-motion-fade-in-up-invisible.md) | #CSS #a11y #reduced-motion #animation |
@@ -24,6 +25,6 @@ _(暂无)_
2425

2526
## 标签速查
2627

27-
- **技术**:#CSS #a11y #React #Vite #Tailwind #CI #GitLFS #electron-builder #GitHubActions #CDN #阿里云
28+
- **技术**:#CSS #a11y #React #Vite #Tailwind #CI #GitLFS #electron-builder #GitHubActions #CDN #阿里云 #环境变量 #Supabase
2829
- **类型**:#bug #方案 #学习 #复盘
2930
- **模块**:#启动仪式 #reduced-motion #animation #发布 #安装包 #性能诊断 #测量方法

0 commit comments

Comments
 (0)