From 1f6af9dd0a0872509caae217b03efbf4b4a92588 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 6 Jun 2026 09:31:19 -0500 Subject: [PATCH 1/2] chore: move CLAUDE.md to .mokogitea/ directory Relocate CLAUDE.md from repo root to .mokogitea/ per project convention. Content updated with focused, repo-specific architecture and rules. Co-Authored-By: Claude Opus 4.6 (1M context) --- .mokogitea/CLAUDE.md | 42 ++++++++++++++++++++++++++++++++++++++++++ AGENTS.md | 16 ---------------- CLAUDE.md | 1 - 3 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 .mokogitea/CLAUDE.md delete mode 100644 AGENTS.md delete mode 100644 CLAUDE.md diff --git a/.mokogitea/CLAUDE.md b/.mokogitea/CLAUDE.md new file mode 100644 index 0000000000..b43f3124aa --- /dev/null +++ b/.mokogitea/CLAUDE.md @@ -0,0 +1,42 @@ +# MokoGitea + +Fork of Gitea — self-hosted Git service at git.mokoconsulting.tech. Go backend + TypeScript frontend. + +## Quick Reference + +| Field | Value | +|---|---| +| **Language** | Go 1.26+ / TypeScript | +| **Module** | `code.mokoconsulting.tech/MokoConsulting/MokoGitea` | +| **Branch** | develop on `dev`, merge to `main` (protected) | +| **Wiki** | [MokoGitea Wiki](https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/wiki) | + +## Commands + +```bash +make help # List all available targets +make fmt # Format .go files +make lint-go # Lint Go code +make lint-js # Lint TypeScript +make tidy # After go.mod changes +make build # Build binary + +# Testing +go test -run '^TestName$' ./modulepath/ # Single Go test +pnpm exec vitest # Single JS test +GITEA_TEST_E2E_FLAGS='' make test-e2e # Single Playwright test +``` + +## Rules + +- Add current year copyright header on new `.go` files +- No trailing whitespace in edited files +- Conventional Commits for commit messages and PR titles +- Never force-push, amend, or squash unless asked — use new commits +- Preserve existing code comments +- TypeScript: use `!` (non-null assertion) not `?.`/`??` when value is known to exist +- CSS: prefer `flex-*` helpers over per-child `tw-ml-*`/`tw-mr-*` margins +- Add `Co-Authored-By` lines to all commits +- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) +- **Attribution**: `Authored-by: Moko Consulting` +- **Standards**: [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home) diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 16770e49fc..0000000000 --- a/AGENTS.md +++ /dev/null @@ -1,16 +0,0 @@ -- Use `make help` to find available development targets -- Run `make fmt` to format `.go` files, and run `make lint-go` to lint them -- Run `make lint-js` to lint `.ts` files -- Run `make tidy` after any `go.mod` changes -- Run single go tests with `go test -run '^TestName$' ./modulepath/` -- Run single js test files with `pnpm exec vitest ` -- Run single playwright e2e test files with `GITEA_TEST_E2E_FLAGS='' make test-e2e` -- Add the current year into the copyright header of new `.go` files -- Ensure no trailing whitespace in edited files -- Use Conventional Commits format for commit messages and PR titles (e.g. `type(scope): subject`) -- Never force-push, amend, or squash unless asked. Use new commits and normal push for pull request updates -- Preserve existing code comments, do not remove or rewrite comments that are still relevant -- In TypeScript, use `!` (non-null assertion) instead of `?.`/`??` when a value is known to always exist -- For CSS layout, prefer `flex-*` helpers over per-child `tw-ml-*` / `tw-mr-*` margins; fall back to `tw-*` utilities when specificity requires `!important` -- Include authorship attribution in issue and pull request comments -- Add `Co-Authored-By` lines to all commits, indicating name and model used diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 43c994c2d3..0000000000 --- a/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@AGENTS.md -- 2.52.0 From dd6e114c706463f7c660c01a3e87e39e8231ebbe Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 6 Jun 2026 09:43:15 -0500 Subject: [PATCH 2/2] chore: move CLAUDE.md to .mokogitea/ directory Also includes: - Auto-sync manifest.xml to DB on push to default branch - Wiki pages for custom fields, custom statuses, manifest settings - Updated wiki home page with all current features Co-Authored-By: Claude Opus 4.6 (1M context) --- services/repository/manifest_sync.go | 98 +++++++++++++++++++ services/repository/push.go | 2 + wiki/custom-fields.md | 136 +++++++++++++++++++++++++++ wiki/custom-issue-statuses.md | 107 +++++++++++++++++++++ wiki/home.md | 50 ++++++++++ wiki/manifest-settings.md | 111 ++++++++++++++++++++++ 6 files changed, 504 insertions(+) create mode 100644 services/repository/manifest_sync.go create mode 100644 wiki/custom-fields.md create mode 100644 wiki/custom-issue-statuses.md create mode 100644 wiki/home.md create mode 100644 wiki/manifest-settings.md diff --git a/services/repository/manifest_sync.go b/services/repository/manifest_sync.go new file mode 100644 index 0000000000..1b65a71825 --- /dev/null +++ b/services/repository/manifest_sync.go @@ -0,0 +1,98 @@ +// Copyright 2026 Moko Consulting +// SPDX-License-Identifier: GPL-3.0-or-later + +package repository + +import ( + "context" + "encoding/xml" + + repo_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/repo" + "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/git" + "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log" +) + +// manifestXML mirrors the .mokogitea/manifest.xml schema for XML parsing. +type manifestXML struct { + XMLName xml.Name `xml:"moko-platform"` + Identity manifestIdentity `xml:"identity"` + Governance manifestGovernance `xml:"governance"` + Build manifestBuild `xml:"build"` +} + +type manifestIdentity struct { + Name string `xml:"name"` + Org string `xml:"org"` + Description string `xml:"description"` + Version string `xml:"version"` + License manifestLicense `xml:"license"` +} + +type manifestLicense struct { + SPDX string `xml:"spdx,attr"` + Name string `xml:",chardata"` +} + +type manifestGovernance struct { + Platform string `xml:"platform"` + StandardsVersion string `xml:"standards-version"` + StandardsSource string `xml:"standards-source"` +} + +type manifestBuild struct { + Language string `xml:"language"` + PackageType string `xml:"package-type"` + EntryPoint string `xml:"entry-point"` +} + +// SyncManifestFromCommit reads .mokogitea/manifest.xml from the given commit +// and upserts the values into the repo_manifest database table. +// This is called on push to the default branch to keep the database in sync +// with the XML file. If no manifest.xml exists, this is a no-op. +func SyncManifestFromCommit(ctx context.Context, repo *repo_model.Repository, commit *git.Commit) { + if commit == nil { + return + } + + entry, err := commit.GetTreeEntryByPath(".mokogitea/manifest.xml") + if err != nil || entry == nil { + return // no manifest.xml — not an error + } + + reader, err := entry.Blob().DataAsync() + if err != nil { + log.Error("SyncManifest: read blob for %s: %v", repo.FullName(), err) + return + } + defer reader.Close() + + var mxml manifestXML + decoder := xml.NewDecoder(reader) + if err := decoder.Decode(&mxml); err != nil { + log.Error("SyncManifest: parse XML for %s: %v", repo.FullName(), err) + return + } + + manifest := &repo_model.RepoManifest{ + RepoID: repo.ID, + Name: mxml.Identity.Name, + Org: mxml.Identity.Org, + Description: mxml.Identity.Description, + Version: mxml.Identity.Version, + LicenseSPDX: mxml.Identity.License.SPDX, + LicenseName: mxml.Identity.License.Name, + Platform: mxml.Governance.Platform, + StandardsVersion: mxml.Governance.StandardsVersion, + StandardsSource: mxml.Governance.StandardsSource, + Language: mxml.Build.Language, + PackageType: mxml.Build.PackageType, + EntryPoint: mxml.Build.EntryPoint, + } + + if err := repo_model.CreateOrUpdateRepoManifest(ctx, manifest); err != nil { + log.Error("SyncManifest: save for %s: %v", repo.FullName(), err) + return + } + + log.Info("SyncManifest: synced .mokogitea/manifest.xml for %s", repo.FullName()) +} diff --git a/services/repository/push.go b/services/repository/push.go index aa598c669f..5519da1409 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -193,6 +193,8 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { if err := DelRepoDivergenceFromCache(ctx, repo.ID); err != nil { log.Error("DelRepoDivergenceFromCache: %v", err) } + // Auto-sync .mokogitea/manifest.xml to database on default branch push + SyncManifestFromCommit(ctx, repo, newCommit) } else { if err := DelDivergenceFromCache(repo.ID, branch); err != nil { log.Error("DelDivergenceFromCache: %v", err) diff --git a/wiki/custom-fields.md b/wiki/custom-fields.md new file mode 100644 index 0000000000..2df4d869c8 --- /dev/null +++ b/wiki/custom-fields.md @@ -0,0 +1,136 @@ +# Custom Fields + +Custom fields allow organizations to define structured metadata that appears in issue sidebars and repository settings across all repos in the organization. + +## Overview + +Custom fields are defined at the **organization level** in Org Settings > Custom Fields. Each field has a scope: + +- **Issue scope** — appears in the issue sidebar for inline editing +- **Repo scope** — appears in Repository Settings > Metadata for repo-level values + +## Field Types + +| Type | Description | Example | +|------|-------------|---------| +| `text` | Free-form text input | "Affected Component" | +| `number` | Numeric input | "Story Points" | +| `date` | Date picker | "Due Date" | +| `dropdown` | Select from predefined options | "Priority: Low/Medium/High/Critical" | +| `checkbox` | Boolean toggle | "Requires QA" | +| `url` | URL input | "Design Link" | + +## Org Settings + +Navigate to **Organization Settings > Custom Fields** to manage field definitions. + +Each field has: + +| Field | Description | +|-------|-------------| +| Name | Display name | +| Scope | `issue` (sidebar) or `repo` (metadata) | +| Type | One of: text, number, date, dropdown, checkbox, url | +| Options | JSON array for dropdown options (e.g., `["Low","Medium","High"]`) | +| Description | Help text (shown as tooltip) | +| Sort Order | Controls display order | +| Is Active | Inactive fields are hidden from new forms but preserved on existing entities | + +## Issue Sidebar + +Issue-scoped fields appear in the sidebar between labels and milestones. Dropdown fields auto-submit on change. Text/number/date fields display their current value. + +Each field renders as an inline form posting to: +``` +POST /{owner}/{repo}/issues/{issue_id}/custom-fields/{field_id} +``` + +## Repository Metadata + +Repo-scoped fields appear on the **Repository Settings > Metadata** page. All fields for the org are shown with their current values for the repository. Values are saved via form POST. + +## Issue Template Integration + +Custom fields can be pre-filled from issue template YAML frontmatter: + +```yaml +name: Bug Report +about: Report a bug +custom_fields: + Priority: High + Affected Component: Backend +``` + +When a new issue is created from this template, the sidebar shows the custom fields with the specified defaults pre-selected. + +## API + +### Issue-Level Custom Fields + +| Method | Path | Description | +|--------|------|-------------| +| GET | `/api/v1/repos/{owner}/{repo}/issues/{index}/custom-fields` | Get field values for an issue | +| PUT | `/api/v1/repos/{owner}/{repo}/issues/{index}/custom-fields` | Set field values (name-value map) | + +### Repo-Level Metadata + +| Method | Path | Description | +|--------|------|-------------| +| GET | `/api/v1/repos/{owner}/{repo}/metadata` | Get repo metadata field values | +| PUT | `/api/v1/repos/{owner}/{repo}/metadata` | Set repo metadata field values | + +### Org-Level Definitions + +| Method | Path | Description | +|--------|------|-------------| +| GET | `/api/v1/orgs/{org}/custom-fields` | List all field definitions | +| POST | `/api/v1/orgs/{org}/custom-fields` | Create a field definition | +| DELETE | `/api/v1/orgs/{org}/custom-fields/{id}` | Delete a field definition | + +## Database + +### Tables + +**`custom_field_def`** — field definitions (org-level) + +| Column | Type | Description | +|--------|------|-------------| +| id | bigint | Primary key | +| owner_id | bigint | Org ID (0 = legacy repo-level) | +| repo_id | bigint | 0 for org-level definitions | +| scope | varchar(10) | `issue` or `repo` | +| name | varchar | Field name | +| field_type | varchar(20) | text, number, date, dropdown, checkbox, url | +| description | text | Help text | +| options | text | JSON array for dropdown options | +| required | bool | Whether the field is required | +| sort_order | int | Display order | +| is_active | bool | Visibility flag | + +**`custom_field_value`** — field values (per entity) + +| Column | Type | Description | +|--------|------|-------------| +| id | bigint | Primary key | +| entity_id | bigint | Issue ID or Repo ID | +| entity_type | varchar(10) | `issue` or `repo` | +| field_id | bigint | FK to custom_field_def | +| value | text | The stored value | + +### Cascade on Delete + +When a field definition is deleted, all associated values in `custom_field_value` are also deleted. + +## Relationship to Other Systems + +| System | Relationship | +|--------|-------------| +| Update Server | Repo-scoped custom fields with specific names (Extension Name, Display Name, etc.) are read by the update feed generators as the highest-priority metadata source. | +| Manifest Settings | Manifest fields follow the moko-platform schema and are separate from custom fields. Custom fields are user-defined; manifest fields are standardized. | +| Issue Statuses | Custom statuses are a separate feature with their own dedicated table and UI, not implemented as custom fields. | + +--- + +| Revision | Date | Author | Description | +|---|---|---|---| +| 1.0 | 2026-06-06 | Jonathan Miller (@jmiller) | Initial version | diff --git a/wiki/custom-issue-statuses.md b/wiki/custom-issue-statuses.md new file mode 100644 index 0000000000..8077e4d880 --- /dev/null +++ b/wiki/custom-issue-statuses.md @@ -0,0 +1,107 @@ +# Custom Issue Statuses + +Custom issue statuses extend Gitea's binary Open/Closed model with org-defined workflow states. Each status has a name, color, and an optional "closes issue" flag that triggers automatic close/reopen when selected. + +## Overview + +Statuses are defined at the **organization level** and appear in the issue sidebar for all repositories under that organization. This is the same pattern as org-level labels and custom fields. + +### Key Concepts + +- **Status definitions** are managed in Org Settings > Issue Statuses +- **Status selection** appears as a dropdown in the issue sidebar +- **Auto close/reopen** — selecting a status with `closes_issue = true` automatically closes the issue; switching to a non-closing status reopens it +- **Status is supplemental** — the existing Open/Closed binary state is preserved; statuses add granularity on top + +## Org Settings + +Navigate to **Organization Settings > Issue Statuses** to manage status definitions. + +Each status has: + +| Field | Description | +|-------|-------------| +| Name | Display name (e.g., "In Progress", "Won't Fix", "Blocked") | +| Color | Hex color for visual distinction (e.g., `#2563eb`) | +| Description | Help text shown to users | +| Closes Issue | When checked, selecting this status automatically closes the issue | +| Sort Order | Controls display order in dropdowns (ascending) | +| Is Active | Inactive statuses are hidden from dropdowns but preserved on existing issues | + +### Example Statuses + +| Status | Color | Closes Issue | Use Case | +|--------|-------|:------------:|----------| +| In Progress | Blue | No | Work is actively being done | +| Needs Info | Yellow | No | Waiting for more information from reporter | +| Blocked | Red | No | Cannot proceed due to external dependency | +| Won't Fix | Gray | Yes | Decided not to address this issue | +| Duplicate | Purple | Yes | Already tracked in another issue | +| Resolved | Green | Yes | Fix has been implemented and verified | + +## Issue Sidebar + +When an organization has custom statuses defined, a **Status** dropdown appears in the issue sidebar between labels and custom fields. The dropdown: + +- Shows all active status definitions for the repo's organization +- Auto-submits on change (no save button needed) +- Displays a colored left border on each option +- Shows a power symbol on statuses that close the issue +- Selecting "—" (empty) clears the status + +### Auto Close/Reopen Behavior + +| Current State | Selected Status | Result | +|:---:|---|---| +| Open | Status with `closes_issue = true` | Issue is closed automatically | +| Closed | Status with `closes_issue = false` | Issue is reopened automatically | +| Open | Status with `closes_issue = false` | Status set, issue stays open | +| Closed | Status with `closes_issue = true` | Status set, issue stays closed | + +All close/reopen actions go through the standard Gitea service layer, so webhooks, notifications, and timeline events fire normally. + +## Database + +### Tables + +**`issue_status_def`** (migration v346) — org-level status definitions + +| Column | Type | Description | +|--------|------|-------------| +| id | bigint | Primary key | +| org_id | bigint | Organization ID | +| name | varchar | Status name | +| color | varchar(7) | Hex color | +| description | text | Help text | +| closes_issue | bool | Auto-close flag | +| sort_order | int | Display order | +| is_active | bool | Visibility flag | + +**`issue`** table — added `status_id` column (bigint, default 0) + +### Cascade on Delete + +When a status definition is deleted, all issues referencing it have their `status_id` set to 0 (cleared). Issues are not closed or reopened during deletion. + +## Routes + +### Web Routes (Org Settings) + +| Method | Path | Handler | +|--------|------|---------| +| GET | `/org/{org}/settings/issue-statuses` | `SettingsIssueStatuses` | +| POST | `/org/{org}/settings/issue-statuses` | `SettingsIssueStatusesCreatePost` | +| POST | `/org/{org}/settings/issue-statuses/{id}/edit` | `SettingsIssueStatusesEditPost` | +| POST | `/org/{org}/settings/issue-statuses/{id}/delete` | `SettingsIssueStatusesDeletePost` | + +### Web Routes (Issue Sidebar) + +| Method | Path | Handler | +|--------|------|---------| +| POST | `/{owner}/{repo}/issues/{id}/custom-status` | `UpdateIssueCustomStatus` | + +--- + +| Revision | Date | Author | Description | +|---|---|---|---| +| 1.0 | 2026-06-06 | Jonathan Miller (@jmiller) | Initial version | diff --git a/wiki/home.md b/wiki/home.md new file mode 100644 index 0000000000..89d80177e5 --- /dev/null +++ b/wiki/home.md @@ -0,0 +1,50 @@ +# MokoGitea + +Moko Consulting's custom fork of [Gitea](https://gitea.com), extending the self-hosted Git service with commercial licensing, update feeds, custom issue workflows, and org-level management features. + +| Field | Value | +|-----|-----| +| **Language** | Go | +| **License** | MIT | +| **Upstream** | Gitea 1.26.1 | +| **Version** | v1.26.1-moko.06.04.00 | +| **Platform** | [Gitea](https://git.mokoconsulting.tech/MokoConsulting/MokoGitea) | + +--- + +## Features + +- **Commercial License System** — Package-based license keys with download gating, domain restriction, key expiry, and payment webhook API +- **Update Server** — Built-in update feeds for Joomla, WordPress, Dolibarr, Composer, Drupal, PrestaShop, and WHMCS +- **Custom Issue Statuses** — Org-defined workflow states (In Progress, Blocked, Won't Fix) with auto close/reopen +- **Custom Fields** — Org-level field definitions for issues (sidebar) and repos (metadata) with dropdown, text, number, date, checkbox, and URL types +- **Manifest Settings** — Per-repo identity/governance/build metadata with REST API for CI/CD integration +- **Well-Known File Tabs** — README/LICENSE/CONTRIBUTING/SECURITY/CHANGELOG tabs on repo home page +- **Org-Level Branch Protection** — Organization-scoped rulesets that cascade to all repos. Supports glob patterns. Full CRUD API +- **Enterprise Sub-Orgs** — Parent-child organization hierarchy +- **Three-Level Visibility** — Public (200), Private (403), Hidden (404) for repositories +- **Configurable Help/Support URLs** — Replace hardcoded docs.gitea.com links via HELP_URL and SUPPORT_URL in app.ini +- **Project Board API** — REST API endpoints for managing project boards, columns, and cards +- **Custom branding** — Moko Consulting visual identity (logos, colors, footer) + +## Pages + +| Page | Description | +|---|---| +| [Branding](Branding) | Custom branding and visual identity details | +| [Custom Fields](Custom-Fields) | Org-level custom fields for issues and repos | +| [Custom Issue Statuses](Custom-Issue-Statuses) | Org-defined workflow states with auto close/reopen | +| [Deployment](Deployment) | Production deployment guide | +| [Manifest Settings](Manifest-Settings) | Per-repo manifest settings and REST API | +| [Org Branch Protection API](Org-Branch-Protection-API) | Org-level branch protection rulesets and API reference | +| [Project API](Project-API) | Custom API endpoint reference for project boards | +| [Roadmap](Roadmap) | Development roadmap and planned features | + +--- + +| Revision | Date | Author | Description | +|---|---|---|---| +| 4.0 | 2026-06-06 | Jonathan Miller (@jmiller) | Add manifest settings, custom statuses, custom fields, well-known tabs, update version to v1.26.1-moko.06.04.00 | +| 3.0 | 2026-05-12 | Jonathan Miller (@jmiller) | Add org branch protection, help URLs, version convention | +| 2.0 | 2026-05-10 | Jonathan Miller (@jmiller) | Rewrite with detailed features and fork documentation | +| 1.0 | 2026-05-09 | Jonathan Miller (@jmiller) | Initial version | diff --git a/wiki/manifest-settings.md b/wiki/manifest-settings.md new file mode 100644 index 0000000000..393c16f01f --- /dev/null +++ b/wiki/manifest-settings.md @@ -0,0 +1,111 @@ +# Manifest Settings + +The manifest settings feature provides a centralized way to store and manage project identity, governance, and build metadata for each repository. Settings are stored in the database and exposed via both a web UI and REST API. + +## Overview + +Each repository can have a manifest that describes: + +- **Identity** — project name, organization, description, version, and license +- **Governance** — platform type, moko-platform standards version, and standards source URL +- **Build** — language, package type, and entry point + +These settings replace the legacy `.mokogitea/manifest.xml` file-based approach. + +## Repo Settings Page + +Navigate to **Repository Settings > Manifest** to view and edit manifest fields. + +| Section | Fields | +|---------|--------| +| Identity | Name, Org, Description, Version, License SPDX, License Name | +| Governance | Platform, Standards Version, Standards Source | +| Build | Language, Package Type, Entry Point | + +### Auto-Migration from manifest.xml + +On first visit to the Manifest settings page, if no manifest exists in the database but a `.mokogitea/manifest.xml` file exists in the repository, the system will: + +1. Parse the XML and extract all fields +2. Store them in the database +3. Display a flash message indicating migration was successful +4. The manifest.xml file can then be manually deleted from the repository + +If a field already has a value in the database (e.g., from org-level custom fields), the existing value is preserved and the manifest.xml value is skipped. + +## REST API + +The manifest API allows Actions workflows and the moko-platform CLI to read and write manifest settings programmatically. + +### Get Manifest + +``` +GET /api/v1/repos/{owner}/{repo}/manifest +Authorization: token {access_token} +``` + +Returns the current manifest settings. If no manifest has been saved, returns defaults derived from repository metadata (name, owner, description). + +**Response:** +```json +{ + "name": "MokoGitea", + "org": "MokoConsulting", + "description": "Moko fork of Gitea", + "version": "06.04.00", + "license_spdx": "GPL-3.0-or-later", + "license_name": "GNU General Public License v3", + "platform": "go", + "standards_version": "05.00.00", + "standards_source": "https://code.mokoconsulting.tech/MokoConsulting/moko-platform", + "language": "Go", + "package_type": "application", + "entry_point": "./" +} +``` + +### Update Manifest + +``` +PUT /api/v1/repos/{owner}/{repo}/manifest +Authorization: token {access_token} +Content-Type: application/json +``` + +Requires repo admin permission. Accepts the same JSON structure as the GET response. Creates or updates the manifest. + +### Usage in Actions Workflows + +```yaml +steps: + - name: Read manifest version + run: | + VERSION=$(curl -s "$GITEA_SERVER_URL/api/v1/repos/$GITHUB_REPOSITORY/manifest" \ + -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" | jq -r '.version') + echo "Current version: $VERSION" + + - name: Bump version + run: | + curl -s -X PUT "$GITEA_SERVER_URL/api/v1/repos/$GITHUB_REPOSITORY/manifest" \ + -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d "{\"version\": \"$NEW_VERSION\"}" +``` + +## Database + +Manifest settings are stored in the `repo_manifest` table (migration v347). One row per repository, keyed by `repo_id`. + +## Relationship to Other Systems + +| System | Relationship | +|--------|-------------| +| Update Server | The update server generators read from both manifest settings and update_stream_config. Manifest provides identity metadata; update_stream_config provides feed-specific settings. | +| Custom Fields | Repo-scoped custom fields (org settings) are separate from manifest fields. Custom fields are user-defined; manifest fields follow the moko-platform schema. | +| moko-platform CLI | The CLI reads manifest settings via the API for version bumping, build decisions, and cross-repo syncing (see issue #505). | + +--- + +| Revision | Date | Author | Description | +|---|---|---|---| +| 1.0 | 2026-06-06 | Jonathan Miller (@jmiller) | Initial version | -- 2.52.0