365 lines
19 KiB
Markdown
365 lines
19 KiB
Markdown
# 贡献指南
|
||
---
|
||
|
||
[English](../CONTRIBUTING.md)
|
||
|
||
欢迎改进主题、工具、文档和翻译。本指南介绍开发环境、命令行工具和贡献流程。安装邮件模板和选择发行版本,请参阅 [README](README.zh-CN.md#安装)及[兼容性表](COMPATIBILITY.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](../preview/index.html),或运行 `go run . dev` 使用实时预览。检查与打包工作流使用 Python 3.11。
|
||
|
||
项目按共享框架、主题样式和构建工具组织。官方模板提供通知内容、条件、主题行和链接;共享框架负责邮件呈现,主题通过元数据和 CSS 选择布局、定义样式。目录说明见 [README](README.zh-CN.md#项目目录结构)。
|
||
|
||
> [!NOTE]
|
||
> 下载的官方文件、生成的模板和预览数据不纳入版本控制。贡献时提交相应源码、测试和文档,无需提交 `build/`、`dist/` 或生成的预览数据。
|
||
|
||
## 开发工具
|
||
|
||
命令行工具提供官方文件准备、主题管理、模板构建和预览功能。
|
||
|
||
> [!TIP]
|
||
> 以下命令均在 `tools/` 中执行;带有位置参数时,将选项放在位置参数之前。示例中的 `my-theme` 表示主题名称,包含空格的路径需要加引号。
|
||
|
||
| 命令 | 用途 |
|
||
|---|---|
|
||
| `upstream` | 准备、同步或校验锁定的官方构建输入 |
|
||
| `build` | 根据官方输入和共享控件生成可安装的主题 |
|
||
| `list` | 列出可用主题及其元数据 |
|
||
| `create` | 创建使用共享框架的主题 CSS 和元数据 |
|
||
| `delete` | 删除一个或多个主题源码目录 |
|
||
| `preview` | 预渲染邮件模板,生成预览和测试数据 |
|
||
| `dev` | 启动通过 SSE 刷新页面的热重载开发服务器 |
|
||
| `help`、`h` | 显示命令列表或指定命令的帮助 |
|
||
|
||
### upstream
|
||
|
||
`upstream` 管理 `gitea.lock.json` 锁定的官方文件,包括邮件模板、语言文件、图标、许可证和已评审的适配参考源码。下载的文件保存到 `build/upstream/`。
|
||
|
||
| 子命令 | 行为 |
|
||
|---|---|
|
||
| `prepare` | 读取根锁文件。缓存缺失时下载并校验;已有缓存则校验后使用。不修改根锁文件。 |
|
||
| `sync --tag <TAG>` | 下载指定稳定版本的官方文件,校验后替换缓存并更新根锁文件。 |
|
||
| `verify` | 对照根锁文件,只读、离线校验已有缓存。 |
|
||
|
||
首次准备或单独检查输入时执行:
|
||
|
||
```bash
|
||
go run . upstream prepare
|
||
go run . upstream verify
|
||
```
|
||
|
||
三个子命令均支持 `--root`,默认值为相对当前工作目录的 `..`。例如:
|
||
|
||
```powershell
|
||
go run . upstream verify --root "C:\Projects\GiteaMailTemplates"
|
||
```
|
||
|
||
根锁文件记录 Gitea 标签、对应提交和文件的 SHA-256。`verify` 检查文件哈希、已评审的适配参考源码,以及官方模板引用的英文翻译键;非英文语言缺少的键会报告警告,并在预览中回退为英文。构建和渲染还会检查框架使用的翻译键及操作链接锚点,缓存校验不能代替这些检查。
|
||
|
||
#### 更新官方版本
|
||
|
||
只有需要评审新的官方版本时才使用 `sync`。例如,明确同步到 `v28.1.0`:
|
||
|
||
```bash
|
||
go run . upstream sync --tag v28.1.0
|
||
go run . upstream verify
|
||
go test ./...
|
||
go run . preview all
|
||
```
|
||
|
||
标签必须采用 `vX.Y.Z` 格式,并且是 Gitea 28 或更高版本的稳定标签;不支持 `latest`、预发布标签或旧版本标签。`sync` 通过 `api.github.com` 解析标签,通过 `raw.githubusercontent.com` 下载文件,不接受本地 Gitea 克隆或认证令牌参数。
|
||
|
||
同步后检查锁文件差异,按需调整适配逻辑和预览数据,完成验证后更新兼容性记录。同步不会自动更新文档、发行标签或兼容性结论。
|
||
|
||
> [!IMPORTANT]
|
||
> 适配参考源码发生变化时,须先评审相关行为,再更新对应参考哈希,不应仅修改哈希以跳过检查。
|
||
|
||
网络或校验错误发生在缓存替换前时,原有文件保持不变。缓存替换和根锁文件写入是两个操作;文件系统错误中断操作后,重试前应检查二者是否一致。更新输入前先停止 `dev`,避免多个进程同时写入缓存。
|
||
|
||
### build
|
||
|
||
`build` 根据锁定的官方文件、共享框架和主题源码生成可安装的邮件模板。必须指定一个或多个主题,或使用 `all` 构建全部主题:
|
||
|
||
```bash
|
||
go run . build aurora
|
||
go run . build aurora bloom
|
||
go run . build all
|
||
```
|
||
|
||
| 选项 | 默认值 | 说明 |
|
||
|---|---|---|
|
||
| `--folder` | `../themes` | 主题源码目录;工具将其父目录作为项目根目录 |
|
||
|
||
使用其他项目路径时,该项目根目录也需要提供锁文件和共享框架:
|
||
|
||
```powershell
|
||
go run . build --folder "C:\Projects\GiteaMailTemplates\themes" aurora
|
||
```
|
||
|
||
结果写入 `build/themes/<名称>/mail/`,同级的 `build.json` 记录构建来源和生成文件的校验值。重新构建会更新所选主题的模板并清理其过时模板,不清理未选中的主题。构建不会部署邮件模板,安装步骤见 [README](README.zh-CN.md#安装主题)。
|
||
|
||
> [!TIP]
|
||
> 需要修改模板时,应编辑主题源码、共享框架或构建适配逻辑。直接修改生成的 `.tmpl` 文件会在后续构建中被覆盖,也会导致打包时的来源校验失败。
|
||
|
||
### list
|
||
|
||
`list` 按名称排序,显示主题名称、模式和简短说明:
|
||
|
||
```bash
|
||
go run . list
|
||
```
|
||
|
||
可通过 `--folder` 指定主题目录,默认值为 `../themes`。命令会校验主题元数据和样式,不下载官方文件,也不生成模板。主题格式无效时,应先修复报告的问题。
|
||
|
||
### create
|
||
|
||
`create` 为新主题创建 `theme.json` 和 `theme.css`,支持一次创建多个主题:
|
||
|
||
```bash
|
||
go run . create my-theme
|
||
go run . create first-theme second-theme
|
||
```
|
||
|
||
可通过 `--folder` 指定主题源码目录,默认值为 `../themes`。命令不会覆盖已存在的目录。主题名称以小写字母开头,仅包含小写字母、数字和连字符;避免使用 `all`,因为构建和预览命令将其作为全部主题的选择参数。
|
||
|
||
编辑生成的元数据和 CSS,定义主题说明及样式。例如:
|
||
|
||
```json
|
||
{
|
||
"name": "my-theme",
|
||
"description": "主题的简短说明",
|
||
"mode": "framed",
|
||
"layout": "standard"
|
||
}
|
||
```
|
||
|
||
`name` 必须与目录名称一致。主题目录仅保存这两个源码文件,不保存官方邮件模板或翻译副本。
|
||
|
||
| 模式 | 展示结构 |
|
||
|---|---|
|
||
| `framed` | 使用共享控件和布局,由主题 CSS 定义样式。新主题默认使用此模式及 `standard` 布局。 |
|
||
| `shared` | 在官方页头片段中加入 CSS,并保留官方页脚片段;不增加框架控件或各类邮件的覆盖模板。 |
|
||
|
||
`framed` 主题可通过 `layout` 选择 `framework/layouts/` 中的布局预设。页头、操作按钮、备用链接、侧栏和页脚位于 `framework/mail/base/`。多个主题共用的结构调整应放在共享框架中,官方内容与控件之间的适配位于 `tools/builder/framework.go`。
|
||
|
||
主题 CSS 使用 `email-heading`、`email-text`、`email-subtext` 等现有类定义标题、正文和辅助说明层级。保留官方通知文字、翻译键、变量和功能链接,不通过 CSS 生成文案或隐藏业务内容。样式校验器会拒绝模板表达式、外部资源引用和不受支持的隐藏规则。
|
||
|
||
完成主题后运行测试并生成预览:
|
||
|
||
```bash
|
||
go test ./...
|
||
go run . preview my-theme
|
||
```
|
||
|
||
### delete
|
||
|
||
`delete` 删除指定主题的源码目录,支持一个或多个名称:
|
||
|
||
```bash
|
||
go run . delete my-theme
|
||
go run . delete first-theme second-theme
|
||
```
|
||
|
||
可通过 `--folder` 指定主题目录,默认值为 `../themes`。
|
||
|
||
> [!WARNING]
|
||
> 命令校验主题后直接删除目录,不提供确认提示或回收站恢复。执行前确认名称,并保留需要的修改。
|
||
|
||
不存在的主题会报告警告;无效主题或符号链接目录会被拒绝。多个主题依次处理,后续失败不会恢复已删除的目录。`all` 不表示删除全部主题。
|
||
|
||
删除源码不会移除之前生成的构建文件、预览数据或已部署的模板。重新执行 `preview all` 更新预览清单;需要移除部署的主题时,按实际安装路径单独处理。
|
||
|
||
### preview
|
||
|
||
`preview` 构建所选主题,并使用示例数据渲染全部锁定的官方语言。必须指定一个或多个主题,或使用 `all`:
|
||
|
||
```bash
|
||
go run . preview aurora
|
||
go run . preview aurora bloom
|
||
go run . preview all
|
||
```
|
||
|
||
| 选项 | 默认值 | 说明 |
|
||
|---|---|---|
|
||
| `--folder` | `../themes` | 主题源码目录;其父目录作为项目根目录 |
|
||
| `--config` | `./data/templates_config.json` | 邮件类型说明和预览示例数据 |
|
||
| `--output` | 项目根目录下的 `preview/rendered.js` | 预览清单路径 |
|
||
|
||
默认输出包括 `preview/rendered.js` 和 `preview/rendered/<语言>.js`。在浏览器中打开 [preview/index.html](../preview/index.html) 即可查看,无需启动服务器。操作和快捷键见 [README](README.zh-CN.md#控制和快捷键)。
|
||
|
||
> [!IMPORTANT]
|
||
> 每次生成会覆盖输出位置的预览清单,不与先前选择的主题合并。例如,执行 `preview aurora` 后,该清单只包含 Aurora;需要恢复全部主题时执行 `preview all`。
|
||
|
||
自定义输出示例:
|
||
|
||
```bash
|
||
go run . preview --config ./data/templates_config.json --output ../build/preview-review/rendered.js all
|
||
```
|
||
|
||
> [!NOTE]
|
||
> 语言数据写入输出文件同级的 `rendered/` 目录。命令不会复制预览界面或修改其脚本引用;现有 `preview/index.html` 仍读取默认位置的数据。
|
||
|
||
新增邮件类型或渲染分支时,补充 `tools/data/templates_config.json` 中的说明和示例上下文。JSON 中用于计数、大小等数值的整数应保持整数形式。正文、发布说明和评审内容等 HTML 字段应使用可控的测试内容,避免包含个人信息或真实凭据。
|
||
|
||
> [!NOTE]
|
||
> 预览用于检查模板结构和展示效果。它使用示例上下文,不能代替目标 Gitea 版本的参数兼容性评审;浏览器与邮件客户端对 CSS 的支持也存在差异。
|
||
|
||
### dev
|
||
|
||
`dev` 启动本地开发服务器,首次启动时构建全部主题并准备预览数据:
|
||
|
||
```bash
|
||
go run . dev
|
||
```
|
||
|
||
打开 [http://127.0.0.1:3456](http://127.0.0.1:3456)。默认端口为 `3456`,可通过 `--port` 修改:
|
||
|
||
```bash
|
||
go run . dev --port 3457
|
||
```
|
||
|
||
服务器仅监听 `127.0.0.1`。在终端中按 `Ctrl + C` 停止运行。该命令按当前 `tools/` 工作目录定位项目,不提供 `--folder`、`--config` 或 `--root` 选项。
|
||
|
||
服务器监听主题源码、共享框架、根锁文件、官方缓存及 `tools/data/` 中的预览数据。文件变化后重新构建,通过服务器发送事件(SSE)刷新预览。构建失败时,根据终端输出修复问题,再保存文件。
|
||
|
||
> [!TIP]
|
||
> 修改 `preview/index.html` 后手动刷新页面;修改 Go 工具代码后停止并重新启动服务器。这些文件不属于当前的自动重建监听范围。
|
||
|
||
### help、h
|
||
|
||
查看全部命令或指定命令的帮助:
|
||
|
||
```bash
|
||
go run . help
|
||
go run . h
|
||
go run . help build
|
||
go run . preview --help
|
||
```
|
||
|
||
查看 `upstream` 子命令的参数时,将 `--help` 放在子命令后:
|
||
|
||
```bash
|
||
go run . upstream prepare --help
|
||
go run . upstream sync --help
|
||
go run . upstream verify --help
|
||
```
|
||
|
||
工具诊断信息采用 `[LEVEL] [NAME] Message` 格式,`[I]`、`[W]`、`[E]`、`[F]` 分别表示信息、警告、错误和致命错误。在支持颜色的终端中,等级标记使用不同颜色;设置 `NO_COLOR` 可禁用颜色。命令失败时返回非零退出码,排查时保留完整输出。
|
||
|
||
## 常见问题
|
||
|
||
### 缺少锁文件或官方缓存怎么办?
|
||
|
||
已有克隆缺少 `gitea.lock.json` 时,应恢复受版本控制的根锁文件。缓存中的 `build/upstream/lock.json` 不能代替它。仅缺少缓存时执行 `upstream prepare`,不要为了恢复缓存而同步到其他版本。`build`、`preview` 和 `dev` 会自动准备官方输入。缓存、Go 工具链和依赖齐备后可以离线使用;`upstream verify` 始终只检查本地文件。首次下载遇到网络错误或 GitHub API 限流时,解决网络问题后重试。
|
||
|
||
### 缓存损坏或与锁文件不匹配怎么办?
|
||
|
||
`prepare` 不会自动修复损坏的缓存,`sync` 也会拒绝替换非空的无效快照。先停止开发服务器,保留根锁文件,将缓存移至备份位置后重新准备。例如,在**仓库根目录的 PowerShell** 中,使用尚不存在的备份名称:
|
||
|
||
```powershell
|
||
Move-Item -LiteralPath .\build\upstream -Destination .\build\upstream.backup
|
||
Set-Location tools
|
||
go run . upstream prepare
|
||
go run . upstream verify
|
||
```
|
||
|
||
> [!WARNING]
|
||
> 不要直接修改缓存中的官方文件,也不要删除 `build/` 中的其他内容。回退官方版本时,恢复此前已评审的根锁文件,再按同样方式重建缓存。
|
||
|
||
### 为什么同步新版本时提示适配源码发生变化?
|
||
|
||
项目固定了已评审的邮件渲染和翻译参考源码。上游修改这些实现后,工具会要求重新评审,避免继续使用不匹配的预览函数或变量结构。检查官方改动,调整适配逻辑和相关测试,再更新参考哈希。新增邮件、翻译键、函数或变量路径都可能需要对应修改。验证通过后再更新[兼容性记录](COMPATIBILITY.zh-CN.md),不要把成功下载等同于完成兼容性确认。
|
||
|
||
### 为什么部分语言使用英文或出现格式警告?
|
||
|
||
官方英文必须包含所有引用的翻译键;其他语言缺少的键回退为英文,并报告警告。保留官方语言文件,不在缓存中补写译文。
|
||
|
||
例如 Gitea v28.0.0 的波兰语 `mail.team_invite.text_1` 存在已知占位符缺陷。预览对已评审的完整原文保留官方输出并报告警告,该例外不适用于其他格式错误。新增问题应提供版本、翻译键和复现信息,以便评审和向上游反馈。
|
||
|
||
### 为什么预览没有显示新主题或最新修改?
|
||
|
||
静态预览不会自动构建。重新执行 `preview all` 并刷新页面,确认预览清单包含所需主题。使用自定义输出路径时,检查预览界面实际读取的位置;使用 `dev` 时,先查看终端是否报告重建失败。Go 代码变更需要重启服务器,预览界面变更需要手动刷新。默认端口被占用时,使用 `--port` 指定其他端口。
|
||
|
||
### 构建成功是否意味着支持所有 Gitea 版本?
|
||
|
||
构建结果针对根锁文件指定的官方输入。不同版本可能修改模板目录、函数或变量结构,不能仅凭构建或预览成功确认向下兼容。部署时按[兼容性表](COMPATIBILITY.zh-CN.md#兼容性表)选择发行包,不将新版本模板直接用于旧版本实例。
|
||
|
||
### 为什么打包脚本拒绝当前产物?
|
||
|
||
打包前执行 `preview all`,确保全部主题和语言数据齐备,且生成文件与当前源码一致。版本参数必须与根锁文件中的标签一致。源码或生成文件变化后,应重新构建和预览。脚本不会覆盖已有发行压缩包。重新打包时选择新的输出目录,保留需要对照的旧产物。
|
||
|
||
## 其它事宜
|
||
|
||
### 主题与共享框架
|
||
|
||
使用适合邮件客户端的 CSS。修改已有主题时,保留其配色、字体、边框和布局特征,使标题、正文和辅助说明的层级清晰,并考虑长文本、长 URL 和移动端宽度。布局片段使用展示性标记,支持 `table`、`tbody`、`tr`、`td`、`div`、`span` 及校验器允许的属性。组合后的标签必须完整配对;`__HEADER__` 插入共享页头,`__MAIL_TYPE__` 展开为邮件 ID,页脚中的 `__SIDEBAR__` 插入共享侧栏。业务变量和通知条件的变更应在构建适配逻辑中评审,不放入主题 CSS 或布局预设。
|
||
|
||
新增主题时更新中英文 README 的画廊。图片使用 PNG,单张不超过 50 KiB,建议为 10–20 KiB;主题、模板、语言和裁切方式按[截图指南](images/README.md)保持一致。
|
||
|
||
### 提交与拉取请求
|
||
|
||
围绕一个明确问题组织改动,避免混入无关的格式调整。拉取请求说明修改原因、影响范围和验证结果;涉及视觉变化时,可附上使用示例数据生成的对照图。修改主题、共享框架或 Go 工具时,在 `tools/` 中运行:
|
||
|
||
```bash
|
||
go test ./...
|
||
go run . preview all
|
||
```
|
||
|
||
涉及邮件内容、链接、变量或函数适配时,补充对应的回归测试,覆盖受影响的条件分支。现有测试检查生成结果、翻译键及全部主题和语言的通知主题行、正文与链接,包括推送、评审、回复、工作流和附件分支。
|
||
|
||
修改打包脚本时,在仓库根目录运行:
|
||
|
||
```bash
|
||
python -B -m unittest discover -s .github/scripts -p 'test_*.py'
|
||
```
|
||
|
||
纯文档修改检查文字、命令示例和链接即可。中文文档与英文文档应保持内容一致;翻译时保留命令、路径、变量和版本信息,不改变原意。
|
||
|
||
提交信息使用简短说明,可参考以下前缀:
|
||
|
||
| 前缀 | 范围 |
|
||
|---|---|
|
||
| `style(<名称>):` | 主题展示样式 |
|
||
| `preview:` | 预览工具 |
|
||
| `tools:` | CLI、构建与快照工具 |
|
||
| `docs:` | 文档和翻译 |
|
||
| `fix:` | 问题修复 |
|
||
| `project:` | 仓库配置和项目结构 |
|
||
| `refactor:` | 代码重构 |
|
||
| `chore:` | 日常维护 |
|
||
|
||
### 版本与发布维护
|
||
|
||
发行标签必须与锁定的 Gitea 标签一致。版本标记、徽章和兼容性记录由维护者手动更新;修改官方输入不会自动触发版本维护。历史发行附件应保留,文档和兼容性记录应在打标签前检查。完成验证并生成全部预览后,可在仓库根目录手动打包:
|
||
|
||
```bash
|
||
python .github/scripts/package_release.py --version v28.1.0 --output build/release-review
|
||
```
|
||
|
||
将示例版本替换为根锁文件中的标签,并使用没有同名发行压缩包的输出目录。脚本检查源码与产物的校验值,打包主题、预览、文档、官方许可证和来源信息,排除残留的旧主题构建。
|
||
|
||
`.github/workflows/validate.yml` 负责普通推送和拉取请求检查,也供 Release 工作流调用。Release 验证通过后打包归档,并通过发布 Action 上传附件,以标签作为标题,新建 Release 的正文为空,不要求发行说明文件。重新发布已有标签时保留已有正文并替换同名附件;失败后重试前检查发行版及附件状态。
|
||
|
||
工作流使用 `linux-amd64-docker-small` Runner 标签,并通过安装步骤准备 Go、Python 和发布所需的 Node.js。Action 使用 `actions/...@版本` 引用,由 Runner 的 Action 来源配置解析;维护时应考虑当前 `github_mirror` 配置。发布使用内置 `GITEA_TOKEN`,仓库需具备发行版写入权限。
|
||
|
||
### 报告问题
|
||
|
||
问题报告应包含 Gitea 版本、模板发行版或源码提交、主题、邮件类型、语言和复现步骤。构建或预览问题还应提供根锁文件中的标签、相关命令和完整错误输出;显示问题注明邮件客户端,并附上移除个人信息后的截图。
|
||
|
||
提出改进建议时,说明使用场景、预期效果及涉及的主题或工具。发现官方模板或翻译问题时,保留原始输入,提供能够复现问题的最小示例。
|
||
|
||
### 许可证
|
||
|
||
本项目采用 [MIT 许可证](../LICENSE)。贡献应使用能够合法分发的代码、样式和图片。生成和分发派生模板时,保留 Gitea 版权、官方许可证及快照来源信息;发行包已包含相关文件。
|