Promote Decap staging branch to cms
This commit is contained in:
@@ -1,23 +1,23 @@
|
|||||||
# Decap CMS pilot: Gitea settings
|
# Decap CMS: Gitea settings
|
||||||
|
|
||||||
Status: applied to the preview-only pilot on 2026-09-04. The stable preview,
|
Status: the preview-only pilot was accepted for promotion on 2026-09-04. The
|
||||||
narrow CORS policy, public PKCE OAuth application, and both branch-protection
|
repository now targets the permanent `cms` staging branch. Update the exact
|
||||||
rules are active. Nothing has been merged to `main`.
|
CORS origin and PKCE OAuth redirect only after its first preview deployment
|
||||||
|
confirms the predicted alias. Nothing has been merged to `main`.
|
||||||
|
|
||||||
The repository implementation targets these fixed public values:
|
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` |
|
||||||
| 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-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-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
|
The pilot and permanent branch names are intentionally slash-free. Decap
|
||||||
CMS 3.15.1 inserts the configured Gitea branch directly into its tree-API URL;
|
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
|
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
|
presented as an empty collection. The permanent `cms` branch is still a
|
||||||
@@ -38,7 +38,7 @@ through the normal infrastructure change process:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- GITEA__cors__ENABLED=true
|
- GITEA__cors__ENABLED=true
|
||||||
- GITEA__cors__ALLOW_DOMAIN=https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev
|
- GITEA__cors__ALLOW_DOMAIN=https://cms-3031023-xyz-www.ksloan90.workers.dev
|
||||||
- GITEA__cors__METHODS=GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
|
- GITEA__cors__METHODS=GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
|
||||||
- GITEA__cors__MAX_AGE=10m
|
- GITEA__cors__MAX_AGE=10m
|
||||||
- GITEA__cors__ALLOW_CREDENTIALS=false
|
- GITEA__cors__ALLOW_CREDENTIALS=false
|
||||||
@@ -56,7 +56,7 @@ token or cookie:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl --request OPTIONS 'https://git.sloanops.com/api/v1/version' \
|
curl --request OPTIONS 'https://git.sloanops.com/api/v1/version' \
|
||||||
--header 'Origin: https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev' \
|
--header 'Origin: https://cms-3031023-xyz-www.ksloan90.workers.dev' \
|
||||||
--header 'Access-Control-Request-Method: GET' \
|
--header 'Access-Control-Request-Method: GET' \
|
||||||
--header 'Access-Control-Request-Headers: authorization,content-type'
|
--header 'Access-Control-Request-Headers: authorization,content-type'
|
||||||
```
|
```
|
||||||
@@ -71,10 +71,10 @@ behavior before continuing.
|
|||||||
The Gitea OAuth2 application was created after the stable preview origin and
|
The Gitea OAuth2 application was created after the stable preview origin and
|
||||||
CORS response were verified:
|
CORS response were verified:
|
||||||
|
|
||||||
- Application name: `3031023.xyz Decap CMS pilot`.
|
- Application name: `3031023.xyz Decap CMS`.
|
||||||
- Confidential client: **unchecked**. The browser client must use PKCE.
|
- Confidential client: **unchecked**. The browser client must use PKCE.
|
||||||
- Redirect URI: exactly
|
- Redirect URI: exactly
|
||||||
`https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/admin/`, including the
|
`https://cms-3031023-xyz-www.ksloan90.workers.dev/admin/`, including the
|
||||||
trailing slash.
|
trailing slash.
|
||||||
- Do not add wildcards, localhost, either production hostname, or the journal
|
- Do not add wildcards, localhost, either production hostname, or the journal
|
||||||
preview as additional redirects.
|
preview as additional redirects.
|
||||||
@@ -148,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` and
|
||||||
on every differently named branch, including:
|
on every differently named branch, including:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@@ -177,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` 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
|
||||||
|
|||||||
+26
-24
@@ -1,8 +1,9 @@
|
|||||||
# Decap CMS Gitea pilot
|
# Decap CMS Gitea pilot and promotion
|
||||||
|
|
||||||
Status: preview-only pilot infrastructure is active on `cms-pilot`: the stable
|
Status: the preview-only pilot was accepted for promotion to the permanent
|
||||||
preview, narrow Gitea CORS policy, public PKCE OAuth application, and two
|
`cms` staging branch on 2026-09-04. Repository configuration now targets the
|
||||||
repository protection rules are configured. Nothing has been merged to
|
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.
|
`main`, and production remains unchanged.
|
||||||
|
|
||||||
Updated: 2026-09-04
|
Updated: 2026-09-04
|
||||||
@@ -55,14 +56,14 @@ recorded in [Decap CMS pilot: Gitea settings](decap-cms-gitea-setup.md).
|
|||||||
|
|
||||||
## Repository implementation
|
## Repository implementation
|
||||||
|
|
||||||
The `review/decap-cms-pilot` branch now contains the repository-side portion of
|
The reviewed pilot implementation is the baseline for the permanent `cms`
|
||||||
the pilot:
|
staging branch:
|
||||||
|
|
||||||
- `public/admin/` provides a permanently no-index admin shell and one shared
|
- `public/admin/` provides a permanently no-index admin shell and one shared
|
||||||
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` 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 content collections and every persisted frontmatter field
|
- All four Markdown content collections and every persisted frontmatter field
|
||||||
are modeled with the current Astro/Zod bounds. Markdown controls remain
|
are modeled with the current Astro/Zod bounds. Markdown controls remain
|
||||||
@@ -88,8 +89,9 @@ the pilot:
|
|||||||
by its former auto-detected private address. Warm jobs reuse dependency
|
by its former auto-detected private address. Warm jobs reuse dependency
|
||||||
tarballs without caching `node_modules`.
|
tarballs without caching `node_modules`.
|
||||||
|
|
||||||
The pilot dependencies are active: the public client ID, exact-origin CORS
|
The pilot dependencies were verified on `cms-pilot`. The same protection rules
|
||||||
policy, `cms-pilot` branch, and both protection rules have been verified.
|
apply to `cms`; its exact-origin CORS and OAuth values are the remaining
|
||||||
|
operator-controlled promotion step.
|
||||||
|
|
||||||
## Proposed pilot architecture
|
## Proposed pilot architecture
|
||||||
|
|
||||||
@@ -98,7 +100,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 branch
|
||||||
|
|
|
|
||||||
+--> primary no-index Worker preview
|
+--> primary no-index Worker preview
|
||||||
|
|
|
|
||||||
@@ -119,11 +121,11 @@ 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.
|
||||||
|
|
||||||
Preview URLs for branch `cms-pilot`:
|
Predicted preview URLs for branch `cms`:
|
||||||
|
|
||||||
- `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/admin/`
|
- `https://cms-3031023-xyz-www.ksloan90.workers.dev/admin/`
|
||||||
- `https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev/`
|
- `https://cms-3031023-xyz-www.ksloan90.workers.dev/`
|
||||||
- `https://cms-pilot-3031023-xyz-blog.ksloan90.workers.dev/`
|
- `https://cms-3031023-xyz-blog.ksloan90.workers.dev/`
|
||||||
|
|
||||||
Confirm the aliases from the successful Gitea Actions run rather than treating
|
Confirm the aliases from the successful Gitea Actions run rather than treating
|
||||||
these predicted URLs as authoritative.
|
these predicted URLs as authoritative.
|
||||||
@@ -229,13 +231,13 @@ 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` 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,
|
The accepted pilot is promoted by replacing the disposable branch with the
|
||||||
slash-free `cms` branch. It remains a preview/staging branch and retains the
|
permanent, slash-free `cms` branch. It remains a preview/staging branch and
|
||||||
same pull-request, validation, and approval path into `main`.
|
retains the same pull-request, validation, and approval path into `main`.
|
||||||
|
|
||||||
## Gitea and Decap setup
|
## Gitea and Decap setup
|
||||||
|
|
||||||
@@ -244,11 +246,11 @@ same pull-request, validation, and approval path into `main`.
|
|||||||
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` 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`.
|
||||||
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.
|
||||||
@@ -269,7 +271,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`; 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. |
|
||||||
@@ -279,10 +281,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` 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 disposable CMS changes on `cms` | 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. |
|
||||||
|
|
||||||
@@ -312,7 +314,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`.
|
||||||
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,15 +1,15 @@
|
|||||||
backend:
|
backend:
|
||||||
name: gitea
|
name: gitea
|
||||||
repo: SloanOps/3031023-xyz
|
repo: SloanOps/3031023-xyz
|
||||||
branch: cms-pilot
|
branch: cms
|
||||||
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
|
||||||
auth_endpoint: https://git.sloanops.com/login/oauth/authorize
|
auth_endpoint: https://git.sloanops.com/login/oauth/authorize
|
||||||
|
|
||||||
publish_mode: simple
|
publish_mode: simple
|
||||||
site_url: https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev
|
site_url: https://cms-3031023-xyz-www.ksloan90.workers.dev
|
||||||
display_url: https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev
|
display_url: https://cms-3031023-xyz-www.ksloan90.workers.dev
|
||||||
show_preview_links: false
|
show_preview_links: false
|
||||||
|
|
||||||
media_folder: public/images/uploads
|
media_folder: public/images/uploads
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ function expectSubset(actual, expected, path) {
|
|||||||
|
|
||||||
const configPath = 'public/admin/config.yml';
|
const configPath = 'public/admin/config.yml';
|
||||||
const config = yaml.load(await readFile(configPath, 'utf8'));
|
const config = yaml.load(await readFile(configPath, 'utf8'));
|
||||||
const expectedOrigin = 'https://cms-pilot-3031023-xyz-www.ksloan90.workers.dev';
|
const expectedOrigin = 'https://cms-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',
|
||||||
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',
|
||||||
|
|||||||
Reference in New Issue
Block a user