# 贡献指南 — Gitea 邮件模板 ## 添加主题 1. 执行 `cd tools && go run . create <名称>`,创建共享框架主题。 2. 编辑 `themes/<名称>/theme.json` 和 `theme.css`。 3. 在 `tools/` 中运行 `go run . upstream prepare`、`go test ./...` 和 `go run . preview all`。 4. 检查英文、简体中文及另一种官方语言的桌面/移动端预览,随 PR 提交截图。 主题名称以小写字母开头,可包含小写字母、数字和连字符。主题只包含 `theme.json` 与 `theme.css`。新主题默认使用 `framed` 模式及 `standard` 框架布局;`layout` 选择共享框架中的结构预设。可选的 `shared` 模式仅注入 CSS,不添加框架控件。 页头、操作按钮、失效提示/备用链接、侧栏和页脚统一由 `framework/mail/base/` 提供;结构预设位于 `framework/layouts/`,均属于框架,而非主题维护的邮件模板。`tools/builder/framework.go` 是唯一的官方操作值/翻译对齐层。通知分支、主题行、附件及上下文链接来自下载的官方模板,不得复制到各主题中。 ## 设计规范 - 主题仅定义展示样式,共享框架使用官方邮件值与翻译组织可复用控件。 - 主题使用兼容邮件客户端的 CSS,框架负责展示结构;主题 CSS 不加载外部资源、不生成文字、不隐藏官方内容。框架引用实例托管的 Logo 是有意保留的图片引用。 - 片段校验允许展示性的 table、tr、td、div、span 等节点及展示属性,检查桌面及 390px 移动端布局。 - 尽可能测试 Gmail、Outlook、Apple Mail;浏览器预览不能模拟所有客户端的 CSS 支持。 - 忠于原主题的配色、字体、边框、页头、按钮/备用链接及布局,不使用通用卡片或新增装饰替代既有设计。 - 画廊截图使用 PNG,单张最多 50 KiB,建议 10–20 KiB。截图须来自当前源码构建,并关闭浮动信息面板。 ## 更新官方快照 源码仅保留工具生成的 `gitea.lock.json`,记录稳定 Gitea 28+ 标签、不可变提交及文件校验值。官方模板、语言 JSON、图标、许可证和适配参考实现均下载到被忽略的 `build/upstream/`,不在仓库中维护副本。 ### 命令参考 以下命令均在 `tools/` 执行。三个子命令都支持 `--root <仓库根目录>`,默认值为相对当前工作目录的 `..`;参数放在子命令之后,含空格的路径须加引号。 ```powershell # 在 tools/ 中显式指定仓库根目录: go run . upstream verify --root "D:\Work\Development\WebSites\GiteaMailTemplates" ``` | 命令 | 用途 | 联网与写入行为 | |---|---|---| | `go run . upstream prepare` | 根据仓库锁文件准备精确匹配的输入 | 缓存不存在时按锁定提交下载,验证 SHA-256 后创建 `build/upstream/`;缓存存在时离线校验。不修改根锁文件。 | | `go run . upstream verify` | 对照根锁文件检查已有缓存 | 离线、只读,不下载;输出 `[PASS]` 及非英文缺键的 `[FALLBACK]` 列表。 | | `go run . upstream sync --tag vX.Y.Z` | 显式选择上游版本 | 通过 GitHub API 解析标签,按提交下载并校验快照,替换缓存并生成 `gitea.lock.json`。仅接受主版本不小于 28 的稳定 `vX.Y.Z` 标签。 | 这些命令不支持隐式 `latest`、读取本地 Gitea 克隆、令牌参数或认证环境变量。`sync` 使用 `api.github.com`,首次 `prepare` 与 `sync` 下载使用 `raw.githubusercontent.com`;网络错误与 API 限流会报错,不会自动换版本。即使快照检查离线,Go 工具链与模块仍可能需要单独联网下载。 ### 已有克隆与离线使用 ```bash cd tools go mod download go run . upstream prepare go run . upstream verify go test ./... go run . preview all ``` `build all`、`preview all` 和 `dev` 会自动准备输入,但仍要求根锁文件存在。缓存完整且 Go 工具链/依赖已安装后可离线构建。`verify` 检查官方输入、适配参考实现哈希和官方英文键;框架新增键与操作锚点由构建和渲染检查,因此单独通过 `verify` 不代表兼容性验证完成。 ### 锁文件缺失与显式更新版本 缺少 `gitea.lock.json` 时,`prepare`、`verify`、构建与预览均在读取锁文件时失败,即使 `build/upstream/lock.json` 仍在也不会代用。普通源码克隆应恢复受版本控制的根锁文件;有意首次初始化时,`sync` 不要求已有根锁文件: ```bash cd tools # 当前源码基线;显式初始化,不是发布操作: go run . upstream sync --tag v28.0.0 go run . upstream verify go test ./... go run . preview all ``` 评审其它版本时显式替换标签,例如此处仍为 [PENDING] 的 `v28.1.0`。检查生成的锁文件差异,对齐共享框架与测试数据,执行全部检查及同版本实例冒烟测试后,再更新兼容性文档。`sync` 不构建主题、不更新 Markdown、不创建 Git 标签、不提交、不推送,也不发布。仅缓存缺失时不应使用它。 翻译或邮件渲染参考实现哈希变化会阻止同步,须先复核 Go 适配逻辑;下载新版本并不等于确认兼容。官方英文须包含官方模板引用的键,构建另行检查框架键;其它语言缺键回退英文。缓存替换前的网络/校验失败不会修改原输入。缓存替换和根锁文件写入是两个操作:文件系统错误可能留下不一致状态,后续校验会失败,重试前先检查二者。 ### 缓存恢复 `prepare` 拒绝损坏、不完整或锁文件不匹配的缓存,不合并、不静默修复;`sync` 也拒绝替换非空的无效快照。检查错误后,将精确的生成缓存目录移到备份位置,再按已复核的根锁文件执行 `prepare`。例如在 **仓库根目录的 PowerShell** 中,选择尚不存在的备份名称: ```powershell Move-Item -LiteralPath .\build\upstream -Destination .\build\upstream.backup Set-Location tools go run . upstream prepare go run . upstream verify ``` 不要删除整个 `build/` 或修改缓存中的官方文件。显式同步后如需回退,恢复之前已复核的根锁文件,再按同样方式重建缓存。避免多个 `sync`/`prepare`/构建进程同时操作同一缓存;替换输入前先停止 `dev`。 邮件类型由快照发现,`tools/data/templates_config.json` 仅提供名称、描述和模拟上下文。新增官方邮件类型后,必须补充测试数据才能通过预览校验。 Gitea v28.0.0 的波兰语 `mail.team_invite.text_1` 存在已确认的占位符缺陷。预览保留官方行为并报告 `[UPSTREAM-WARN]`,例外严格匹配官方原文。其他格式错误会使渲染失败。不要直接修改语言快照来隐藏官方问题。 ## 本地开发 使用 **Go 1.24+**。CLI 依赖 urfave/cli,HTML 校验使用 Go 的 x/net 解析器。先执行 `go mod download` 和 `upstream prepare` 下载依赖及锁定输入,之后可离线构建。 ```bash cd tools go run . list go run . build all go run . preview all go run . dev # http://127.0.0.1:3456 ``` `build` 将安装文件写入 `build/themes/<名称>/mail/`。`preview` 同时完成构建,生成小型清单和每种官方语言各自的 JS 数据包。直接打开 `preview/index.html` 即可静态预览,语言加载支持 `file://`。 回环开发服务器监听主题 CSS/元数据、共享框架、锁文件/缓存和测试数据,通过 SSE 刷新。安装模板的 Logo 引用 `{{AppUrl}}assets/img/favicon.png`;仅静态预览的生成数据嵌入下载的官方图标,以支持离线显示。 ## 验证与发布 测试检查框架适配与生成的确定性、操作锚点变化时失败、官方翻译键及通知语义保留。渲染覆盖全部主题/语言及推送、评审、回复、工作流和附件分支。控件及品牌区域是明确的展示增补;按钮文字、备用链接目标和 Logo 引用单独校验。 发布前,在与快照标签一致的隔离 Gitea 实例中触发真实的密码重置或通知邮件。管理后台的测试邮件按钮不会使用自定义模板。确认模板加载并捕获邮件,避免向真实用户发送测试内容。 可选的 `tools/integration` 测试使用临时 SQLite、用户、Git/SSH 路径及回环 SMTP 自动完成此流程。将 `GITEA_SMOKE_BINARY` 设为已校验官方 SHA-256、版本与快照一致的 Gitea 可执行文件,在 `tools/` 执行 `go test ./integration -v -count=1`。浏览器检查位于 `tools/qa`:生成预览后安装其可选依赖并运行 `npm test`;设置 `PREVIEW_DEV_URL` 可同时检查 HTTP 预览,`--update-gallery` 可更新截图。 发行标签须与快照中的 Gitea 版本一致,在 `.github/release-notes/vX.Y.Z.md` 添加已复核的说明。工作流校验快照和测试,打包生成主题、多语言预览、文档及官方许可证/来源信息,再更新发布标签区块。源码修改与已发布兼容矩阵保持区分;历史标签和附件不变。 手动打包时,先执行 `preview all`,再从仓库根目录运行 `python .github/scripts/package_release.py --version vX.Y.Z --output <新输出目录>`。发布工作流使用同一脚本;它校验源码/产物哈希和全部语言包,排除未声明的旧构建目录,并拒绝覆盖已有压缩包。 ## 报告问题 注明快照标签/提交、主题、邮件类型、预览语言和错误。先运行 `go run . upstream verify` 与 `go run . preview all`,附上截图或渲染诊断。 ## 提交规范 - `style(<名称>):` — 主题展示样式 - `preview:` — 浏览器预览 - `tools:` — CLI、构建及快照工具 - `docs:` — 文档和翻译 - `fix:` — 修复 - `refactor:` — 重构 - `chore:` — 维护 ## 翻译与许可证 - [English CONTRIBUTING](../CONTRIBUTING.md) - 简体中文(本文) 贡献以 MIT 许可证授权,分发派生模板时须保留 Gitea 版权及官方许可证。