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

13 KiB
Raw Permalink Blame History

贡献指南

English · 项目概览 · 兼容性

欢迎改进主题、工具、测试、文档和翻译。本指南介绍当前源码架构的开发流程;安装和版本选择请参阅 README。

本地开发

使用 Go 1.24 或更高版本。从仓库根目录开始,准备依赖和锁定的官方文件,再运行检查并生成预览:

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 使用实时预览。开发服务器监听主题、框架、锁文件与缓存、预览测试数据的变化。

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。

{
  "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。按截图指南保持截图一致。

更新官方快照

gitea.lock.json 记录稳定的 Gitea 28+ 标签、对应提交和每个文件的 SHA-256。官方邮件模板、语言文件、图标、许可证和已评审的适配参考源码下载到 build/upstream/。仓库仅提交生成的根锁文件,不维护官方文件副本。

命令参考

在 tools/ 中执行。每个上游子命令均支持 --root <仓库根目录>,默认值为相对当前工作目录的 ..。参数放在子命令之后,包含空格的路径需要加引号:

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 中的副本不能替代根锁文件。需要有意初始化锁文件时,执行:

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 中,使用尚不存在的备份名称:

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。测试覆盖生成结果的确定性、操作锚点变化、翻译键,以及全部主题和语言的通知主题行、正文与链接。测试数据包含推送、评审、回复、工作流和附件分支;共享控件与品牌展示作为附加内容单独处理。

修改文档、追踪脚本或打包流程时,在仓库根目录执行:

python -B -m unittest discover -s .github/scripts -p 'test_*.py'

调整通用说明时,同步更新英文和简体中文指南。拉取请求应说明改动内容及相关检查结果,涉及视觉变化时附上截图。

浏览器与 Gitea 实例检查

生成预览数据后,可运行浏览器检查:

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. 打包并检查发行包内容后再发布。

手动打包时,在仓库根目录执行:

python .github/scripts/package_release.py --version vX.Y.Z --output <new-output-directory>

将版本和输出目录占位符替换为已评审的标签及新的目录。脚本会检查源码与产物哈希,包含所有语言数据包,排除残留的旧主题构建,并拒绝覆盖已有压缩包。

发布工作流使用同一脚本打包模板、预览、文档、官方许可证和来源信息,并更新受管理的版本标记。依赖自动发布前,请确认所用 Gitea 主机的 Actions 支持和写入权限。Markdown 管理区块的说明见版本追踪。

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: 日常维护

翻译与许可证

英文指南介绍相同的开发流程。贡献采用 MIT 许可证;分发派生模板时,请保留 Gitea 版权和官方许可证,详见第三方声明。