diff --git a/.mokogitea/manifest.xml b/.mokogitea/manifest.xml new file mode 100644 index 0000000..eeac3cb --- /dev/null +++ b/.mokogitea/manifest.xml @@ -0,0 +1,24 @@ + + + + + MokoWaaS + MokoConsulting + White-label identity, security hardening, and tenant restriction layer for WaaS-managed Joomla environments + GNU General Public License v3 + + + joomla + 05.00.00 + https://git.mokoconsulting.tech/MokoConsulting/moko-platform + 2026-05-21T20:48:00+00:00 + + + PHP + plugin + src/ + + diff --git a/.mokogitea/workflows/auto-release.yml b/.mokogitea/workflows/auto-release.yml index dbaf151..c863ce2 100644 --- a/.mokogitea/workflows/auto-release.yml +++ b/.mokogitea/workflows/auto-release.yml @@ -8,13 +8,13 @@ # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards-API # PATH: /templates/workflows/universal/auto-release.yml.template # VERSION: 05.00.00 -# BRIEF: Universal build & release � detects platform from manifest.xml +# BRIEF: Universal build & release � detects platform from .moko-platform # # +========================================================================+ # | UNIVERSAL BUILD & RELEASE PIPELINE | # +========================================================================+ # | | -# | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. | +# | Reads .moko-platform (joomla|dolibarr|generic) to branch logic. | # | | # | Platform-specific: | # | joomla: XML manifest, updates.xml, type-prefixed packages | @@ -79,16 +79,15 @@ jobs: - name: Detect platform id: platform run: | - # Parse .manifest.xml via manifest_read.php — outputs all fields to GITHUB_OUTPUT - php /tmp/mokostandards-api/cli/manifest_read.php --path . --github-output 2>/dev/null || true - PLATFORM=$(php /tmp/mokostandards-api/cli/manifest_read.php --path . --field platform 2>/dev/null) + PLATFORM=$(cat .mokogitea/.moko-platform 2>/dev/null | tr -d '[:space:]') [ -z "$PLATFORM" ] && PLATFORM="generic" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" echo "Platform detected: ${PLATFORM}" - # entry-point from manifest, find as fallback - MOD_FILE=$(php /tmp/mokostandards-api/cli/manifest_read.php --path . --field entry-point 2>/dev/null) - [ -z "$MOD_FILE" ] && MOD_FILE=$(find . -maxdepth 4 -name "mod*.class.php" ! -path "./.git/*" -exec grep -l 'extends DolibarrModules' {} \; 2>/dev/null | head -1) - MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '/dev/null | head -1) + # For packages: prefer pkg_*.xml in src/; fallback to any manifest + 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" @@ -161,6 +160,17 @@ jobs: [ -n "$MANIFEST_VER" ] && sed -i "s|${MANIFEST_VER}|${VERSION}|" "$MANIFEST" sed -i "s|[^<]*|${TODAY}|" "$MANIFEST" fi + # For packages: also bump version in all sub-extension manifests + if [ -d "src/packages" ]; then + for SUB_MANIFEST in $(find src/packages -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null); do + SUB_VER=$(sed -n 's/.*\([^<]*\)<\/version>.*/\1/p' "$SUB_MANIFEST" | head -1) + if [ -n "$SUB_VER" ]; then + sed -i "s|${SUB_VER}|${VERSION}|" "$SUB_MANIFEST" + sed -i "s|[^<]*|${TODAY}|" "$SUB_MANIFEST" + echo " Bumped sub-extension: $(basename $SUB_MANIFEST) ${SUB_VER} → ${VERSION}" + fi + done + fi ;; dolibarr) if [ -n "$MOD_FILE" ]; then @@ -187,7 +197,7 @@ jobs: git add -A git diff --cached --quiet || { git commit -m "chore(version): bump ${CURRENT} → ${VERSION} [skip ci]" - git push origin HEAD:dev 2>&1 || git push origin HEAD:main 2>&1 + git push origin HEAD:main 2>&1 } # Override version output for rest of pipeline @@ -364,7 +374,8 @@ jobs: REPO="${{ github.repository }}" # -- Parse extension metadata from XML manifest ---------------- - MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1) + MANIFEST=$(find ./src -maxdepth 1 -name "pkg_*.xml" -exec grep -l '/dev/null | head -1) + [ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 2 -name "*.xml" ! -path "*/packages/*" -exec grep -l '/dev/null | head -1) if [ -z "$MANIFEST" ]; then echo "Warning: No Joomla XML manifest found — skipping updates.xml" >> $GITHUB_STEP_SUMMARY exit 0 @@ -621,7 +632,8 @@ jobs: fi # Find extension element name from manifest - MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1 || true) + MANIFEST=$(find ./src -maxdepth 1 -name "pkg_*.xml" -exec grep -l '/dev/null | head -1) + [ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 2 -name "*.xml" ! -path "*/packages/*" -exec grep -l '/dev/null | head -1 || true) [ -z "$MANIFEST" ] && exit 0 # Reuse element from Step 5, with same fallback chain @@ -654,15 +666,39 @@ jobs: EXCLUDES=".ftpignore sftp-config* *.ppk *.pem *.key .env*" - # ZIP package - cd "$SOURCE_DIR" - zip -r "/tmp/${ZIP_NAME}" . -x $EXCLUDES - cd .. + if [ "$EXT_TYPE" = "package" ] && [ -d "${SOURCE_DIR}/packages" ]; then + echo "=== Building Joomla PACKAGE (multi-extension) ===" + PKG_STAGE=$(mktemp -d) - # tar.gz package - tar -czf "/tmp/${TAR_NAME}" -C "$SOURCE_DIR" \ - --exclude='.ftpignore' --exclude='sftp-config*' \ - --exclude='*.ppk' --exclude='*.pem' --exclude='*.key' --exclude='.env*' . + # ZIP each sub-extension + for ext_dir in "${SOURCE_DIR}"/packages/*/; do + [ ! -d "$ext_dir" ] && continue + SUB_NAME=$(basename "$ext_dir") + echo " Packaging sub-extension: ${SUB_NAME}" + (cd "$ext_dir" && zip -r "${PKG_STAGE}/${SUB_NAME}.zip" . -x $EXCLUDES) + done + + # Copy package-level files (manifest, script, etc.) + for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do + [ -f "$f" ] && cp "$f" "${PKG_STAGE}/" + done + + # Create ZIP and tar.gz from staged package + (cd "$PKG_STAGE" && zip -r "/tmp/${ZIP_NAME}" .) + tar -czf "/tmp/${TAR_NAME}" -C "$PKG_STAGE" . + + rm -rf "$PKG_STAGE" + echo "Package contents built with sub-extension ZIPs" + else + # Standard extension: flat ZIP from src/ + cd "$SOURCE_DIR" + zip -r "/tmp/${ZIP_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*' . + fi 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") @@ -941,30 +977,25 @@ jobs: done echo "Cleaned up ${DELETED} pre-release channel(s)" >> $GITHUB_STEP_SUMMARY - # -- STEP 11: Sync dev branch with main + version bump ---------------------- - - name: "Step 11: Merge main into dev (version bump lands on dev)" + # -- STEP 11: Reset dev branch from main ------------------------------------ + - name: "Step 11: Delete and recreate dev branch from main" 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 }}" - # Merge main into dev so dev has the release + version bump + # Delete dev branch + curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \ + "${API_BASE}/branches/dev" 2>/dev/null && echo "Deleted dev branch" + + # Recreate dev from main (now includes version bump + changelog promotion) curl -sf -X POST -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ - "${API_BASE}/merges" \ - -d "{\"base\":\"dev\",\"head\":\"main\",\"message\":\"chore: sync main into dev after release [skip ci]\"}" \ - 2>/dev/null && echo "Merged main into dev" + "${API_BASE}/branches" \ + -d '{"new_branch_name":"dev","old_branch_name":"main"}' 2>/dev/null && echo "Recreated dev from main" - # If dev doesn't exist, create it from main - if [ $? -ne 0 ]; then - curl -sf -X POST -H "Authorization: token ${TOKEN}" \ - -H "Content-Type: application/json" \ - "${API_BASE}/branches" \ - -d '{"new_branch_name":"dev","old_branch_name":"main"}' 2>/dev/null && echo "Created dev from main" - fi - - echo "Dev branch synced with main (version bump on dev)" >> $GITHUB_STEP_SUMMARY + echo "Dev branch reset from main (keeps dev ahead after release)" >> $GITHUB_STEP_SUMMARY # -- Dolibarr post-release: Reset dev version ----------------------------- diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml index c70ea7d..8a7a766 100644 --- a/.mokogitea/workflows/pre-release.yml +++ b/.mokogitea/workflows/pre-release.yml @@ -55,12 +55,13 @@ jobs: - name: Detect platform id: platform run: | - # Read platform from XML manifest ( tag) or plain text fallback - PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1) - [ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogitea/manifest.xml 2>/dev/null | tr -d '[:space:]') + PLATFORM=$(cat .mokogitea/.moko-platform 2>/dev/null | tr -d '[:space:]') [ -z "$PLATFORM" ] && PLATFORM="generic" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" - MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '/dev/null | head -1) + # For packages: prefer pkg_*.xml in src/; fallback to any manifest + 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" @@ -118,6 +119,17 @@ jobs: sed -i "s|${MANIFEST_VER}|${VERSION}|" "$MANIFEST" sed -i "s|[^<]*|${TODAY}|" "$MANIFEST" fi + # For packages: also bump version in all sub-extension manifests + if [ -d "src/packages" ]; then + for SUB_MANIFEST in $(find src/packages -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null); do + SUB_VER=$(sed -n 's/.*\([^<]*\)<\/version>.*/\1/p' "$SUB_MANIFEST" | head -1) + if [ -n "$SUB_VER" ]; then + sed -i "s|${SUB_VER}|${VERSION}|" "$SUB_MANIFEST" + sed -i "s|[^<]*|${TODAY}|" "$SUB_MANIFEST" + echo " Bumped sub-extension: $(basename $SUB_MANIFEST) ${SUB_VER} → ${VERSION}" + fi + done + fi ;; dolibarr) if [ -n "$MOD_FILE" ]; then @@ -189,17 +201,49 @@ jobs: 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 - rsync -a \ - --exclude='sftp-config*' \ - --exclude='.ftpignore' \ - --exclude='*.ppk' \ - --exclude='*.pem' \ - --exclude='*.key' \ - --exclude='.env*' \ - --exclude='*.local' \ - --exclude='.build-trigger' \ - "${SOURCE_DIR}/" build/package/ + + if [ "$EXT_TYPE" = "package" ] && [ -d "${SOURCE_DIR}/packages" ]; then + echo "=== Building Joomla PACKAGE (multi-extension) ===" + + # 1) ZIP each sub-extension in src/packages/ + 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 + + # 2) Copy package-level files (manifest, script, etc.) + for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do + [ -f "$f" ] && cp "$f" build/package/ + done + + echo "Package contents:" + ls -la build/package/ + else + echo "=== Building standard Joomla 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