The repo metadata 'platform' field was a hardcoded enum; changing the
taxonomy meant a code change + redeploy. Make it admin-configurable:
- modules/setting/metadata.go: new [metadata] PLATFORM_OPTIONS setting
(default joomla,dolibarr,go,npm,generic), loaded in loadCommonSettingsFrom
- routers/web/admin/metadata.go + templates/admin/metadata.tmpl: new
Admin -> Metadata page to edit the list (persisted to app.ini), with a
nav entry and route
- routers/web/repo/setting/metadata.go + template: platform dropdown now
reads from the setting; a repo's current value stays selectable even if
removed from the list (no silent drop)
Closes#777
Deploy workflows in go/npm repos live in the workflows root, not custom/
(mirrors npm repos' npm-publish.yml in root). The sync's curated set does
not include deploy-*, so root placement is not clobbered. Moved: deploy-dev.yml, deploy-mokogitea.yml, deploy-rc.yml
These are repo-specific (not platform-standard) and belong in custom/ so
the workflow sync never distributes/clobbers them. They still run here
(Gitea Actions executes custom/). Moved: deploy-rc.yml
sync-on-merge.yml and workflow-sync-trigger.yml are template-only (gated
if: Template-*), dead no-ops in this child repo, inherited at scaffold time.
sync-on-merge.yml is also broken. The real sync lives in the templates'
workflows/custom/.
Rewind the uploaded stream between targets and write/close each file in
turn instead of a shared io.MultiWriter, so a failure writing a later
target (e.g. logo.png) can never leave an earlier one (logo-small.png)
truncated. Addresses review feedback on #774.
The app icon (logo.png) is the PWA/web-manifest icon and the navbar
fallback, but had no Branding control, so it stayed the shipped default
even on a fully branded instance. Uploading the Nav Icon now also writes
logo.png (single io.MultiWriter pass), and resetting the Nav Icon reverts
both to the built-in default.
Closes#773
The repo metadata org field was a stored, editable value that snapshotted
the owner name and could drift when an organization was renamed. It is now
derived from the org profile (repository owner) on read and is read-only.
- models/repo/repo.go: add Repository.DerivedOrgName (owner FullName, falling
back to the handle, then the denormalized OwnerName)
- models/repo/repo_manifest.go: drop the Org struct field
- models/migrations/v1_27/v369.go + migrations.go: migration #368 drops the
repo_manifest.org column
- routers/api/v1/repo/manifest.go: derive org in the response, ignore it on write
- routers/web/repo/setting/metadata.go + templates: show org read-only (derived)
- services/updateserver/joomla.go: use DerivedOrgName for the feed maintainer
Closes#771
Land deploy-mokogitea.yml robustness fix on main. [skip ci] — workflow-file-only change; no rebuild/redeploy needed (prod already live on stable-289 from #733).
The prod deploy (deploy-mokogitea.yml, on push to main) failed the #733 release and
silently corrupted the shared compose. Three fixes:
- Removed the 'Verify dev environment is healthy' gate: it curled git.dev and exit 1
on failure, so a dev blip false-negatives the PROD deploy (wrong-tier gate; the
dev->rc->main pipeline + RC env is the real gate).
- Replaced 'sed s|mokogitea:...|:$TAG|' (matched ALL mokogitea service lines and
clobbered the dev+rc ${MOKOGITEA_*_TAG} env-vars with the prod tag) with the
env-var pattern: env $TAG_ENV=$TAG docker compose up -- drives only the target
service, no sed.
- Added 'docker rm -f $CONTAINER' + '-p gitea-dev' + '--force-recreate' before the
compose up, fixing the 'Container name /mokogitea already in use' conflict.
Aligns deploy-mokogitea.yml with the fixed deploy-dev/deploy-rc pattern. Host compose
was separately restored to env-var form (the bad run had clobbered dev+rc tags).
Long-term: cut over Template-Go#5 deploy-prod.yml. Refs #733, #752.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
The Gitea Actions scheduler on the current build does not offer the dependent
2nd job of a needs-chain to runners: the Tests job (needs: lint) reaches
'waiting' but is never claimed even with idle, label-matching runners, then is
reaped by ABANDONED_JOB_TIMEOUT. Verified via dispatch on idle runners (run
34933: lint claimed+success, Tests waiting/runner_id 0, never scheduled).
Drop 'needs: lint' + the always() gate; guard template repos directly so Tests
runs as an independent, schedulable job.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Two compile errors blocked the whole tests/integration package (prereq for the
layered test pipeline, Template-Go#4, and the clean go-compile owed by #733):
- api_packages_composer_test.go: composer.PackageMetadataResponse{} (value) used
where *PackageMetadataResponse (pointer) is required -> take the address.
- oauth_avatar_test.go: 10 stale upstream 'code.gitea.io/gitea/' imports (never
updated after the fork module rename) -> 'code.mokoconsulting.tech/MokoConsulting/MokoGitea/'.
go vet ./tests/integration/... now exits 0 (compiles clean).
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
The /manifest GET+PUT routes were backward-compat aliases for the canonical
/metadata routes. Completing the manifest->metadata migration (#752): drop the
alias so /metadata is the single path. Handlers (GetRepoMetadata/UpdateRepoMetadata)
are unchanged. The MCP already calls /metadata (mcp-mokogitea-api v1.4.2,
gitea_metadata_get/update); the stale gitea_manifest_* tools only exist in older
deployed MCP builds and drop out on redeploy.
Refs #752
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
The .mokogitea/manifest.xml file is deprecated - the first-class RepoMetadata DB
fields (set via the /manifest API) are the authoritative repository metadata (see
issue #752). Remove the legacy XML auto-sync path rather than teaching it the
renamed mokocli root element:
- delete services/repository/manifest_sync.go (manifestXML parser)
- drop the SyncMetadataFromCommit call on default-branch push (push.go)
- rebrand remaining mokoplatform->mokocli refs (repo_manifest.go, v347.go comment,
locale manifest_desc)
The RepoMetadata model, /manifest API, settings UI, and update-feed generation
(first-class fields) are unchanged. gofmt-normalized repo_manifest.go struct tags.
Refs #752
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Lets deploy-rc be run on demand (from a ref carrying current source) to verify
the RC pipeline end-to-end without a full rc promotion + pre-release.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Shared DEPLOY_HOST/PORT/USER assumed all tiers live on one host. Scope every
deploy variable to the rc tier (mirrors the org's DEV_SSH_* convention) so a repo
inheriting this template can host rc/dev/prod on separate machines independently.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
The registry token is the org-wide MOKOGITEA_TOKEN secret (already configured,
used by deploy-dev/deploy-mokogitea), not a new DEPLOY_REGISTRY_TOKEN. Reuse the
existing secret names so no new secret values are needed; only the non-sensitive
tier variables get set per-repo.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
- Moved from custom/ to the root .mokogitea/workflows/ (synced/template-owned area).
- All deployment config now comes from repo Actions variables (DEPLOY_HOST/PORT/USER,
DEPLOY_REGISTRY/IMAGE, RC_CONTAINER/COMPOSE_PROJECT/COMPOSE_DIR/SOURCE_DIR/TAG_ENV/
HEALTH_URL) and secrets (DEPLOY_SSH_KEY, DEPLOY_REGISTRY_TOKEN) — nothing hardcoded,
so it works across Go server repos. Clone URL derived from github.server_url/repository.
- To become Template-Go-owned (Template-Go#3).
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Adds a custom deploy workflow that builds and deploys the release candidate
to rc.git.mokoconsulting.tech (mokogitea-rc container, port 3110, DB
mokogitea_rc) on push to the rc branch — the branch promote-rc creates when
a PR to main is opened. Mirrors the fixed deploy-dev.yml: env-var image tag
(MOKOGITEA_RC_TAG) driving the shared compose file (no sed), rm -f before
force-recreate, quoted-heredoc remote expansion, health check + external
verify. Gives a real release-candidate environment to validate before prod.
Intended to move to Template-Go as the canonical synced source once validated
(kept in custom/ for now so it isn't overwritten by workflow sync).
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Extend org-level branch protection to support per-user allowlists (resolved
from username OR email) and an "allow Actions bot" toggle, alongside the
existing team allowlists, for all five categories (push, merge, force-push,
delete, approvals).
- models/git/org_protected_branch.go: add WhitelistUserIDs, MergeWhitelistUserIDs,
ForcePushAllowlistUserIDs, DeleteAllowlistUserIDs, ApprovalsWhitelistUserIDs
([]int64) plus WhitelistActionsUser, MergeWhitelistActionsUser,
ForcePushAllowlistActionsUser, DeleteAllowlistActionsUser (bool); copy all 9
into ProtectedBranch in ToProtectedBranch().
- models/migrations/v1_27/v368.go: migration 367 adds the 9 columns.
- modules/structs/org_branch.go: add *Usernames []string and *ActionsUser bool
to Create/Edit options and the response, matching repo-level json names.
- routers/api/v1/org/branch_protection.go: resolveUserIDs (username then email,
dedupe, 422 on unknown); wire into Create + Edit and toAPIOrgBranchProtection.
- models/git/protected_branch_merge.go: add mergeAllowFlag and merge the four
Actions-user flags most-restrictively (org can now express them); deploy-key
flags stay repo-only pass-through.
- models/git/protected_branch_merge_test.go: mergeAllowFlag truth table, user-ID
intersection, deploy-key pass-through.
- regenerate swagger v1 + openapi3 specs.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
The branch-protection delete feature (#696/#728) added a second
"repo.settings.event_delete" entry ("Branch Deletion") to locale_en-US.json,
reusing the existing webhook-event key (value "Delete"). The old JSON decoder
silently kept the last value; Go 1.26's jsonv2 decoder rejects duplicate
object keys, so InitLocales fails ("duplicate object member name
repo.settings.event_delete") and the server crash-loops at startup. Like the
code-scanner regexp panic, this only surfaces on a fresh boot, which is why it
shipped unnoticed.
Give the branch-protection section header its own key
"repo.settings.protect_branch_deletion" and point protected_branch.tmpl at it,
so the webhook "Delete" label and the branch-protection "Branch Deletion"
header both render correctly and the JSON has no duplicate. Verified: no
duplicate keys remain in any options/locale/*.json.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
The "deserialize-yaml-py" rule in services/security/code_scanner.go used a
negative lookahead `(?!\s*#)` in regexp.MustCompile. Go's regexp engine is
RE2, which has no lookahead/lookbehind, so MustCompile panics during the
package init() — crash-looping the entire server at startup. `go build` and
`go vet` do not execute init(), and CI never boots the binary, so this
shipped to main via #552 undetected; the running instances survived only
because they predate that image.
Replace the pattern with an RE2-safe equivalent `(?i)yaml\.load\s*\(`, which
matches the rule's stated intent (flag yaml.load() without SafeLoader,
CWE-502). Add a regression test that forces the package init and asserts
every DefaultCodeRules pattern compiled, so a future RE2-incompatible
pattern fails in CI here instead of on a live deploy.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Code-review findings on the org-governance release:
- Fail closed on org-rule lookup error: getFirstMatchProtectedBranchRule
swallowed FindOrgBranchRuleForBranch errors (returned nil,nil), silently
dropping the org floor and falling back to the repo rule on a transient DB
error. Propagate the error so the org rule stays enforced.
- Stop the org rule locking out deploy-key and Actions-bot pushes:
OrgProtectedBranch is team-only, so mergeMostRestrictive was ANDing the
repo's WhitelistDeployKeys / WhitelistActionsUser (and the force-push,
delete and merge counterparts) against the org side's always-false zero
value, blocking every deploy-key and Actions push in any org with a
matching branch rule. Carry those org-unmanaged fields through from the
repo rule unchanged.
- Org push-policy max-file-size now inspects only the pushed delta
(diff-tree + cat-file --batch-check) instead of the full tip tree via
ls-tree, so a pre-existing oversized file can no longer permanently block
unrelated pushes. New branches (no base commit) still scan the full tree.
Dev deploy targeting:
- deploy-dev.yml drove the dev container image via `sed` on the SHARED
compose file, but the pattern matched the *prod* service line
(container_name: mokogitea) — leaving the dev service pinned to a stale
image (so every "green" deploy recreated old code) while corrupting the
prod image pin. Drive the dev service image from ${MOKOGITEA_DEV_TAG}
instead; the env-var only affects the dev service.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
After the tag fix (#737) the dev deploy builds and pushes the image
fine but fails at `docker compose up -d` with:
Conflict. The container name "/mokogitea-dev" is already in use
The dev service uses a fixed container_name, and the symlinked
/opt/gitea-dev path makes compose's derived project name unstable, so
an existing container is not recognized as the project's and `up`
tries to create rather than recreate. Remove any lingering
fixed-name container first, pin the compose project name, and force a
fresh recreate so migrations run against the new image.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Annotate the four previously undocumented org-governance API handlers
(tag_protection, push_policy, repo_defaults, email_domain) with
swagger:operation blocks, and register the swagger:response models the
branch_protection operations already referenced. Register the org
option DTOs in the parameterBodies hack so their definitions are
emitted.
Also fix pre-existing spec-generation blockers surfaced once the spec
became regenerable: a stray comment glued to the repoUpdateManifest
swagger block (broke YAML parsing), missing owner/repo path params on
the manifest operations, a Manifest response registration, and missing
definitions for EditAccessTokenOption, the IssueBulk* options, and the
Issue{Priority,Status,Type}Def types. Regenerated v1_json.tmpl and
v1_openapi3_json.tmpl; spec now validates cleanly against Swagger 2.0.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Add an Org Governance entry to the README key-features list (org-wide
branch/tag protection, push policy, repo defaults, email-domain
allowlist) and record the recent build/CI fixes (#734, #735, #736,
#737) under CHANGELOG [Unreleased].
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
The dev deploy step used an unquoted SSH heredoc and referenced
runner-side values as \$TAG / \$REGISTRY_TOKEN, deferring their
expansion to the remote shell where those names are unset. The
Docker build tag collapsed to "mokogitea:" and every dev deploy
failed with `invalid tag ... invalid reference format` before any
migration or server boot could run.
Inject TAG and REGISTRY_TOKEN as an env prefix on the ssh command
(`TAG='...' REGISTRY_TOKEN='...' bash -s`) and switch to a quoted
heredoc so every $var expands in exactly one place: the remote host.
Also fixes HEALTH_FMT (was defined on the runner but referenced
remotely) and adds an explicit empty-TAG guard so a future
regression fails loudly instead of building an untagged image.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
api_license_keys_test.go used the outdated NewRequestWithBody signature
(passing []byte where io.Reader is now required) — wrapped the string bodies in
strings.NewReader. Note: tests/integration remains broadly pre-existing-broken
across multiple other fork-added files (api_packages_composer type mismatch,
etc.); those are a separate dedicated cleanup, not part of #727.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
`go vet ./...` (finally runnable with a local Go toolchain) surfaced three
pre-existing failures that prevented the whole test tree from compiling — which
is very likely why the "Project CI / Tests" job never went green. None relate to
#727; all pre-existing on main.
- modules/util/util_test.go: CryptoRandomInt/String/Bytes now return (value,
error); the tests used single-value assignment. Updated to capture + assert
the error (and dropped a now-redundant `var err error`).
- tests/integration/auth_oauth2_test.go: `newFakeOIDCServer` was declared twice
with different signatures (redeclaration = build failure). Renamed the
config-struct variant to `newFakeOIDCServerWithConfig` and updated its caller;
the (sub, oid) variant keeps the original name for its caller.
- routers/web/repo/issue_comment.go: removed a redundant `&& statusIDStr != ""`
duplicate condition (vet: redundant and).
Verified: `go vet ./modules/util` clean; full `go vet ./...` re-run.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
Two pre-existing issues surfaced when the org-governance series was compiled
locally with a real Go toolchain (go1.26.3) for the first time:
- routers/api/v1/api.go:519 called organization.HasOrgOrUserVisible, which no
longer exists — it was renamed to IsOwnerVisibleToDoer (models/organization/
org.go:548, identical signature). This one missed call site meant the whole
routers/api/v1 package (and therefore the server binary) failed `go build`.
With the rename, `go build ./...` is clean.
- gofmt: api.go (a mis-indented commented-out /projects route block) and
release.go (import sort: repo before updateserver) were gofmt-dirty. Fixed
with gofmt -w on the two files this change already touches.
Not part of #727, but blocks building/releasing the fork; found while validating
the dev -> main promotion (#733).
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
| python3 -c "import sys,json; d=json.load(sys.stdin); print(next((str(p['number']) for p in d if p.get('head',{}).get('ref')=='main'), ''))" 2>/dev/null || echo "")
-d '{"head":"main","base":"dev","title":"chore(sync): cascade main -> dev","body":"Automated cascade of main into dev. Auto-merges when conflict-free, auto-resolves VERSION-stamp-only conflicts, otherwise left open for manual resolution."}')
PR=$(printf '%s' "$RESP" | jqget number)
if [ -z "$PR" ]; then
echo "::warning::Could not open cascade PR: $RESP"; exit 0
fi
echo "Opened cascade PR #${PR}"
else
echo "Reusing open cascade PR #${PR}"
fi
notify() {
curl -sS \
-H "Title: ${REPO}: dev cascade needs manual merge" \
-d '{"body":"<!-- wiki-reminder -->\n\n**Wiki reminder:** docs are wiki-first -- if this PR changes behavior, usage, config, or standards, please update the repo wiki before/after merge. _(non-blocking)_"}' >/dev/null 2>&1 || true
echo "::error::Manifest contains legacy raw/branch update server URL on MokoGitea. Use the Gitea Pages URL instead (e.g. /{REPO}/updates.xml not /{REPO}/raw/branch/main/updates.xml)"
echo "::error::Manifest contains legacy raw/branch update server URL on MokoGitea. Use the MokoGitea Pages URL instead (e.g. /{REPO}/updates.xml not /{REPO}/raw/branch/main/updates.xml)"
- Metadata platform options are now **admin-configurable** instead of hardcoded: a new **Admin → Metadata** page edits the allowed `platform` values (persisted to `app.ini``[metadata] PLATFORM_OPTIONS`, default `joomla,dolibarr,go,npm,generic`), and the repo Settings → Metadata platform dropdown reads from it. Changing the taxonomy no longer needs a code change/redeploy. A repo's existing platform value stays selectable even if later removed from the list (#777)
- Org branch protection: repositories now show the inherited organization rules read-only in their Branch Protection settings, with an expandable detail (direct push, force-push, branch deletion, merge restrictions, required approvals, status checks, protected files, and whitelisted teams) — like GitHub surfaces org rulesets in a repo (#727)
- Org branch protection: org-level rules can now also protect against branch deletion (`enable_delete` + delete allowlist teams), mirroring the per-repo delete allowlist (#727)
- Org-level tag protection: protect tag patterns org-wide (e.g. `v*`) with a team allowlist, layered on top of each repo's own protected tags — a tag is controllable only if allowed at both levels (fail-closed). API at `/orgs/{org}/tag_protections`; enforced at the git push/delete hook and the release create/delete paths; shown read-only in the repo Tag settings (#727)
- Repo metadata `org` is now **derived from the org profile** (the repository owner) instead of being stored/editable, so it can never drift when an organization is renamed. The `org` column is dropped from `repo_manifest` (migration #368) and the field is derived on read via `Repository.DerivedOrgName` (owner display name, falling back to the handle) across the metadata API, the Settings → Metadata page (now read-only), and the Joomla update-server feed. The API `PUT` and MCP `metadata_update` now ignore `org` (read-only, like the already-derived `display_name`) (#771)
- Admin Branding: uploading a custom **Nav Icon** now also sets the **app icon** (`logo.png`, the PWA / web-manifest icon and navbar fallback), so a branded instance shows its own installable app icon instead of the shipped default; resetting the Nav Icon reverts both (#773)
- Fork server binary now compiles: `routers/api/v1/api.go` called `organization.HasOrgOrUserVisible`, which had been renamed to `IsOwnerVisibleToDoer`; the one missed call site broke `go build` of the entire `routers/api/v1` package (CI's Lint & Validate does not run a full build, so it went unnoticed) (#735)
- Dev deploy workflow: the build/deploy step referenced runner-side values as `\$TAG` / `\$REGISTRY_TOKEN` inside an unquoted SSH heredoc, deferring expansion to the remote shell where those names are unset — the Docker tag collapsed to an empty `mokogitea:` and every dev deploy failed with `invalid reference format`. Runner values are now injected via an ssh env-prefix and the heredoc is quoted so each `$var` expands in exactly one place (#737)
- Repaired unit-test compile and `go vet` failures: `CryptoRandomInt/String/Bytes` now return two values (updated `modules/util/util_test.go`), removed a redundant `&&` condition in `issue_comment.go`, and cleaned up isolated integration-test compile errors (#736)
- Removed a stray `package-lock.json` (13.9k lines) that a `git add -A` had accidentally swept into the org-push-policy branch (#734)
- Org-level branch protection now **layers** with per-repo rules instead of being ignored whenever a repo rule exists. When both an org rule and a repo rule match a branch, the effective rule is the most-restrictive (fail-closed) combination — the org rule is a mandatory floor a repo cannot weaken: allow flags AND'd, gate/require/block flags OR'd, required approvals max'd, status checks and protected-file patterns unioned, whitelists intersected. Previously a repo rule shadowed the org rule entirely at the enforcement choke point (`GetFirstMatchProtectedBranchRule`), letting a repo opt out of org protection (#727)
- Org Teams page: list now renders — the handler wrote `ctx.Data["OrgListTeams"]` but the template reads `.Teams`, so the page showed header/nav but no teams (#720)
- Issue type: now editable after creation for users with issue write permission — the sidebar gated editing on a `FieldEditFlags` data key that was never populated (always read-only); now uses `HasIssuesOrPullsWritePermission` like the priority field (#721)
"repo.settings.support_url_help":"Shown when downloads are gated. Can point to your wiki, product page, or external support site.",
"repo.settings.custom_fields":"Custom Fields",
"repo.settings.manifest":"Manifest",
"repo.settings.manifest_desc":"Project identity, governance, and build settings from the MokoPlatform manifest. These are accessible via API for Actions workflows and the MokoPlatform CLI.",
"repo.settings.manifest_desc":"Project identity, governance, and build settings for the repository. These are accessible via API for Actions workflows and MokoCLI.",
<strong>Nav Icon</strong> {{if.HasNavIcon}}<span class="ui mini green label">Custom</span>{{else}}<span class="ui mini grey label">Default</span>{{end}}
<div class="tw-text-text-light tw-text-sm tw-mt-1">Top-left corner across all pages. Square, 30x30px.</div>
<div class="tw-text-text-light tw-text-sm tw-mt-1">Top-left corner across all pages. Square, 30x30px. Also sets the app icon (PWA / web manifest); use at least 512x512px for a crisp installed icon.</div>
<p class="tw-text-text-light tw-text-sm">Allowed values for the repository metadata <strong>Platform</strong> field. One per line (or comma-separated). Changes take effect immediately and are saved to <code>app.ini</code> <code>[metadata] PLATFORM_OPTIONS</code>.</p>
<button type="submit" class="ui primary small button tw-mt-2">{{svg"octicon-check"14}} Save Settings</button>
</form>
<p class="tw-text-text-light tw-text-sm tw-mt-3">Existing repositories keep their stored platform value even if it is later removed from this list; it simply won't be offered to other repos.</p>
@@ -126,7 +126,7 @@ When a field definition is deleted, all associated values in `custom_field_value
| 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. |
| Manifest Settings | Manifest fields follow the mokocli 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. |
@@ -101,8 +101,8 @@ Manifest settings are stored in the `repo_manifest` table (migration v347). One
| 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). |
| Custom Fields | Repo-scoped custom fields (org settings) are separate from manifest fields. Custom fields are user-defined; manifest fields follow the mokocli schema. |
| mokocli CLI | The CLI reads manifest settings via the API for version bumping, build decisions, and cross-repo syncing (see issue #505). |
- Granular role-based permissions for all features (#9)
- Wire moko-platform CLI to manifest API (#505)
- Wire mokocli CLI to manifest API (#505)
- Bulk migrate remaining 41 flat wikis to folders
## Planned
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.