diff --git a/.mokogitea/manifest.xml b/.mokogitea/manifest.xml
index e134379..dea8d4e 100644
--- a/.mokogitea/manifest.xml
+++ b/.mokogitea/manifest.xml
@@ -9,7 +9,7 @@
Template - MokoOnyx
MokoConsulting
MokoOnyx - Joomla site template (successor to MokoCassiopeia)
- 02.20.00
+ 02.19.06
GNU General Public License v3
diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml
index 5e03998..5906d98 100644
--- a/.mokogitea/workflows/issue-branch.yml
+++ b/.mokogitea/workflows/issue-branch.yml
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Automation
-# VERSION: 02.20.00
+# VERSION: 02.19.06
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml
index 780150d..1a9eeef 100644
--- a/.mokogitea/workflows/pre-release.yml
+++ b/.mokogitea/workflows/pre-release.yml
@@ -63,16 +63,22 @@ jobs:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: |
- if ! command -v composer &> /dev/null; 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
+ # 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/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; 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
+ git clone --depth 1 --branch main --quiet \
+ “https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git” \
+ /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
- # Always fetch latest CLI tools — never use stale cache from previous runs
- rm -rf /tmp/moko-platform-api
- git clone --depth 1 --branch main --quiet \
- "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
- /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"
- name: Detect platform
id: platform
@@ -96,20 +102,23 @@ jobs:
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
esac
- # Read current version (bump already handled by push workflow)
- VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null)
- [ -z "$VERSION" ] && VERSION="00.00.01"
+ # Bump version via CLI: patch for dev/alpha/beta, minor for RC
+ case "$STABILITY" in
+ release-candidate) BUMP="minor" ;;
+ *) BUMP="patch" ;;
+ esac
- # Strip any existing suffix from version before applying stability
+ 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
-
- # Verify version consistency across all files
php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
- # Update VERSION variable with suffix
+ # Append suffix for output
if [ -n "$SUFFIX" ]; then
VERSION="${VERSION}${SUFFIX}"
fi
@@ -155,19 +164,39 @@ jobs:
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --branch dev --prerelease
- - name: Ensure prerelease flag
+ - 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}"
- # Get release ID by tag and force prerelease=true
- RELEASE_ID=$(curl -s "${API_BASE}/releases/tags/${TAG}" \
- -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" | jq -r '.id // empty')
+
+ # 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
- curl -s -X PATCH "${API_BASE}/releases/${RELEASE_ID}" \
- -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
- -H "Content-Type: application/json" \
- -d '{"prerelease": true}'
- echo "Marked release ${TAG} (id=${RELEASE_ID}) as prerelease"
+ 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
@@ -181,55 +210,8 @@ jobs:
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --output /tmp || true
- - name: Update updates.xml
- if: steps.platform.outputs.platform == 'joomla'
- run: |
- VERSION="${{ steps.meta.outputs.version }}"
- STABILITY="${{ steps.meta.outputs.stability }}"
- SHA256="${{ steps.package.outputs.sha256_zip }}"
-
- if [ ! -f "updates.xml" ]; then
- echo "No updates.xml -- skipping"
- exit 0
- fi
-
- SHA_FLAG=""
- [ -n "$SHA256" ] && SHA_FLAG="--sha ${SHA256}"
-
- php ${MOKO_CLI}/updates_xml_build.php \
- --path . --version "${VERSION}" --stability "${STABILITY}" \
- --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \
- ${SHA_FLAG}
-
- # Commit and push
- if ! git diff --quiet updates.xml 2>/dev/null; then
- git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
- git config --local user.name "gitea-actions[bot]"
- git add updates.xml
- git commit -m "chore: update ${STABILITY} channel ${VERSION} [skip ci]"
- git push origin HEAD 2>&1 || echo "WARNING: push failed"
- fi
-
- - name: "Sync updates.xml to all branches"
- if: steps.platform.outputs.platform == 'joomla'
- run: |
- CURRENT_BRANCH="${{ github.ref_name }}"
- git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
- git config --local user.name "gitea-actions[bot]"
-
- for BRANCH in main dev; do
- [ "$BRANCH" = "$CURRENT_BRANCH" ] && continue
- echo "Syncing updates.xml -> ${BRANCH}"
- git fetch origin "${BRANCH}" 2>/dev/null || continue
- git checkout "origin/${BRANCH}" -- updates.xml 2>/dev/null || continue
- git checkout "${CURRENT_BRANCH}" -- updates.xml
- if ! git diff --quiet updates.xml 2>/dev/null; then
- git add updates.xml
- git commit -m "chore: sync updates.xml from ${CURRENT_BRANCH} [skip ci]"
- git push origin HEAD:refs/heads/${BRANCH} 2>&1 || echo "WARNING: push to ${BRANCH} failed"
- fi
- git checkout "${CURRENT_BRANCH}" 2>/dev/null
- done
+ # 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
diff --git a/.mokogitea/workflows/update-submodule-waas.yml b/.mokogitea/workflows/update-submodule-waas.yml
deleted file mode 100644
index 39461ce..0000000
--- a/.mokogitea/workflows/update-submodule-waas.yml
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (C) 2026 Moko Consulting
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-# BRIEF: Update MokoOnyx submodule in MokoWaas on main and dev branches
-
-name: "Update MokoWaas Submodule"
-
-on:
- release:
- types: [published]
-
-env:
- FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
- GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
- WAAS_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
- WAAS_REPO: MokoWaaS
- # Path where MokoOnyx lives as a submodule inside MokoWaaS
- SUBMODULE_PATH: src/packages/tpl_mokoonyx
-
-permissions:
- contents: read
-
-jobs:
- update-submodule:
- name: "Update submodule on ${{ matrix.branch }}"
- runs-on: ubuntu-latest
- strategy:
- matrix:
- branch: [main, dev]
- fail-fast: false
-
- steps:
- - name: Get release info
- id: release
- run: |
- TAG="${{ github.event.release.tag_name }}"
- IS_PRE="${{ github.event.release.prerelease }}"
- echo "tag=${TAG}" >> $GITHUB_OUTPUT
- echo "prerelease=${IS_PRE}" >> $GITHUB_OUTPUT
- echo "Release tag: ${TAG} (prerelease: ${IS_PRE})"
-
- # Skip pre-releases (RC) — only update on stable releases
- - name: Skip pre-releases
- if: steps.release.outputs.prerelease == 'true'
- run: |
- echo "Skipping pre-release ${TAG} — only stable releases update MokoWaas"
- exit 0
-
- - name: Clone MokoWaas
- if: steps.release.outputs.prerelease != 'true'
- run: |
- git clone --branch "${{ matrix.branch }}" --depth 1 --recurse-submodules \
- "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${WAAS_ORG}/${WAAS_REPO}.git" \
- waas
- env:
- GIT_TERMINAL_PROMPT: 0
-
- - name: Configure git
- if: steps.release.outputs.prerelease != 'true'
- working-directory: waas
- run: |
- git config user.email "gitea-actions[bot]@mokoconsulting.tech"
- git config user.name "gitea-actions[bot]"
- git remote set-url origin \
- "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${WAAS_ORG}/${WAAS_REPO}.git"
-
- - name: Update submodule to release tag
- if: steps.release.outputs.prerelease != 'true'
- working-directory: waas
- run: |
- TAG="${{ steps.release.outputs.tag }}"
- SUBPATH="${SUBMODULE_PATH}"
-
- # Verify submodule exists
- if [ ! -f ".gitmodules" ] || ! grep -q "${SUBPATH}" .gitmodules; then
- echo "::error::Submodule '${SUBPATH}' not found in .gitmodules on ${{ matrix.branch }}"
- exit 1
- fi
-
- # Fetch the tag in the submodule and update to it
- cd "${SUBPATH}"
- git fetch origin "refs/tags/${TAG}:refs/tags/${TAG}" --depth 1
- git checkout "${TAG}"
- cd -
-
- # Stage the submodule pointer change
- git add "${SUBPATH}"
-
- # Only commit if there's actually a change
- if git diff --cached --quiet; then
- echo "Submodule already at ${TAG} on ${{ matrix.branch }} — nothing to do"
- else
- git commit -m "chore: update MokoOnyx submodule to ${TAG}
-
-Authored-by: Moko Consulting"
- git push origin "${{ matrix.branch }}"
- echo "Updated MokoOnyx to ${TAG} on ${{ matrix.branch }}"
- fi
-
- - name: Summary
- if: always() && steps.release.outputs.prerelease != 'true'
- run: |
- TAG="${{ steps.release.outputs.tag }}"
- echo "## MokoWaas Submodule Update (${{ matrix.branch }})" >> $GITHUB_STEP_SUMMARY
- echo "Updated \`${SUBMODULE_PATH}\` to \`${TAG}\`" >> $GITHUB_STEP_SUMMARY
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4561fb2..6a0bcae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,16 +8,13 @@
DEFGROUP: Joomla.Template.Site
INGROUP: MokoOnyx.Documentation
PATH: ./CHANGELOG.md
- VERSION: 02.20.00
+ VERSION: 02.19.06
BRIEF: Changelog file documenting version history of MokoOnyx
-->
-# Changelog — MokoOnyx (VERSION: 02.20.00)
-
+# Changelog — MokoOnyx (VERSION: 02.19.06)
## [Unreleased]
-## [02.20.00] --- 2026-06-04
-
### Fixed
- Strip Joomla-injected `p-2` padding class from Font Awesome icons in all menu overrides (default, mainmenu, horizontal)
diff --git a/SECURITY.md b/SECURITY.md
index 46cba7c..325251f 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -10,7 +10,7 @@
INGROUP: MokoOnyx.Governance
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
FILE: SECURITY.md
- VERSION: 02.20.00
+ VERSION: 02.19.06
BRIEF: Security policy and vulnerability reporting process for MokoOnyx.
PATH: /SECURITY.md
NOTE: This policy is process oriented and does not replace secure engineering practices.
diff --git a/src/helper/migrate.php b/src/helper/migrate.php
index b57d956..1c9e088 100644
--- a/src/helper/migrate.php
+++ b/src/helper/migrate.php
@@ -236,11 +236,11 @@ use Joomla\CMS\Log\Log;
// Update the update server
try {
- $onyxUpdatesUrl = 'https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/updates.xml';
+ $onyxUpdatesUrl = 'https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/updates.xml';
$query = $db->getQuery(true)
->update('#__update_sites')
->set($db->quoteName('location') . ' = ' . $db->quote($onyxUpdatesUrl))
- ->set($db->quoteName('name') . ' = ' . $db->quote($newDisplay))
+ ->set($db->quoteName('name') . ' = ' . $db->quote('Template - MokoOnyx'))
->where($db->quoteName('location') . ' LIKE ' . $db->quote('%MokoCassiopeia%'));
$db->setQuery($query)->execute();
$n = $db->getAffectedRows();
diff --git a/src/html/layouts/joomla/module/card.php b/src/html/layouts/joomla/module/card.php
index 316554d..cf2ec1d 100644
--- a/src/html/layouts/joomla/module/card.php
+++ b/src/html/layouts/joomla/module/card.php
@@ -10,7 +10,7 @@
* INGROUP: MokoOnyx
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /html/layouts/joomla/module/card.php
- * VERSION: 02.20.00
+ * VERSION: 02.19.06
* BRIEF: Custom card module chrome — renders module titles for all modules
*/
diff --git a/src/html/layouts/mokoonyx/article-metadata.php b/src/html/layouts/mokoonyx/article-metadata.php
index 17812e1..020bff6 100644
--- a/src/html/layouts/mokoonyx/article-metadata.php
+++ b/src/html/layouts/mokoonyx/article-metadata.php
@@ -11,7 +11,7 @@
* INGROUP: MokoOnyx.Layouts
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /src/html/layouts/mokoonyx/article-metadata.php
- * VERSION: 02.20.00
+ * VERSION: 02.19.06
* BRIEF: Article metadata footer layout -- renders jcfields grouped by field group
*/
diff --git a/src/media/css/a11y-high-contrast.css b/src/media/css/a11y-high-contrast.css
index e9e2471..5c2b707 100644
--- a/src/media/css/a11y-high-contrast.css
+++ b/src/media/css/a11y-high-contrast.css
@@ -10,7 +10,7 @@
* INGROUP: MokoOnyx.Accessibility
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: ./media/css/a11y-high-contrast.css
- * VERSION: 02.20.00
+ * VERSION: 02.19.06
* BRIEF: High-contrast stylesheet for accessibility toolbar
*/
diff --git a/src/script.php b/src/script.php
index 35f6641..839642f 100644
--- a/src/script.php
+++ b/src/script.php
@@ -533,6 +533,37 @@ class Tpl_MokoonyxInstallerScript implements InstallerScriptInterface
}
}
+ // Remove faulty "template-mokoonyx" duplicate (wrong element name from bad install)
+ $faultyId = (int) $db->setQuery(
+ $db->getQuery(true)
+ ->select('extension_id')
+ ->from('#__extensions')
+ ->where($db->quoteName('element') . ' = ' . $db->quote('template-mokoonyx'))
+ ->where($db->quoteName('type') . ' = ' . $db->quote('template'))
+ )->loadResult();
+
+ if ($faultyId) {
+ $db->setQuery(
+ $db->getQuery(true)
+ ->delete('#__update_sites_extensions')
+ ->where('extension_id = ' . $faultyId)
+ )->execute();
+
+ $db->setQuery(
+ $db->getQuery(true)
+ ->delete('#__extensions')
+ ->where('extension_id = ' . $faultyId)
+ )->execute();
+
+ $db->setQuery(
+ $db->getQuery(true)
+ ->delete('#__template_styles')
+ ->where($db->quoteName('template') . ' = ' . $db->quote('template-mokoonyx'))
+ )->execute();
+
+ $this->logMessage('Removed faulty template-mokoonyx duplicate extension.');
+ }
+
// Remove stale MokoCassiopeia if not set as default
$oldExt = (int) $db->setQuery(
$db->getQuery(true)
diff --git a/src/templateDetails.xml b/src/templateDetails.xml
index a8bd706..0517138 100644
--- a/src/templateDetails.xml
+++ b/src/templateDetails.xml
@@ -35,7 +35,7 @@
mokoonyx
- 02.20.00
+ 02.19.06-dev
script.php
2026-05-16
Jonathan Miller || Moko Consulting
diff --git a/updates.xml b/updates.xml
deleted file mode 100644
index eb3c962..0000000
--- a/updates.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
- Template - MokoOnyx
- Template - MokoOnyx development build.
- mokoonyx
- template
- site
- 02.19.06-dev
- 2026-06-04
- https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/development
-
- https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/development/tpl_mokoonyx-02.19.06-dev.zip
-
- 718dd24295a5c8e3a0c855b01f86bf619bae84a4f7ab6e037c5cd5bfaadb2e30
- dev
- https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/CHANGELOG.md
- Moko Consulting
- https://mokoconsulting.tech
-
- 8.1.0
-
-
- Template - MokoOnyx
- Template - MokoOnyx stable build.
- mokoonyx
- template
- site
- 02.20.00
- 2026-06-04
- https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/stable
-
- https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/stable/tpl_mokoonyx-02.20.00.zip
-
- 00851a8a0ce9f64b873cbfbf4495422e78788d303ad5a4ac13f48122a8bc9e30
- stable
- https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/CHANGELOG.md
- Moko Consulting
- https://mokoconsulting.tech
-
- 8.1.0
-
-