diff --git a/.mokogitea/manifest.xml b/.mokogitea/manifest.xml
index b68bb4d0..13dbf20b 100644
--- a/.mokogitea/manifest.xml
+++ b/.mokogitea/manifest.xml
@@ -8,7 +8,7 @@
MokoWaaS
MokoConsulting
White-label identity, security hardening, and tenant restriction layer for WaaS-managed Joomla environments
- 02.10.06
+ 02.11.00
GNU General Public License v3
diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml
index 698251d1..2f70d8cc 100644
--- a/.mokogitea/workflows/pre-release.yml
+++ b/.mokogitea/workflows/pre-release.yml
@@ -78,15 +78,7 @@ jobs:
- name: Detect platform
id: platform
run: |
- PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1 | tr -d '[:space:]')
- [ -z "$PLATFORM" ] && PLATFORM="generic"
- echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
- MANIFEST=$(find ./src -maxdepth 1 -name "pkg_*.xml" -exec grep -l '/dev/null | head -1)
- [ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" ! -path "*/packages/*" -exec grep -l '/dev/null | head -1)
- [ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '/dev/null | head -1)
- MOD_FILE=$(find . -maxdepth 4 -name "mod*.class.php" ! -path "./.git/*" -exec grep -l 'extends DolibarrModules' {} \; 2>/dev/null | head -1)
- echo "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT"
- echo "mod_file=${MOD_FILE}" >> "$GITHUB_OUTPUT"
+ php ${MOKO_CLI}/manifest_read.php --path . --github-output
- name: Resolve metadata and bump version
id: meta
@@ -104,12 +96,6 @@ jobs:
php ${MOKO_CLI}/version_bump.php --path .
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null)
[ -z "$VERSION" ] && VERSION="00.00.01"
- TODAY=$(date +%Y-%m-%d)
-
- # Update platform-specific manifest
- PLATFORM="${{ steps.platform.outputs.platform }}"
- MANIFEST="${{ steps.platform.outputs.manifest }}"
- MOD_FILE="${{ steps.platform.outputs.mod_file }}"
php ${MOKO_CLI}/version_set_platform.php \
--path . --version "$VERSION" --branch "${{ github.ref_name }}" 2>/dev/null || true
@@ -127,36 +113,16 @@ jobs:
git push origin HEAD 2>&1
}
- # Auto-detect element (platform-aware)
- EXT_ELEMENT=""
- case "$PLATFORM" in
- joomla)
- if [ -n "$MANIFEST" ]; then
- EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1)
- if [ -z "$EXT_ELEMENT" ]; then
- EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]')
- case "$EXT_ELEMENT" in
- templatedetails|manifest) EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ;;
- esac
- fi
- else
- EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
- fi
- ;;
- dolibarr)
- if [ -n "$MOD_FILE" ]; then
- MOD_BASENAME=$(basename "$MOD_FILE" .class.php)
- EXT_ELEMENT=$(echo "$MOD_BASENAME" | sed 's/^mod//' | tr '[:upper:]' '[:lower:]')
- else
- EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
- fi
- ;;
- *)
- EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
- ;;
- esac
+ # Auto-detect element via manifest_element.php
+ php ${MOKO_CLI}/manifest_element.php \
+ --path . --version "$VERSION" --stability "$STABILITY" \
+ --repo "${GITEA_REPO}" --github-output
- ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip"
+ # 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}${SUFFIX}.zip"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
@@ -278,54 +244,17 @@ jobs:
- name: Update updates.xml
if: steps.platform.outputs.platform == 'joomla'
run: |
- STABILITY="${{ steps.meta.outputs.stability }}"
VERSION="${{ steps.meta.outputs.version }}"
- SHA256="${{ steps.zip.outputs.sha256 }}"
- ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
- TAG="${{ steps.meta.outputs.tag }}"
+ STABILITY="${{ steps.meta.outputs.stability }}"
if [ ! -f "updates.xml" ]; then
echo "No updates.xml -- skipping"
exit 0
fi
- # Map stability to XML tag name
- case "$STABILITY" in
- development) XML_TAG="development" ;;
- alpha) XML_TAG="alpha" ;;
- beta) XML_TAG="beta" ;;
- release-candidate) XML_TAG="rc" ;;
- *) XML_TAG="$STABILITY" ;;
- esac
-
- DOWNLOAD_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${TAG}/${ZIP_NAME}"
-
- # Use PHP to update the channel in updates.xml
- php -r '
- $xml_tag = $argv[1];
- $version = $argv[2];
- $sha256 = $argv[3];
- $url = $argv[4];
- $date = date("Y-m-d");
-
- $content = file_get_contents("updates.xml");
- $pattern = "/((?:(?!<\/update>).)*?" . preg_quote($xml_tag) . "<\/tag>.*?<\/update>)/s";
-
- $content = preg_replace_callback($pattern, function($m) use ($version, $sha256, $url, $date) {
- $block = $m[0];
- $block = preg_replace("/[^<]*<\/version>/", "{$version}", $block);
- if (strpos($block, "") !== false) {
- $block = preg_replace("/[^<]*<\/sha256>/", "{$sha256}", $block);
- } else {
- $block = str_replace("", "\n {$sha256}", $block);
- }
- $block = preg_replace("/(]*>)[^<]*(<\/downloadurl>)/", "\${1}{$url}\${2}", $block);
- return $block;
- }, $content);
-
- file_put_contents("updates.xml", $content);
- echo "Updated {$xml_tag} channel: version={$version}\n";
- ' "$XML_TAG" "$VERSION" "$SHA256" "$DOWNLOAD_URL"
+ php ${MOKO_CLI}/updates_xml_build.php \
+ --path . --version "${VERSION}" --stability "${STABILITY}" \
+ --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}"
# Commit and push
if ! git diff --quiet updates.xml 2>/dev/null; then
diff --git a/.mokogitea/workflows/update-server.yml b/.mokogitea/workflows/update-server.yml
index fd6407f7..8660a431 100644
--- a/.mokogitea/workflows/update-server.yml
+++ b/.mokogitea/workflows/update-server.yml
@@ -206,13 +206,76 @@ jobs:
DOWNLOAD_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}"
INFO_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}"
- # -- Build install packages and upload to release --------------------
- php /tmp/moko-platform/cli/release_package.php \
- --path . --version "${DISPLAY_VERSION}" --tag "${RELEASE_TAG}" \
- --token "${{ secrets.GA_TOKEN }}" --api-base "${API_BASE}" \
- --repo "${GITEA_REPO}" --output /tmp 2>&1 || true
+ # -- Build install packages (ZIP + tar.gz) --------------------
+ SOURCE_DIR="src"
+ [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
+ if [ -d "$SOURCE_DIR" ]; then
+ EXCLUDES=".ftpignore sftp-config* *.ppk *.pem *.key .env*"
+ TAR_NAME="${EXT_ELEMENT}-${DISPLAY_VERSION}.tar.gz"
- echo "Package built and uploaded for ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY
+ cd "$SOURCE_DIR"
+ zip -r "/tmp/${PACKAGE_NAME}" . -x $EXCLUDES
+ cd ..
+ tar -czf "/tmp/${TAR_NAME}" -C "$SOURCE_DIR" \
+ --exclude='.ftpignore' --exclude='sftp-config*' \
+ --exclude='*.ppk' --exclude='*.pem' --exclude='*.key' --exclude='.env*' .
+
+ SHA256=$(sha256sum "/tmp/${PACKAGE_NAME}" | cut -d' ' -f1)
+
+ # Ensure release exists on Gitea
+ RELEASE_JSON=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
+ "${API_BASE}/releases/tags/${RELEASE_TAG}" 2>/dev/null || true)
+ RELEASE_ID=$(echo "$RELEASE_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
+
+ if [ -z "$RELEASE_ID" ]; then
+ # Create release
+ RELEASE_JSON=$(curl -sf -X POST -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
+ -H "Content-Type: application/json" \
+ "${API_BASE}/releases" \
+ -d "$(python3 -c "import json; print(json.dumps({
+ 'tag_name': '${RELEASE_TAG}',
+ 'name': '${RELEASE_TAG} (${DISPLAY_VERSION})',
+ 'body': '${STABILITY} release',
+ 'prerelease': True,
+ 'target_commitish': 'main'
+ }))")" 2>/dev/null || true)
+ RELEASE_ID=$(echo "$RELEASE_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
+ fi
+
+ if [ -n "$RELEASE_ID" ]; then
+ # Delete existing assets with same name before uploading
+ ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
+ "${API_BASE}/releases/${RELEASE_ID}/assets" 2>/dev/null || echo "[]")
+ for ASSET_FILE in "$PACKAGE_NAME" "$TAR_NAME"; do
+ ASSET_ID=$(echo "$ASSETS" | python3 -c "
+ import sys,json
+ assets = json.load(sys.stdin)
+ for a in assets:
+ if a['name'] == '${ASSET_FILE}':
+ print(a['id']); break
+ " 2>/dev/null || true)
+ if [ -n "$ASSET_ID" ]; then
+ curl -sf -X DELETE -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
+ "${API_BASE}/releases/${RELEASE_ID}/assets/${ASSET_ID}" 2>/dev/null || true
+ fi
+ done
+
+ # Upload both formats
+ curl -sf -X POST -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
+ -H "Content-Type: application/octet-stream" \
+ --data-binary @"/tmp/${PACKAGE_NAME}" \
+ "${API_BASE}/releases/${RELEASE_ID}/assets?name=${PACKAGE_NAME}" > /dev/null 2>&1 || true
+
+ curl -sf -X POST -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
+ -H "Content-Type: application/octet-stream" \
+ --data-binary @"/tmp/${TAR_NAME}" \
+ "${API_BASE}/releases/${RELEASE_ID}/assets?name=${TAR_NAME}" > /dev/null 2>&1 || true
+ fi
+
+ echo "Packages: ${PACKAGE_NAME} + ${TAR_NAME} (SHA: ${SHA256})" >> $GITHUB_STEP_SUMMARY
+ else
+ SHA256=""
+ fi
# -- Build the new entry (canonical format matching release.yml) --
NEW_ENTRY=""
diff --git a/README.md b/README.md
index c271f197..72702fad 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoWaaS
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS
- VERSION: 02.10.06
+ VERSION: 02.11.00
PATH: /README.md
BRIEF: MokoWaaS platform plugin for Joomla
-->
diff --git a/src/packages/com_mokowaas/mokowaas.xml b/src/packages/com_mokowaas/mokowaas.xml
index 3ad2c3dd..e55bc1bf 100644
--- a/src/packages/com_mokowaas/mokowaas.xml
+++ b/src/packages/com_mokowaas/mokowaas.xml
@@ -7,7 +7,7 @@
GPL-3.0-or-later
hello@mokoconsulting.tech
https://mokoconsulting.tech
- 02.10.06
+ 02.11.00
Minimal API-only component for MokoWaaS. Provides REST endpoints for site health, cache, updates, and backups.
Moko\Component\MokoWaaS\Api
diff --git a/src/packages/plg_system_mokowaas/mokowaas.xml b/src/packages/plg_system_mokowaas/mokowaas.xml
index 392ad3dc..7b2ca644 100644
--- a/src/packages/plg_system_mokowaas/mokowaas.xml
+++ b/src/packages/plg_system_mokowaas/mokowaas.xml
@@ -30,7 +30,7 @@
GNU General Public License version 3 or later; see LICENSE.md
hello@mokoconsulting.tech
https://mokoconsulting.tech
- 02.10.06
+ 02.11.00
This plugin rebrands the Joomla system interface with MokoWaaS identity. It applies language overrides and ensures consistent branding across the platform.
Moko\Plugin\System\MokoWaaS
script.php
diff --git a/src/packages/plg_webservices_mokowaas/mokowaas.xml b/src/packages/plg_webservices_mokowaas/mokowaas.xml
index dfd5973c..a90c72e5 100644
--- a/src/packages/plg_webservices_mokowaas/mokowaas.xml
+++ b/src/packages/plg_webservices_mokowaas/mokowaas.xml
@@ -7,7 +7,7 @@
GPL-3.0-or-later
hello@mokoconsulting.tech
https://mokoconsulting.tech
- 02.10.06
+ 02.11.00
Joomla Web Services API routes for MokoWaaS site management — health checks, cache, updates, backups, and site info.
Moko\Plugin\WebServices\MokoWaaS
diff --git a/src/pkg_mokowaas.xml b/src/pkg_mokowaas.xml
index b5c30358..063c39e5 100644
--- a/src/pkg_mokowaas.xml
+++ b/src/pkg_mokowaas.xml
@@ -2,7 +2,7 @@
MokoWaaS
mokowaas
- 02.10.06
+ 02.11.00
2026-05-23
Moko Consulting
hello@mokoconsulting.tech