Compare commits

...

30 Commits

Author SHA1 Message Date
gitea-actions[bot] 3bfcc9f79a chore(version): pre-release bump to 06.16.01-dev [skip ci]
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 2m29s
2026-06-18 17:02:03 +00:00
Jonathan Miller e427bee210 merge: resolve version conflicts, keep main release version
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Branch Policy Check / Verify merge target (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 12s
Generic: Project CI / Lint & Validate (pull_request) Successful in 38s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 56s
PR RC Release / Build RC Release (pull_request) Failing after 56s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m55s
Universal: Build & Release / Promote to RC (pull_request) Successful in 18s
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
2026-06-18 12:00:41 -05:00
gitea-actions[bot] 3af6265802 chore(release): build 06.16.00 [skip ci] 2026-06-18 16:58:44 +00:00
jmiller c456258540 Merge pull request 'fix: remove version from manifest first-class fields' (#641) from fix into main
Deploy MokoGitea / deploy (push) Failing after 3m33s
2026-06-18 16:57:55 +00:00
Jonathan Miller 91e50fe4bf fix: remove version from manifest first-class fields
Universal: Auto Version Bump / Version Bump (push) Successful in 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m35s
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 8s
Generic: Project CI / Lint & Validate (pull_request) Successful in 32s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 39s
PR RC Release / Build RC Release (pull_request) Failing after 49s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Failing after 1s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 2m24s
Version is not a required metadata field — it's derived from git tags
and releases, not stored in the manifest. Remove from RepoManifest
model and the manifest API request/response struct.

VersionPrefix, StandardsVersion, and TargetVersion are kept as they
serve different purposes (tag parsing, standards compliance, platform
targeting).
2026-06-18 11:01:23 -05:00
gitea-actions[bot] 9b766c3dee chore(release): build 06.15.00 [skip ci] 2026-06-18 15:37:13 +00:00
gitea-actions[bot] 7ca3593f74 chore(version): pre-release bump to 06.14.03-dev [skip ci] 2026-06-18 15:33:59 +00:00
jmiller bf5b759398 Merge pull request 'merge: dev into main — CI workflow triggers + version bump' (#640) from dev into main
Deploy MokoGitea / deploy (push) Successful in 5m12s
2026-06-18 15:31:59 +00:00
Jonathan Miller d877bbbe0c merge: resolve auto-bump version conflicts
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Failing after 11s
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 35s
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 1m2s
PR RC Release / Build RC Release (pull_request) Failing after 1m30s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m50s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 2m36s
2026-06-18 10:31:45 -05:00
Jonathan Miller 5e401c659b merge: resolve version conflicts, keep main release version 2026-06-18 10:30:44 -05:00
gitea-actions[bot] 7d0b3f042c chore(version): pre-release bump to 06.14.02-dev [skip ci] 2026-06-18 15:28:34 +00:00
Jonathan Miller e0c492c7df fix(ci): run CI and repo-health on PR to main, not on push
Universal: Auto Version Bump / Version Bump (push) Successful in 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m19s
CI and repo-health were triggering on push to main, running alongside
(or after) the deploy workflow instead of gating the merge. Move both
to pull_request triggers so they run as PR checks before merge.

- ci-generic: remove push trigger, keep pull_request to main/dev/rc
- repo-health: remove bare push trigger, scope pull_request to main
- deploy-mokogitea stays on push:main (fires only after merge)
2026-06-18 10:27:50 -05:00
gitea-actions[bot] 5fec351426 chore(release): build 06.15.00 [skip ci] 2026-06-18 15:23:45 +00:00
gitea-actions[bot] 7f09fa0b98 chore(version): pre-release bump to 06.14.01-dev [skip ci] 2026-06-18 15:21:24 +00:00
jmiller 1b0b62db38 Merge pull request 'merge: dev into main' (#639) from dev into main
Generic: Project CI / Tests (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Project CI / Lint & Validate (push) Successful in 38s
Deploy MokoGitea / deploy (push) Successful in 4m58s
2026-06-18 15:20:31 +00:00
Jonathan Miller 0d9d526203 merge: resolve version conflicts, keep main release version (06.14.00)
Generic: Project CI / Tests (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 3s
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 45s
Generic: Project CI / Lint & Validate (push) Successful in 50s
Universal: PR Check / Validate PR (pull_request) Failing after 10s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 1m21s
PR RC Release / Build RC Release (pull_request) Failing after 45s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m47s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 2m31s
2026-06-18 10:19:56 -05:00
gitea-actions[bot] b321273306 chore(version): pre-release bump to 06.13.04-dev [skip ci] 2026-06-18 15:06:43 +00:00
jmiller 8adccbcb40 Merge pull request 'fix: Joomla update server — element names, platform gating, domain race' (#638) from fix into dev
Generic: Project CI / Tests (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Project CI / Lint & Validate (push) Successful in 24s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 1m59s
2026-06-18 15:06:01 +00:00
Jonathan Miller 08f6454dd2 fix: address PR review findings — error handling, type safety, comments
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
PR RC Release / Build RC Release (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Generic: Project CI / Lint & Validate (pull_request) Successful in 28s
Review fixes:
- Propagate updateDomainRestriction error in grace-period path instead
  of silently discarding it (was same bug class as the TOCTOU fix)
- Propagate IsDomainKnownForKey error inside transaction — discarding
  it defeated the atomicity guarantee
- Wrap updateDomainRestriction error with context message
- Use boolean flags for changelog manifest fallback instead of fragile
  sentinel comparison against strings.ToLower(repo.Name)
- Type-assert ctx.Data["RepoUpdatePlatform"] to string instead of
  comparing interface{} values
- Use log.Warn instead of log.Error for manifest fallback (intentional
  degradation, not a failure)
- Clarify comments: doc comment scope, hyphen removal wording
2026-06-18 09:51:33 -05:00
Jonathan Miller a83d2ee3bd fix: changelog element mismatch, platform gating, domain race condition
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 8s
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (push) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Successful in 6s
Generic: Project CI / Lint & Validate (pull_request) Successful in 39s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 1m12s
PR RC Release / Build RC Release (pull_request) Failing after 1m10s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m1s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Three fixes for the Joomla update server system:

1. changelog_xml.go: Resolve element name from manifest first (same
   priority as updates.xml) so changelog.xml and updates.xml emit
   matching <element> values. Previously only checked the config table.

2. updateserver.go: Only serve Joomla XML when platform is joomla,
   both, or unset. Previously only blocked dolibarr, meaning WordPress/
   PrestaShop/Drupal/WHMCS repos incorrectly served Joomla XML.

3. license_key.go: Wrap domain auto-association in db.WithTx to prevent
   TOCTOU race where concurrent requests from different domains could
   exceed MaxSites. Also removes a duplicate site-limit check that was
   unreachable dead code.
2026-06-18 09:14:13 -05:00
Jonathan Miller 73a1320d72 fix: derive Joomla element name with correct lowercase + type prefix
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Failing after 10s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Project CI / Lint & Validate (pull_request) Successful in 32s
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 41s
PR RC Release / Build RC Release (pull_request) Failing after 34s
Universal: Auto Version Bump / Version Bump (push) Successful in 4s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 1m46s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
AutoElementName() was using the manifest Name field verbatim, producing
element names like "pkg_MokoSuiteBackup" instead of "pkg_mokosuitebackup".
Joomla's updater matches by element+type+client_id in #__extensions, so
the case mismatch made updates invisible.

Changes:
- Lowercase name and strip hyphens in AutoElementName()
- Remove incorrect "plg_" prefix for plugins (Joomla plugins have no
  element prefix; the folder column determines the plugin group)

Fixes #635
2026-06-18 08:33:35 -05:00
gitea-actions[bot] 4694fbf719 chore(release): build 06.14.00 [skip ci] 2026-06-14 20:04:31 +00:00
gitea-actions[bot] 0a0d7b704d chore(version): pre-release bump to 06.13.03-dev [skip ci] 2026-06-14 20:02:18 +00:00
jmiller 3cc68ec310 Merge pull request 'fix: correct <client> tag per extension type in Joomla update feed (#611)' (#634) from dev into main
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Project CI / Lint & Validate (push) Successful in 32s
Deploy MokoGitea / deploy (push) Failing after 4m7s
Generic: Project CI / Tests (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
fix: correct client tag per extension type in Joomla update feed (#611)
2026-06-14 20:01:47 +00:00
Jonathan Miller 96a51574e2 merge: resolve issue-branch.yml conflict
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Branch Policy Check / Verify merge target (pull_request) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Failing after 8s
Generic: Project CI / Lint & Validate (push) Successful in 31s
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 38s
PR RC Release / Build RC Release (pull_request) Failing after 1m43s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 1m46s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m20s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 2m37s
Generic: Project CI / Tests (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
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
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
2026-06-14 15:01:04 -05:00
Jonathan Miller 93f20b9671 merge: resolve conflicts, keep client_id fix 2026-06-14 15:00:16 -05:00
gitea-actions[bot] d419033384 chore(version): pre-release bump to 06.13.02-dev [skip ci] 2026-06-14 19:55:02 +00:00
Jonathan Miller c453310834 fix: set correct <client> per extension type in Joomla update feed (#611)
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 5s
Branch Policy Check / Verify merge target (pull_request) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Failing after 9s
Generic: Project CI / Lint & Validate (push) Successful in 31s
Generic: Project CI / Lint & Validate (pull_request) Successful in 28s
PR RC Release / Build RC Release (pull_request) Failing after 1m11s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 1m14s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 2m6s
Universal: Build & Release / Promote to RC (pull_request) Successful in 17s
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Generic: Project CI / Tests (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
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
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
2026-06-14 14:53:53 -05:00
gitea-actions[bot] 041adc50e5 chore(version): pre-release bump to 06.13.01-dev [skip ci] 2026-06-11 20:33:20 +00:00
jmiller cd305a2332 ci(pre-release): sync universal v05 workflow with chore/** branch trigger
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Generic: Project CI / Lint & Validate (push) Successful in 43s
Universal: Auto Version Bump / Version Bump (push) Failing after 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 1m16s
Generic: Project CI / Tests (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-11 20:31:40 +00:00
13 changed files with 387 additions and 156 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<name>MokoGitea</name>
<org>MokoConsulting</org>
<description>Moko fork of Gitea - adding project board REST API endpoints and custom enhancements</description>
<version>06.15.00</version>
<version>06.16.01</version>
<version-prefix>v1.26.1+MOKO</version-prefix>
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
</identity>
-7
View File
@@ -13,13 +13,6 @@
name: "Generic: Project CI"
on:
push:
branches:
- main
- dev
- dev/**
- rc/**
- version/**
pull_request:
branches:
- main
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokoplatform.Automation
# VERSION: 06.15.00
# VERSION: 06.16.01
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+242 -1
View File
@@ -8,4 +8,245 @@
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /templates/workflows/universal/pre-release.yml.template
# VERSION: 05.01.00
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
name: "Universal: Pre-Release"
on:
push:
branches:
- dev
- 'fix/**'
- 'patch/**'
- 'hotfix/**'
- 'bugfix/**'
- 'chore/**'
- alpha
- beta
- rc
workflow_dispatch:
inputs:
stability:
description: 'Pre-release channel'
required: true
type: choice
options:
- development
- alpha
- beta
- release-candidate
permissions:
contents: write
env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
jobs:
build:
name: "Build Pre-Release (${{ inputs.stability || github.ref_name }})"
runs-on: release
if: >-
github.event_name == 'workflow_dispatch' ||
github.event_name == 'push'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }}
ref: ${{ github.ref_name }}
- name: Setup moko-platform tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: |
# Use pre-installed /opt/moko-platform if available (updated by cron every 6h)
if [ -f /opt/moko-platform/cli/version_bump.php ] && [ -f /opt/moko-platform/cli/manifest_element.php ] && [ -f /opt/moko-platform/vendor/autoload.php ]; then
echo Using pre-installed /opt/moko-platform
echo MOKO_CLI=/opt/moko-platform/cli >> $GITHUB_ENV
else
echo Falling back to fresh clone
if ! command -v composer > /dev/null 2>&1; then
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
fi
rm -rf /tmp/moko-platform-api
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/moko-platform-api
cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet
echo MOKO_CLI=/tmp/moko-platform-api/cli >> $GITHUB_ENV
fi
- name: Detect platform
id: platform
run: |
# Auto-detect and update platform if not set in manifest
php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true
php ${MOKO_CLI}/manifest_read.php --path . --github-output
- name: Resolve metadata and bump version
id: meta
run: |
# Auto-detect stability from branch name on push, or use input on dispatch
if [ "${{ github.event_name }}" = "push" ]; then
case "${{ github.ref_name }}" in
rc) STABILITY="release-candidate" ;;
alpha) STABILITY="alpha" ;;
beta) STABILITY="beta" ;;
*) STABILITY="development" ;;
esac
else
STABILITY="${{ inputs.stability || 'development' }}"
fi
case "$STABILITY" in
development) SUFFIX="-dev"; TAG="development" ;;
alpha) SUFFIX="-alpha"; TAG="alpha" ;;
beta) SUFFIX="-beta"; TAG="beta" ;;
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
esac
# Bump version via CLI: patch for dev/alpha/beta, minor for RC
case "$STABILITY" in
release-candidate) BUMP="minor" ;;
*) BUMP="patch" ;;
esac
php ${MOKO_CLI}/version_bump.php --path . $([ "$BUMP" = "minor" ] && echo "--minor") 2>/dev/null || true
# Set stability suffix and verify consistency
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "00.00.01")
VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
php ${MOKO_CLI}/version_set_platform.php \
--path . --version "$VERSION" --branch "${{ github.ref_name }}" --stability "$STABILITY" 2>/dev/null || true
php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
# Ensure licensing tags (updateservers, dlid) if enabled in manifest.xml
php ${MOKO_CLI}/manifest_licensing.php --path . --fix 2>/dev/null || true
# Append suffix for output
if [ -n "$SUFFIX" ]; then
VERSION="${VERSION}${SUFFIX}"
fi
# Commit version bump
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git add -A
git diff --cached --quiet || {
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
git push origin HEAD 2>&1
}
# Auto-detect element via manifest_element.php
php ${MOKO_CLI}/manifest_element.php \
--path . --version "$VERSION" --stability "$STABILITY" \
--repo "${GITEA_REPO}" --github-output
# Read back element outputs
EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
[ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
[ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT"
echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ==="
- name: Create release
id: release
run: |
TAG="${{ steps.meta.outputs.tag }}"
VERSION="${{ steps.meta.outputs.version }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php ${MOKO_CLI}/release_create.php \
--path . --version "$VERSION" --tag "$TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --branch "${{ github.ref_name }}" --prerelease
- name: Update release notes from CHANGELOG.md
run: |
TAG="${{ steps.meta.outputs.tag }}"
VERSION="${{ steps.meta.outputs.version }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
# Extract [Unreleased] section from changelog (everything between [Unreleased] and next ## heading)
if [ -f "CHANGELOG.md" ]; then
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
[ -z "$NOTES" ] && NOTES="Release ${VERSION}"
else
NOTES="Release ${VERSION}"
fi
# Update release body via API
RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
"${API_BASE}/releases/tags/${TAG}" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
if [ -n "$RELEASE_ID" ]; then
python3 -c "
import json, urllib.request
body = open('/dev/stdin').read()
payload = json.dumps({'body': body}).encode()
req = urllib.request.Request(
'${API_BASE}/releases/${RELEASE_ID}',
data=payload, method='PATCH',
headers={
'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}',
'Content-Type': 'application/json'
})
urllib.request.urlopen(req)
" <<< "$NOTES"
echo "Release notes updated from CHANGELOG.md"
fi
- name: Build package and upload
id: package
run: |
VERSION="${{ steps.meta.outputs.version }}"
TAG="${{ steps.meta.outputs.tag }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php ${MOKO_CLI}/release_package.php \
--path . --version "$VERSION" --tag "$TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --output /tmp || true
# updates.xml is generated dynamically by MokoGitea license server
# No need to build, commit, or sync updates.xml from workflows
- name: "Delete lesser pre-release channels (cascade)"
continue-on-error: true
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
php ${MOKO_CLI}/release_cascade.php \
--stability "${{ steps.meta.outputs.stability }}" \
--token "${TOKEN}" \
--api-base "${API_BASE}"
- name: Summary
if: always()
run: |
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}"
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
SHA256="${{ steps.package.outputs.sha256_zip }}"
echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
+2 -1
View File
@@ -33,7 +33,8 @@ on:
- scripts
- repo
pull_request:
push:
branches:
- main
permissions:
contents: read
+8 -56
View File
@@ -1,61 +1,13 @@
# Changelog
## [Unreleased]
## [06.15.00] --- 2026-06-12
## [06.16.00] --- 2026-06-18
## [06.15.00] --- 2026-06-18
## [06.15.00] --- 2026-06-18
## [06.14.00] --- 2026-06-14
## [06.15.00] --- 2026-06-12
* FEATURES
* feat(custom-fields): required flag UI and API validation (#597, PR #612)
* Required checkbox in org custom field settings
* Red asterisk indicator on required fields
* API returns 422 when required custom fields are missing
* Validation runs before issue creation (no orphaned issues)
* feat(issues): make status_id, priority_id, type_id required on issue create (#598, PR #613)
* `CreateIssueOption` fields changed from optional `*int64` to `int64`
* Auto-assigns org defaults when value is 0
* MCP `gitea_issue_create` now requires these fields (pass 0 for defaults)
* Explicit metadata errors now return 500 instead of being silently discarded
## [06.14.00] --- 2026-06-11
* FIXES
* fix: return 404 for update feeds when update server is disabled (#589, PR #599)
* fix(ui): raw file button opens in new tab with rel="noopener noreferrer" (#581, PR #600)
* fix: update server feed generation bugs (#601, PR #605)
* default targetplatform changed from `(5|6)\\..*` to `6\\..*` for Joomla 6 compat
* `<client>` uses string values `site`/`administrator` per Joomla update spec (#611)
* pre-release version suffix number preserved (e.g. `-rc2` not `-rc`)
* feed generator uses `FullElementName()` for auto-constructed element names
* fix: wiki API sub-page support and content response (#606, #607, PR #608)
* wiki routes use wildcard to support pages with path separators
* `ListWikiPages` returns pages in subdirectories
* error logging for empty content_base64 responses
* fix: deploy workflow clones wrong repo and runs swapoff (#609)
* removed `swapoff -a` that crashed MySQL during deploys
* fixed source repo URL from MokoGitea to MokoGitea-APP
* MCP
* metadata update tool now exposes element_name, display_name, description, license_name, language fields
## [06.14.00] --- 2026-06-11
All notable changes to MokoGitea are documented here. Versions follow the format
`v{upstream}-moko.{major}.{minor}` (e.g. `v1.26.1-moko.06.03`).
## [06.14.00] --- 2026-06-09
* FEATURES
* feat(api): issue status/priority/type exposed in REST API - GET/PATCH on issues now includes status_id, priority_id, type_id with resolved names
* feat(api): org-level issue metadata endpoints - GET /orgs/{org}/issue-statuses, /issue-priorities, /issue-types
* feat(wiki): org wiki tab - inline wiki rendering from convention repos (wiki / wiki-private)
* feat(wiki): public/private wiki toggle dropdown (same UX as org profile README selector)
* feat(wiki): external wiki support - link to an outside URL from the org wiki tab
* feat(settings): wiki mode setting in org settings (internal repos vs external URL)
* feat(mcp): 5 new MCP tools - gitea_org_issue_statuses_list, gitea_org_issue_priorities_list, gitea_org_issue_types_list, gitea_issue_set_status, gitea_issue_set_priority
* feat(mcp): gitea_issue_create and gitea_issue_update now accept status_id, priority_id, type_id
* MIGRATIONS
* migration 354: add wiki_mode and wiki_url columns to user table for org wiki settings
+1
Submodule mcp-mokogitea-api added at dbaf91546e
+8 -4
View File
@@ -5,6 +5,7 @@ package repo
import (
"context"
"strings"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/db"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/timeutil"
@@ -25,7 +26,6 @@ type RepoManifest struct {
Name string `xorm:"TEXT 'name'"` // project name
Org string `xorm:"TEXT 'org'"` // organization name
Description string `xorm:"TEXT 'description'"` // project description
Version string `xorm:"TEXT 'version'"` // current version string
LicenseSPDX string `xorm:"VARCHAR(50) 'license_spdx'"` // SPDX identifier, e.g. "GPL-3.0-or-later"
LicenseName string `xorm:"TEXT 'license_name'"` // human-readable license name
@@ -60,10 +60,11 @@ func (RepoManifest) TableName() string {
}
// joomlaTypePrefix maps Joomla extension types to their element name prefixes.
// Plugins have no prefix in Joomla's #__extensions table — the element is the
// lowercased, hyphen-free name, and the folder column determines the plugin group.
var joomlaTypePrefix = map[string]string{
"component": "com_",
"module": "mod_",
"plugin": "plg_",
"package": "pkg_",
"template": "tpl_",
"library": "lib_",
@@ -71,14 +72,17 @@ var joomlaTypePrefix = map[string]string{
}
// AutoElementName returns the auto-constructed Joomla element name (e.g. pkg_mokowaas).
// The name is lowercased and hyphens are removed to produce clean element names
// for the #__extensions.element column (e.g. "MokoSuiteBackup" → "pkg_mokosuitebackup").
func (m *RepoManifest) AutoElementName() string {
if m.Name == "" || m.PackageType == "" {
return ""
}
lower := strings.ToLower(strings.ReplaceAll(m.Name, "-", ""))
if prefix, ok := joomlaTypePrefix[m.PackageType]; ok {
return prefix + m.Name
return prefix + lower
}
return m.Name
return lower
}
// FullElementName returns the effective element name: override if set, otherwise auto-constructed.
+76 -68
View File
@@ -256,74 +256,8 @@ func ValidateLicenseKey(ctx context.Context, rawKey, domain string) (*LicenseKey
// Domain restriction check — skip for internal/master keys.
if domain != "" && !key.IsInternal {
now := timeutil.TimeStampNow()
if key.DomainRestriction != "" {
// Domain restriction is set — enforce it.
allowed := false
for _, d := range strings.Split(key.DomainRestriction, ",") {
if strings.EqualFold(strings.TrimSpace(d), domain) {
allowed = true
break
}
}
if !allowed {
// Check if still within the domain lock grace period.
lockHours := pkg.DomainLockHours
if lockHours > 0 && key.FirstUsedUnix > 0 {
lockDeadline := key.FirstUsedUnix + timeutil.TimeStamp(int64(lockHours)*3600)
if now < lockDeadline {
// Grace period active — allow and auto-add this domain.
_ = updateDomainRestriction(ctx, key.ID, domain)
key.DomainRestriction = key.DomainRestriction + "," + domain
allowed = true
}
}
if !allowed {
return nil, nil, fmt.Errorf("domain not allowed for this license key")
}
}
} else {
// No domain restriction set — auto-associate domain.
maxSites := key.MaxSites
if maxSites == 0 {
maxSites = pkg.MaxSites
}
domainKnown, _ := IsDomainKnownForKey(ctx, key.ID, domain)
if !domainKnown {
if maxSites > 0 {
uniqueDomains, err := CountUniqueDomainsByKey(ctx, key.ID)
if err != nil {
return nil, nil, fmt.Errorf("failed to count domains: %w", err)
}
if uniqueDomains >= int64(maxSites) {
return nil, nil, fmt.Errorf("site limit reached (%d/%d)", uniqueDomains, maxSites)
}
}
_ = updateDomainRestriction(ctx, key.ID, domain)
if key.DomainRestriction == "" {
key.DomainRestriction = domain
} else {
key.DomainRestriction = key.DomainRestriction + "," + domain
}
}
}
// Site limit check: use key's MaxSites, fall back to package default.
maxSites := key.MaxSites
if maxSites == 0 {
maxSites = pkg.MaxSites
}
if maxSites > 0 {
uniqueDomains, err := CountUniqueDomainsByKey(ctx, key.ID)
if err != nil {
return nil, nil, fmt.Errorf("failed to count domains: %w", err)
}
// Allow if this domain is already recorded, or if under the limit.
domainKnown, _ := IsDomainKnownForKey(ctx, key.ID, domain)
if !domainKnown && uniqueDomains >= int64(maxSites) {
return nil, nil, fmt.Errorf("site limit reached (%d/%d)", uniqueDomains, maxSites)
}
if err := validateAndAssociateDomain(ctx, key, pkg, domain); err != nil {
return nil, nil, err
}
}
@@ -374,6 +308,80 @@ func ValidateLicenseKeyForRepo(ctx context.Context, rawKey, domain string, repoI
return key, pkg, nil
}
// validateAndAssociateDomain checks domain restrictions and auto-associates new
// domains. The auto-associate path (no existing restriction) runs inside a
// transaction to prevent TOCTOU races on the MaxSites limit. The grace-period
// path (existing restriction, lock window open) also propagates DB errors.
func validateAndAssociateDomain(ctx context.Context, key *LicenseKey, pkg *LicensePackage, domain string) error {
if key.DomainRestriction != "" {
// Domain restriction is set — enforce it.
allowed := false
for _, d := range strings.Split(key.DomainRestriction, ",") {
if strings.EqualFold(strings.TrimSpace(d), domain) {
allowed = true
break
}
}
if !allowed {
// Check if still within the domain lock grace period.
now := timeutil.TimeStampNow()
lockHours := pkg.DomainLockHours
if lockHours > 0 && key.FirstUsedUnix > 0 {
lockDeadline := key.FirstUsedUnix + timeutil.TimeStamp(int64(lockHours)*3600)
if now < lockDeadline {
// Grace period active — allow and auto-add this domain.
if err := updateDomainRestriction(ctx, key.ID, domain); err != nil {
return fmt.Errorf("failed to auto-add domain during grace period: %w", err)
}
key.DomainRestriction = key.DomainRestriction + "," + domain
allowed = true
}
}
if !allowed {
return fmt.Errorf("domain not allowed for this license key")
}
}
return nil
}
// No domain restriction set — auto-associate domain within a transaction
// so the count check and insert are atomic (prevents exceeding MaxSites).
maxSites := key.MaxSites
if maxSites == 0 {
maxSites = pkg.MaxSites
}
return db.WithTx(ctx, func(txCtx context.Context) error {
domainKnown, err := IsDomainKnownForKey(txCtx, key.ID, domain)
if err != nil {
return fmt.Errorf("failed to check domain association: %w", err)
}
if domainKnown {
return nil // already associated, nothing to do
}
if maxSites > 0 {
uniqueDomains, err := CountUniqueDomainsByKey(txCtx, key.ID)
if err != nil {
return fmt.Errorf("failed to count domains: %w", err)
}
if uniqueDomains >= int64(maxSites) {
return fmt.Errorf("site limit reached (%d/%d)", uniqueDomains, maxSites)
}
}
if err := updateDomainRestriction(txCtx, key.ID, domain); err != nil {
return fmt.Errorf("failed to update domain restriction: %w", err)
}
if key.DomainRestriction == "" {
key.DomainRestriction = domain
} else {
key.DomainRestriction = key.DomainRestriction + "," + domain
}
return nil
})
}
// updateDomainRestriction appends a domain to a key's DomainRestriction field in the DB.
func updateDomainRestriction(ctx context.Context, keyID int64, domain string) error {
key, err := GetLicenseKeyByID(ctx, keyID)
+3 -4
View File
@@ -16,7 +16,6 @@ type apiManifest struct {
Name string `json:"name"`
Org string `json:"org"`
Description string `json:"description"`
Version string `json:"version"`
LicenseSPDX string `json:"license_spdx"`
LicenseName string `json:"license_name"`
VersionPrefix string `json:"version_prefix"`
@@ -65,7 +64,7 @@ func GetRepoManifest(ctx *context.APIContext) {
Name: m.Name,
Org: m.Org,
Description: m.Description,
Version: m.Version,
LicenseSPDX: m.LicenseSPDX,
LicenseName: m.LicenseName,
VersionPrefix: m.VersionPrefix,
@@ -108,7 +107,7 @@ func UpdateRepoManifest(ctx *context.APIContext) {
Name: req.Name,
Org: req.Org,
Description: req.Description,
Version: req.Version,
LicenseSPDX: req.LicenseSPDX,
LicenseName: req.LicenseName,
VersionPrefix: req.VersionPrefix,
@@ -136,7 +135,7 @@ func UpdateRepoManifest(ctx *context.APIContext) {
Name: m.Name,
Org: m.Org,
Description: m.Description,
Version: m.Version,
LicenseSPDX: m.LicenseSPDX,
LicenseName: m.LicenseName,
VersionPrefix: m.VersionPrefix,
+26 -5
View File
@@ -10,8 +10,9 @@ import (
"strings"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/db"
updateserver_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/updateserver"
repo_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/repo"
updateserver_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/updateserver"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/services/context"
)
@@ -57,15 +58,35 @@ func ServeChangelogXML(ctx *context.Context) {
return
}
// Get extension metadata for element name and type.
cfg := updateserver_model.GetEffectiveConfig(ctx, repo.OwnerID, repo.ID)
// Resolve element name and type:
// manifest first, then config table fallback, then repo-derived default.
element := strings.ToLower(repo.Name)
extType := "component"
elementFromManifest := false
extTypeFromManifest := false
manifest, err := repo_model.GetRepoManifest(ctx, repo.ID)
if err != nil {
log.Warn("ServeChangelogXML: GetRepoManifest for repo %d: %v", repo.ID, err)
}
if manifest != nil {
if elem := manifest.FullElementName(); elem != "" {
element = elem
elementFromManifest = true
}
if manifest.PackageType != "" {
extType = manifest.PackageType
extTypeFromManifest = true
}
}
// Config table fallback: apply only when the manifest did not provide a value.
cfg := updateserver_model.GetEffectiveConfig(ctx, repo.OwnerID, repo.ID)
if cfg != nil {
if cfg.ExtensionName != "" {
if !elementFromManifest && cfg.ExtensionName != "" {
element = cfg.ExtensionName
}
if cfg.ExtensionType != "" {
if !extTypeFromManifest && cfg.ExtensionType != "" {
extType = cfg.ExtensionType
}
}
+4 -3
View File
@@ -78,9 +78,10 @@ func validateUpdateKey(ctx *context.Context) (allowedChannels []string, ok bool,
// ServeUpdatesXML generates and serves a Joomla-compatible updates.xml
// from the repository's releases.
func ServeUpdatesXML(ctx *context.Context) {
// Block if platform doesn't include joomla.
platform := ctx.Data["RepoUpdatePlatform"]
if platform == "dolibarr" {
// Block if platform is set to a non-Joomla value.
// Empty/unset defaults to joomla for backwards compatibility.
platform, _ := ctx.Data["RepoUpdatePlatform"].(string)
if platform != "" && platform != "joomla" && platform != "both" {
ctx.NotFound(nil)
return
}
+15 -5
View File
@@ -383,12 +383,22 @@ func GenerateJoomlaXML(ctx context.Context, repo *repo_model.Repository, require
infoURL = meta.SupportURL
}
// Joomla <client> element uses string values per the update server spec.
// Joomla's XML parser maps these to client_id internally (0/1).
client := "site"
// Joomla <client> element must match the client_id stored in #__extensions.
// Joomla's update finder matches by (element, type, client_id, folder) —
// a mismatch causes extension_id=0 and the update never shows.
//
// Joomla hardcodes client_id per extension type in the installer adapters:
// component → client_id=1 (ComponentAdapter.php:900)
// package → client_id=0 (PackageAdapter.php:548)
// plugin → client_id=0 (PluginAdapter.php:492)
// library → client_id=0 (LibraryAdapter.php:420)
// file → client_id=0 (FileAdapter.php:422)
// module → client_id from manifest (0=site, 1=admin)
// template → client_id from manifest (0=site, 1=admin)
client := "site" // default: client_id=0
switch extType {
case "package", "component", "library", "file":
client = "administrator"
case "component":
client = "administrator" // client_id=1
}
u := xmlUpdate{