release: npm/mcp metadata + platform registry + update-server + packaging hook (dev -> main) [#367] #828

Merged
jmiller merged 10 commits from dev into main 2026-07-19 04:00:40 +00:00
Owner

Promotes the four EPIC #367 forge features from dev to main. All four merged to dev and the dev deploy built + deployed successfully (deploy-dev run 4705, Verify Dev instance passed) — so this set compiles and runs on the dev forge.

Bundles:

  • #827 — persist npm/mcp metadata fields (RepoMetadata + apiMetadata + migration v373).
  • #826 — platform registry ([metadata] PLATFORM_REGISTRY + GET /api/v1/platforms + updateserver registry helpers).
  • #825 — update server: npm/mcp return N/A (not a Joomla feed) + platform derived from metadata.
  • #814 — server-side release packaging hook (full-repo + entry_point-subtree zips + sha256 on release).

Merging this to main triggers a PRODUCTION forge deploy — review + confirm before merge. Run the migration (v373) as part of deploy.

Authored-by: Moko Consulting

Promotes the four EPIC #367 forge features from `dev` to `main`. All four merged to `dev` and the **dev deploy built + deployed successfully** (deploy-dev run 4705, Verify Dev instance passed) — so this set compiles and runs on the dev forge. Bundles: - **#827** — persist npm/mcp metadata fields (`RepoMetadata` + `apiMetadata` + migration v373). - **#826** — platform registry (`[metadata] PLATFORM_REGISTRY` + `GET /api/v1/platforms` + updateserver registry helpers). - **#825** — update server: npm/mcp return N/A (not a Joomla feed) + platform derived from metadata. - **#814** — server-side release packaging hook (full-repo + entry_point-subtree zips + sha256 on release). **Merging this to `main` triggers a PRODUCTION forge deploy** — review + confirm before merge. Run the migration (v373) as part of deploy. Authored-by: Moko Consulting
jmiller added 10 commits 2026-07-19 03:01:36 +00:00
feat(release): server-side packaging — attach full-repo + entry_point subtree zips on release [#809]
Universal: Auto Version Bump / Version Bump (push) Successful in 25s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Project CI / Lint & Validate (pull_request) Successful in 43s
Universal: PR Check / Validate PR (pull_request) Successful in 20s
Universal: PR Check / Secret Scan (pull_request) Successful in 1m31s
Generic: Project CI / Tests (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
2280f02bec
Add GenerateReleaseArtifacts in services/release/packaging.go, invoked from
CreateRelease and the UpdateRelease publish path (drafts skipped). It streams a
full-repository zip (<repo>-<tag>.zip) and, when repo metadata declares a
non-root entry_point, an entry_point subtree zip (<repo>-<tag>-source.zip) via
gitrepo.CreateArchive through an io.Pipe into attachment_service.NewAttachment,
so archives are never buffered in memory. The helper is idempotent (existing
artifacts of the same name are replaced) and runs before GenerateReleaseChecksums
so each zip receives a .sha256 sidecar automatically.

Refs #809 #812 EPIC #367

Authored-by: Moko Consulting
fix(release): mark generated artifacts, serialize + reorder attach to prevent data loss [#809]
Universal: Auto Version Bump / Version Bump (push) Successful in 21s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Project CI / Lint & Validate (pull_request) Successful in 43s
Universal: PR Check / Validate PR (pull_request) Successful in 14s
Universal: PR Check / Secret Scan (pull_request) Successful in 1m32s
Generic: Project CI / Tests (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
19d498f6c3
Address data-safety review of the server-side packaging hook:

- DATA LOSS (HIGH): tag generated zips with UploaderID = user_model.ActionsUserID
  (-2), a built-in bot sentinel that cannot collide with human uploads (which
  always use a positive doer ID). Only attachments carrying this marker are ever
  deleted, so a user-uploaded asset sharing a generated name is never destroyed.

- CONCURRENCY (HIGH): serialize the per-release delete+attach sequence with
  globallock.LockAndDo, keyed release_packaging_<id>, matching the forge's
  existing working-lock convention. Attachments are re-read inside the lock.

- DELETE-THEN-FAIL (LOW): reorder to attach-new-then-delete-old — the fresh
  archive is stored under the canonical name first and stale generated copies
  are removed only on success, so a failed regeneration never nets asset loss.

- FILENAME (LOW): sanitize the tag segment (replace path separators) so a tag
  like release/1.0 yields a clean asset name.

- ENTRY_POINT (LOW): normalizeEntryPoint trims a leading slash (git archive
  rejects absolute paths) and treats a now-empty result as root/skip.

- CHECKSUM re-hash cost (MEDIUM): documented as a follow-up at the checksum
  call sites in release.go.

The verified-correct io.Pipe streaming is unchanged.

Refs #809 #812 EPIC #367

Authored-by: Moko Consulting
Merge pull request 'chore: cascade main -> dev (.mokogitea -> .mokogit / MOKOGIT_TOKEN)' (#796) from main into dev
MokoGIT: Sync MokoOnyx Theme / Vendor MokoOnyx theme CSS (push) Failing after 48s
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 3m3s
Deploy (Dev) / Build & Deploy to Dev (push) Successful in 7m21s
e24e4db542
feat(updateserver): npm/mcp return N-A instead of Joomla feed; derive platform from metadata [#810 #811]
Universal: PR Check / Branch Policy (pull_request) Successful in 5s
Universal: PR Check / Require Docs Update (pull_request) Has been skipped
Universal: PR Check / Wiki Update Reminder (pull_request) Has been skipped
Generic: Project CI / Tests (pull_request) Successful in 36s
Generic: Project CI / Lint & Validate (pull_request) Successful in 39s
Universal: PR Check / Validate PR (pull_request) Successful in 11s
Universal: PR Check / Secret Scan (pull_request) Successful in 53s
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Failing after 5m10s
RC Revert / Rename rc/ back to dev/ (pull_request) Failing after 7m39s
9a8d9bc504
#810: The update-feed handlers no longer fall back to a Joomla feed for
unset or feedless platforms. Every Serve* handler now gates positively on
its own platform constant, so npm/mcp (and any unrecognized platform)
return NotFound instead of an (empty) Joomla updates.xml. Added npm/mcp as
recognized platform constants and an IsFeedlessPlatform helper.

#811: The effective update-stream platform (RepoUpdatePlatform) is now
resolved via ResolvePlatform(cfgPlatform, metadataPlatform): an explicit
update-stream config platform wins; otherwise it derives from the repo
metadata platform (metadata.platform); only when neither is set does it
fall back to "joomla". This stops the update-stream store and the repo
metadata store from drifting and removes the "empty => joomla" fallback
at its root (services/context/repo_public_feed.go and repo.go).

No schema/migration required: UpdateStreamConfig.Platform is a plain string
column with no DB-level enum/CHECK constraint, so npm/mcp are enforced at
the application layer only.

Authored-by: Moko Consulting
feat(platform): structured platform registry + /api/v1/platforms; update server reads registry [#367]
Universal: Auto Version Bump / Version Bump (push) Successful in 23s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Universal: PR Check / Require Docs Update (pull_request) Has been skipped
Universal: PR Check / Wiki Update Reminder (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 33s
Universal: PR Check / Validate PR (pull_request) Successful in 8s
Generic: Project CI / Tests (pull_request) Successful in 27s
Universal: PR Check / Secret Scan (pull_request) Successful in 50s
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
38aa4de412
Turn the flat admin [metadata] PLATFORM_OPTIONS key list into a structured
platform registry where each key carries capability attributes (family,
artifact, update_generator, feed_format, template_repo, manifest_based,
publish_target, detect_globs, aliases), and expose it so CI / the update
server / mokocli can read platform behavior from config instead of hardcoding.

Storage: new [metadata] PLATFORM_REGISTRY key in app.ini — inline JSON array
or a path to a JSON file (e.g. custom/platforms.json), parsed in
modules/setting. No DB table (idiomatic: mirrors existing app.ini + file-path
config patterns; non-secret capability config only). Built-in DEFAULT registry
(joomla, dolibarr, go, npm, mcp, generic) keeps behavior unchanged when
unconfigured, and reconciles with PLATFORM_OPTIONS.

API: GET /api/v1/platforms (whole registry) and GET /api/v1/platforms/{key}
(one), wired into the public misc group.

Update server: additive registry-driven helpers in services/updateserver
(GeneratorForPlatform / FeedFormatForPlatform / ContentTypeForPlatform /
PlatformServesGenerator) that replace hardcoded per-platform generator/feed
decisions with registry lookups. Handler bodies left untouched to avoid
conflicting with PR #825 (feature/updateserver-npm-mcp), which is concurrently
rewiring routers/web/repo/updateserver.go and adding
models/updateserver/platform.go; helpers are drop-in for adoption once #825
lands.

Admin UI: read-only resolved-registry table added to Admin -> Metadata; the
textarea still edits the flat key list. Capabilities edited via config for now.

Does NOT touch models/repo/repo_manifest.go or the per-repo apiMetadata struct
(owned by a separate PR).

Authored-by: Moko Consulting
feat(metadata): persist npm/mcp fields (node_minimum, npm_package, npm_scope, registry_url, bin, publish_target) [#363]
Universal: Auto Version Bump / Version Bump (push) Successful in 24s
Universal: PR Check / Branch Policy (pull_request) Successful in 3s
Universal: PR Check / Require Docs Update (pull_request) Has been skipped
Universal: PR Check / Wiki Update Reminder (pull_request) Has been skipped
Generic: Project CI / Tests (pull_request) Successful in 35s
Generic: Project CI / Lint & Validate (pull_request) Successful in 39s
Universal: PR Check / Validate PR (pull_request) Successful in 8s
Universal: PR Check / Secret Scan (pull_request) Successful in 37s
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
5f85b278da
Add six npm/mcp metadata columns to the repo_manifest table and round-trip
them through the /metadata API (GET response, PUT apply, PUT response) so they
are no longer silently dropped by the fixed struct property set.

Authored-by: Moko Consulting
Merge pull request 'feat(metadata): persist npm/mcp fields [#363]' (#827) from feature/npm-metadata-schema into dev
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 1m22s
MokoGIT: Sync MokoOnyx Theme / Vendor MokoOnyx theme CSS (push) Failing after 2m35s
Deploy (Dev) / Build & Deploy to Dev (push) Failing after 8m55s
adee35573e
Merge pull request 'feat(platform): structured platform registry + /api/v1/platforms; update server reads registry [#367]' (#826) from feature/platform-registry into dev
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 4m3s
MokoGIT: Sync MokoOnyx Theme / Vendor MokoOnyx theme CSS (push) Failing after 5m18s
Deploy (Dev) / Build & Deploy to Dev (push) Successful in 8m46s
74fc2d3101
Merge pull request 'feat(updateserver): npm/mcp return N-A instead of Joomla feed; derive platform from metadata [#810 #811]' (#825) from feature/updateserver-npm-mcp into dev
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m7s
MokoGIT: Sync MokoOnyx Theme / Vendor MokoOnyx theme CSS (push) Failing after 7m19s
Deploy (Dev) / Build & Deploy to Dev (push) Failing after 7m30s
0efb0eb7bc
Merge pull request 'feat(release): server-side packaging — attach full-repo + entry_point subtree zips on release [#809]' (#814) from feature/release-packaging-hook into dev
MokoGIT: Sync MokoOnyx Theme / Vendor MokoOnyx theme CSS (push) Failing after 1m25s
Deploy (Dev) / Build & Deploy to Dev (push) Successful in 4m35s
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 30s
Generic: Project CI / Tests (pull_request) Successful in 21s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: PR Check / Wiki Update Reminder (pull_request) Successful in 5s
Universal: PR Check / Require Docs Update (pull_request) Failing after 54s
Universal: PR Check / Validate PR (pull_request) Successful in 9s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Standards Compliance / Secret Scanning (pull_request) Failing after 17s
Generic: Standards Compliance / License Header Validation (pull_request) Successful in 17s
Universal: PR Check / Secret Scan (pull_request) Successful in 1m1s
Generic: Standards Compliance / Repository Structure Validation (pull_request) Successful in 15s
Generic: Standards Compliance / Coding Standards Check (pull_request) Successful in 13s
Generic: Standards Compliance / Documentation Quality Check (pull_request) Successful in 12s
Generic: Standards Compliance / Workflow Configuration Check (pull_request) Failing after 13s
Generic: Standards Compliance / README Completeness Check (pull_request) Failing after 8s
Generic: Standards Compliance / Version Consistency Check (pull_request) Successful in 1m11s
Generic: Standards Compliance / Script Integrity Validation (pull_request) Successful in 8s
Generic: Standards Compliance / Git Repository Hygiene (pull_request) Successful in 57s
Generic: Standards Compliance / Line Length Check (pull_request) Successful in 14s
Generic: Standards Compliance / File Naming Standards (pull_request) Successful in 9s
Generic: Standards Compliance / Insecure Code Pattern Detection (pull_request) Successful in 20s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Failing after 7m13s
Generic: Standards Compliance / Code Complexity Analysis (pull_request) Successful in 1m20s
Generic: Standards Compliance / Code Duplication Detection (pull_request) Successful in 1m9s
Generic: Standards Compliance / Dead Code Detection (pull_request) Successful in 8s
Generic: Standards Compliance / File Size Limits (pull_request) Successful in 6s
Generic: Standards Compliance / TODO/FIXME Tracking (pull_request) Successful in 6s
Generic: Standards Compliance / Dependency Vulnerability Scanning (pull_request) Successful in 58s
Generic: Standards Compliance / Binary File Detection (pull_request) Successful in 1m29s
Generic: Standards Compliance / Broken Link Detection (pull_request) Successful in 15s
Generic: Standards Compliance / API Documentation Coverage (pull_request) Successful in 6s
Generic: Standards Compliance / Accessibility Check (pull_request) Successful in 5s
Generic: Standards Compliance / Unused Dependencies Check (pull_request) Successful in 53s
Generic: Standards Compliance / Performance Metrics (pull_request) Successful in 6s
Generic: Standards Compliance / Enterprise Readiness Check (pull_request) Successful in 53s
Generic: Standards Compliance / Repository Health Check (pull_request) Successful in 52s
Generic: Standards Compliance / Terraform Configuration Validation (pull_request) Successful in 11s
Deploy (RC) / Build & Deploy to RC (push) Successful in 5m57s
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
Generic: Standards Compliance / Compliance Summary (pull_request) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Failing after 2m24s
df67ff07b8
Author
Owner

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)

<!-- wiki-reminder --> **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)_
jmiller merged commit ae5fbc74b3 into main 2026-07-19 04:00:40 +00:00
Sign in to join this conversation.