From c0b06feaa448492b7228abe54ef3012d2476e430 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Thu, 18 Dec 2025 17:13:38 -0600 Subject: [PATCH] Update build_joomla_zip.yml --- .github/workflows/build_joomla_zip.yml | 269 ++++++++++++------------- 1 file changed, 129 insertions(+), 140 deletions(-) diff --git a/.github/workflows/build_joomla_zip.yml b/.github/workflows/build_joomla_zip.yml index 4d9f7e0..e5dd164 100644 --- a/.github/workflows/build_joomla_zip.yml +++ b/.github/workflows/build_joomla_zip.yml @@ -1,158 +1,147 @@ -name: Build Joomla ZIP from src folder +# ============================================================================ +# Copyright (C) 2025 Moko Consulting +# +# This file is part of a Moko Consulting project. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# FILE INFORMATION +# DEFGROUP: MokoStandards +# INGROUP: GitHub.Workflows +# REPO: https://github.com/mokoconsulting-tech/MokoDefaults +# PATH: /.github/workflows/build_joomla_zip.yml +# VERSION: 01.00.00 +# BRIEF: Build a Joomla ZIP from /src and optionally attach it to a GitHub Release. +# Script details +# - Builds a ZIP artifact from the repository /src folder. +# - Runs automatically when a GitHub Release is created. +# - Can be executed manually from the Actions menu (workflow_dispatch). +# - Optionally uploads the ZIP as a Release asset. +# - Provides CI artifacts when not attaching to a Release. + +name: Build Joomla ZIP from src on: - workflow_dispatch: - inputs: - attach_to_release: - description: "Attach ZIP to a GitHub Release" - required: true - default: "false" - type: choice - options: - - "false" - - "true" - release_tag: - description: "Release tag to upload to. If blank, defaults to dev/ using templateDetails.xml (example dev/03.02.00)" - required: false - default: "" + release: + types: [created] + workflow_dispatch: + inputs: + attach_to_release: + description: "Attach the generated ZIP to a GitHub Release" + required: false + default: "false" + type: choice + options: + - "false" + - "true" + release_tag: + description: "Release tag to upload to. If blank, defaults to dev/ using templateDetails.xml (example dev/03.02.00)" + required: false + default: "" + zip_name: + description: "ZIP base name without extension (defaults to repository name)" + required: false + default: "" + zip_suffix: + description: "Optional suffix appended after version (example rc1, beta, build.5)" + required: false + default: "" + prerelease: + description: "Mark the uploaded asset as prerelease when attaching to a Release" + required: false + default: "false" + type: choice + options: + - "false" + - "true" permissions: - contents: write + contents: write jobs: - build: - name: Package template - runs-on: ubuntu-latest + build-zip: + name: Build ZIP + runs-on: ubuntu-latest - env: - TEMPLATE_DIR: src/templates/moko-cassiopeia - SRC_LANGUAGE_DIR: src/language - SRC_MEDIA_DIR: src/media - OUT_DIR: dist - STAGE_DIR: dist/stage - ZIP_BASENAME: moko-cassiopeia + steps: + - name: Checkout + uses: actions/checkout@v4 - steps: - - name: Checkout - uses: actions/checkout@v4 + - name: Validate src folder exists + shell: bash + run: | + set -euo pipefail + if [ ! -d "src" ]; then + echo "ERROR: Required folder 'src' not found at repository root." >&2 + echo "Expected: ./src" >&2 + exit 1 + fi - - name: Build staging package and ZIP - id: pkg - shell: bash - run: | - set -euo pipefail + - name: Resolve build parameters + id: params + shell: bash + run: | + set -euo pipefail - rm -rf "${OUT_DIR}" - mkdir -p "${STAGE_DIR}" + REPO_NAME="${GITHUB_REPOSITORY#*/}" - # Validate template source - if [ ! -f "${TEMPLATE_DIR}/templateDetails.xml" ]; then - echo "ERROR: Missing ${TEMPLATE_DIR}/templateDetails.xml" - exit 1 - fi + ZIP_BASE_INPUT="${{ github.event.inputs.zip_name }}" + if [ -n "${ZIP_BASE_INPUT}" ]; then + ZIP_BASE="${ZIP_BASE_INPUT}" + else + ZIP_BASE="${REPO_NAME}" - # Flatten template root into stage root - cp -R "${TEMPLATE_DIR}/." "${STAGE_DIR}/" + VERSION="" + SUFFIX_INPUT="${{ github.event.inputs.zip_suffix }}" - # Copy language and media to stage root if present - if [ -d "${SRC_LANGUAGE_DIR}" ]; then - cp -R "${SRC_LANGUAGE_DIR}" "${STAGE_DIR}/language" - fi + ATTACH_INPUT="${{ github.event.inputs.attach_to_release }}" - if [ -d "${SRC_MEDIA_DIR}" ]; then - cp -R "${SRC_MEDIA_DIR}" "${STAGE_DIR}/media" - fi + if [ "${GITHUB_EVENT_NAME}" = "release" ]; then + ATTACH="true" + TAG_NAME="${{ github.event.release.tag_name }}" + VERSION="${TAG_NAME##*/}" + else + if [ "${ATTACH_INPUT}" = "true" ]; then + ATTACH="true" + else + ATTACH="false" + fi - # Hard checks for installer-critical items - test -f "${STAGE_DIR}/templateDetails.xml" - test -f "${STAGE_DIR}/index.php" - test -f "${STAGE_DIR}/component.php" + TAG_INPUT="${{ github.event.inputs.release_tag }}" + if [ -n "${TAG_INPUT}" ]; then + TAG_NAME="${TAG_INPUT}" + VERSION="${TAG_NAME##*/}" + else + if [ ! -f "src/templateDetails.xml" ]; then + echo "ERROR: src/templateDetails.xml not found and release_tag not provided." >&2 + exit 1 + fi - # Read version from manifest - VERSION="$(python - << 'PY' - import xml.etree.ElementTree as ET - root = ET.parse("dist/stage/templateDetails.xml").getroot() - v = root.findtext("version") or "" - v = v.strip() - if not v: - raise SystemExit("ERROR: not found in templateDetails.xml") - print(v) - PY - )" + VERSION=$(grep -Eo '[0-9]+(\.[0-9]+)*' src/templateDetails.xml | head -n1 | sed -E 's###g') + if [ -z "${VERSION}" ]; then + echo "ERROR: Unable to extract from src/templateDetails.xml." >&2 + exit 1 + fi - ZIP_NAME="${ZIP_BASENAME}-${VERSION}.zip" - ZIP_PATH="${OUT_DIR}/${ZIP_NAME}" + TAG_NAME="dev/${VERSION}" + fi + fi - (cd "${STAGE_DIR}" && zip -r "../${ZIP_NAME}" .) - - echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" - echo "zip_name=${ZIP_NAME}" >> "${GITHUB_OUTPUT}" - echo "zip_path=${ZIP_PATH}" >> "${GITHUB_OUTPUT}" - - - name: Compute effective release tag - id: tag - shell: bash - run: | - set -euo pipefail - - INPUT_TAG="${{ github.event.inputs.release_tag }}" - INPUT_TAG="$(echo "${INPUT_TAG}" | tr -d '[:space:]')" - - if [ -n "${INPUT_TAG}" ]; then - EFFECTIVE_TAG="${INPUT_TAG}" - else - EFFECTIVE_TAG="dev/${{ steps.pkg.outputs.version }}" - fi - - echo "effective_tag=${EFFECTIVE_TAG}" >> "${GITHUB_OUTPUT}" - - - name: Upload workflow artifact (temporary) - uses: actions/upload-artifact@v4 - with: - name: ${{ steps.pkg.outputs.zip_name }} - path: ${{ steps.pkg.outputs.zip_path }} - retention-days: 30 - - - name: Attach ZIP to GitHub Release (optional) - if: ${{ github.event.inputs.attach_to_release == 'true' }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - shell: bash - run: | - set -euo pipefail - - TAG="${{ steps.tag.outputs.effective_tag }}" - ZIP="${{ steps.pkg.outputs.zip_path }}" - - if [ -z "${TAG}" ]; then - echo "ERROR: release tag is empty." - exit 1 - fi - - # Ensure the tag exists locally for release creation (optional) - # GitHub will still allow creating a release for a tag name, but tagging is best practice. - if ! git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null 2>&1; then - echo "INFO: Tag ${TAG} not found locally. Creating lightweight tag on current commit." - git tag "${TAG}" - git push origin "${TAG}" - fi - - # Create release if missing, then upload asset with clobber - if ! gh release view "${TAG}" >/dev/null 2>&1; then - gh release create "${TAG}" \ - --title "${TAG}" \ - --notes "Automated build artifact upload." \ - --draft - fi - - # Upload asset - set +e - gh release upload "${TAG}" "${ZIP}" --clobber - RC=$? - set -e - - if [ $RC -ne 0 ]; then - echo "ERROR: Failed to upload asset to release ${TAG}." - echo "NOTE: GitHub may reject uploads to an immutable release. If so, create a new draft release or a new tag and retry." - exit $RC - fi + if [ -n "${SUFFIX_INPUT}" ]; then + ZIP_NAME="${ZIP_BASE}-${VERSION}-${SUFFIX_INPUT}.zip" + else + ZIP_NAME="${ZIP_BASE}-${VERSION}.zip" + fi