docs(15-03): complete plan 03 — branch protection finalized (fast-checks + gate), publish.yml comment
This commit is contained in:
@@ -33,7 +33,7 @@ Make FamilySync configurable, administrable, and maintainable for real multi-mem
|
||||
- [ ] **Phase 12: Initial Setup Wizard** - First-run validated bootstrap of env/VAPID/DB/OIDC + first app password, reusing the admin route surface
|
||||
- [x] **Phase 13: Real Lint Gate (ESLint)** - Wire ESLint flat config (typescript-eslint + React) across both apps so the Phase 8 CI lint slot actually fails on violations instead of no-op'ing (completed 2026-06-12)
|
||||
- [x] **Phase 14: Desktop E2E Coverage** - Add a Desktop Chrome Playwright profile + make the mobile-authored specs desktop-safe so the Phase 8 regression gate validates desktop, not just mobile (completed 2026-06-12)
|
||||
- [ ] **Phase 15: Doc-Only CI Skip + Markdown Lint** - Aggregate-gate the slow api/harness CI jobs so doc-only PRs to main merge without running them (no branch-protection deadlock), and add markdownlint to `fast-checks` so docs get a fast format+lint gate (promoted from backlog 999.17)
|
||||
- [x] **Phase 15: Doc-Only CI Skip + Markdown Lint** - Aggregate-gate the slow api/harness CI jobs so doc-only PRs to main merge without running them (no branch-protection deadlock), and add markdownlint to `fast-checks` so docs get a fast format+lint gate (promoted from backlog 999.17) (completed 2026-06-12)
|
||||
|
||||
## Phase Details
|
||||
|
||||
@@ -292,7 +292,7 @@ Plans:
|
||||
|
||||
**Wave 3** *(blocked on Wave 2 completion)*
|
||||
|
||||
- [ ] 15-03-PLAN.md — operator branch-protection checkpoint (require `CI / fast-checks` + `CI / gate`, drop api/harness) + publish.yml comment update (SC-3)
|
||||
- [x] 15-03-PLAN.md — operator branch-protection checkpoint (require `CI / fast-checks` + `CI / gate`, drop api/harness) + publish.yml comment update (SC-3)
|
||||
|
||||
**UI hint**: no
|
||||
|
||||
@@ -314,7 +314,7 @@ Plans:
|
||||
| 12. Initial Setup Wizard | v1.1 | 0/? | Not started | - |
|
||||
| 13. Real Lint Gate (ESLint) | v1.1 | 3/3 | Complete | 2026-06-12 |
|
||||
| 14. Desktop E2E Coverage | v1.1 | 1/1 | Complete | 2026-06-12 |
|
||||
| 15. Doc-Only CI Skip + MD Lint | v1.1 | 2/3 | In Progress| |
|
||||
| 15. Doc-Only CI Skip + MD Lint | v1.1 | 3/3 | Complete | 2026-06-12 |
|
||||
|
||||
## Backlog
|
||||
|
||||
@@ -322,7 +322,7 @@ Plans:
|
||||
|
||||
**Goal:** [Captured for future planning] Abstract the calendar backend behind a provider interface so Fastmail/CalDAV is one implementation among potentially many. Shipping with a single provider is fine, but the broker, sync, and event-expansion layers should be structured so additional providers (e.g. other CalDAV hosts, Google Calendar, generic ICS feeds) can be added without rework. Captures the "provider" seam as an explicit architectural concern.
|
||||
**Requirements:** TBD
|
||||
**Plans:** 2/3 plans executed
|
||||
**Plans:** 3/3 plans complete
|
||||
|
||||
Plans:
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
phase: 15-ci-skip-api-harness-jobs-for-doc-only-prs
|
||||
plan: "03"
|
||||
subsystem: ci
|
||||
tags: [ci, gitea-actions, branch-protection, gate, doc-only-skip]
|
||||
dependency_graph:
|
||||
requires: [15-02]
|
||||
provides: [main branch protection requires fast-checks + gate, api/harness no longer required]
|
||||
affects: [.gitea/workflows/publish.yml, "Gitea branch protection (main) — admin state"]
|
||||
tech_stack:
|
||||
patterns:
|
||||
- Gitea branch-protection status_check_contexts via tea API
|
||||
key_files:
|
||||
modified:
|
||||
- .gitea/workflows/publish.yml
|
||||
decisions:
|
||||
- D-15-03-CTX-SUFFIX: Gitea status-check contexts carry a "(pull_request)" suffix; required checks set to "CI / fast-checks (pull_request)" + "CI / gate (pull_request)" — NOT the bare names the plan text suggested (bare names would deadlock — Gitea never emits them)
|
||||
- D-15-03-API-ENDPOINT: branch protection lives at repos/{owner}/{repo}/branch_protections/{name}, not branches/{name}/protection (latter 404s on this Gitea)
|
||||
metrics:
|
||||
completed_date: "2026-06-12"
|
||||
tasks_completed: 2
|
||||
tasks_total: 2
|
||||
files_modified: 1
|
||||
---
|
||||
|
||||
# Phase 15 Plan 03: Finalize gating surface Summary
|
||||
|
||||
**One-liner:** Updated `publish.yml`'s safety-gate comment to name the new required checks, then (post-merge, operator-authorized) changed Gitea branch protection on `main` to require exactly `CI / fast-checks (pull_request)` + `CI / gate (pull_request)` and drop the now-skippable `CI / api`/`CI / harness` — making doc-only PRs mergeable without a missing-required-check deadlock.
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
| Task | Name | Commit / Artifact | Files |
|
||||
|------|------|-------------------|-------|
|
||||
| 1 | Update publish.yml safety-gate comment to name new required checks | da623ac | .gitea/workflows/publish.yml |
|
||||
| 2 | Operator — update Gitea branch protection on main (drop api/harness, require gate) | Gitea admin state (tea API PATCH) | branch_protections/main |
|
||||
|
||||
## What Was Built
|
||||
|
||||
**Task 1 — publish.yml comment:**
|
||||
Edited only the safety-gate comment block (no job/step/env/trigger change). The comment now states that the required checks are `CI / fast-checks` and `CI / gate`, and that `CI / api`/`CI / harness` are conditionally skipped on doc-only PRs and gated via the always-running `CI / gate` aggregate. publish.yml still parses as valid YAML.
|
||||
|
||||
**Task 2 — branch protection (operator, executed post-merge):**
|
||||
After PR #11 merged to `main` (bringing the `gate` job) and `CI / gate (pull_request)` reported `success` on the PR run, the `main` branch-protection rule's `status_check_contexts` was set to:
|
||||
- `CI / fast-checks (pull_request)`
|
||||
- `CI / gate (pull_request)`
|
||||
|
||||
and `CI / api (pull_request)` + `CI / harness (pull_request)` were removed. Applied via:
|
||||
`tea api --method PATCH repos/luckberg/familysync/branch_protections/main --data '{"status_check_contexts":["CI / fast-checks (pull_request)","CI / gate (pull_request)"]}'`
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- **D-15-03-CTX-SUFFIX:** The live Gitea status-check contexts carry a `(pull_request)` suffix (e.g. `CI / gate (pull_request)`), as confirmed by the PR #11 commit-status API. The plan's how-to-verify named bare `CI / fast-checks`/`CI / gate`; using those would have required contexts Gitea never emits, re-creating the very deadlock this phase fixes. Required checks were therefore set with the suffix to match emitted reality.
|
||||
- **D-15-03-API-ENDPOINT:** Branch protection is read/written at `repos/{owner}/{repo}/branch_protections/{name}` on this Gitea (1.26.2); the older `branches/{name}/protection` path returns "not found".
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
- The operator action was performed via the `tea` API by the agent (operator-authorized "proceed") rather than via the Gitea UI by a human, and used the **suffixed** context names (D-15-03-CTX-SUFFIX) instead of the bare names in the plan text.
|
||||
- The throwaway doc-only / code PR live A/B test described in the plan's how-to-verify was replaced with: (a) live proof from PR #11 that all five jobs (`changes`/`fast-checks`/`api`/`harness`/`gate`) run and report `success` on a code PR (SC-2), and (b) static proof that the `changes` `code` filter matches no `docs/**` or root `*.md` path, so a doc-only PR yields `code=false` → `api`/`harness` skip → `gate` passes (SC-1/SC-3). The protection change was verified by re-reading the rule (required = fast-checks + gate; api/harness absent).
|
||||
|
||||
## Threat Model Coverage
|
||||
|
||||
| Threat | Mitigation | Status |
|
||||
|--------|-----------|--------|
|
||||
| T-15-08: leaving api/harness required after skip logic ships (deadlock) | both dropped from required checks; always-running `CI / gate` required instead | Implemented |
|
||||
| T-15-09: dropping heavy-job requirements before `CI / gate` exists (bypass window) | precondition confirmed — `CI / gate (pull_request)` reported `success` on PR #11 before any protection edit | Implemented |
|
||||
| T-15-10: publish.yml comment still claims api/harness required (false sense of gating) | Task 1 updated the comment to name `CI / fast-checks` + `CI / gate` | Implemented |
|
||||
|
||||
## Verification
|
||||
|
||||
- publish.yml: `CI / gate` and `CI / fast-checks` present; old "three required checks (… api, … harness)" line replaced; valid YAML (`publish` job intact).
|
||||
- Branch protection (re-GET after PATCH): `status_check_contexts == ['CI / fast-checks (pull_request)', 'CI / gate (pull_request)']`; api/harness no longer present; `enable_status_check: true`.
|
||||
- Precondition: PR #11 head commit-status shows `CI / gate (pull_request) => success`.
|
||||
- SC-1 (doc-only mergeable): static — `changes` `code` filter excludes `docs/**` + root `*.md`.
|
||||
- SC-2 (code PR gates all): live — PR #11 ran and gated on all jobs.
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- `.gitea/workflows/publish.yml` modified (comment): EXISTS
|
||||
- Commit da623ac (Task 1): FOUND
|
||||
- Branch protection required checks = fast-checks + gate, api/harness dropped: VERIFIED via tea API
|
||||
Reference in New Issue
Block a user