diff --git a/.github/workflows/build_joomla_zip.yml b/.github/workflows/build_joomla_zip.yml new file mode 100644 index 0000000..4d9f7e0 --- /dev/null +++ b/.github/workflows/build_joomla_zip.yml @@ -0,0 +1,158 @@ +name: Build Joomla ZIP from src folder + +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: "" + +permissions: + contents: write + +jobs: + build: + name: Package template + 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 + + - name: Build staging package and ZIP + id: pkg + shell: bash + run: | + set -euo pipefail + + rm -rf "${OUT_DIR}" + mkdir -p "${STAGE_DIR}" + + # Validate template source + if [ ! -f "${TEMPLATE_DIR}/templateDetails.xml" ]; then + echo "ERROR: Missing ${TEMPLATE_DIR}/templateDetails.xml" + exit 1 + fi + + # Flatten template root into stage root + cp -R "${TEMPLATE_DIR}/." "${STAGE_DIR}/" + + # Copy language and media to stage root if present + if [ -d "${SRC_LANGUAGE_DIR}" ]; then + cp -R "${SRC_LANGUAGE_DIR}" "${STAGE_DIR}/language" + fi + + if [ -d "${SRC_MEDIA_DIR}" ]; then + cp -R "${SRC_MEDIA_DIR}" "${STAGE_DIR}/media" + 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" + + # 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 + )" + + ZIP_NAME="${ZIP_BASENAME}-${VERSION}.zip" + ZIP_PATH="${OUT_DIR}/${ZIP_NAME}" + + (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