Optimize CMS images during builds

This commit is contained in:
Kevin
2026-09-04 12:11:09 -04:00
parent 80dd0e0904
commit dd6fae06c9
11 changed files with 136 additions and 22 deletions
+14 -7
View File
@@ -74,7 +74,8 @@ staging branch:
replace, or remove an image reference while retaining accessible image
descriptions and a layout fallback. URL insertion and SVG paths are
rejected. Builds additionally verify the extension, raster signature, flat
upload path, and 500 KiB limit.
upload path, and a 25 MiB source safety ceiling. Every build re-encodes the
public copy to at most 1920 pixels and 500 KiB and removes embedded metadata.
- `.gitea/workflows/cms-content-validation.yml` runs on every pull request into
`main`, uses no secrets, and reports
`CMS content validation / cms-content-validation (pull_request)` after
@@ -151,10 +152,16 @@ Do not expose `sites.json`, either `site.json`, schemas, workflows, Wrangler
configuration, package files, source components, scripts, contact routing, or
analytics through the CMS during this pilot.
Configure the default media library with a conservative file-size limit. Do
not accept executables, archives, HTML, scripts, or SVG uploads. Asset rights,
alt text, crop, dimensions, and optimization remain operator review items even
when the CMS accepts an upload.
Configure image fields with a 25 MiB source safety limit so ordinary camera
photos can be uploaded. Do not accept executables, archives, HTML, scripts, or
SVG uploads. The repository verifier applies the same safety ceiling to every
upload, including files added through Decap's standalone media gallery.
The build re-encodes every uploaded raster without changing its public URL. It
auto-orients and scales the deployed copy to at most 1920 pixels, targets a
500 KiB output ceiling, and strips EXIF and other embedded metadata. The source
file stays unchanged in the private repository. Asset rights, alt text, and
crop remain operator review items.
Decap's image widget applies its field `pattern` to the selected file's base
name, not to the repository-relative media path. Keep that UI pattern limited
@@ -286,8 +293,8 @@ not record OAuth tokens or Cloudflare credentials.
| DC-07 | Edit a primary FAQ | Only the primary preview rebuilds and displays the change. |
| DC-08 | Edit service ordering and featured state | YAML types remain correct and the primary verifier passes. |
| DC-09 | Add, replace, and remove a team portrait | The selected upload renders in the team card; removal uses the initials fallback. |
| DC-10 | Upload a bounded raster image and select it in the fixed page-image record | File lands only in the approved media path and renders on the relevant primary preview page. |
| DC-11 | Attempt an oversized upload and a disallowed file type | The CMS size limit rejects the oversized file before upload; Gitea's unprotected-extension patterns reject the disallowed path. |
| DC-10 | Upload a camera-sized raster image and select it in the fixed page-image record | File lands only in the approved media path; its deployed copy is at most 1920 pixels and 500 KiB, contains no embedded metadata, and renders on the relevant primary preview page. |
| DC-11 | Attempt an upload over 25 MiB and a disallowed file type | The source safety limit rejects the oversized file; Gitea's unprotected-extension patterns reject the disallowed path. |
| DC-12 | Attempt to modify `.gitea/workflows/**`, source, package, script, schema, Wrangler, and site-manifest paths with the CMS account | Gitea rejects every push. |
| DC-13 | Attempt to create a differently named branch and change a protected file | The fallback rule rejects the push; branch naming cannot bypass protection. |
| DC-14 | Attempt a direct push to `main` | Gitea rejects it. |