Record completed internal CMS rollout
This commit is contained in:
+84
-50
@@ -1,19 +1,21 @@
|
||||
# Decap CMS Gitea pilot and promotion
|
||||
|
||||
Status: the preview-only pilot was accepted for promotion to the permanent
|
||||
`cms` staging branch on 2026-09-04. Repository configuration now targets the
|
||||
predicted stable `cms` preview origin. CORS and OAuth must be changed together
|
||||
only after that first preview confirms the alias. Nothing has been merged to
|
||||
`main`, and production remains unchanged.
|
||||
Status: completed and operational for internal SloanOps use as of 2026-09-04.
|
||||
The reviewed CMS application is deployed from `main`, Decap writes only to the
|
||||
protected `cms` staging branch, and the final Journal date-control repair is
|
||||
present on both branches. Production deployments from the approved merge
|
||||
completed successfully.
|
||||
|
||||
This remains an internal capability for `sloanops.admin`, not a public feature
|
||||
or a client-editing offer. No client account has been invited.
|
||||
|
||||
Updated: 2026-09-04
|
||||
|
||||
## Purpose
|
||||
|
||||
Use the `3031023.xyz` demonstration repository to determine whether
|
||||
Decap CMS can provide a useful editing interface for all sites owned under one
|
||||
root domain without allowing an editor to publish directly to production or
|
||||
modify deployment code.
|
||||
Record and operate the Decap CMS editing interface for both sites in the
|
||||
`3031023.xyz` demonstration repository without allowing an editor to publish
|
||||
directly to production or modify deployment code.
|
||||
|
||||
The pilot covers both the primary Happy Tails site and its journal subdomain.
|
||||
That matches the SloanOps repository boundary: one private repository per root
|
||||
@@ -21,8 +23,9 @@ domain, with independently built sites beneath `sites/`. A future client who
|
||||
owns the root-domain site also owns the hosted subdomains represented in that
|
||||
repository.
|
||||
|
||||
This plan does not authorize a production merge, domain change, contact-form
|
||||
activation, repository invitation, or removal of a rollback resource.
|
||||
The completed internal rollout does not authorize public discovery, a client
|
||||
repository invitation, contact-form changes, a broader OAuth grant, or removal
|
||||
of a rollback resource.
|
||||
|
||||
## Current evidence
|
||||
|
||||
@@ -41,6 +44,13 @@ activation, repository invitation, or removal of a rollback resource.
|
||||
writes directly to the configured branch.
|
||||
- The Gitea backend does not support Git LFS. Pilot media must remain small,
|
||||
ordinary repository assets.
|
||||
- The approved `sloanops.admin` account can authenticate at the production
|
||||
admin route, load all collections, and write through the `cms` branch.
|
||||
- Gitea rejects protected-file pushes to `cms` and direct pushes to `main`;
|
||||
operator code/configuration changes therefore use pull requests as well.
|
||||
- Arbitrary branch-preview hostnames are deliberately absent from the OAuth
|
||||
redirect and CORS allowlists. Login from one returns `Unregistered Redirect
|
||||
URI`; rendered branch previews remain usable without expanding OAuth.
|
||||
|
||||
References:
|
||||
|
||||
@@ -56,8 +66,8 @@ recorded in [Decap CMS pilot: Gitea settings](decap-cms-gitea-setup.md).
|
||||
|
||||
## Repository implementation
|
||||
|
||||
The reviewed pilot implementation is the baseline for the permanent `cms`
|
||||
staging branch:
|
||||
The reviewed production implementation and permanent `cms` staging branch
|
||||
provide the following controls:
|
||||
|
||||
- `public/admin/` provides a permanently no-index admin shell and one shared
|
||||
configuration for both site builds.
|
||||
@@ -68,6 +78,10 @@ staging branch:
|
||||
- All four Markdown content collections and every persisted frontmatter field
|
||||
are modeled with the current Astro/Zod bounds. Markdown controls remain
|
||||
text-first; embedded images and general file widgets are absent.
|
||||
- Journal publish and optional updated dates use the supported Decap
|
||||
`datetime` widget in date-only UTC mode. New posts default to the current UTC
|
||||
date, and the verifier rejects the unsupported `date` widget that caused the
|
||||
original create/update failures.
|
||||
- A fixed image-only Markdown record controls the primary home, About,
|
||||
Services, and Contact page imagery without exposing either `site.json`.
|
||||
- Team and page-image fields accept optional bounded uploads. Editors can add,
|
||||
@@ -94,11 +108,11 @@ staging branch:
|
||||
repository cache without trusting a mutable tag or refreshing GitHub on every
|
||||
job.
|
||||
|
||||
The pilot dependencies were verified on `cms-pilot`. The same protection rules
|
||||
apply to `cms`; its exact-origin CORS and OAuth values are the remaining
|
||||
operator-controlled promotion step.
|
||||
The pilot dependencies were verified on `cms-pilot`, promoted to the permanent
|
||||
`cms` branch, and deployed to `main`. Exact-origin CORS, PKCE OAuth, branch
|
||||
protection, previews, validation, and production deployment are all applied.
|
||||
|
||||
## Proposed pilot architecture
|
||||
## Operating architecture
|
||||
|
||||
```text
|
||||
Decap at /admin/
|
||||
@@ -126,16 +140,17 @@ is acceptable because both sites belong to the same root-domain repository and
|
||||
the same owner. One Decap configuration exposes clearly labeled Primary Site
|
||||
and Journal collection groups.
|
||||
|
||||
Predicted preview URLs for branch `cms`:
|
||||
Confirmed stable preview URLs for branch `cms`:
|
||||
|
||||
- `https://cms-3031023-xyz-www.ksloan90.workers.dev/admin/`
|
||||
- `https://cms-3031023-xyz-www.ksloan90.workers.dev/`
|
||||
- `https://cms-3031023-xyz-blog.ksloan90.workers.dev/`
|
||||
|
||||
Confirm the aliases from the successful Gitea Actions run rather than treating
|
||||
these predicted URLs as authoritative.
|
||||
The production admin entry is `https://3031023.xyz/admin/`. Use the stable
|
||||
`cms` admin origin or the production admin entry for interactive CMS testing;
|
||||
do not use arbitrary branch aliases for OAuth login.
|
||||
|
||||
## Initial Decap scope
|
||||
## Internal Decap scope
|
||||
|
||||
Allow editing and creation only within these collections:
|
||||
|
||||
@@ -248,34 +263,30 @@ Preview deployment remains branch-specific and may use the existing Worker
|
||||
workflows. Cloudflare credentials stay scoped to the deployment step; content
|
||||
validation does not need them.
|
||||
|
||||
Because Decap writes to a fixed `cms` branch, SloanOps creates the pull
|
||||
request in Gitea. After an approved merge, synchronize the CMS branch with
|
||||
`main` before the next editing cycle. Do not automate production merge.
|
||||
Because Decap writes to a fixed `cms` branch, SloanOps creates the pull request
|
||||
from `cms` to `main` in Gitea. Internal CMS application/configuration changes
|
||||
start from the current `cms` state, enter protected `cms` through an
|
||||
operator-reviewed pull request, and are then promoted with the staged content.
|
||||
After an approved `main` merge, synchronize its merge commit back into `cms`
|
||||
through a protected-branch pull request before the next editing cycle. Do not
|
||||
automate production merge.
|
||||
|
||||
The accepted pilot is promoted by replacing the disposable branch with the
|
||||
permanent, slash-free `cms` branch. It remains a preview/staging branch and
|
||||
retains the same pull-request, validation, and approval path into `main`.
|
||||
|
||||
## Gitea and Decap setup
|
||||
## Routine operating sequence
|
||||
|
||||
1. Add a non-confidential Gitea OAuth application for the exact preview
|
||||
`/admin/` redirect URI or URIs. Store only the public client ID in Decap.
|
||||
2. Enable Gitea API CORS for the exact approved preview origin or origins.
|
||||
Allow only required methods and headers, including `Authorization` and
|
||||
`Content-Type`; do not use a wildcard origin.
|
||||
3. Create `cms` from the reviewed repository baseline.
|
||||
4. Review the pinned Decap admin assets beneath `public/admin/`. Do not replace
|
||||
the exact version and integrity value with a floating range.
|
||||
5. Configure the Gitea backend for `SloanOps/3031023-xyz` and branch
|
||||
`cms`.
|
||||
6. Model every persisted frontmatter field with limits matching
|
||||
`src/content.config.ts`. Do not let a CMS save silently remove an existing
|
||||
field.
|
||||
7. Apply and verify the `main` and fallback branch protections before inviting
|
||||
or testing a non-operator editor.
|
||||
8. Add the secret-free pull-request validation workflow.
|
||||
9. Push only the review branch and confirm both no-index preview builds before
|
||||
any CMS login test.
|
||||
1. Edit through an approved admin origin and confirm the commit lands only on
|
||||
`cms` in an allowed content or media path.
|
||||
2. Confirm the affected no-index Worker version preview succeeds.
|
||||
3. Run the local CMS verifier and both site build/verifier pairs before any
|
||||
operator-authored CMS application or configuration PR into `cms`.
|
||||
4. Review the complete staged diff and open `cms` to `main`.
|
||||
5. Require the stable secret-free validation status and SloanOps approval.
|
||||
6. Merge deliberately and confirm the affected production Worker jobs pass.
|
||||
7. Synchronize the resulting `main` merge commit back into protected `cms`
|
||||
before another editing cycle.
|
||||
|
||||
## Test matrix
|
||||
|
||||
@@ -305,13 +316,36 @@ not record OAuth tokens or Cloudflare credentials.
|
||||
| DC-19 | Refresh, sign out, reauthenticate, and let a session expire | Session behavior is understandable and no unsaved-content loss is observed. |
|
||||
| DC-20 | Review commit attribution and audit history | Gitea identifies the editor and the exact content/media changes. |
|
||||
|
||||
Do not merge DC-15 during the initial infrastructure and editing test. A later
|
||||
harmless demo-content merge requires explicit approval and repeats both public
|
||||
site checks after deployment.
|
||||
The initial no-merge restriction applied only while the pilot was being
|
||||
evaluated. Promotion is now allowed through the protected workflow above; each
|
||||
release still requires explicit review and repeats both public site checks.
|
||||
|
||||
## Acceptance criteria
|
||||
## Completion record — 2026-09-04
|
||||
|
||||
Accept the pilot only when:
|
||||
- PR #1 launched the no-index Decap shell and Gitea-backed collections.
|
||||
- PRs #2 and #3 tightened image filename validation and added bounded,
|
||||
metadata-stripping build optimization.
|
||||
- PRs #4 and #5 synchronized the reviewed implementation into `cms` and then
|
||||
promoted it to `main`.
|
||||
- Disposable Journal, page-image, and FAQ edits exposed workflow and schema
|
||||
behavior; the test content was reverted and the temporary FAQ was removed.
|
||||
- PR #9 consolidated the rollback history and resynchronized the branches.
|
||||
- Failed Journal content runs were traced to Decap's unsupported `date` widget.
|
||||
PR #10 replaced it with date-only `datetime` controls, defaulted new publish
|
||||
dates, and added a verifier regression guard.
|
||||
- PR #11 synchronized the final repair into protected `cms` after the direct
|
||||
protected-file push was correctly rejected.
|
||||
- CMS validation and both site builds passed locally. The PR #10 required
|
||||
validation passed, and production blog run 342 plus primary run 343 both
|
||||
completed successfully.
|
||||
- The deployed Journal editor was opened at `3031023.xyz/admin/`; Publish date
|
||||
displayed a populated UTC date and Updated date displayed an optional date
|
||||
control. No post was saved during this final smoke test.
|
||||
|
||||
## Operating acceptance boundary
|
||||
|
||||
The internal pilot was accepted against these controls. Re-evaluate them before
|
||||
any client rollout:
|
||||
|
||||
- both site families are understandable in one CMS;
|
||||
- content edits preserve every modeled field and pass Astro validation;
|
||||
@@ -329,7 +363,7 @@ account control over executable deployment files.
|
||||
|
||||
## Rollback and cleanup
|
||||
|
||||
If the pilot is rejected or paused:
|
||||
If the internal CMS is paused:
|
||||
|
||||
1. Revert or delete disposable changes on `cms`.
|
||||
2. Delete the two disposable preview aliases/versions if desired; do not delete
|
||||
@@ -341,7 +375,7 @@ If the pilot is rejected or paused:
|
||||
6. Remove or retain branch protections deliberately; never weaken `main` as
|
||||
cleanup.
|
||||
|
||||
## Implementation estimate
|
||||
## Historical implementation estimate
|
||||
|
||||
Expected hands-on implementation time: **6–9 hours**, normally one focused
|
||||
working day. Budget up to two elapsed days if OAuth/CORS behavior or Gitea
|
||||
|
||||
Reference in New Issue
Block a user