Files
KenanZhu f4d96de79e
Release / Validate Templates (push) Successful in 3m1s
Release / Package & Release (push) Skipped
Release / Update Latest Release Documentation (push) Skipped
chore: refresh docs and adapt workflows for Gitea
2026-10-09 22:02:33 +08:00

220 lines
13 KiB
Markdown
Raw Permalink 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.
# 贡献指南
[English](../CONTRIBUTING.md) · [项目概览](README.zh-CN.md) · [兼容性](../COMPATIBILITY.md)
欢迎改进主题、工具、测试、文档和翻译。本指南介绍当前源码架构的开发流程;安装和版本选择请参阅 [README](README.zh-CN.md#安装)。
## 本地开发
使用 **Go 1.24 或更高版本**。从仓库根目录开始,准备依赖和锁定的官方文件,再运行检查并生成预览:
```bash
cd tools
go mod download
go run . upstream prepare
go test ./...
go run . preview all
```
在浏览器中打开 `preview/index.html`,或在 `tools/` 中运行 `go run . dev`,访问 [http://127.0.0.1:3456](http://127.0.0.1:3456) 使用实时预览。开发服务器监听主题、框架、锁文件与缓存、预览测试数据的变化。
CLI 使用 urfave/cli 和 x/net HTML 解析器。文档与打包检查使用 Python 3.11 或更高版本;只有浏览器检查需要 Node.js 和 `tools/qa` 中的依赖。
### 常用命令
以下命令均在 `tools/` 中执行。带有位置参数时,将选项放在位置参数之前。
| 命令 | 用途 |
|---|---|
| `go run . list` | 列出可用主题 |
| `go run . create my-theme` | 创建主题元数据和 CSS |
| `go run . build my-theme` | 生成指定主题的安装模板 |
| `go run . build all` | 生成全部主题 |
| `go run . preview all` | 构建全部主题并渲染所有官方语言 |
| `go run . dev` | 在端口 3456 启动开发服务器 |
| `go run . dev --port 3457` | 指定其他本地端口 |
| `go run . delete my-theme` | 删除指定主题的源码目录 |
`build` 将模板写入 `build/themes/<名称>/mail/`,并在 `build.json` 中记录文件和源码哈希。`preview` 同时完成构建,随后写入 `preview/rendered.js` 和 `preview/rendered/<语言>.js`。这些生成文件和下载的官方文件均被 Git 忽略,无需随贡献提交。
## 添加主题
1. 在 `tools/` 中运行 `go run . create my-theme`。
2. 编辑 `themes/my-theme/theme.json` 和 `theme.css`。
3. 在 `tools/` 中运行 `go test ./...` 和 `go run . preview all`。
4. 检查英文、简体中文及至少另一种官方语言的桌面与移动端布局,在拉取请求中附上截图。
主题名称以小写字母开头,可包含小写字母、数字和连字符。主题目录只包含 `theme.json` 和 `theme.css`。
```json
{
"name": "my-theme",
"description": "主题的简短说明",
"mode": "framed",
"layout": "standard"
}
```
| 模式 | 生成的展示结构 |
|---|---|
| `framed` | 使用共享控件和框架布局,由主题 CSS 定义样式。新主题默认使用此模式及 `standard` 布局。 |
| `shared` | 在官方页头片段中加入 CSS,并保留官方页脚片段;不增加框架控件或各类邮件的覆盖模板。 |
### 共享框架
页头、操作按钮、备用链接、侧栏和页脚位于 `framework/mail/base/`。布局预设位于 `framework/layouts/`,`framed` 主题可通过可选的 `layout` 字段选择预设。配色、字体和间距由主题 CSS 定义。
`tools/builder/framework.go` 将官方操作值和翻译键适配到共享控件。通知条件、主题行、附件和上下文链接由官方模板定义。控件或布局结构的修改应放在框架中,使各主题使用同一套适配逻辑。
布局片段组合后必须形成标签配对完整的展示结构。`__HEADER__` 插入共享页头,`__MAIL_TYPE__` 展开为发现的邮件 ID,页脚片段中的 `__SIDEBAR__` 插入共享侧栏。部署模板的 Logo 使用 `{{AppUrl}}assets/img/favicon.png`;生成的预览数据嵌入下载的图标,供离线显示。
## 设计规范
- 使用兼容邮件客户端的 CSS。主题 CSS 不得加载外部资源、生成文字或隐藏官方内容。
- 布局片段使用展示性标记。校验器接受 `table`、`tbody`、`tr`、`td`、`div`、`span` 及支持的展示属性。
- 修改已有主题时,保留其配色、字体、边框、页头、按钮和布局特征。
- 检查桌面和 390px 移动端预览,覆盖长文本和长 URL。条件允许时测试 Gmail、Outlook 和 Apple Mail;浏览器预览不能模拟邮件客户端。
- 画廊图片使用 PNG,单张不超过 50 KiB,建议为 10–20 KiB。按[截图指南](images/README.md)保持截图一致。
## 更新官方快照
`gitea.lock.json` 记录稳定的 Gitea 28+ 标签、对应提交和每个文件的 SHA-256。官方邮件模板、语言文件、图标、许可证和已评审的适配参考源码下载到 `build/upstream/`。仓库仅提交生成的根锁文件,不维护官方文件副本。
### 命令参考
在 `tools/` 中执行。每个上游子命令均支持 `--root <仓库根目录>`,默认值为相对当前工作目录的 `..`。参数放在子命令之后,包含空格的路径需要加引号:
```powershell
go run . upstream verify --root "C:\Projects\GiteaMailTemplates"
```
| 命令 | 行为 |
|---|---|
| `go run . upstream prepare` | 读取根锁文件。缓存不存在时下载并校验对应文件;已有缓存则离线校验。不修改根锁文件。 |
| `go run . upstream verify` | 对照根锁文件离线、只读检查已有缓存。输出 `[PASS]`,并以 `[FALLBACK]` 列出非英文语言缺少的键。 |
| `go run . upstream sync --tag vX.Y.Z` | 通过 GitHub API 解析明确指定的稳定 Gitea 28+ 标签,下载并校验文件,然后替换缓存并生成根锁文件。 |
`sync` 使用 `api.github.com`,文件下载使用 `raw.githubusercontent.com`。这些命令不接受本地 Gitea 克隆、认证令牌或隐式的 `latest` 版本。网络错误和 API 限流会中止操作;Go 工具链或模块可能仍需单独联网下载。
### 已有克隆与离线使用
`build`、`preview` 和 `dev` 会自动准备输入,需要已提交的根锁文件,并在使用缓存前完成校验。缓存、Go 工具链和依赖齐备后,可以离线构建。
需要单独检查缓存时,使用 `upstream verify`。它校验官方文件哈希、已评审的适配参考源码,以及官方模板引用的英文翻译键。构建和渲染还会检查框架翻译键及主要操作链接的锚点,因此缓存校验只是兼容性测试的一部分。
### 锁文件缺失与显式更新版本
已有克隆缺少 `gitea.lock.json` 时,应恢复受版本控制的文件。`build/upstream/lock.json` 中的副本不能替代根锁文件。需要有意初始化锁文件时,执行:
```bash
cd tools
go run . upstream sync --tag v28.0.0
go run . upstream verify
go test ./...
go run . preview all
```
评审其他版本时,明确指定对应标签。检查锁文件差异,按需更新框架适配逻辑和测试数据,完成检查及同版本实例冒烟测试后,再更新兼容性记录。`sync` 只修改缓存和锁文件,文档更新与版本发布需单独完成。仅缺少缓存时使用 `prepare`。
已评审的翻译或邮件渲染参考源码发生变化时,须先评审适配逻辑,再更新参考哈希。官方英文必须包含所有引用的翻译键;其他语言缺少的翻译回退为英文。新增邮件类型需要补充框架适配和 `tools/data/templates_config.json` 中的测试数据,该文件提供预览元数据和示例上下文。JSON 测试数据中的整数应保持整数形式,以便 Go 正确格式化。
缓存替换前发生网络或校验错误时,原有文件保持不变。缓存替换和根锁文件写入是两个操作;文件系统错误中断操作后,重试前应检查二者是否一致。
### 缓存恢复
`prepare` 会报告损坏、不完整或与锁文件不匹配的缓存,不会自动修复。`sync` 同样拒绝替换非空的无效快照。检查错误后,将生成的缓存移至备份位置,再按已评审的根锁文件重新准备。
例如,在**仓库根目录的 PowerShell** 中,使用尚不存在的备份名称:
```powershell
Move-Item -LiteralPath .\build\upstream -Destination .\build\upstream.backup
Set-Location tools
go run . upstream prepare
go run . upstream verify
```
保留 `build/` 中的其他内容,不直接编辑缓存中的官方文件。需要回退快照时,恢复此前已评审的根锁文件,再按同样方式重建缓存。替换输入前先停止 `dev`,避免多个进程同时写入同一缓存。
### 已知上游格式问题
Gitea v28.0.0 的波兰语 `mail.team_invite.text_1` 存在占位符缺陷。预览保留官方输出并报告 `[UPSTREAM-WARN]`。该例外仅匹配已评审的完整原文,其他格式错误会使渲染失败。发现上游问题时应报告问题,不修改缓存中的语言文件。
## 验证与发布
### 拉取请求检查
在 `tools/` 中运行 `go test ./...` 和 `go run . preview all`。测试覆盖生成结果的确定性、操作锚点变化、翻译键,以及全部主题和语言的通知主题行、正文与链接。测试数据包含推送、评审、回复、工作流和附件分支;共享控件与品牌展示作为附加内容单独处理。
修改文档、追踪脚本或打包流程时,在仓库根目录执行:
```bash
python -B -m unittest discover -s .github/scripts -p 'test_*.py'
```
调整通用说明时,同步更新英文和简体中文指南。拉取请求应说明改动内容及相关检查结果,涉及视觉变化时附上截图。
### 浏览器与 Gitea 实例检查
生成预览数据后,可运行浏览器检查:
```bash
cd tools/qa
npm install
npx playwright install chromium
npm test
```
如需使用已安装的 Chrome 或 Edge,设置 `BROWSER_EXECUTABLE_PATH`,无需再安装 Chromium。设置 `PREVIEW_DEV_URL` 可同时检查运行中的 HTTP 预览。`npm test -- --update-gallery` 会一并更新画廊截图。
发布前,在与锁定版本一致的隔离 Gitea 实例中加载生成的模板,捕获真实的密码重置或通知邮件。管理后台的测试邮件按钮不使用自定义模板。
可选的 `tools/integration` 测试使用临时 SQLite 数据、用户、Git/SSH 路径和回环 SMTP。将 `GITEA_SMOKE_BINARY` 设为已校验官方校验值、版本与锁文件一致的 Gitea 可执行文件,再在 `tools/` 中运行 `go test ./integration -v -count=1`。邮件仅在本地捕获,不发送给真实用户。未设置该变量时会跳过此测试。发布工作流不会自动运行可选的浏览器和真实 Gitea 实例检查。
### 准备发行版
发行标签必须与锁定的 Gitea 版本一致。当前源码重构尚未发布,已有 v28.0.0 和历史版本的附件应保留。
1. 完成自动化检查、预览检查和同版本实例冒烟测试。
2. 在 `.github/release-notes/vX.Y.Z.md` 添加已评审的发行说明,并按验证结果更新兼容性记录。
3. 在 `tools/` 中运行 `go run . preview all`,生成全部主题和语言数据。
4. 打包并检查发行包内容后再发布。
手动打包时,在仓库根目录执行:
```bash
python .github/scripts/package_release.py --version vX.Y.Z --output <new-output-directory>
```
将版本和输出目录占位符替换为已评审的标签及新的目录。脚本会检查源码与产物哈希,包含所有语言数据包,排除残留的旧主题构建,并拒绝覆盖已有压缩包。
发布工作流使用同一脚本打包模板、预览、文档、官方许可证和来源信息,并更新受管理的版本标记。依赖自动发布前,请确认所用 Gitea 主机的 Actions 支持和写入权限。Markdown 管理区块的说明见[版本追踪](../COMPATIBILITY.md#version-tracking)。
### Gitea 工作流配置
两个工作流均使用 `linux-amd64-docker-small` Runner 标签。任务镜像需要支持检出和工具链安装步骤使用的 Node.js Action,并提供 Git 和 POSIX Shell。Go 与 Python 由安装步骤准备。
PR 创建和发行附件上传通过 `.github/scripts/gitea_actions.py` 调用实例的 `/api/v1` API。工作流传入实例地址、仓库名称和内置 `GITEA_TOKEN`,仓库设置需要允许所请求的代码、发行版及拉取请求写入权限。可选的 `UPSTREAM_GITHUB_TOKEN` Secret 仅用于查询 GitHub 上的官方发行版;未配置时使用 GitHub 的匿名 API 限额。
追踪工作流会复用内容相同的已有分支及对应的未关闭 PR。分支内容不同时需要人工检查,工作流不会强制推送。发布流程拒绝修改任何已有发行版,包括草稿;新版本在两个压缩包上传成功后才从草稿转为发布状态。上传失败时,重试前先检查草稿;已发布版本及附件应保持不变。
## 报告问题
请提供 Gitea 版本、模板发行版或源码提交、主题、邮件类型、语言和复现步骤。源码构建问题还应包含快照标签与提交,以及 `go run . upstream verify` 或 `go run . preview all` 的输出。显示问题请注明邮件客户端,并附上移除个人信息后的截图。
## 提交规范
| 前缀 | 范围 |
|---|---|
| `style(<名称>):` | 主题展示样式 |
| `preview:` | 浏览器预览 |
| `tools:` | CLI、构建与快照工具 |
| `docs:` | 文档和翻译 |
| `fix:` | 问题修复 |
| `project:` | 仓库配置和项目结构 |
| `refactor:` | 代码重构 |
| `chore:` | 日常维护 |
## 翻译与许可证
[英文指南](../CONTRIBUTING.md)介绍相同的开发流程。贡献采用 MIT 许可证;分发派生模板时,请保留 Gitea 版权和官方许可证,详见[第三方声明](../THIRD_PARTY_NOTICES.md)。