From e256acbcbbe616cf29c891adccee9331f8700903 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:12:03 +0000 Subject: [PATCH 01/11] chore(ci): add auto-bump.yml from moko-platform [skip ci] --- .mokogitea/workflows/auto-bump.yml | 82 ++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 .mokogitea/workflows/auto-bump.yml diff --git a/.mokogitea/workflows/auto-bump.yml b/.mokogitea/workflows/auto-bump.yml new file mode 100644 index 0000000..ef0aedc --- /dev/null +++ b/.mokogitea/workflows/auto-bump.yml @@ -0,0 +1,82 @@ +# Copyright (C) 2026 Moko Consulting +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# FILE INFORMATION +# DEFGROUP: Gitea.Workflow +# INGROUP: moko-platform.Release +# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform +# PATH: /.mokogitea/workflows/auto-bump.yml +# VERSION: 09.02.00 +# BRIEF: Auto patch-bump version on every push to dev + +name: "Universal: Auto Version Bump" + +on: + push: + branches: + - dev + +env: + GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + +permissions: + contents: write + +jobs: + bump: + name: Patch Bump + runs-on: release + if: >- + !contains(github.event.head_commit.message, '[skip ci]') && + !contains(github.event.head_commit.message, '[skip bump]') + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + token: ${{ secrets.GA_TOKEN }} + fetch-depth: 1 + + - name: Setup moko-platform tools + 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 + fi + if [ -d "/opt/moko-platform/cli" ]; then + echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV" + else + git clone --depth 1 --branch main --quiet \ + "https://x-access-token:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/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 + + - name: Patch bump version + run: | + BUMP=$(php ${MOKO_CLI}/version_bump.php --path . 2>&1) || true + echo "$BUMP" + + VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) || true + [ -z "$VERSION" ] && { echo "No version found — skipping"; exit 0; } + + # Propagate to platform manifests + php ${MOKO_CLI}/version_set_platform.php \ + --path . --version "$VERSION" --branch dev 2>/dev/null || true + php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true + + # Commit if anything changed + if git diff --quiet && git diff --cached --quiet; then + echo "No version changes to commit" + exit 0 + fi + + git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" + git config --local user.name "gitea-actions[bot]" + git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" + git add -A + git commit -m "chore(version): patch bump to ${VERSION} [skip ci]" \ + --author="gitea-actions[bot] " + git push origin dev + echo "Bumped to ${VERSION}" >> $GITHUB_STEP_SUMMARY From e030d85886f1a2bb973260bf254265872573719e Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:13:15 +0000 Subject: [PATCH 02/11] chore(ci): update pre-release.yml from moko-platform [skip ci] --- .mokogitea/workflows/pre-release.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml index 2f70d8c..83443c7 100644 --- a/.mokogitea/workflows/pre-release.yml +++ b/.mokogitea/workflows/pre-release.yml @@ -92,8 +92,7 @@ jobs: release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;; esac - # Patch bump via CLI tool - php ${MOKO_CLI}/version_bump.php --path . + # 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" @@ -276,7 +275,7 @@ jobs: [ "$BRANCH" = "$CURRENT_BRANCH" ] && continue echo "Syncing updates.xml -> ${BRANCH}" git fetch origin "${BRANCH}" 2>/dev/null || continue - git checkout "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 From ebbd1058f3b1c693123f7cbad5f7212e3d55a254 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:23:51 +0000 Subject: [PATCH 03/11] chore(ci): update auto-release.yml from moko-platform [skip ci] --- .mokogitea/workflows/auto-release.yml | 380 ++++---------------------- 1 file changed, 51 insertions(+), 329 deletions(-) diff --git a/.mokogitea/workflows/auto-release.yml b/.mokogitea/workflows/auto-release.yml index eca25d8..d665ce7 100644 --- a/.mokogitea/workflows/auto-release.yml +++ b/.mokogitea/workflows/auto-release.yml @@ -31,6 +31,15 @@ on: branches: - main workflow_dispatch: + inputs: + action: + description: 'Action to perform' + required: false + type: choice + default: release + options: + - release + - promote-rc env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true @@ -47,8 +56,8 @@ jobs: name: Promote Pre-Release to RC runs-on: release if: >- - github.event.action == 'opened' && - github.event.pull_request.draft == true + (github.event.action == 'opened' && github.event.pull_request.draft == true) || + (github.event_name == 'workflow_dispatch' && inputs.action == 'promote-rc') steps: - name: Checkout repository @@ -100,7 +109,8 @@ jobs: name: Build & Release Pipeline runs-on: release if: >- - github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' + github.event.pull_request.merged == true || + (github.event_name == 'workflow_dispatch' && inputs.action != 'promote-rc') steps: - name: Checkout repository @@ -170,18 +180,7 @@ jobs: echo "::notice::No RC release — full build pipeline" fi - - name: "Step 1b: Bump version" - id: bump - if: >- - steps.version.outputs.skip != 'true' && - steps.rc.outputs.promote != 'true' - run: | - MOKO_API="/tmp/moko-platform-api/cli" - BUMP=$(php ${MOKO_API}/version_bump.php --path . --minor) - VERSION=$(echo "$BUMP" | grep -oP '\d{2}\.\d{2}\.\d{2}$' || true) - [ -z "$VERSION" ] && VERSION=$(php ${MOKO_API}/version_read.php --path .) - echo "version=${VERSION}" >> "$GITHUB_OUTPUT" - echo "Bumped to: ${VERSION}" + # Version bump handled by auto-bump.yml (minor on main, patch on dev) - name: Check if already released if: steps.version.outputs.skip != 'true' @@ -208,96 +207,9 @@ jobs: steps.version.outputs.skip != 'true' && steps.check.outputs.already_released != 'true' run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - ERRORS=0 - - PLATFORM="${{ steps.platform.outputs.platform }}" - MANIFEST="${{ steps.platform.outputs.manifest }}" - MOD_FILE="${{ steps.platform.outputs.mod_file }}" - echo "## Pre-Release Sanity Checks (${PLATFORM})" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - # -- Version drift check (must pass before release) -------- - README_VER=$(sed -n 's/.*VERSION:[[:space:]]*\([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\).*/\1/p' README.md 2>/dev/null | head -1) - if [ "$README_VER" != "$VERSION" ]; then - echo "- Version drift: README says \`${README_VER}\` but releasing \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - else - echo "- Version consistent: \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY - fi - - # Check CHANGELOG version matches - CL_VER=$(sed -n 's/.*VERSION:[[:space:]]*\([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\).*/\1/p' CHANGELOG.md 2>/dev/null | head -1) - if [ -n "$CL_VER" ] && [ "$CL_VER" != "$VERSION" ]; then - echo "- CHANGELOG drift: \`${CL_VER}\` != \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - fi - - # Check composer.json version if present - if [ -f "composer.json" ]; then - COMP_VER=$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' composer.json 2>/dev/null | head -1) - if [ -n "$COMP_VER" ] && [ "$COMP_VER" != "$VERSION" ]; then - echo "- composer.json drift: \`${COMP_VER}\` != \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - fi - fi - - # Common checks - if [ ! -f "LICENSE" ]; then - echo "- Missing LICENSE file" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - else - echo "- LICENSE present" >> $GITHUB_STEP_SUMMARY - fi - - if [ ! -d "src" ] && [ ! -d "htdocs" ]; then - echo "- Warning: No src/ or htdocs/ directory" >> $GITHUB_STEP_SUMMARY - else - echo "- Source directory present" >> $GITHUB_STEP_SUMMARY - fi - - # -- Platform-specific checks -------- - case "$PLATFORM" in - joomla) - if [ -n "$MANIFEST" ]; then - XML_VER=$(sed -n 's/.*\([^<]*\)<\/version>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1) - if [ -n "$XML_VER" ] && [ "$XML_VER" != "$VERSION" ]; then - echo "- Manifest drift: \`${XML_VER}\` != \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - else - echo "- Manifest version: \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY - fi - TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" 2>/dev/null) - echo "- Extension type: ${TYPE:-unknown}" >> $GITHUB_STEP_SUMMARY - else - echo "- No Joomla XML manifest (WaaS site)" >> $GITHUB_STEP_SUMMARY - fi ;; - dolibarr) - if [ -n "$MOD_FILE" ]; then - MOD_VER=$(sed -n "s/.*\\\$this->version = '\([^']*\)'.*/\1/p" "$MOD_FILE" 2>/dev/null | head -1) - if [ -n "$MOD_VER" ] && [ "$MOD_VER" != "$VERSION" ]; then - echo "- Module drift: \`${MOD_VER}\` != \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - else - echo "- Module version: \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY - fi - else - echo "- No mod*.class.php found" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - fi - if [ ! -f "update.txt" ]; then - echo "- Missing update.txt" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - fi ;; - *) echo "- Generic platform � no manifest checks" >> $GITHUB_STEP_SUMMARY ;; - esac - - echo "" >> $GITHUB_STEP_SUMMARY - if [ "$ERRORS" -gt 0 ]; then - echo "**${ERRORS} error(s) — release may be incomplete**" >> $GITHUB_STEP_SUMMARY - else - echo "**All sanity checks passed**" >> $GITHUB_STEP_SUMMARY - fi + VERSION="${{ steps.version.outputs.version }}" + php /tmp/moko-platform-api/cli/release_validate.php \ + --path . --version "$VERSION" --output-summary --github-output || true # -- STEP 2: Create or update version/XX.YY archive branch --------------- # Always runs — every version change on main archives to version/XX.YY @@ -306,7 +218,7 @@ jobs: run: | BRANCH="${{ steps.version.outputs.branch }}" IS_MINOR="${{ steps.version.outputs.is_minor }}" - PATCH="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + PATCH="${{ steps.version.outputs.version }}" PATCH_NUM=$(echo "$PATCH" | awk -F. '{print $3}') # Check if branch exists @@ -325,7 +237,7 @@ jobs: steps.version.outputs.skip != 'true' && steps.check.outputs.already_released != 'true' run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" php /tmp/moko-platform-api/cli/version_set_platform.php \ --path . --version "$VERSION" --branch main @@ -333,7 +245,7 @@ jobs: - name: "Step 4: Update version badges" if: steps.version.outputs.skip != 'true' run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" php /tmp/moko-platform-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true php /tmp/moko-platform-api/cli/version_check.php --path . --fix 2>/dev/null || true @@ -342,7 +254,7 @@ jobs: steps.version.outputs.skip != 'true' && steps.platform.outputs.platform == 'joomla' run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" # Fetch latest updates.xml from main so preserve logic has all channels GA_TOKEN="${{ secrets.GA_TOKEN }}" @@ -366,7 +278,7 @@ jobs: echo "No changes to commit" exit 0 fi - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" git config --local user.name "gitea-actions[bot]" # Set push URL with token for branch-protected repos @@ -413,187 +325,34 @@ jobs: steps.version.outputs.skip != 'true' && steps.rc.outputs.promote != 'true' run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - BRANCH="${{ steps.version.outputs.branch }}" - MAJOR="${{ steps.version.outputs.major }}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + php /tmp/moko-platform-api/cli/release_create.php \ + --path . --version "$VERSION" --tag "$RELEASE_TAG" \ + --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \ + --repo "${GITEA_REPO}" --branch main + echo "Release created: ${VERSION}" >> $GITHUB_STEP_SUMMARY - # Reuse metadata from Step 5 (single source of truth) - EXT_ELEMENT="${{ steps.updates.outputs.ext_element }}" - EXT_NAME="${{ steps.updates.outputs.ext_name }}" - EXT_TYPE="${{ steps.updates.outputs.ext_type }}" - EXT_FOLDER="${{ steps.updates.outputs.ext_folder }}" - - # Fallbacks if Step 5 was skipped - if [ -z "$EXT_ELEMENT" ]; then - EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') - fi - [ -z "$EXT_NAME" ] && EXT_NAME="${GITEA_REPO}" - - NOTES=$(php /tmp/moko-platform-api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null) - [ -z "$NOTES" ] && NOTES="Release ${VERSION}" - - # Build release name: "Pretty Name VERSION (type_element-VERSION)" - # Strip existing type prefix to prevent duplication - EXT_ELEMENT=$(echo "$EXT_ELEMENT" | sed -E 's/^(pkg_|com_|mod_|plg_[a-z]+_|tpl_|lib_)//') - TYPE_PREFIX="" - case "${EXT_TYPE}" in - plugin) TYPE_PREFIX="plg_${EXT_FOLDER}_" ;; - module) TYPE_PREFIX="mod_" ;; - component) TYPE_PREFIX="com_" ;; - template) TYPE_PREFIX="tpl_" ;; - library) TYPE_PREFIX="lib_" ;; - package) TYPE_PREFIX="pkg_" ;; - esac - RELEASE_NAME="${EXT_NAME} ${VERSION} (${TYPE_PREFIX}${EXT_ELEMENT}-${VERSION})" - - # Delete existing release if present (overwrite, not append) - EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ - "${API_BASE}/releases/tags/${RELEASE_TAG}" 2>/dev/null || true) - EXISTING_ID=$(echo "$EXISTING" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id',''))" 2>/dev/null || true) - - if [ -n "$EXISTING_ID" ]; then - curl -sS -X DELETE -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ - "${API_BASE}/releases/${EXISTING_ID}" 2>/dev/null || true - curl -sS -X DELETE -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ - "${API_BASE}/tags/${RELEASE_TAG}" 2>/dev/null || true - echo "Deleted previous stable release (id: ${EXISTING_ID})" - fi - - # Create fresh release - 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_NAME}', - 'body': '''## ${VERSION} ($(date +%Y-%m-%d))\n${NOTES}''', - 'target_commitish': '${BRANCH}' - }))")" - echo "Release created: ${RELEASE_NAME}" >> $GITHUB_STEP_SUMMARY - - # -- STEP 8: Build Joomla install ZIP + SHA-256 checksum ------------------ - - name: "Step 8: Build package and update checksum" + # -- STEP 8: Build packages and upload to release ---------------------------- + - name: "Step 8: Build package and upload" if: >- steps.version.outputs.skip != 'true' && steps.rc.outputs.promote != 'true' run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - REPO="${{ github.repository }}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - - # All ZIPs upload to the major release tag (vXX) - 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 - echo "No release ${RELEASE_TAG} found — skipping ZIP upload" - exit 0 - fi - - # Find extension element name from manifest - MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1 || true) - [ -z "$MANIFEST" ] && exit 0 - - # Reuse element from Step 5, with same fallback chain - EXT_ELEMENT="${{ steps.updates.outputs.ext_element }}" - if [ -z "$EXT_ELEMENT" ]; then - EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1) - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(sed -n 's/.*plugin="\([^"]*\)".*/\1/p' "$MANIFEST" 2>/dev/null | head -1) - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]') - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') - fi - # ZIP name: type_folder_element-VERSION (e.g. plg_system_mokojgdpc-01.01.00.zip) - EXT_TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) - EXT_FOLDER=$(sed -n 's/.*]*group="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) - # For packages, prefer over filename-derived element - if [ "$EXT_TYPE" = "package" ]; then - PKG_NAME=$(sed -n 's/.*\([^<]*\)<\/packagename>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1) - [ -n "$PKG_NAME" ] && EXT_ELEMENT="$PKG_NAME" - fi - # Strip existing type prefix to prevent duplication (e.g. pkg_mokowaas → mokowaas) - EXT_ELEMENT=$(echo "$EXT_ELEMENT" | sed -E 's/^(pkg_|com_|mod_|plg_[a-z]+_|tpl_|lib_)//') - TYPE_PREFIX="" - case "${EXT_TYPE}" in - plugin) TYPE_PREFIX="plg_${EXT_FOLDER}_" ;; - module) TYPE_PREFIX="mod_" ;; - component) TYPE_PREFIX="com_" ;; - template) TYPE_PREFIX="tpl_" ;; - library) TYPE_PREFIX="lib_" ;; - package) TYPE_PREFIX="pkg_" ;; - esac - ZIP_NAME="${TYPE_PREFIX}${EXT_ELEMENT}-${VERSION}.zip" - TAR_NAME="${TYPE_PREFIX}${EXT_ELEMENT}-${VERSION}.tar.gz" - - # -- Build install packages from src/ ---------------------------- - SOURCE_DIR="src" - [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs" - [ ! -d "$SOURCE_DIR" ] && { echo "No src/ or htdocs/"; exit 0; } - - # ZIP package (type-aware via moko-platform PHP API) - php /tmp/moko-platform-api/cli/joomla_build.php --path . --version "${VERSION}" --output /tmp - # Match the expected ZIP_NAME for upload - BUILT_ZIP=$(ls /tmp/${TYPE_PREFIX}${EXT_ELEMENT}-${VERSION}.zip 2>/dev/null | head -1 || true) - if [ -n "$BUILT_ZIP" ] && [ "$BUILT_ZIP" != "/tmp/${ZIP_NAME}" ]; then - mv "$BUILT_ZIP" "/tmp/${ZIP_NAME}" - fi - - # tar.gz package (flat source archive) - tar -czf "/tmp/${TAR_NAME}" -C "$SOURCE_DIR" --exclude='.ftpignore' --exclude='sftp-config*' --exclude='*.ppk' --exclude='*.pem' --exclude='*.key' --exclude='.env*' . - - ZIP_SIZE=$(stat -c%s "/tmp/${ZIP_NAME}" 2>/dev/null || stat -f%z "/tmp/${ZIP_NAME}" 2>/dev/null || echo "unknown") - TAR_SIZE=$(stat -c%s "/tmp/${TAR_NAME}" 2>/dev/null || stat -f%z "/tmp/${TAR_NAME}" 2>/dev/null || echo "unknown") - - # -- Calculate SHA-256 for both ---------------------------------- - SHA256_ZIP=$(sha256sum "/tmp/${ZIP_NAME}" | cut -d' ' -f1) - SHA256_TAR=$(sha256sum "/tmp/${TAR_NAME}" | cut -d' ' -f1) - - # -- Get existing assets for cleanup -------------------------------- - ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ - "${API_BASE}/releases/${RELEASE_ID}/assets" 2>/dev/null || echo "[]") - - # -- Create per-file .sha256 checksum files ------------------------- - echo "${SHA256_ZIP} ${ZIP_NAME}" > "/tmp/${ZIP_NAME}.sha256" - echo "${SHA256_TAR} ${TAR_NAME}" > "/tmp/${TAR_NAME}.sha256" - - # -- Upload packages + checksums to release tag -------------------- - for ASSET in "${ZIP_NAME}" "${TAR_NAME}" "${ZIP_NAME}.sha256" "${TAR_NAME}.sha256"; do - [ ! -f "/tmp/${ASSET}" ] && continue - # Delete existing asset with same name - ASSET_ID=$(echo "$ASSETS" | python3 -c " - import sys,json - assets = json.load(sys.stdin) - for a in assets: - if a['name'] == '${ASSET}': - print(a['id']); break - " 2>/dev/null || true) - [ -n "$ASSET_ID" ] && curl -sf -X DELETE -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ - "${API_BASE}/releases/${RELEASE_ID}/assets/${ASSET_ID}" 2>/dev/null || true - # Upload - curl -sf -X POST -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ - -H "Content-Type: application/octet-stream" \ - --data-binary @"/tmp/${ASSET}" \ - "${API_BASE}/releases/${RELEASE_ID}/assets?name=${ASSET}" > /dev/null 2>&1 || true - done - - # updates.xml already handled by Step 5 (updates_xml_build.php with preserve logic) - - echo "### Packages" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Package | Size | SHA-256 |" >> $GITHUB_STEP_SUMMARY - echo "|---------|------|---------|" >> $GITHUB_STEP_SUMMARY - echo "| \`${ZIP_NAME}\` | ${ZIP_SIZE} | \`${SHA256_ZIP}\` |" >> $GITHUB_STEP_SUMMARY - echo "| \`${TAR_NAME}\` | ${TAR_SIZE} | \`${SHA256_TAR}\` |" >> $GITHUB_STEP_SUMMARY - echo "| Release | \`${RELEASE_TAG}\` | |" >> $GITHUB_STEP_SUMMARY - echo "| Download | [${ZIP_NAME}](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}) |" >> $GITHUB_STEP_SUMMARY + php /tmp/moko-platform-api/cli/release_package.php \ + --path . --version "$VERSION" --tag "$RELEASE_TAG" \ + --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \ + --repo "${GITEA_REPO}" --output /tmp || true # -- STEP 8b: Update release description with changelog ---------------------- - name: "Step 8b: Update release body" if: steps.version.outputs.skip != 'true' run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" MOKO_CLI="/tmp/moko-platform-api/cli" @@ -621,44 +380,19 @@ jobs: - name: "Step 9: Mirror release to GitHub" if: >- steps.version.outputs.skip != 'true' && - steps.version.outputs.stability == 'stable' && secrets.GH_TOKEN != '' continue-on-error: true - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - MAJOR="${{ steps.version.outputs.major }}" - BRANCH="${{ steps.version.outputs.branch }}" GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}" - - NOTES=$(php /tmp/moko-platform-api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null || true) - [ -z "$NOTES" ] && NOTES="Release ${VERSION}" - echo "$NOTES" > /tmp/release_notes.md - - EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".tag_name // empty" || true) - - if [ -z "$EXISTING" ]; then - gh release create "$RELEASE_TAG" \ - --repo "$GH_REPO" \ - --title "v${MAJOR} (latest: ${VERSION})" \ - --notes-file /tmp/release_notes.md \ - --target "$BRANCH" || true - else - gh release edit "$RELEASE_TAG" \ - --repo "$GH_REPO" \ - --title "v${MAJOR} (latest: ${VERSION})" || true - fi - - # Upload assets to GitHub mirror - for PKG in /tmp/${EXT_ELEMENT:-pkg}-${VERSION}.*; do - if [ -f "$PKG" ]; then - _RELID=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".id // empty") - [ -n "$_RELID" ] && curl -sf -X POST -H "Authorization: token ${{ secrets.GA_TOKEN }}" -H "Content-Type: application/octet-stream" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/${_RELID}/assets?name=$(basename $PKG)" --data-binary "@$PKG" > /dev/null 2>&1 || true - fi - done - echo "GitHub mirror updated: ${GH_REPO} ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY + API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + php /tmp/moko-platform-api/cli/release_mirror.php \ + --version "$VERSION" --tag "$RELEASE_TAG" \ + --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \ + --gh-token "${{ secrets.GH_TOKEN }}" --gh-repo "$GH_REPO" \ + --branch main 2>&1 || true + echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY # -- STEP 10: Sync main branch to GitHub mirror ---------------------------- - name: "Step 10: Push main to GitHub mirror" @@ -682,7 +416,7 @@ jobs: - name: "Delete lesser pre-release channels" continue-on-error: true run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" php /tmp/moko-platform-api/cli/release_cascade.php \ --stability stable \ @@ -711,32 +445,20 @@ jobs: # -- Dolibarr post-release: Reset dev version ----------------------------- - - name: "Dolibarr: Reset dev version" - if: >- - steps.version.outputs.skip != 'true' && - steps.platform.outputs.platform == 'dolibarr' && - steps.platform.outputs.mod_file != '' + - name: "Post-release: Reset dev version" + if: steps.version.outputs.skip != 'true' continue-on-error: true run: | API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - TOKEN="${{ secrets.GA_TOKEN }}" - MOD_FILE="${{ steps.platform.outputs.mod_file }}" - ENCODED_PATH=$(echo "$MOD_FILE" | sed 's|^\./||' | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))") - FILE_RESP=$(curl -sf -H "Authorization: token ${TOKEN}" "${API_BASE}/contents/${ENCODED_PATH}?ref=dev" 2>/dev/null || true) - FILE_SHA=$(echo "$FILE_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('sha',''))" 2>/dev/null || true) - FILE_CONTENT=$(echo "$FILE_RESP" | python3 -c "import sys,json,base64; print(base64.b64decode(json.load(sys.stdin).get('content','')).decode())" 2>/dev/null || true) - if [ -n "$FILE_SHA" ] && [ -n "$FILE_CONTENT" ]; then - UPDATED=$(echo "$FILE_CONTENT" | sed "s/\$this->version = '[^']*'/\$this->version = 'development'/") - ENCODED=$(echo "$UPDATED" | base64 -w0) - curl -sf -X PUT -H "Authorization: token ${TOKEN}" -H "Content-Type: application/json" "${API_BASE}/contents/${ENCODED_PATH}" \ - -d "$(jq -n --arg content \"$ENCODED\" --arg sha \"$FILE_SHA\" --arg msg \"chore(version): reset dev version [skip ci]\" --arg branch \"dev\" '{content:$content,sha:$sha,message:$msg,branch:$branch}')" > /dev/null 2>&1 || true - fi + php /tmp/moko-platform-api/cli/version_reset_dev.php \ + --token "${{ secrets.GA_TOKEN }}" --api-base "${API_BASE}" \ + --branch dev --path . 2>&1 || true # -- Summary -------------------------------------------------------------- - name: Pipeline Summary if: always() run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + VERSION="${{ steps.version.outputs.version }}" PLATFORM="${{ steps.platform.outputs.platform }}" if [ "${{ steps.version.outputs.skip }}" = "true" ]; then echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY From f47a4d3c772cad6a0d2f4a9a262613a25b29ab41 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:25:08 +0000 Subject: [PATCH 04/11] chore(ci): update auto-bump.yml from moko-platform [skip ci] --- .mokogitea/workflows/auto-bump.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.mokogitea/workflows/auto-bump.yml b/.mokogitea/workflows/auto-bump.yml index ef0aedc..d1dedf1 100644 --- a/.mokogitea/workflows/auto-bump.yml +++ b/.mokogitea/workflows/auto-bump.yml @@ -16,6 +16,7 @@ on: push: branches: - dev + - main env: GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} @@ -53,9 +54,20 @@ jobs: echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV" fi - - name: Patch bump version + - name: Bump version run: | - BUMP=$(php ${MOKO_CLI}/version_bump.php --path . 2>&1) || true + BRANCH="${{ github.ref_name }}" + + # main = minor bump, dev = patch bump + if [ "$BRANCH" = "main" ]; then + BUMP_TYPE="--minor" + BUMP_LABEL="minor" + else + BUMP_TYPE="" + BUMP_LABEL="patch" + fi + + BUMP=$(php ${MOKO_CLI}/version_bump.php --path . $BUMP_TYPE 2>&1) || true echo "$BUMP" VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) || true @@ -63,7 +75,7 @@ jobs: # Propagate to platform manifests php ${MOKO_CLI}/version_set_platform.php \ - --path . --version "$VERSION" --branch dev 2>/dev/null || true + --path . --version "$VERSION" --branch "$BRANCH" 2>/dev/null || true php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true # Commit if anything changed @@ -76,7 +88,7 @@ jobs: git config --local user.name "gitea-actions[bot]" git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git add -A - git commit -m "chore(version): patch bump to ${VERSION} [skip ci]" \ + git commit -m "chore(version): ${BUMP_LABEL} bump to ${VERSION} [skip ci]" \ --author="gitea-actions[bot] " - git push origin dev - echo "Bumped to ${VERSION}" >> $GITHUB_STEP_SUMMARY + git push origin "$BRANCH" + echo "Bumped to ${VERSION} (${BUMP_LABEL})" >> $GITHUB_STEP_SUMMARY From 1a81267d38113c85d170fd88aade6fa2c9428a55 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:35:31 +0000 Subject: [PATCH 05/11] chore(ci): update auto-release.yml from moko-platform [skip ci] --- .mokogitea/workflows/auto-release.yml | 55 ++++++++++++++++++--------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/.mokogitea/workflows/auto-release.yml b/.mokogitea/workflows/auto-release.yml index d665ce7..e555c14 100644 --- a/.mokogitea/workflows/auto-release.yml +++ b/.mokogitea/workflows/auto-release.yml @@ -249,25 +249,7 @@ jobs: php /tmp/moko-platform-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true php /tmp/moko-platform-api/cli/version_check.php --path . --fix 2>/dev/null || true - - name: "Step 5: Write update stream" - if: >- - steps.version.outputs.skip != 'true' && - steps.platform.outputs.platform == 'joomla' - run: | - VERSION="${{ steps.version.outputs.version }}" - - # Fetch latest updates.xml from main so preserve logic has all channels - GA_TOKEN="${{ secrets.GA_TOKEN }}" - API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" - curl -sf -H "Authorization: token ${GA_TOKEN}" \ - "${API}/contents/updates.xml?ref=main" 2>/dev/null | \ - python3 -c "import sys,json,base64; print(base64.b64decode(json.load(sys.stdin)['content']).decode())" \ - > updates.xml 2>/dev/null || true - - php /tmp/moko-platform-api/cli/updates_xml_build.php \ - --path . --version "${VERSION}" --stability stable \ - --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ - --github-output + # Step 5 (updates.xml) moved after Step 8 to include SHA-256 checksum - name: Commit release changes if: >- @@ -336,6 +318,7 @@ jobs: # -- STEP 8: Build packages and upload to release ---------------------------- - name: "Step 8: Build package and upload" + id: package if: >- steps.version.outputs.skip != 'true' && steps.rc.outputs.promote != 'true' @@ -348,6 +331,40 @@ jobs: --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \ --repo "${GITEA_REPO}" --output /tmp || true + # -- STEP 5: Write update stream (after build so SHA-256 is available) ----- + - name: "Step 5: Write update stream" + if: steps.version.outputs.skip != 'true' + run: | + VERSION="${{ steps.version.outputs.version }}" + SHA256="${{ steps.package.outputs.sha256_zip }}" + + # Fetch latest updates.xml from main so preserve logic has all channels + GA_TOKEN="${{ secrets.GA_TOKEN }}" + API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" + curl -sf -H "Authorization: token ${GA_TOKEN}" \ + "${API}/contents/updates.xml?ref=main" 2>/dev/null | \ + python3 -c "import sys,json,base64; print(base64.b64decode(json.load(sys.stdin)['content']).decode())" \ + > updates.xml 2>/dev/null || true + + SHA_FLAG="" + [ -n "$SHA256" ] && SHA_FLAG="--sha ${SHA256}" + + php /tmp/moko-platform-api/cli/updates_xml_build.php \ + --path . --version "${VERSION}" --stability stable \ + --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ + ${SHA_FLAG} --github-output + + # Commit updates.xml if changed + 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 remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" + git add updates.xml + git commit -m "chore: update stable channel ${VERSION} [skip ci]" \ + --author="gitea-actions[bot] " + git push origin HEAD 2>&1 || true + fi + # -- STEP 8b: Update release description with changelog ---------------------- - name: "Step 8b: Update release body" if: steps.version.outputs.skip != 'true' From e86cc2b48bd33671481fa406a9c214f14ccbcd61 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:36:53 +0000 Subject: [PATCH 06/11] chore(ci): update pre-release.yml from moko-platform [skip ci] --- .mokogitea/workflows/pre-release.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml index 83443c7..a84e469 100644 --- a/.mokogitea/workflows/pre-release.yml +++ b/.mokogitea/workflows/pre-release.yml @@ -162,9 +162,18 @@ jobs: zip -r "../../build/package/${EXT_NAME}.zip" . -x $EXCLUDES cd "$OLDPWD" done + # Copy top-level files (manifest XML, script PHP, etc.) for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do [ -f "$f" ] && cp "$f" build/package/ done + # Copy top-level directories (language/, media/, etc.) — exclude packages/ + for d in "${SOURCE_DIR}"/*/; do + [ ! -d "$d" ] && continue + DIRNAME=$(basename "$d") + [ "$DIRNAME" = "packages" ] && continue + cp -r "$d" "build/package/${DIRNAME}" + echo " Included dir: ${DIRNAME}/" + done else echo "=== Building standard extension ===" rsync -a \ @@ -245,15 +254,20 @@ jobs: run: | VERSION="${{ steps.meta.outputs.version }}" STABILITY="${{ steps.meta.outputs.stability }}" + SHA256="${{ steps.zip.outputs.sha256 }}" 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}" + --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 From 05c3f5fd1f7971417d35a5dda4105608604aa573 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:48:24 +0000 Subject: [PATCH 07/11] chore(ci): update auto-release.yml from moko-platform [skip ci] --- .mokogitea/workflows/auto-release.yml | 60 +++++++++++++-------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/.mokogitea/workflows/auto-release.yml b/.mokogitea/workflows/auto-release.yml index e555c14..80908e4 100644 --- a/.mokogitea/workflows/auto-release.yml +++ b/.mokogitea/workflows/auto-release.yml @@ -87,7 +87,7 @@ jobs: --from auto --to release-candidate \ --token "${{ secrets.GA_TOKEN }}" \ --api-base "${API_BASE}" \ - --branch "${{ github.event.pull_request.head.ref }}" + --branch "${{ github.event.pull_request.head.ref || 'dev' }}" - name: Cascade lesser channels continue-on-error: true @@ -180,7 +180,17 @@ jobs: echo "::notice::No RC release — full build pipeline" fi - # Version bump handled by auto-bump.yml (minor on main, patch on dev) + - name: "Step 1b: Minor bump version" + id: bump + if: >- + steps.version.outputs.skip != 'true' && + steps.rc.outputs.promote != 'true' + run: | + MOKO_API="/tmp/moko-platform-api/cli" + php ${MOKO_API}/version_bump.php --path . --minor 2>&1 || true + VERSION=$(php ${MOKO_API}/version_read.php --path .) + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + echo "Bumped to: ${VERSION}" - name: Check if already released if: steps.version.outputs.skip != 'true' @@ -207,7 +217,7 @@ jobs: steps.version.outputs.skip != 'true' && steps.check.outputs.already_released != 'true' run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" php /tmp/moko-platform-api/cli/release_validate.php \ --path . --version "$VERSION" --output-summary --github-output || true @@ -218,7 +228,7 @@ jobs: run: | BRANCH="${{ steps.version.outputs.branch }}" IS_MINOR="${{ steps.version.outputs.is_minor }}" - PATCH="${{ steps.version.outputs.version }}" + PATCH="${{ steps.bump.outputs.version || steps.version.outputs.version }}" PATCH_NUM=$(echo "$PATCH" | awk -F. '{print $3}') # Check if branch exists @@ -237,7 +247,7 @@ jobs: steps.version.outputs.skip != 'true' && steps.check.outputs.already_released != 'true' run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" php /tmp/moko-platform-api/cli/version_set_platform.php \ --path . --version "$VERSION" --branch main @@ -245,7 +255,7 @@ jobs: - name: "Step 4: Update version badges" if: steps.version.outputs.skip != 'true' run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" php /tmp/moko-platform-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true php /tmp/moko-platform-api/cli/version_check.php --path . --fix 2>/dev/null || true @@ -260,7 +270,7 @@ jobs: echo "No changes to commit" exit 0 fi - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" git config --local user.name "gitea-actions[bot]" # Set push URL with token for branch-protected repos @@ -292,7 +302,7 @@ jobs: steps.version.outputs.skip != 'true' && steps.rc.outputs.promote == 'true' run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" php /tmp/moko-platform-api/cli/release_promote.php \ --from release-candidate --to stable \ @@ -307,7 +317,7 @@ jobs: steps.version.outputs.skip != 'true' && steps.rc.outputs.promote != 'true' run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" php /tmp/moko-platform-api/cli/release_create.php \ @@ -323,7 +333,7 @@ jobs: steps.version.outputs.skip != 'true' && steps.rc.outputs.promote != 'true' run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" php /tmp/moko-platform-api/cli/release_package.php \ @@ -335,7 +345,7 @@ jobs: - name: "Step 5: Write update stream" if: steps.version.outputs.skip != 'true' run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" SHA256="${{ steps.package.outputs.sha256_zip }}" # Fetch latest updates.xml from main so preserve logic has all channels @@ -368,29 +378,15 @@ jobs: # -- STEP 8b: Update release description with changelog ---------------------- - name: "Step 8b: Update release body" if: steps.version.outputs.skip != 'true' + continue-on-error: true run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - MOKO_CLI="/tmp/moko-platform-api/cli" - - php ${MOKO_CLI}/release_body_update.php \ + php /tmp/moko-platform-api/cli/release_body_update.php \ --path . --version "${VERSION}" --tag "${RELEASE_TAG}" \ --token "${{ secrets.GA_TOKEN }}" \ --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ - 2>/dev/null || { - # Fallback: simple body update if CLI not available - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ - "${API_BASE}/releases/tags/${RELEASE_TAG}" 2>/dev/null | \ - python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true) - if [ -n "$RELEASE_ID" ] && [ "$RELEASE_ID" != "None" ]; then - BODY="## ${VERSION} ($(date +%Y-%m-%d))\n\nChecksum files attached as \`*.sha256\` assets." - curl -sf -X PATCH -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ - -H "Content-Type: application/json" \ - "${API_BASE}/releases/${RELEASE_ID}" \ - -d "{\"body\":\"${BODY}\"}" > /dev/null 2>&1 - fi - } + 2>&1 || true echo "Release body updated" >> $GITHUB_STEP_SUMMARY # -- STEP 9: Mirror to GitHub (stable only) -------------------------------- @@ -400,7 +396,7 @@ jobs: secrets.GH_TOKEN != '' continue-on-error: true run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" @@ -433,7 +429,7 @@ jobs: - name: "Delete lesser pre-release channels" continue-on-error: true run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" php /tmp/moko-platform-api/cli/release_cascade.php \ --stability stable \ @@ -475,7 +471,7 @@ jobs: - name: Pipeline Summary if: always() run: | - VERSION="${{ steps.version.outputs.version }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" PLATFORM="${{ steps.platform.outputs.platform }}" if [ "${{ steps.version.outputs.skip }}" = "true" ]; then echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY From 3bbaee7c86f949d56d24d983e47f0daf614ccfaa Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:49:37 +0000 Subject: [PATCH 08/11] chore(ci): update auto-bump.yml from moko-platform [skip ci] --- .mokogitea/workflows/auto-bump.yml | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/.mokogitea/workflows/auto-bump.yml b/.mokogitea/workflows/auto-bump.yml index d1dedf1..10a7e51 100644 --- a/.mokogitea/workflows/auto-bump.yml +++ b/.mokogitea/workflows/auto-bump.yml @@ -8,7 +8,7 @@ # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform # PATH: /.mokogitea/workflows/auto-bump.yml # VERSION: 09.02.00 -# BRIEF: Auto patch-bump version on every push to dev +# BRIEF: Auto patch-bump version on every push to dev (skips merge commits) name: "Universal: Auto Version Bump" @@ -16,9 +16,9 @@ on: push: branches: - dev - - main env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} permissions: @@ -26,11 +26,12 @@ permissions: jobs: bump: - name: Patch Bump + name: Version Bump runs-on: release if: >- !contains(github.event.head_commit.message, '[skip ci]') && - !contains(github.event.head_commit.message, '[skip bump]') + !contains(github.event.head_commit.message, '[skip bump]') && + !startsWith(github.event.head_commit.message, 'Merge pull request') steps: - name: Checkout @@ -56,18 +57,7 @@ jobs: - name: Bump version run: | - BRANCH="${{ github.ref_name }}" - - # main = minor bump, dev = patch bump - if [ "$BRANCH" = "main" ]; then - BUMP_TYPE="--minor" - BUMP_LABEL="minor" - else - BUMP_TYPE="" - BUMP_LABEL="patch" - fi - - BUMP=$(php ${MOKO_CLI}/version_bump.php --path . $BUMP_TYPE 2>&1) || true + BUMP=$(php ${MOKO_CLI}/version_bump.php --path . 2>&1) || true echo "$BUMP" VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) || true @@ -75,7 +65,7 @@ jobs: # Propagate to platform manifests php ${MOKO_CLI}/version_set_platform.php \ - --path . --version "$VERSION" --branch "$BRANCH" 2>/dev/null || true + --path . --version "$VERSION" --branch dev 2>/dev/null || true php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true # Commit if anything changed @@ -88,7 +78,7 @@ jobs: git config --local user.name "gitea-actions[bot]" git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git add -A - git commit -m "chore(version): ${BUMP_LABEL} bump to ${VERSION} [skip ci]" \ + git commit -m "chore(version): patch bump to ${VERSION} [skip ci]" \ --author="gitea-actions[bot] " - git push origin "$BRANCH" - echo "Bumped to ${VERSION} (${BUMP_LABEL})" >> $GITHUB_STEP_SUMMARY + git push origin dev + echo "Bumped to ${VERSION}" >> $GITHUB_STEP_SUMMARY From d9ce74cf38ba3ff13a174f58e29b7f30b8ec8d0d Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Tue, 26 May 2026 22:50:50 +0000 Subject: [PATCH 09/11] chore(ci): update pre-release.yml from moko-platform [skip ci] --- .mokogitea/workflows/pre-release.yml | 162 +++++---------------------- 1 file changed, 29 insertions(+), 133 deletions(-) diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml index a84e469..f0b1d88 100644 --- a/.mokogitea/workflows/pre-release.yml +++ b/.mokogitea/workflows/pre-release.yml @@ -52,28 +52,19 @@ jobs: fetch-depth: 0 token: ${{ secrets.GA_TOKEN }} - - name: Setup tools + - name: Setup moko-platform tools + env: + MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN }} + MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting run: | - # Update moko-platform CLI tools if available; install PHP if missing - if command -v moko-platform-update &> /dev/null; then - moko-platform-update - elif [ -d "/opt/moko-platform" ]; then - cd /opt/moko-platform && git pull origin main --quiet 2>/dev/null || true - else - if ! command -v php &> /dev/null; then - sudo apt-get update -qq - sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl >/dev/null 2>&1 - fi - git clone --depth 1 --branch main --quiet \ - "https://x-access-token:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/moko-platform.git" \ - /tmp/moko-platform-api - fi - # Set MOKO_CLI to whichever path exists - if [ -d "/opt/moko-platform/cli" ]; then - echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV" - else - echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV" + 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 + 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 @@ -129,132 +120,37 @@ jobs: echo "tag=${TAG}" >> "$GITHUB_OUTPUT" echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT" - echo "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT" echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ===" - - name: Build package - run: | - SOURCE_DIR="src" - [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs" - if [ ! -d "$SOURCE_DIR" ]; then - echo "::error::No src/ or htdocs/ directory" - exit 1 - fi - - MANIFEST="${{ steps.meta.outputs.manifest }}" - EXT_TYPE="" - if [ -n "$MANIFEST" ]; then - EXT_TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) - fi - - EXCLUDES="sftp-config* .ftpignore *.ppk *.pem *.key .env* *.local .build-trigger" - - mkdir -p build/package - - if [ "$EXT_TYPE" = "package" ] && [ -d "${SOURCE_DIR}/packages" ]; then - echo "=== Building Joomla PACKAGE (multi-extension) ===" - for ext_dir in "${SOURCE_DIR}"/packages/*/; do - [ ! -d "$ext_dir" ] && continue - EXT_NAME=$(basename "$ext_dir") - echo " Packaging sub-extension: ${EXT_NAME}" - cd "$ext_dir" - zip -r "../../build/package/${EXT_NAME}.zip" . -x $EXCLUDES - cd "$OLDPWD" - done - # Copy top-level files (manifest XML, script PHP, etc.) - for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do - [ -f "$f" ] && cp "$f" build/package/ - done - # Copy top-level directories (language/, media/, etc.) — exclude packages/ - for d in "${SOURCE_DIR}"/*/; do - [ ! -d "$d" ] && continue - DIRNAME=$(basename "$d") - [ "$DIRNAME" = "packages" ] && continue - cp -r "$d" "build/package/${DIRNAME}" - echo " Included dir: ${DIRNAME}/" - done - else - echo "=== Building standard extension ===" - rsync -a \ - --exclude='sftp-config*' \ - --exclude='.ftpignore' \ - --exclude='*.ppk' \ - --exclude='*.pem' \ - --exclude='*.key' \ - --exclude='.env*' \ - --exclude='*.local' \ - --exclude='.build-trigger' \ - "${SOURCE_DIR}/" build/package/ - fi - - - name: Create ZIP - id: zip - run: | - ZIP_NAME="${{ steps.meta.outputs.zip_name }}" - cd build/package - zip -r "../${ZIP_NAME}" . - cd .. - - SHA256=$(sha256sum "${ZIP_NAME}" | cut -d' ' -f1) - echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" - echo "ZIP: ${ZIP_NAME} (SHA: ${SHA256:0:16}...)" - - - name: Create or replace Gitea release + - name: Create release id: release run: | TAG="${{ steps.meta.outputs.tag }}" VERSION="${{ steps.meta.outputs.version }}" - STABILITY="${{ steps.meta.outputs.stability }}" - SHA256="${{ steps.zip.outputs.sha256 }}" - ZIP_NAME="${{ steps.meta.outputs.zip_name }}" - EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}" - TOKEN="${{ secrets.GA_TOKEN }}" - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - BRANCH=$(git branch --show-current) + API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + php ${MOKO_CLI}/release_create.php \ + --path . --version "$VERSION" --tag "$TAG" \ + --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \ + --repo "${GITEA_REPO}" --branch dev --prerelease - BODY="## ${VERSION} ($(date +%Y-%m-%d)) - **Channel:** ${STABILITY} - **SHA-256:** \`${SHA256}\`" - - # Delete existing release - EXISTING_ID=$(curl -sS -H "Authorization: token ${TOKEN}" \ - "${API}/releases/tags/${TAG}" | jq -r '.id // empty' 2>/dev/null) - if [ -n "$EXISTING_ID" ]; then - curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \ - "${API}/releases/${EXISTING_ID}" 2>/dev/null || true - curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \ - "${API}/tags/${TAG}" 2>/dev/null || true - fi - - # Create release - RELEASE_ID=$(curl -sS -X POST -H "Authorization: token ${TOKEN}" \ - -H "Content-Type: application/json" \ - "${API}/releases" \ - -d "$(jq -n \ - --arg tag "$TAG" \ - --arg target "$BRANCH" \ - --arg name "${EXT_ELEMENT} ${VERSION} (${STABILITY})" \ - --arg body "$BODY" \ - '{tag_name: $tag, target_commitish: $target, name: $name, body: $body, prerelease: true}' - )" | jq -r '.id') - - echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT" - - # Upload ZIP - curl -sS -X POST -H "Authorization: token ${TOKEN}" \ - -H "Content-Type: application/octet-stream" \ - "${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \ - --data-binary "@build/${ZIP_NAME}" - - echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})" + - 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.GA_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.zip.outputs.sha256 }}" + SHA256="${{ steps.package.outputs.sha256_zip }}" if [ ! -f "updates.xml" ]; then echo "No updates.xml -- skipping" @@ -316,7 +212,7 @@ jobs: VERSION="${{ steps.meta.outputs.version }}" STABILITY="${{ steps.meta.outputs.stability }}" ZIP_NAME="${{ steps.meta.outputs.zip_name }}" - SHA256="${{ steps.zip.outputs.sha256 }}" + SHA256="${{ steps.package.outputs.sha256_zip }}" echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY From 9f1848d218db437eb49c437c35e75c3cfc664571 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 26 May 2026 18:40:31 -0500 Subject: [PATCH 10/11] fix: move trusted IP session bypass to boot() for early execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Joomla validates sessions during initialise(), before onAfterInitialise fires. The previous ini_set approach ran too late — the session was already expired. Now implements BootableExtensionInterface so the session lifetime is extended before Joomla's session handler runs. Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 3 ++ .../Extension/MokoWaaS.php | 43 ++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e3e140..04efaf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Each entry has a label and enabled toggle for easy management - Current IP display above trusted IPs table so admins can easily add their own IP +### Fixed +- Trusted IP session bypass: moved from `onAfterInitialise` to `boot()` so Joomla's session lifetime is extended before the session handler validates it (was too late, Joomla expired the session first) + ## [02.06.00] - 2026-05-25 ### Added diff --git a/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php b/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php index f99ce7b..2f29125 100644 --- a/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php +++ b/src/packages/plg_system_mokowaas/Extension/MokoWaaS.php @@ -31,6 +31,7 @@ namespace Moko\Plugin\System\MokoWaaS\Extension; defined('_JEXEC') or die; +use Joomla\CMS\Extension\BootableExtensionInterface; use Joomla\CMS\Factory; use Joomla\CMS\Log\Log; use Joomla\CMS\Plugin\CMSPlugin; @@ -38,6 +39,7 @@ use Joomla\CMS\Router\Route; use Joomla\CMS\Language\Language; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\UserHelper; +use Psr\Container\ContainerInterface; /** * MokoWaaS Brand System Plugin @@ -47,7 +49,7 @@ use Joomla\CMS\User\UserHelper; * * @since 01.04.00 */ -class MokoWaaS extends CMSPlugin +class MokoWaaS extends CMSPlugin implements BootableExtensionInterface { /** * Obfuscated Grafana URL (XOR + base64). @@ -114,6 +116,37 @@ class MokoWaaS extends CMSPlugin */ protected $app; + /** + * Boot the extension — runs BEFORE Joomla creates the session. + * + * Extends the Joomla session lifetime for trusted IPs so the + * session handler does not destroy the session before + * onAfterInitialise can run. + * + * @param ContainerInterface $container The DI container. + * + * @return void + * + * @since 02.11.00 + */ + public function boot(ContainerInterface $container): void + { + $timeout = (int) $this->params->get('admin_session_timeout', 0); + + if ($timeout <= 0) + { + return; + } + + if ($this->ipIsTrusted()) + { + // Set both PHP and Joomla session lifetimes before the + // session handler runs its expiry check. + ini_set('session.gc_maxlifetime', 315360000); + Factory::getConfig()->set('lifetime', 525600); + } + } + /** * Event triggered after the framework has loaded and the application initialise method has been called. * @@ -3343,11 +3376,9 @@ class MokoWaaS extends CMSPlugin return; } - // Don't timeout trusted IPs — extend their session instead + // Trusted IPs — session lifetime already extended in boot() if ($this->ipIsTrusted()) { - ini_set('session.gc_maxlifetime', 315360000); - return; } @@ -3398,7 +3429,9 @@ class MokoWaaS extends CMSPlugin return false; } - $ip = $this->app->input->server->getString('REMOTE_ADDR', ''); + $ip = $this->app + ? $this->app->input->server->getString('REMOTE_ADDR', '') + : ($_SERVER['REMOTE_ADDR'] ?? ''); $ipLong = ip2long($ip); if ($ipLong === false) From 21de2fa1155dae443c5a4e968625f883553938ec Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Tue, 26 May 2026 23:46:20 +0000 Subject: [PATCH 11/11] chore(version): patch bump to 02.11.02 [skip ci] --- README.md | 2 +- src/packages/com_mokowaas/mokowaas.xml | 2 +- src/packages/plg_system_mokowaas/mokowaas.xml | 2 +- src/packages/plg_webservices_mokowaas/mokowaas.xml | 2 +- src/pkg_mokowaas.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8f7ee22..0c75e9a 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.11.01 + VERSION: 02.11.02 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 70359c5..2e65791 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.11.01 + 02.11.02 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 a30881b..12cad11 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.11.01 + 02.11.02 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 2d239a8..ec53c7b 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.11.01 + 02.11.02 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 18ae5ec..e4ec44b 100644 --- a/src/pkg_mokowaas.xml +++ b/src/pkg_mokowaas.xml @@ -2,7 +2,7 @@ MokoWaaS mokowaas - 02.11.01 + 02.11.02 2026-05-23 Moko Consulting hello@mokoconsulting.tech