Use slash-free CMS pilot branch

This commit is contained in:
Kevin
2026-09-04 01:17:42 -04:00
parent 93090ecf87
commit 357a0f0dc1
4 changed files with 30 additions and 19 deletions
+11 -3
View File
@@ -9,13 +9,21 @@ The repository implementation targets these fixed public values:
| Setting | Value | | Setting | Value |
| --- | --- | | --- | --- |
| Gitea repository | `SloanOps/3031023-xyz` | | Gitea repository | `SloanOps/3031023-xyz` |
| Decap write branch | `cms/pilot` | | Decap write branch | `cms-pilot` |
| Planned live write branch | `cms` |
| Gitea base URL | `https://git.sloanops.com` | | Gitea base URL | `https://git.sloanops.com` |
| Gitea API root | `https://git.sloanops.com/api/v1` | | Gitea API root | `https://git.sloanops.com/api/v1` |
| Stable CMS origin | `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev` | | Stable CMS origin | `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev` |
| Exact OAuth redirect URI | `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/admin/` | | Exact OAuth redirect URI | `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/admin/` |
| Required status context | `CMS content validation / cms-content-validation (pull_request)` | | Required status context | `CMS content validation / cms-content-validation (pull_request)` |
The pilot and planned live branch names are intentionally slash-free. Decap
CMS 3.15.1 inserts the configured Gitea branch directly into its tree-API URL;
a slash-named branch such as `cms/pilot` is split as an API path and its 404 is
presented as an empty collection. The permanent `cms` branch is still a
non-production staging branch: changes reach `main` only through the protected
pull-request flow.
The Workers alias was confirmed after the first approved preview deployment. The Workers alias was confirmed after the first approved preview deployment.
If Cloudflare later assigns a different stable origin, If Cloudflare later assigns a different stable origin,
update the repository configuration, CORS origin, and OAuth redirect URI update the repository configuration, CORS origin, and OAuth redirect URI
@@ -140,7 +148,7 @@ directly into the flat uploads directory, and the local verifier rejects nested
media paths. Gitea file patterns are case-insensitive; CI verifies actual file media paths. Gitea file patterns are case-insensitive; CI verifies actual file
signatures and the 500 KiB limit before a preview can upload. signatures and the 500 KiB limit before a preview can upload.
Everything not listed is protected from CMS/client pushes on `cms/pilot` and Everything not listed is protected from CMS/client pushes on `cms-pilot` and
on every differently named branch, including: on every differently named branch, including:
```text ```text
@@ -169,7 +177,7 @@ altered by choosing another branch name.
## Verification before an editor invitation ## Verification before an editor invitation
1. Run `npm ci`, `npm run verify:cms`, and both site build/verifier pairs. 1. Run `npm ci`, `npm run verify:cms`, and both site build/verifier pairs.
2. Create `cms/pilot` from the reviewed baseline only after approval. 2. Create `cms-pilot` from the reviewed baseline only after approval.
3. Apply both protection rules together and confirm `main` is priority 1 and 3. Apply both protection rules together and confirm `main` is priority 1 and
`*` is priority 2. `*` is priority 2.
4. Use the same non-operator account intended for Decap to prove allowed 4. Use the same non-operator account intended for Decap to prove allowed
+17 -14
View File
@@ -1,6 +1,6 @@
# Decap CMS Gitea pilot # Decap CMS Gitea pilot
Status: preview-only pilot infrastructure is active on `cms/pilot`: the stable Status: preview-only pilot infrastructure is active on `cms-pilot`: the stable
preview, narrow Gitea CORS policy, public PKCE OAuth application, and two preview, narrow Gitea CORS policy, public PKCE OAuth application, and two
repository protection rules are configured. Nothing has been merged to repository protection rules are configured. Nothing has been merged to
`main`, and production remains unchanged. `main`, and production remains unchanged.
@@ -62,7 +62,7 @@ the pilot:
configuration for both site builds. configuration for both site builds.
- The shell pins Decap CMS `3.15.1` by exact URL and verified SHA-384 integrity - The shell pins Decap CMS `3.15.1` by exact URL and verified SHA-384 integrity
value rather than a floating release range. value rather than a floating release range.
- The backend is fixed to `SloanOps/3031023-xyz` and `cms/pilot` and contains - The backend is fixed to `SloanOps/3031023-xyz` and `cms-pilot` and contains
only the public client ID for the non-confidential Gitea PKCE application. only the public client ID for the non-confidential Gitea PKCE application.
- All four Markdown collections and every persisted frontmatter field are - All four Markdown collections and every persisted frontmatter field are
modeled with the current Astro/Zod bounds. Markdown controls are text-first; modeled with the current Astro/Zod bounds. Markdown controls are text-first;
@@ -78,9 +78,8 @@ the pilot:
now prove preview robots rules and page metadata stay no-index and that the now prove preview robots rules and page metadata stay no-index and that the
admin response has a no-index header rule. admin response has a no-index header rule.
This preparation does not make the CMS usable yet: the placeholder public The pilot dependencies are active: the public client ID, exact-origin CORS
client ID, unapplied CORS setting, absent `cms/pilot` remote branch, and absent policy, `cms-pilot` branch, and both protection rules have been verified.
branch rules are intentional review gates.
## Proposed pilot architecture ## Proposed pilot architecture
@@ -89,7 +88,7 @@ Decap at /admin/
| |
| Gitea PKCE OAuth and content/media commits only | Gitea PKCE OAuth and content/media commits only
v v
cms/pilot branch cms-pilot branch
| |
+--> primary no-index Worker preview +--> primary no-index Worker preview
| |
@@ -110,7 +109,7 @@ is acceptable because both sites belong to the same root-domain repository and
the same owner. One Decap configuration exposes clearly labeled Primary Site the same owner. One Decap configuration exposes clearly labeled Primary Site
and Journal collection groups. and Journal collection groups.
Expected preview URLs for branch `cms/pilot`: Preview URLs for branch `cms-pilot`:
- `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/admin/` - `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/admin/`
- `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/` - `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/`
@@ -213,10 +212,14 @@ Preview deployment remains branch-specific and may use the existing Worker
workflows. Cloudflare credentials stay scoped to the deployment step; content workflows. Cloudflare credentials stay scoped to the deployment step; content
validation does not need them. validation does not need them.
Because Decap writes to a fixed `cms/pilot` branch, SloanOps creates the pull Because Decap writes to a fixed `cms-pilot` branch, SloanOps creates the pull
request in Gitea. After an approved merge, synchronize the CMS branch with request in Gitea. After an approved merge, synchronize the CMS branch with
`main` before the next editing cycle. Do not automate production merge. `main` before the next editing cycle. Do not automate production merge.
If the pilot is accepted, replace the disposable branch with a 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 ## Gitea and Decap setup
1. Add a non-confidential Gitea OAuth application for the exact preview 1. Add a non-confidential Gitea OAuth application for the exact preview
@@ -224,11 +227,11 @@ request in Gitea. After an approved merge, synchronize the CMS branch with
2. Enable Gitea API CORS for the exact approved preview origin or origins. 2. Enable Gitea API CORS for the exact approved preview origin or origins.
Allow only required methods and headers, including `Authorization` and Allow only required methods and headers, including `Authorization` and
`Content-Type`; do not use a wildcard origin. `Content-Type`; do not use a wildcard origin.
3. Create `cms/pilot` from the reviewed repository baseline. 3. Create `cms-pilot` from the reviewed repository baseline.
4. Review the pinned Decap admin assets beneath `public/admin/`. Do not replace 4. Review the pinned Decap admin assets beneath `public/admin/`. Do not replace
the exact version and integrity value with a floating range. the exact version and integrity value with a floating range.
5. Configure the Gitea backend for `SloanOps/3031023-xyz` and branch 5. Configure the Gitea backend for `SloanOps/3031023-xyz` and branch
`cms/pilot`. `cms-pilot`.
6. Model every persisted frontmatter field with limits matching 6. Model every persisted frontmatter field with limits matching
`src/content.config.ts`. Do not let a CMS save silently remove an existing `src/content.config.ts`. Do not let a CMS save silently remove an existing
field. field.
@@ -249,7 +252,7 @@ not record OAuth tokens or Cloudflare credentials.
| DC-02 | Open each preview `/admin/` route | Admin shell loads and remains no-index. | | DC-02 | Open each preview `/admin/` route | Admin shell loads and remains no-index. |
| DC-03 | Authenticate with the approved operator account | PKCE login succeeds and the configured collections load. | | DC-03 | Authenticate with the approved operator account | PKCE login succeeds and the configured collections load. |
| DC-04 | Authenticate with an account without repository write access | Repository editing is unavailable. | | DC-04 | Authenticate with an account without repository write access | Repository editing is unavailable. |
| DC-05 | Edit an existing draft journal post | One content-only commit lands on `cms/pilot`; the blog preview rebuilds. | | DC-05 | Edit an existing draft journal post | One content-only commit lands on `cms-pilot`; the blog preview rebuilds. |
| DC-06 | Create, edit, and delete a disposable journal post | Filename, dates, tags, body, draft state, and cleanup remain schema-valid. | | DC-06 | Create, edit, and delete a disposable journal post | Filename, dates, tags, body, draft state, and cleanup remain schema-valid. |
| DC-07 | Edit a primary FAQ | Only the primary preview rebuilds and displays the change. | | 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-08 | Edit service ordering and featured state | YAML types remain correct and the primary verifier passes. |
@@ -259,10 +262,10 @@ not record OAuth tokens or Cloudflare credentials.
| 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-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-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. | | DC-14 | Attempt a direct push to `main` | Gitea rejects it. |
| DC-15 | Open a pull request from `cms/pilot` to `main` | Both sites validate; required review and merge controls are present. | | DC-15 | Open a pull request from `cms-pilot` to `main` | Both sites validate; required review and merge controls are present. |
| DC-16 | Attempt to merge without status or approval | Gitea blocks the merge. | | DC-16 | Attempt to merge without status or approval | Gitea blocks the merge. |
| DC-17 | Inspect both preview responses | Expected routes work; preview metadata/headers prevent indexing; production remains unchanged. | | DC-17 | Inspect both preview responses | Expected routes work; preview metadata/headers prevent indexing; production remains unchanged. |
| DC-18 | Revert the disposable CMS changes on `cms/pilot` | Preview returns to baseline without changing either public site. | | DC-18 | Revert the disposable CMS changes on `cms-pilot` | Preview returns to baseline without changing either public site. |
| DC-19 | Refresh, sign out, reauthenticate, and let a session expire | Session behavior is understandable and no unsaved-content loss is observed. | | 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. | | DC-20 | Review commit attribution and audit history | Gitea identifies the editor and the exact content/media changes. |
@@ -292,7 +295,7 @@ account control over executable deployment files.
If the pilot is rejected or paused: If the pilot is rejected or paused:
1. Revert or delete disposable changes on `cms/pilot`. 1. Revert or delete disposable changes on `cms-pilot`.
2. Delete the two disposable preview aliases/versions if desired; do not delete 2. Delete the two disposable preview aliases/versions if desired; do not delete
production Workers or retained legacy rollback resources. production Workers or retained legacy rollback resources.
3. Revoke/delete the Decap OAuth application. 3. Revoke/delete the Decap OAuth application.
+1 -1
View File
@@ -1,7 +1,7 @@
backend: backend:
name: gitea name: gitea
repo: SloanOps/3031023-xyz repo: SloanOps/3031023-xyz
branch: cms/pilot branch: cms-pilot
app_id: c07dba05-eb09-48f0-8da4-6df775a13995 app_id: c07dba05-eb09-48f0-8da4-6df775a13995
api_root: https://git.sloanops.com/api/v1 api_root: https://git.sloanops.com/api/v1
base_url: https://git.sloanops.com base_url: https://git.sloanops.com
+1 -1
View File
@@ -21,7 +21,7 @@ const expectedOrigin = 'https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev';
const expectedBackend = { const expectedBackend = {
name: 'gitea', name: 'gitea',
repo: 'SloanOps/3031023-xyz', repo: 'SloanOps/3031023-xyz',
branch: 'cms/pilot', branch: 'cms-pilot',
api_root: 'https://git.sloanops.com/api/v1', api_root: 'https://git.sloanops.com/api/v1',
base_url: 'https://git.sloanops.com', base_url: 'https://git.sloanops.com',
auth_endpoint: 'https://git.sloanops.com/login/oauth/authorize', auth_endpoint: 'https://git.sloanops.com/login/oauth/authorize',