From 8fea27e8b60791649f8b3ccc85e84f2a0edf37aa Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Mon, 25 May 2026 04:12:59 +0000 Subject: [PATCH] fix(ci): update pre-release.yml - PHP CLI tools, fix broken platform detection [skip ci] --- .mokogitea/workflows/pre-release.yml | 321 ++++++++++++++++++--------- 1 file changed, 218 insertions(+), 103 deletions(-) diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml index 903f1b92..44d3de69 100644 --- a/.mokogitea/workflows/pre-release.yml +++ b/.mokogitea/workflows/pre-release.yml @@ -7,8 +7,8 @@ # INGROUP: moko-platform.Release # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform # PATH: /templates/workflows/universal/pre-release.yml.template -# VERSION: 05.00.00 -# BRIEF: Manual pre-release — builds dev/alpha/beta/rc packages from any branch +# VERSION: 05.01.00 +# BRIEF: Manual pre-release -- builds dev/alpha/beta/rc packages from any branch name: "Universal: Pre-Release" @@ -45,30 +45,46 @@ jobs: fetch-depth: 0 token: ${{ secrets.GA_TOKEN }} - - name: Setup PHP + - name: Setup tools run: | - 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 + # 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" fi - - - name: Setup moko-platform tools - env: - MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN }} - MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting - run: | - git clone --depth 1 --branch main --quiet "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" /tmp/moko-platform-api - name: Detect platform id: platform run: | - php /tmp/moko-platform-api/cli/manifest_read.php --path . --github-output + PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1 | tr -d '[:space:]') + [ -z "$PLATFORM" ] && PLATFORM="generic" + echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" + MANIFEST=$(find ./src -maxdepth 1 -name "pkg_*.xml" -exec grep -l '/dev/null | head -1) + [ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" ! -path "*/packages/*" -exec grep -l '/dev/null | head -1) + [ -z "$MANIFEST" ] && MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '/dev/null | head -1) + MOD_FILE=$(find . -maxdepth 4 -name "mod*.class.php" ! -path "./.git/*" -exec grep -l 'extends DolibarrModules' {} \; 2>/dev/null | head -1) + echo "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT" + echo "mod_file=${MOD_FILE}" >> "$GITHUB_OUTPUT" - - name: Resolve metadata + - name: Resolve metadata and bump version id: meta run: | STABILITY="${{ inputs.stability }}" - MOKO_API="/tmp/moko-platform-api/cli" case "$STABILITY" in development) SUFFIX="-dev"; TAG="development" ;; @@ -77,32 +93,58 @@ jobs: release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;; esac - # Read current version from manifest (priority) or README — no bump yet - VERSION=$(php ${MOKO_API}/version_read.php --path .) - echo "Version: ${VERSION}" + # Patch bump via CLI tool + php ${MOKO_CLI}/version_bump.php --path . + VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) + [ -z "$VERSION" ] && VERSION="00.00.01" + TODAY=$(date +%Y-%m-%d) - # Ensure platform-specific manifest matches - php ${MOKO_API}/version_set_platform.php --path . --version "${VERSION}" + # Update platform-specific manifest + PLATFORM="${{ steps.platform.outputs.platform }}" + MANIFEST="${{ steps.platform.outputs.manifest }}" + MOD_FILE="${{ steps.platform.outputs.mod_file }}" - # Git setup for later commits + php ${MOKO_CLI}/version_set_platform.php \ + --path . --version "$VERSION" --branch "${{ github.ref_name }}" 2>/dev/null || true + + # Commit version bump 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 diff --cached --quiet || { + git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]" + git push origin HEAD 2>&1 + } - # Detect element from Joomla/Dolibarr manifest - set +o pipefail - PLATFORM="${{ steps.platform.outputs.platform }}" - EXT_ELEMENT=$(php ${MOKO_API}/manifest_read.php --path . --field name 2>/dev/null | tr -d ' ' | tr '[:upper:]' '[:lower:]' || true) - # For Joomla, prefer tag - if [ "$PLATFORM" = "joomla" ]; then - MANIFEST=$(find . -maxdepth 4 -name "*.xml" ! -path "./.git/*" -print0 2>/dev/null | xargs -0 grep -l '/dev/null | head -1 || true) - if [ -n "$MANIFEST" ]; then - ELEM=$(grep -oP "\K[^<]+" "$MANIFEST" 2>/dev/null | head -1 || true) - [ -n "$ELEM" ] && EXT_ELEMENT="$ELEM" - fi - fi - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') - set -o pipefail + # Auto-detect element (platform-aware) + EXT_ELEMENT="" + case "$PLATFORM" in + joomla) + if [ -n "$MANIFEST" ]; then + EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1) + if [ -z "$EXT_ELEMENT" ]; then + EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]') + case "$EXT_ELEMENT" in + templatedetails|manifest) EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ;; + esac + fi + else + EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + fi + ;; + dolibarr) + if [ -n "$MOD_FILE" ]; then + MOD_BASENAME=$(basename "$MOD_FILE" .class.php) + EXT_ELEMENT=$(echo "$MOD_BASENAME" | sed 's/^mod//' | tr '[:upper:]' '[:lower:]') + else + EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + fi + ;; + *) + EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + ;; + esac ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip" @@ -112,42 +154,76 @@ 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 + for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do + [ -f "$f" ] && cp "$f" build/package/ + 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: | - VERSION="${{ steps.meta.outputs.version }}" - SUFFIX="${{ steps.meta.outputs.suffix }}" - PLATFORM="${{ steps.platform.outputs.platform }}" + ZIP_NAME="${{ steps.meta.outputs.zip_name }}" + cd build/package + zip -r "../${ZIP_NAME}" . + cd .. - if [ "$PLATFORM" = "joomla" ]; then - php /tmp/moko-platform-api/cli/joomla_build.php --path . --version "${VERSION}" --suffix "${SUFFIX}" --output build --github-output - else - # Generic build: zip src/ directory - SOURCE_DIR="src" - [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs" - [ ! -d "$SOURCE_DIR" ] && { echo "::error::No src/ or htdocs/"; exit 1; } - EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}" - ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip" - mkdir -p build - cd "$SOURCE_DIR" && zip -r "../build/${ZIP_NAME}" . && cd .. - SHA256=$(sha256sum "build/${ZIP_NAME}" | cut -d' ' -f1) - echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" - echo "zip_path=build/${ZIP_NAME}" >> "$GITHUB_OUTPUT" - echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" - fi + 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 id: release - continue-on-error: true run: | TAG="${{ steps.meta.outputs.tag }}" VERSION="${{ steps.meta.outputs.version }}" STABILITY="${{ steps.meta.outputs.stability }}" SHA256="${{ steps.zip.outputs.sha256 }}" - ZIP_NAME="${{ steps.zip.outputs.zip_name }}" + 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}" @@ -185,76 +261,115 @@ jobs: curl -sS -X POST -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/octet-stream" \ "${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \ - --data-binary "@${{ steps.zip.outputs.zip_path }}" + --data-binary "@build/${ZIP_NAME}" echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})" - - name: "Update updates.xml" + - name: Update updates.xml if: steps.platform.outputs.platform == 'joomla' run: | - VERSION="${{ steps.meta.outputs.version }}" STABILITY="${{ steps.meta.outputs.stability }}" + VERSION="${{ steps.meta.outputs.version }}" SHA256="${{ steps.zip.outputs.sha256 }}" - php /tmp/moko-platform-api/cli/updates_xml_build.php --path . --version "$VERSION" --stability "$STABILITY" --sha "$SHA256" --gitea-url "$GITEA_URL" --org "$GITEA_ORG" --repo "$GITEA_REPO" + ZIP_NAME="${{ steps.meta.outputs.zip_name }}" + TAG="${{ steps.meta.outputs.tag }}" + + if [ ! -f "updates.xml" ]; then + echo "No updates.xml -- skipping" + exit 0 + fi + + # Map stability to XML tag name + case "$STABILITY" in + development) XML_TAG="development" ;; + alpha) XML_TAG="alpha" ;; + beta) XML_TAG="beta" ;; + release-candidate) XML_TAG="rc" ;; + *) XML_TAG="$STABILITY" ;; + esac + + DOWNLOAD_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${TAG}/${ZIP_NAME}" + + # Use PHP to update the channel in updates.xml + php -r ' + $xml_tag = $argv[1]; + $version = $argv[2]; + $sha256 = $argv[3]; + $url = $argv[4]; + $date = date("Y-m-d"); + + $content = file_get_contents("updates.xml"); + $pattern = "/((?:(?!<\/update>).)*?" . preg_quote($xml_tag) . "<\/tag>.*?<\/update>)/s"; + + $content = preg_replace_callback($pattern, function($m) use ($version, $sha256, $url, $date) { + $block = $m[0]; + $block = preg_replace("/[^<]*<\/version>/", "{$version}", $block); + if (strpos($block, "") !== false) { + $block = preg_replace("/[^<]*<\/sha256>/", "{$sha256}", $block); + } else { + $block = str_replace("", "\n {$sha256}", $block); + } + $block = preg_replace("/(]*>)[^<]*(<\/downloadurl>)/", "\${1}{$url}\${2}", $block); + return $block; + }, $content); + + file_put_contents("updates.xml", $content); + echo "Updated {$xml_tag} channel: version={$version}\n"; + ' "$XML_TAG" "$VERSION" "$SHA256" "$DOWNLOAD_URL" + + # Commit and push if ! git diff --quiet updates.xml 2>/dev/null; then git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" git config --local user.name "gitea-actions[bot]" git add updates.xml - git commit -m "chore: update $STABILITY channel $VERSION [skip ci]" + git commit -m "chore: update ${STABILITY} channel ${VERSION} [skip ci]" git push origin HEAD 2>&1 || echo "WARNING: push failed" fi - name: "Sync updates.xml to all branches" if: steps.platform.outputs.platform == 'joomla' run: | - php /tmp/moko-platform-api/cli/updates_xml_sync.php --path . --current "${{ github.ref_name }}" --branches main,dev --version "${{ steps.meta.outputs.version }}" --token "${{ secrets.GA_TOKEN }}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" --gitea-url "${GITEA_URL}" + CURRENT_BRANCH="${{ github.ref_name }}" + git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" + git config --local user.name "gitea-actions[bot]" + + for BRANCH in main dev; do + [ "$BRANCH" = "$CURRENT_BRANCH" ] && continue + echo "Syncing updates.xml -> ${BRANCH}" + git fetch origin "${BRANCH}" 2>/dev/null || continue + git checkout "origin/${BRANCH}" -- . 2>/dev/null || continue + git checkout "${CURRENT_BRANCH}" -- updates.xml + if ! git diff --quiet updates.xml 2>/dev/null; then + git add updates.xml + git commit -m "chore: sync updates.xml from ${CURRENT_BRANCH} [skip ci]" + git push origin HEAD:refs/heads/${BRANCH} 2>&1 || echo "WARNING: push to ${BRANCH} failed" + fi + git checkout "${CURRENT_BRANCH}" 2>/dev/null + done - name: "Delete lesser pre-release channels (cascade)" continue-on-error: true run: | API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" TOKEN="${{ secrets.GA_TOKEN }}" - STABILITY="${{ steps.meta.outputs.stability }}" - # Cascade: rc → beta,alpha,dev | beta → alpha,dev | alpha → dev | dev → nothing - case "$STABILITY" in - release-candidate) TAGS_TO_DELETE="beta alpha development" ;; - beta) TAGS_TO_DELETE="alpha development" ;; - alpha) TAGS_TO_DELETE="development" ;; - *) TAGS_TO_DELETE="" ;; - esac + php ${MOKO_CLI}/release_cascade.php \ + --stability "${{ steps.meta.outputs.stability }}" \ + --token "${TOKEN}" \ + --api-base "${API_BASE}" - [ -z "$TAGS_TO_DELETE" ] && exit 0 - - for TAG in $TAGS_TO_DELETE; do - RELEASE_ID=$(curl -sS -H "Authorization: token ${TOKEN}" \ - "${API_BASE}/releases/tags/${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 - curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \ - "${API_BASE}/releases/${RELEASE_ID}" 2>/dev/null || true - curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \ - "${API_BASE}/tags/${TAG}" 2>/dev/null || true - echo "Deleted: ${TAG} (id: ${RELEASE_ID})" - fi - done - - - name: "Post-release version bump" + - name: Summary + if: always() run: | - MOKO_API="/tmp/moko-platform-api/cli" VERSION="${{ steps.meta.outputs.version }}" - - # Bump patch for next dev cycle - BUMP_OUTPUT=$(php ${MOKO_API}/version_bump.php --path .) - NEXT=$(echo "$BUMP_OUTPUT" | grep -oP '\d{2}\.\d{2}\.\d{2}$' || true) - [ -z "$NEXT" ] && exit 0 - - # Update platform-specific manifest to next version - php ${MOKO_API}/version_set_platform.php --path . --version "${NEXT}" - - git add -A - git diff --cached --quiet || { - git commit -m "chore: update development channel ${VERSION} [skip ci]" - git push origin HEAD 2>&1 - } + 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