Files
GiteaMailTemplates/CONTRIBUTING.md
T
KenanZhu fec3ace600
Release / Validate Templates (push) Canceled after 0s
Release / Package & Release (push) Canceled after 0s
Release / Update Latest Release Documentation (push) Canceled after 0s
chore: migrate mail themes to shared framework and locked upstream inputs
2026-10-09 18:34:36 +08:00

11 KiB
Raw Blame History

Contributing to Gitea Mail Templates

Adding a Theme

  1. Run cd tools && go run . create <name> to create a framework-backed theme.
  2. Edit themes/<name>/theme.json and theme.css.
  3. Run go run . upstream prepare, go test ./... and go run . preview all from tools/.
  4. Check desktop/mobile previews in English, Simplified Chinese and another official language; submit screenshots with the PR.

Theme names use lowercase letters, digits and hyphens, starting with a letter. Themes contain only theme.json and theme.css. New themes default to framed with the standard layout; layout selects a structural preset from the shared framework. The optional shared mode remains CSS-only and does not add framework controls.

Shared header, action button, fallback URL, sidebar and footer controls live in framework/mail/base/. Structural presets live in framework/layouts/; they are framework code, not theme-owned mail templates. tools/builder/framework.go is the single alignment layer for official primary-action values and translations. Notification branches, subjects, attachments and contextual links come from downloaded official templates. Do not copy business logic into a theme.

Design Guidelines

  • Theme sources define presentation only; the shared framework organizes official mail values and translations into reusable controls.
  • Use email-compatible CSS in theme sources and presentation markup in the framework. Theme CSS cannot load external resources, generate text or hide official content; the framework's instance-hosted logo is an intentional exception to external-image avoidance.
  • The fragment validator permits tables, table rows/cells, divs and spans with presentation attributes. Review desktop and 390px mobile layouts.
  • Test Gmail, Outlook and Apple Mail where available. Browser preview does not simulate every mail client's CSS support.
  • Preserve the original theme's colors, fonts, borders, header treatment, button/fallback controls and layout. Do not replace established designs with generic cards or invented decorations.
  • Gallery screenshots must be PNG, at most 50 KiB each; 10–20 KiB is preferred. Capture the current source build with the floating inspector closed.

Official Snapshot Updates

Only the tool-generated gitea.lock.json is committed: stable Gitea 28+ tag, immutable commit and file checksums. Official templates, locale JSON files, favicon, license and adapter reference sources are downloaded to ignored build/upstream/. Do not maintain copies in the source repository.

Command Reference

Run the following commands from tools/. All three subcommands accept --root <repository-root> (default: .., relative to the working directory); place this flag after the subcommand. Paths containing spaces must be quoted.

# From tools/, with an explicit repository root:
go run . upstream verify --root "D:\Work\Development\WebSites\GiteaMailTemplates"
Command Purpose Network and writes
go run . upstream prepare Read the repository lock and prepare its exact inputs If no cache exists, download files by locked commit, validate SHA-256 and create build/upstream/; otherwise verify the existing cache offline. Never changes the root lock.
go run . upstream verify Audit the existing cache against the root lock Offline, read-only; does not download files. Reports [PASS] and non-English missing-key [FALLBACK] lists.
go run . upstream sync --tag vX.Y.Z Explicitly select an upstream version Resolve the tag through the GitHub API, download by resolved commit and validate the snapshot; replace the cache and generate gitea.lock.json. Requires a stable vX.Y.Z tag with major version 28 or later.

There is no implicit latest, local Gitea checkout input, token flag or authentication environment-variable support in these commands. Downloads use api.github.com (sync) and raw.githubusercontent.com (sync/first prepare); network errors and API rate limits are failures, not permission to change versions. Go may separately need network access for its toolchain/modules, even when snapshot verification itself is offline.

Existing Clone and Offline Use

cd tools
go mod download
go run . upstream prepare
go run . upstream verify
go test ./...
go run . preview all

build all, preview all and dev invoke preparation automatically. They still require the root lock. A complete verified cache and already installed Go dependencies/toolchain allow offline builds. verify checks official inputs, adapter reference hashes and official English keys; framework-added keys/action anchors are checked by build and rendering, so verify alone is not a compatibility certification.

Missing Lock and Explicit Version Updates

If gitea.lock.json is missing, prepare, verify, build and preview fail when opening it—even if build/upstream/lock.json remains. The cache lock is not a substitute. Restore the tracked root lock for a normal clone. For intentional initialization, sync does not require a prior root lock:

cd tools
# Current source baseline; explicit initialization, not a release operation:
go run . upstream sync --tag v28.0.0
go run . upstream verify
go test ./...
go run . preview all

To review another version, replace the tag explicitly (for example, v28.1.0, still [PENDING] here). Review the generated lock diff, align the shared framework and fixtures, run all checks and the matching-instance smoke test, then update compatibility documentation. sync does not build themes, update Markdown, create Git tags, commit, push or publish a release. It must not be run merely to fix a missing cache.

Changed translation or mail-renderer reference hashes block synchronization until the Go adapter is reviewed; downloading a newer version is not enough to approve it. Official English must contain all official template keys; builds additionally validate framework keys. Other languages fall back to English. Validation/network failures before cache replacement leave existing inputs unchanged. Cache replacement and writing the root lock are separate operations: if a filesystem failure leaves them inconsistent, subsequent verification fails; inspect both before retrying.

Cache Recovery

prepare refuses corrupt, incomplete or lock-mismatched caches; it does not merge or silently repair them. sync also refuses to replace a non-empty invalid snapshot. After inspecting the error, preserve the exact generated cache directory by moving it aside, then run prepare using the reviewed root lock. For example, in PowerShell from the repository root, choose an unused backup name:

Move-Item -LiteralPath .\build\upstream -Destination .\build\upstream.backup
Set-Location tools
go run . upstream prepare
go run . upstream verify

Do not remove the whole build/ directory or edit cached official files. To restore a previous version after a deliberate sync, restore its reviewed root lock and rebuild the cache in the same way. Avoid simultaneous sync/prepare/build processes against one cache; stop dev while replacing inputs.

Mail types are discovered from the snapshot. tools/data/templates_config.json supplies names, descriptions and mock contexts only. A new official mail type requires a fixture before preview can pass.

Gitea v28.0.0 has a reviewed Polish mail.team_invite.text_1 placeholder defect. Preview preserves official behavior and reports [UPSTREAM-WARN]; the exception matches the exact official text. Other formatting errors fail rendering. Do not edit locale snapshots to conceal upstream defects.

Local Development

Use Go 1.24+. The CLI uses urfave/cli; HTML validation uses Go's x/net HTML parser. Run go mod download and upstream prepare once; subsequent verified builds work offline.

cd tools
go run . list
go run . build all
go run . preview all
go run . dev
# http://127.0.0.1:3456

build writes installable files to build/themes/<name>/mail/. preview also builds them, then writes a small manifest and one JS bundle per official language. Open preview/index.html directly for static preview; its language loader supports file://.

The loopback development server watches theme CSS/metadata, shared framework, lock/cache and fixtures. It rebuilds in-process and sends SSE reloads. Installable logos reference {{AppUrl}}assets/img/favicon.png; only the generated static preview embeds the downloaded official icon for offline display.

Verification and Release

Tests check deterministic framework adaptation and generation, fail-closed action anchors, official keys and preserved notification semantics. Rendering tests cover all themes/languages and push, review, reply, workflow and attachment branches. Shared controls/branding are explicit presentation additions; button labels, fallback targets and logo references are validated separately.

Before a release, use an isolated Gitea instance matching the locked tag and trigger a real password-reset or notification email. The administration test-email button bypasses custom templates. Confirm template loading and capture the rendered mail without sending to real users.

The optional tools/integration test automates this with disposable SQLite, users, Git/SSH paths and loopback SMTP. Set GITEA_SMOKE_BINARY to a checksum-verified official binary of the locked version, then run go test ./integration -v -count=1 from tools/. Optional browser QA lives in tools/qa: install its dependencies, then run npm test after generating preview data; PREVIEW_DEV_URL includes HTTP preview checks and --update-gallery refreshes screenshots.

Release tags must match the snapshot's Gitea version. Add reviewed notes at .github/release-notes/vX.Y.Z.md. The workflow verifies the lock and tests, packages generated themes, multilingual preview, documentation and upstream license/provenance, then updates marked release labels. Keep source-only work separate from the published compatibility matrix. Existing historical tags and assets are unchanged.

From the repository root, run python .github/scripts/package_release.py --version vX.Y.Z --output <new-output-directory> after preview all for manual packaging. The same script is used by the release workflow. It verifies source/generated hashes and all language bundles, excludes undeclared stale build directories, and refuses to overwrite existing archives.

Reporting Problems

Include the snapshot tag/commit, theme, email type, preview language and error. Run go run . upstream verify and go run . preview all first; attach screenshots or the relevant render diagnostic.

Commit Conventions

  • style(<name>): — theme presentation
  • preview: — browser preview
  • tools: — CLI/build/snapshot tooling
  • docs: — documentation and translations
  • fix: — bug fixes
  • refactor: — restructuring
  • chore: — maintenance

Translations and License

Contributions are licensed under MIT. Retain Gitea copyright and the upstream license when distributing derived templates.