Merge pull request 'Release 02.09.00: CI fixes, update server standard, Joomla skill' (#44) from dev into main
Universal: Cascade Main → Dev / Cascade main → branches (push) Has been cancelled
Joomla: Repo Health / Access control (push) Has been cancelled
Joomla: Repo Health / Release configuration (push) Has been cancelled
Joomla: Repo Health / Scripts governance (push) Has been cancelled
Joomla: Repo Health / Repository health (push) Has been cancelled

This commit was merged in pull request #44.
This commit is contained in:
2026-05-26 04:37:36 +00:00
8 changed files with 1038 additions and 1141 deletions
File diff suppressed because it is too large Load Diff
+361 -375
View File
@@ -1,375 +1,361 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech> # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
# #
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Release # INGROUP: moko-platform.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /templates/workflows/universal/pre-release.yml.template # PATH: /templates/workflows/universal/pre-release.yml.template
# VERSION: 05.01.00 # VERSION: 05.01.00
# BRIEF: Manual pre-release -- builds dev/alpha/beta/rc packages from any branch # BRIEF: Manual pre-release -- builds dev/alpha/beta/rc packages from any branch
name: "Universal: Pre-Release" name: "Universal: Pre-Release"
on: on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
stability: stability:
description: 'Pre-release channel' description: 'Pre-release channel'
required: true required: true
type: choice type: choice
options: options:
- development - development
- alpha - alpha
- beta - beta
- release-candidate - release-candidate
permissions: permissions:
contents: write contents: write
env: env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
jobs: jobs:
build: build:
name: "Build Pre-Release (${{ inputs.stability }})" name: "Build Pre-Release (${{ inputs.stability }})"
runs-on: release runs-on: release
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.GA_TOKEN }} token: ${{ secrets.GA_TOKEN }}
- name: Setup tools - name: Setup tools
run: | run: |
# Update moko-platform CLI tools if available; install PHP if missing # Update moko-platform CLI tools if available; install PHP if missing
if command -v moko-platform-update &> /dev/null; then if command -v moko-platform-update &> /dev/null; then
moko-platform-update moko-platform-update
elif [ -d "/opt/moko-platform" ]; then elif [ -d "/opt/moko-platform" ]; then
cd /opt/moko-platform && git pull origin main --quiet 2>/dev/null || true cd /opt/moko-platform && git pull origin main --quiet 2>/dev/null || true
else else
if ! command -v php &> /dev/null; then if ! command -v php &> /dev/null; then
sudo apt-get update -qq 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 sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl >/dev/null 2>&1
fi fi
git clone --depth 1 --branch main --quiet \ git clone --depth 1 --branch main --quiet \
"https://x-access-token:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/moko-platform.git" \ "https://x-access-token:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/moko-platform.git" \
/tmp/moko-platform-api /tmp/moko-platform-api
fi fi
# Set MOKO_CLI to whichever path exists # Set MOKO_CLI to whichever path exists
if [ -d "/opt/moko-platform/cli" ]; then if [ -d "/opt/moko-platform/cli" ]; then
echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV" echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV"
else else
echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV" echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV"
fi fi
- name: Detect platform - name: Detect platform
id: platform id: platform
run: | run: |
PLATFORM=$(sed -n 's/.*<platform>\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1 | tr -d '[:space:]') PLATFORM=$(sed -n 's/.*<platform>\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1 | tr -d '[:space:]')
[ -z "$PLATFORM" ] && PLATFORM="generic" [ -z "$PLATFORM" ] && PLATFORM="generic"
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
MANIFEST=$(find ./src -maxdepth 1 -name "pkg_*.xml" -exec grep -l '<extension' {} \; 2>/dev/null | head -1) MANIFEST=$(find ./src -maxdepth 1 -name "pkg_*.xml" -exec grep -l '<extension' {} \; 2>/dev/null | head -1)
[ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" ! -path "*/packages/*" -exec grep -l '<extension' {} \; 2>/dev/null | head -1) [ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" ! -path "*/packages/*" -exec grep -l '<extension' {} \; 2>/dev/null | head -1)
[ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '<extension' {} \; 2>/dev/null | head -1) [ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '<extension' {} \; 2>/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) 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 "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT"
echo "mod_file=${MOD_FILE}" >> "$GITHUB_OUTPUT" echo "mod_file=${MOD_FILE}" >> "$GITHUB_OUTPUT"
- name: Resolve metadata and bump version - name: Resolve metadata and bump version
id: meta id: meta
run: | run: |
STABILITY="${{ inputs.stability }}" STABILITY="${{ inputs.stability }}"
case "$STABILITY" in case "$STABILITY" in
development) SUFFIX="-dev"; TAG="development" ;; development) SUFFIX="-dev"; TAG="development" ;;
alpha) SUFFIX="-alpha"; TAG="alpha" ;; alpha) SUFFIX="-alpha"; TAG="alpha" ;;
beta) SUFFIX="-beta"; TAG="beta" ;; beta) SUFFIX="-beta"; TAG="beta" ;;
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;; release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
esac esac
# Patch bump via CLI tool # Patch bump via CLI tool
php ${MOKO_CLI}/version_bump.php --path . php ${MOKO_CLI}/version_bump.php --path .
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null)
[ -z "$VERSION" ] && VERSION="00.00.01" [ -z "$VERSION" ] && VERSION="00.00.01"
TODAY=$(date +%Y-%m-%d) TODAY=$(date +%Y-%m-%d)
# Update platform-specific manifest # Update platform-specific manifest
PLATFORM="${{ steps.platform.outputs.platform }}" PLATFORM="${{ steps.platform.outputs.platform }}"
MANIFEST="${{ steps.platform.outputs.manifest }}" MANIFEST="${{ steps.platform.outputs.manifest }}"
MOD_FILE="${{ steps.platform.outputs.mod_file }}" MOD_FILE="${{ steps.platform.outputs.mod_file }}"
php ${MOKO_CLI}/version_set_platform.php \ php ${MOKO_CLI}/version_set_platform.php \
--path . --version "$VERSION" --branch "${{ github.ref_name }}" 2>/dev/null || true --path . --version "$VERSION" --branch "${{ github.ref_name }}" 2>/dev/null || true
# Commit version bump # Verify version consistency across all files
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" # Commit version bump
git add -A git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git diff --cached --quiet || { git config --local user.name "gitea-actions[bot]"
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]" git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git push origin HEAD 2>&1 git add -A
} git diff --cached --quiet || {
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
# Auto-detect element (platform-aware) git push origin HEAD 2>&1
EXT_ELEMENT="" }
case "$PLATFORM" in
joomla) # Auto-detect element (platform-aware)
if [ -n "$MANIFEST" ]; then EXT_ELEMENT=""
EXT_ELEMENT=$(sed -n 's/.*<element>\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1) case "$PLATFORM" in
if [ -z "$EXT_ELEMENT" ]; then joomla)
EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]') if [ -n "$MANIFEST" ]; then
case "$EXT_ELEMENT" in EXT_ELEMENT=$(sed -n 's/.*<element>\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1)
templatedetails|manifest) EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ;; if [ -z "$EXT_ELEMENT" ]; then
esac EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]')
fi case "$EXT_ELEMENT" in
else templatedetails|manifest) EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ;;
EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') esac
fi fi
;; else
dolibarr) EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
if [ -n "$MOD_FILE" ]; then fi
MOD_BASENAME=$(basename "$MOD_FILE" .class.php) ;;
EXT_ELEMENT=$(echo "$MOD_BASENAME" | sed 's/^mod//' | tr '[:upper:]' '[:lower:]') dolibarr)
else if [ -n "$MOD_FILE" ]; then
EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') MOD_BASENAME=$(basename "$MOD_FILE" .class.php)
fi EXT_ELEMENT=$(echo "$MOD_BASENAME" | sed 's/^mod//' | tr '[:upper:]' '[:lower:]')
;; else
*) EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi
;; ;;
esac *)
EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip" ;;
esac
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT" ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip"
echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT" echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT" echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT"
echo "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT" echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ===" echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT"
echo "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT"
- name: Build package
run: | echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ==="
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs" - name: Build package
if [ ! -d "$SOURCE_DIR" ]; then run: |
echo "::error::No src/ or htdocs/ directory" SOURCE_DIR="src"
exit 1 [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
fi if [ ! -d "$SOURCE_DIR" ]; then
echo "::error::No src/ or htdocs/ directory"
MANIFEST="${{ steps.meta.outputs.manifest }}" exit 1
EXT_TYPE="" fi
if [ -n "$MANIFEST" ]; then
EXT_TYPE=$(sed -n 's/.*<extension[^>]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) MANIFEST="${{ steps.meta.outputs.manifest }}"
fi EXT_TYPE=""
if [ -n "$MANIFEST" ]; then
EXCLUDES="sftp-config* .ftpignore *.ppk *.pem *.key .env* *.local .build-trigger" EXT_TYPE=$(sed -n 's/.*<extension[^>]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
fi
mkdir -p build/package
EXCLUDES="sftp-config* .ftpignore *.ppk *.pem *.key .env* *.local .build-trigger"
if [ "$EXT_TYPE" = "package" ] && [ -d "${SOURCE_DIR}/packages" ]; then
echo "=== Building Joomla PACKAGE (multi-extension) ===" mkdir -p build/package
for ext_dir in "${SOURCE_DIR}"/packages/*/; do
[ ! -d "$ext_dir" ] && continue REPO_ROOT=$(pwd)
EXT_NAME=$(basename "$ext_dir")
echo " Packaging sub-extension: ${EXT_NAME}" if [ "$EXT_TYPE" = "package" ] && [ -d "${SOURCE_DIR}/packages" ]; then
cd "$ext_dir" echo "=== Building Joomla PACKAGE (multi-extension) ==="
zip -r "../../build/package/${EXT_NAME}.zip" . -x $EXCLUDES for ext_dir in "${SOURCE_DIR}"/packages/*/; do
cd "$OLDPWD" [ ! -d "$ext_dir" ] && continue
done EXT_NAME=$(basename "$ext_dir")
for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do echo " Packaging sub-extension: ${EXT_NAME}"
[ -f "$f" ] && cp "$f" build/package/ cd "$ext_dir"
done zip -r "${REPO_ROOT}/build/package/${EXT_NAME}.zip" . -x $EXCLUDES
else cd "${REPO_ROOT}"
echo "=== Building standard extension ===" done
rsync -a \ for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do
--exclude='sftp-config*' \ [ -f "$f" ] && cp "$f" build/package/
--exclude='.ftpignore' \ done
--exclude='*.ppk' \ else
--exclude='*.pem' \ echo "=== Building standard extension ==="
--exclude='*.key' \ rsync -a \
--exclude='.env*' \ --exclude='sftp-config*' \
--exclude='*.local' \ --exclude='.ftpignore' \
--exclude='.build-trigger' \ --exclude='*.ppk' \
"${SOURCE_DIR}/" build/package/ --exclude='*.pem' \
fi --exclude='*.key' \
--exclude='.env*' \
- name: Create ZIP --exclude='*.local' \
id: zip --exclude='.build-trigger' \
run: | "${SOURCE_DIR}/" build/package/
ZIP_NAME="${{ steps.meta.outputs.zip_name }}" fi
cd build/package
zip -r "../${ZIP_NAME}" . - name: Create ZIP
cd .. id: zip
run: |
SHA256=$(sha256sum "${ZIP_NAME}" | cut -d' ' -f1) ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" cd build/package
echo "ZIP: ${ZIP_NAME} (SHA: ${SHA256:0:16}...)" zip -r "../${ZIP_NAME}" .
cd ..
- name: Create or replace Gitea release
id: release SHA256=$(sha256sum "${ZIP_NAME}" | cut -d' ' -f1)
run: | echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT"
TAG="${{ steps.meta.outputs.tag }}" echo "ZIP: ${ZIP_NAME} (SHA: ${SHA256:0:16}...)"
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}" - name: Create or replace Gitea release
SHA256="${{ steps.zip.outputs.sha256 }}" id: release
ZIP_NAME="${{ steps.meta.outputs.zip_name }}" run: |
EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}" TAG="${{ steps.meta.outputs.tag }}"
TOKEN="${{ secrets.GA_TOKEN }}" VERSION="${{ steps.meta.outputs.version }}"
API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" STABILITY="${{ steps.meta.outputs.stability }}"
BRANCH=$(git branch --show-current) SHA256="${{ steps.zip.outputs.sha256 }}"
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
BODY="## ${VERSION} ($(date +%Y-%m-%d)) EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}"
**Channel:** ${STABILITY} TOKEN="${{ secrets.GA_TOKEN }}"
**SHA-256:** \`${SHA256}\`" API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
BRANCH=$(git branch --show-current)
# Delete existing release
EXISTING_ID=$(curl -sS -H "Authorization: token ${TOKEN}" \ BODY="## ${VERSION} ($(date +%Y-%m-%d))
"${API}/releases/tags/${TAG}" | jq -r '.id // empty' 2>/dev/null) **Channel:** ${STABILITY}
if [ -n "$EXISTING_ID" ]; then Checksum file attached as \`${ZIP_NAME}.sha256\`."
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
"${API}/releases/${EXISTING_ID}" 2>/dev/null || true # Delete existing release
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \ EXISTING_ID=$(curl -sS -H "Authorization: token ${TOKEN}" \
"${API}/tags/${TAG}" 2>/dev/null || true "${API}/releases/tags/${TAG}" | jq -r '.id // empty' 2>/dev/null)
fi if [ -n "$EXISTING_ID" ]; then
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
# Create release "${API}/releases/${EXISTING_ID}" 2>/dev/null || true
RELEASE_ID=$(curl -sS -X POST -H "Authorization: token ${TOKEN}" \ curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \ "${API}/tags/${TAG}" 2>/dev/null || true
"${API}/releases" \ fi
-d "$(jq -n \
--arg tag "$TAG" \ # Create release
--arg target "$BRANCH" \ RELEASE_ID=$(curl -sS -X POST -H "Authorization: token ${TOKEN}" \
--arg name "${EXT_ELEMENT} ${VERSION} (${STABILITY})" \ -H "Content-Type: application/json" \
--arg body "$BODY" \ "${API}/releases" \
'{tag_name: $tag, target_commitish: $target, name: $name, body: $body, prerelease: true}' -d "$(jq -n \
)" | jq -r '.id') --arg tag "$TAG" \
--arg target "$BRANCH" \
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT" --arg name "${EXT_ELEMENT} ${VERSION} (${STABILITY})" \
--arg body "$BODY" \
# Upload ZIP '{tag_name: $tag, target_commitish: $target, name: $name, body: $body, prerelease: true}'
curl -sS -X POST -H "Authorization: token ${TOKEN}" \ )" | jq -r '.id')
-H "Content-Type: application/octet-stream" \
"${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \ echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"
--data-binary "@build/${ZIP_NAME}"
# Upload ZIP
echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})" curl -sS -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/octet-stream" \
- name: Update updates.xml "${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \
if: steps.platform.outputs.platform == 'joomla' --data-binary "@build/${ZIP_NAME}"
run: |
STABILITY="${{ steps.meta.outputs.stability }}" # Upload per-file checksum
VERSION="${{ steps.meta.outputs.version }}" echo "${SHA256} ${ZIP_NAME}" > "build/${ZIP_NAME}.sha256"
SHA256="${{ steps.zip.outputs.sha256 }}" curl -sS -X POST -H "Authorization: token ${TOKEN}" \
ZIP_NAME="${{ steps.meta.outputs.zip_name }}" -H "Content-Type: application/octet-stream" \
TAG="${{ steps.meta.outputs.tag }}" "${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}.sha256" \
--data-binary "@build/${ZIP_NAME}.sha256"
if [ ! -f "updates.xml" ]; then
echo "No updates.xml -- skipping" echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})"
exit 0
fi - name: Update updates.xml
if: steps.platform.outputs.platform == 'joomla'
# Map stability to XML tag name run: |
case "$STABILITY" in STABILITY="${{ steps.meta.outputs.stability }}"
development) XML_TAG="development" ;; VERSION="${{ steps.meta.outputs.version }}"
alpha) XML_TAG="alpha" ;; SHA256="${{ steps.zip.outputs.sha256 }}"
beta) XML_TAG="beta" ;; ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
release-candidate) XML_TAG="rc" ;; TAG="${{ steps.meta.outputs.tag }}"
*) XML_TAG="$STABILITY" ;;
esac if [ ! -f "updates.xml" ]; then
echo "No updates.xml -- skipping"
DOWNLOAD_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${TAG}/${ZIP_NAME}" exit 0
fi
# Use PHP to update the channel in updates.xml
php -r ' # Use moko-platform CLI to build/update updates.xml (preserves other channels)
$xml_tag = $argv[1]; MOKO_CLI="/tmp/moko-platform-api/cli"
$version = $argv[2]; if [ -f "${MOKO_CLI}/updates_xml_build.php" ]; then
$sha256 = $argv[3]; php "${MOKO_CLI}/updates_xml_build.php" \
$url = $argv[4]; --path . --version "${VERSION}" --stability "${STABILITY}" \
$date = date("Y-m-d"); --sha "${SHA256}" \
--gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}"
$content = file_get_contents("updates.xml"); echo "Updated ${STABILITY} channel via CLI: version=${VERSION}"
$pattern = "/(<update>(?:(?!<\/update>).)*?<tag>" . preg_quote($xml_tag) . "<\/tag>.*?<\/update>)/s"; else
echo "WARNING: updates_xml_build.php not found — skipping"
$content = preg_replace_callback($pattern, function($m) use ($version, $sha256, $url, $date) { fi
$block = $m[0];
$block = preg_replace("/<version>[^<]*<\/version>/", "<version>{$version}</version>", $block); # Commit and push
if (strpos($block, "<sha256>") !== false) { if ! git diff --quiet updates.xml 2>/dev/null; then
$block = preg_replace("/<sha256>[^<]*<\/sha256>/", "<sha256>{$sha256}</sha256>", $block); git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
} else { git config --local user.name "gitea-actions[bot]"
$block = str_replace("</downloads>", "</downloads>\n <sha256>{$sha256}</sha256>", $block); git add updates.xml
} git commit -m "chore: update ${STABILITY} channel ${VERSION} [skip ci]"
$block = preg_replace("/(<downloadurl[^>]*>)[^<]*(<\/downloadurl>)/", "\${1}{$url}\${2}", $block); git push origin HEAD 2>&1 || echo "WARNING: push failed"
return $block; fi
}, $content);
- name: "Sync updates.xml to all branches"
file_put_contents("updates.xml", $content); if: steps.platform.outputs.platform == 'joomla'
echo "Updated {$xml_tag} channel: version={$version}\n"; run: |
' "$XML_TAG" "$VERSION" "$SHA256" "$DOWNLOAD_URL" CURRENT_BRANCH="${{ github.ref_name }}"
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
# Commit and push git config --local user.name "gitea-actions[bot]"
if ! git diff --quiet updates.xml 2>/dev/null; then
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" for BRANCH in main dev; do
git config --local user.name "gitea-actions[bot]" [ "$BRANCH" = "$CURRENT_BRANCH" ] && continue
git add updates.xml echo "Syncing updates.xml -> ${BRANCH}"
git commit -m "chore: update ${STABILITY} channel ${VERSION} [skip ci]" git fetch origin "${BRANCH}" 2>/dev/null || continue
git push origin HEAD 2>&1 || echo "WARNING: push failed" git checkout "origin/${BRANCH}" -- . 2>/dev/null || continue
fi git checkout "${CURRENT_BRANCH}" -- updates.xml
if ! git diff --quiet updates.xml 2>/dev/null; then
- name: "Sync updates.xml to all branches" git add updates.xml
if: steps.platform.outputs.platform == 'joomla' git commit -m "chore: sync updates.xml from ${CURRENT_BRANCH} [skip ci]"
run: | git push origin HEAD:refs/heads/${BRANCH} 2>&1 || echo "WARNING: push to ${BRANCH} failed"
CURRENT_BRANCH="${{ github.ref_name }}" fi
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" git checkout "${CURRENT_BRANCH}" 2>/dev/null
git config --local user.name "gitea-actions[bot]" done
for BRANCH in main dev; do - name: "Delete lesser pre-release channels (cascade)"
[ "$BRANCH" = "$CURRENT_BRANCH" ] && continue continue-on-error: true
echo "Syncing updates.xml -> ${BRANCH}" run: |
git fetch origin "${BRANCH}" 2>/dev/null || continue API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
git checkout "origin/${BRANCH}" -- . 2>/dev/null || continue TOKEN="${{ secrets.GA_TOKEN }}"
git checkout "${CURRENT_BRANCH}" -- updates.xml
if ! git diff --quiet updates.xml 2>/dev/null; then php ${MOKO_CLI}/release_cascade.php \
git add updates.xml --stability "${{ steps.meta.outputs.stability }}" \
git commit -m "chore: sync updates.xml from ${CURRENT_BRANCH} [skip ci]" --token "${TOKEN}" \
git push origin HEAD:refs/heads/${BRANCH} 2>&1 || echo "WARNING: push to ${BRANCH} failed" --api-base "${API_BASE}"
fi
git checkout "${CURRENT_BRANCH}" 2>/dev/null - name: Summary
done if: always()
run: |
- name: "Delete lesser pre-release channels (cascade)" VERSION="${{ steps.meta.outputs.version }}"
continue-on-error: true STABILITY="${{ steps.meta.outputs.stability }}"
run: | ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" SHA256="${{ steps.zip.outputs.sha256 }}"
TOKEN="${{ secrets.GA_TOKEN }}" echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
php ${MOKO_CLI}/release_cascade.php \ echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
--stability "${{ steps.meta.outputs.stability }}" \ echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
--token "${TOKEN}" \ echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
--api-base "${API_BASE}" echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
- name: Summary echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
if: always()
run: |
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}"
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
SHA256="${{ steps.zip.outputs.sha256 }}"
echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
+6
View File
@@ -42,6 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Install API endpoint: extract ZIP to temp directory before passing to Joomla Installer (was passing ZIP path directly) - Install API endpoint: extract ZIP to temp directory before passing to Joomla Installer (was passing ZIP path directly)
- Clean up extracted temp directory on success or failure - Clean up extracted temp directory on success or failure
- Update site disabled by Joomla when protected=1 — ensureProtectedFlag() now re-enables it - Update site disabled by Joomla when protected=1 — ensureProtectedFlag() now re-enables it
- CI: auto-release fetches updates.xml from main before building (preserves all channels)
- CI: version_check.php --fix runs after version bump in both workflows
- CI: checksums attached as `[filename].sha256` files instead of in release body
- CI: auto-release cleaned up — removed duplicate asset loops, inline Python updater, dead code
- CI: Step 8b uses `release_body_update.php` CLI instead of inline Python
- CI: Step 6 tag creation no longer gated by `is_minor` (was never set)
### Changed ### Changed
- CI: auto-release uses stream tag `stable` instead of version tag `vXX` - CI: auto-release uses stream tag `stable` instead of version tag `vXX`
+1 -1
View File
@@ -9,7 +9,7 @@
DEFGROUP: Joomla.Plugin DEFGROUP: Joomla.Plugin
INGROUP: MokoWaaS INGROUP: MokoWaaS
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS
VERSION: 02.06.04 VERSION: 02.08.03
PATH: /README.md PATH: /README.md
BRIEF: MokoWaaS platform plugin for Joomla BRIEF: MokoWaaS platform plugin for Joomla
--> -->
+1 -1
View File
@@ -7,7 +7,7 @@
<license>GPL-3.0-or-later</license> <license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail> <authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl> <authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.06.04</version> <version>02.08.03</version>
<description>Minimal API-only component for MokoWaaS. Provides REST endpoints for site health, cache, updates, and backups.</description> <description>Minimal API-only component for MokoWaaS. Provides REST endpoints for site health, cache, updates, and backups.</description>
<namespace path="api/src">Moko\Component\MokoWaaS\Api</namespace> <namespace path="api/src">Moko\Component\MokoWaaS\Api</namespace>
<administration> <administration>
@@ -30,7 +30,7 @@
<license>GNU General Public License version 3 or later; see LICENSE.md</license> <license>GNU General Public License version 3 or later; see LICENSE.md</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail> <authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl> <authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.06.04</version> <version>02.08.03</version>
<description>This plugin rebrands the Joomla system interface with MokoWaaS identity. It applies language overrides and ensures consistent branding across the platform.</description> <description>This plugin rebrands the Joomla system interface with MokoWaaS identity. It applies language overrides and ensures consistent branding across the platform.</description>
<namespace path=".">Moko\Plugin\System\MokoWaaS</namespace> <namespace path=".">Moko\Plugin\System\MokoWaaS</namespace>
<scriptfile>script.php</scriptfile> <scriptfile>script.php</scriptfile>
@@ -7,7 +7,7 @@
<license>GPL-3.0-or-later</license> <license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail> <authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl> <authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.06.04</version> <version>02.08.03</version>
<description>Joomla Web Services API routes for MokoWaaS site management — health checks, cache, updates, backups, and site info.</description> <description>Joomla Web Services API routes for MokoWaaS site management — health checks, cache, updates, backups, and site info.</description>
<namespace path="src">Moko\Plugin\WebServices\MokoWaaS</namespace> <namespace path="src">Moko\Plugin\WebServices\MokoWaaS</namespace>
<files> <files>
+1 -1
View File
@@ -2,7 +2,7 @@
<extension type="package" method="upgrade"> <extension type="package" method="upgrade">
<name>MokoWaaS</name> <name>MokoWaaS</name>
<packagename>mokowaas</packagename> <packagename>mokowaas</packagename>
<version>02.06.04</version> <version>02.08.03</version>
<creationDate>2026-05-23</creationDate> <creationDate>2026-05-23</creationDate>
<author>Moko Consulting</author> <author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail> <authorEmail>hello@mokoconsulting.tech</authorEmail>