From 4ce29b2e4a7c38429e55da0a0acc9574ed9b9832 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Thu, 9 Apr 2026 10:51:16 -0500 Subject: [PATCH] chore: update .github/workflows/auto-release.yml from MokoStandards --- .github/workflows/auto-release.yml | 255 ++--------------------------- 1 file changed, 16 insertions(+), 239 deletions(-) diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 62eff0f..7098b62 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -6,24 +6,22 @@ # DEFGROUP: GitHub.Workflow # INGROUP: MokoStandards.Release # REPO: https://github.com/mokoconsulting-tech/MokoStandards -# PATH: /templates/workflows/joomla/auto-release.yml.template -# VERSION: 04.06.00 -# BRIEF: Joomla build & release — ZIP package, updates.xml, SHA-256 checksum +# PATH: /templates/workflows/shared/auto-release.yml +# VERSION: 04.05.13 +# BRIEF: Generic build & release pipeline — version branch, platform version, badges, tag, release # # +========================================================================+ -# | BUILD & RELEASE PIPELINE (JOOMLA) | +# | BUILD & RELEASE PIPELINE | # +========================================================================+ # | | # | Triggers on push to main (skips bot commits + [skip ci]): | # | | # | Every push: | # | 1. Read version from README.md | -# | 3. Set platform version (Joomla ) | +# | 3. Set platform version | # | 4. Update [VERSION: XX.YY.ZZ] badges in markdown files | -# | 5. Write updates.xml (Joomla update server XML) | # | 6. Create git tag vXX.YY.ZZ | # | 7a. Patch: update existing GitHub Release for this minor | -# | 8. Build ZIP, upload asset, write SHA-256 to updates.xml | # | | # | Every version change: archives main -> version/XX.YY branch | # | Patch 00 = development (no release). First release = patch 01. | @@ -35,14 +33,13 @@ name: Build & Release on: - pull_request: - types: [closed] + push: branches: - main + - master paths: - 'src/**' - 'htdocs/**' - workflow_dispatch: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true @@ -55,7 +52,8 @@ jobs: name: Build & Release Pipeline runs-on: ubuntu-latest if: >- - github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' + !contains(github.event.head_commit.message, '[skip ci]') && + github.actor != 'github-actions[bot]' steps: - name: Checkout repository @@ -143,11 +141,11 @@ jobs: VERSION="${{ steps.version.outputs.version }}" ERRORS=0 - echo "## Pre-Release Sanity Checks (Joomla)" >> $GITHUB_STEP_SUMMARY + echo "## Pre-Release Sanity Checks" >> $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) + README_VER=$(grep -oP 'VERSION:\s*\K[\d.]+' 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)) @@ -156,7 +154,7 @@ jobs: 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) + CL_VER=$(grep -oP 'VERSION:\s*\K[\d.]+' 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)) @@ -164,7 +162,7 @@ jobs: # 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) + COMP_VER=$(grep -oP '"version"\s*:\s*"\K[^"]+' 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)) @@ -185,30 +183,6 @@ jobs: echo "- Source directory present" >> $GITHUB_STEP_SUMMARY fi - # -- Joomla: manifest version drift -------- - MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1) - 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 - fi - - # -- Joomla: XML manifest existence -------- - if [ -z "$MANIFEST" ]; then - echo "- No Joomla XML manifest found" >> $GITHUB_STEP_SUMMARY - ERRORS=$((ERRORS+1)) - else - echo "- Manifest: \`${MANIFEST}\`" >> $GITHUB_STEP_SUMMARY - - # -- Joomla: extension type check -------- - TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" 2>/dev/null) - echo "- Extension type: ${TYPE:-unknown}" >> $GITHUB_STEP_SUMMARY - fi - echo "" >> $GITHUB_STEP_SUMMARY if [ "$ERRORS" -gt 0 ]; then echo "**${ERRORS} error(s) — release may be incomplete**" >> $GITHUB_STEP_SUMMARY @@ -259,120 +233,6 @@ jobs: fi done - # -- STEP 5: Write updates.xml (Joomla update server) --------------------- - - name: "Step 5: Write updates.xml" - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.already_released != 'true' - run: | - VERSION="${{ steps.version.outputs.version }}" - REPO="${{ github.repository }}" - - # -- Parse extension metadata from XML manifest ---------------- - MANIFEST=$(find . -maxdepth 2 -name "*.xml" -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 - fi - - # Extract fields using sed (portable — no grep -P) - EXT_NAME=$(sed -n 's/.*\([^<]*\)<\/name>.*/\1/p' "$MANIFEST" | head -1) - EXT_TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) - EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" | head -1) - EXT_CLIENT=$(sed -n 's/.*]*client="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) - EXT_FOLDER=$(sed -n 's/.*]*group="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) - TARGET_PLATFORM=$(sed -n 's/.*\(\).*/\1/p' "$MANIFEST" | head -1) - PHP_MINIMUM=$(sed -n 's/.*\([^<]*\)<\/php_minimum>.*/\1/p' "$MANIFEST" | head -1) - - # Fallbacks - [ -z "$EXT_NAME" ] && EXT_NAME="${{ github.event.repository.name }}" - [ -z "$EXT_TYPE" ] && EXT_TYPE="component" - - # Templates/modules don't have — derive from (lowercased) - if [ -z "$EXT_ELEMENT" ]; then - EXT_ELEMENT=$(echo "$EXT_NAME" | tr '[:upper:]' '[:lower:]' | tr -d ' ') - fi - - # Build client tag: plugins and frontend modules need site - CLIENT_TAG="" - if [ -n "$EXT_CLIENT" ]; then - CLIENT_TAG="${EXT_CLIENT}" - elif [ "$EXT_TYPE" = "module" ] || [ "$EXT_TYPE" = "plugin" ]; then - CLIENT_TAG="site" - fi - - # Build folder tag for plugins (required for Joomla to match the update) - FOLDER_TAG="" - if [ -n "$EXT_FOLDER" ] && [ "$EXT_TYPE" = "plugin" ]; then - FOLDER_TAG="${EXT_FOLDER}" - fi - - # Build targetplatform (fallback to Joomla 5 if not in manifest) - if [ -z "$TARGET_PLATFORM" ]; then - TARGET_PLATFORM=$(printf '' "/") - fi - - # Build php_minimum tag - PHP_TAG="" - if [ -n "$PHP_MINIMUM" ]; then - PHP_TAG="${PHP_MINIMUM}" - fi - - DOWNLOAD_URL="https://github.com/${REPO}/releases/download/v${VERSION}/${EXT_ELEMENT}-${VERSION}.zip" - INFO_URL="https://github.com/${REPO}/releases/tag/v${VERSION}" - - # -- Build stable entry to temp file ───────────────────────── - { - printf '%s\n' ' ' - printf '%s\n' " ${EXT_NAME}" - printf '%s\n' " ${EXT_NAME} update" - printf '%s\n' " ${EXT_ELEMENT}" - printf '%s\n' " ${EXT_TYPE}" - printf '%s\n' " ${VERSION}" - [ -n "$CLIENT_TAG" ] && printf '%s\n' " ${CLIENT_TAG}" - [ -n "$FOLDER_TAG" ] && printf '%s\n' " ${FOLDER_TAG}" - printf '%s\n' ' ' - printf '%s\n' ' stable' - printf '%s\n' ' ' - printf '%s\n' " ${INFO_URL}" - printf '%s\n' ' ' - printf '%s\n' " ${DOWNLOAD_URL}" - printf '%s\n' ' ' - printf '%s\n' " ${TARGET_PLATFORM}" - [ -n "$PHP_TAG" ] && printf '%s\n' " ${PHP_TAG}" - printf '%s\n' ' Moko Consulting' - printf '%s\n' ' https://mokoconsulting.tech' - printf '%s\n' ' ' - } > /tmp/stable_entry.xml - - # -- Write updates.xml preserving dev/rc entries ────────────── - # Extract existing entries for other stability levels - # Order reflects release workflow: development → alpha → beta → rc → stable - if [ -f "updates.xml" ]; then - printf 'import re, sys\n' > /tmp/extract.py - printf 'with open("updates.xml") as f: c = f.read()\n' >> /tmp/extract.py - printf 'tag = sys.argv[1]\n' >> /tmp/extract.py - printf 'm = re.search(r"( .*?" + re.escape(tag) + r".*?)", c, re.DOTALL)\n' >> /tmp/extract.py - printf 'if m: print(m.group(1))\n' >> /tmp/extract.py - fi - DEV_ENTRY=$(python3 /tmp/extract.py development 2>/dev/null || true) - ALPHA_ENTRY=$(python3 /tmp/extract.py alpha 2>/dev/null || true) - BETA_ENTRY=$(python3 /tmp/extract.py beta 2>/dev/null || true) - RC_ENTRY=$(python3 /tmp/extract.py rc 2>/dev/null || true) - - { - printf '%s\n' '' - printf '%s\n' '' - [ -n "$DEV_ENTRY" ] && echo "$DEV_ENTRY" - [ -n "$ALPHA_ENTRY" ] && echo "$ALPHA_ENTRY" - [ -n "$BETA_ENTRY" ] && echo "$BETA_ENTRY" - [ -n "$RC_ENTRY" ] && echo "$RC_ENTRY" - cat /tmp/stable_entry.xml - printf '%s\n' '' - } > updates.xml - - echo "updates.xml: ${VERSION} (stable + rc/dev preserved)" >> $GITHUB_STEP_SUMMARY - # -- Commit all changes --------------------------------------------------- - name: Commit release changes if: >- @@ -430,14 +290,14 @@ jobs: EXISTING=$(gh release view "$RELEASE_TAG" --json tagName -q .tagName 2>/dev/null || true) if [ -z "$EXISTING" ]; then - # First release for this major + # First release for this major: create GitHub Release gh release create "$RELEASE_TAG" \ --title "v${MAJOR} (latest: ${VERSION})" \ --notes-file /tmp/release_notes.md \ --target "$BRANCH" echo "Release created: ${RELEASE_TAG} (${VERSION})" >> $GITHUB_STEP_SUMMARY else - # Append version notes to existing major release + # Update existing major release with new version info CURRENT_NOTES=$(gh release view "$RELEASE_TAG" --json body -q .body 2>/dev/null || true) { echo "$CURRENT_NOTES" @@ -454,89 +314,6 @@ jobs: echo "Release updated: ${RELEASE_TAG} -> ${VERSION}" >> $GITHUB_STEP_SUMMARY fi - # -- STEP 8: Build Joomla install ZIP + SHA-256 checksum ------------------ - # Every patch builds an install-ready ZIP and uploads it to the minor release. - # Result: one Release per minor version with a ZIP for each patch. - - name: "Step 8: Build Joomla package and update checksum" - if: >- - steps.version.outputs.skip != 'true' - env: - GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }} - run: | - VERSION="${{ steps.version.outputs.version }}" - RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - REPO="${{ github.repository }}" - - # All ZIPs upload to the major release tag (vXX) - gh release view "$RELEASE_TAG" --json tagName > /dev/null 2>&1 || { - echo "No release ${RELEASE_TAG} found — skipping ZIP upload" - exit 0 - } - - # Find extension element name from manifest - MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1 || true) - [ -z "$MANIFEST" ] && exit 0 - - EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1 || basename "$MANIFEST" .xml) - ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip" - TAR_NAME="${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/ — skipping package"; exit 0; } - - EXCLUDES=".ftpignore sftp-config* *.ppk *.pem *.key .env*" - - # ZIP package - cd "$SOURCE_DIR" - zip -r "/tmp/${ZIP_NAME}" . -x $EXCLUDES - cd .. - - # 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_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) - - # -- Upload both to release tag ---------------------------------- - gh release upload "$RELEASE_TAG" "/tmp/${ZIP_NAME}" --clobber 2>/dev/null || true - gh release upload "$RELEASE_TAG" "/tmp/${TAR_NAME}" --clobber 2>/dev/null || true - - # -- Update updates.xml with both download formats --------------- - if [ -f "updates.xml" ]; then - ZIP_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}" - TAR_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${TAR_NAME}" - - # Replace downloads block with both formats + SHA - sed -i "s|.*|\n ${ZIP_URL}\n ${TAR_URL}\n |" updates.xml 2>/dev/null || true - if grep -q '' updates.xml; then - sed -i "s|.*|sha256:${SHA256_ZIP}|" updates.xml - else - sed -i "s||\n sha256:${SHA256_ZIP}|" updates.xml - fi - - git add updates.xml - git commit -m "chore(release): ZIP + tar.gz for ${VERSION} [skip ci]" \ - --author="github-actions[bot] " || true - git push || true - fi - - echo "### Joomla 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 | [${PACKAGE_NAME}](https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}) |" >> $GITHUB_STEP_SUMMARY - # -- Summary -------------------------------------------------------------- - name: Pipeline Summary if: always() @@ -549,7 +326,7 @@ jobs: echo "## Already Released — ${VERSION}" >> $GITHUB_STEP_SUMMARY else echo "" >> $GITHUB_STEP_SUMMARY - echo "## Build & Release Complete (Joomla)" >> $GITHUB_STEP_SUMMARY + echo "## Build & Release Complete" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Step | Result |" >> $GITHUB_STEP_SUMMARY echo "|------|--------|" >> $GITHUB_STEP_SUMMARY