Update build_template_zip.yml
This commit is contained in:
381
.github/workflows/build_template_zip.yml
vendored
381
.github/workflows/build_template_zip.yml
vendored
@@ -1,285 +1,158 @@
|
|||||||
name: Build Joomla Tenplate ZIP from src folder
|
name: Build Joomla Template ZIP from src folder
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
target_folder:
|
attach_to_release:
|
||||||
description: "Folder to zip (relative to repo root)"
|
description: "Attach ZIP to a GitHub Release"
|
||||||
required: false
|
required: true
|
||||||
default: "src"
|
default: "false"
|
||||||
zip_name:
|
type: choice
|
||||||
description: "Base ZIP name (default: repository name, lowercase)"
|
options:
|
||||||
required: false
|
- "false"
|
||||||
default: ""
|
- "true"
|
||||||
version_suffix:
|
release_tag:
|
||||||
description: "Optional version suffix for filename (example 01.02.03)"
|
description: "Release tag to upload to. If blank, defaults to dev/<version> using templateDetails.xml (example dev/03.02.00)"
|
||||||
required: false
|
required: false
|
||||||
default: ""
|
default: ""
|
||||||
publish_release:
|
|
||||||
description: "If true, upload ZIP and SHA256 as GitHub Release assets"
|
|
||||||
required: false
|
|
||||||
default: "false"
|
|
||||||
type: choice
|
|
||||||
options:
|
|
||||||
- "false"
|
|
||||||
- "true"
|
|
||||||
release_tag:
|
|
||||||
description: "Release tag to publish to (required if publish_release=true)"
|
|
||||||
required: false
|
|
||||||
default: ""
|
|
||||||
prerelease:
|
|
||||||
description: "If true, mark the release as prerelease"
|
|
||||||
required: false
|
|
||||||
default: "true"
|
|
||||||
type: choice
|
|
||||||
options:
|
|
||||||
- "false"
|
|
||||||
- "true"
|
|
||||||
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
target_folder:
|
|
||||||
description: "Folder to zip (relative to repo root)"
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: "src"
|
|
||||||
zip_name:
|
|
||||||
description: "Base ZIP name (default: repository name, lowercase)"
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
version_suffix:
|
|
||||||
description: "Optional version suffix for filename (example 01.02.03)"
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
publish_release:
|
|
||||||
description: "If true, upload ZIP and SHA256 as GitHub Release assets"
|
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
release_tag:
|
|
||||||
description: "Release tag to publish to (required if publish_release=true)"
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
default: ""
|
|
||||||
prerelease:
|
|
||||||
description: "If true, mark the release as prerelease"
|
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
zip:
|
build:
|
||||||
name: Package folder as ZIP
|
name: Package template
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
env:
|
||||||
- name: Checkout repository
|
TEMPLATE_DIR: src/templates/moko-cassiopeia
|
||||||
uses: actions/checkout@v4
|
SRC_LANGUAGE_DIR: src/language
|
||||||
|
SRC_MEDIA_DIR: src/media
|
||||||
|
OUT_DIR: dist
|
||||||
|
STAGE_DIR: dist/stage
|
||||||
|
ZIP_BASENAME: moko-cassiopeia
|
||||||
|
|
||||||
- name: Verify tooling
|
steps:
|
||||||
shell: bash
|
- name: Checkout
|
||||||
run: |
|
uses: actions/checkout@v4
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
if ! command -v zip >/dev/null 2>&1; then
|
- name: Build staging package and ZIP
|
||||||
echo "ERROR: zip is not installed on runner" >&2
|
id: pkg
|
||||||
exit 1
|
shell: bash
|
||||||
fi
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
if ! command -v sha256sum >/dev/null 2>&1; then
|
rm -rf "${OUT_DIR}"
|
||||||
echo "ERROR: sha256sum is not available on runner" >&2
|
mkdir -p "${STAGE_DIR}"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Resolve and validate inputs
|
# Validate template source
|
||||||
shell: bash
|
if [ ! -f "${TEMPLATE_DIR}/templateDetails.xml" ]; then
|
||||||
run: |
|
echo "ERROR: Missing ${TEMPLATE_DIR}/templateDetails.xml"
|
||||||
set -euo pipefail
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Prefer workflow_call inputs when present, otherwise use workflow_dispatch inputs.
|
# Flatten template root into stage root
|
||||||
TARGET_FOLDER="${{ inputs.target_folder }}"
|
cp -R "${TEMPLATE_DIR}/." "${STAGE_DIR}/"
|
||||||
ZIP_NAME_INPUT="${{ inputs.zip_name }}"
|
|
||||||
VERSION_SUFFIX="${{ inputs.version_suffix }}"
|
|
||||||
PUBLISH_RELEASE="${{ inputs.publish_release }}"
|
|
||||||
RELEASE_TAG="${{ inputs.release_tag }}"
|
|
||||||
PRERELEASE="${{ inputs.prerelease }}"
|
|
||||||
|
|
||||||
if [[ -z "$TARGET_FOLDER" ]]; then TARGET_FOLDER="${{ github.event.inputs.target_folder }}"; fi
|
# Copy language and media to stage root if present
|
||||||
if [[ -z "$ZIP_NAME_INPUT" ]]; then ZIP_NAME_INPUT="${{ github.event.inputs.zip_name }}"; fi
|
if [ -d "${SRC_LANGUAGE_DIR}" ]; then
|
||||||
if [[ -z "$VERSION_SUFFIX" ]]; then VERSION_SUFFIX="${{ github.event.inputs.version_suffix }}"; fi
|
cp -R "${SRC_LANGUAGE_DIR}" "${STAGE_DIR}/language"
|
||||||
if [[ -z "$PUBLISH_RELEASE" ]]; then PUBLISH_RELEASE="${{ github.event.inputs.publish_release }}"; fi
|
fi
|
||||||
if [[ -z "$RELEASE_TAG" ]]; then RELEASE_TAG="${{ github.event.inputs.release_tag }}"; fi
|
|
||||||
if [[ -z "$PRERELEASE" ]]; then PRERELEASE="${{ github.event.inputs.prerelease }}"; fi
|
|
||||||
|
|
||||||
TARGET_FOLDER="${TARGET_FOLDER//[[:space:]]/}"
|
if [ -d "${SRC_MEDIA_DIR}" ]; then
|
||||||
ZIP_NAME_INPUT="${ZIP_NAME_INPUT//[[:space:]]/}"
|
cp -R "${SRC_MEDIA_DIR}" "${STAGE_DIR}/media"
|
||||||
VERSION_SUFFIX="${VERSION_SUFFIX//[[:space:]]/}"
|
fi
|
||||||
RELEASE_TAG="${RELEASE_TAG//[[:space:]]/}"
|
|
||||||
|
|
||||||
if [[ -z "$TARGET_FOLDER" ]]; then
|
# Hard checks for installer-critical items
|
||||||
TARGET_FOLDER="src"
|
test -f "${STAGE_DIR}/templateDetails.xml"
|
||||||
fi
|
test -f "${STAGE_DIR}/index.php"
|
||||||
|
test -f "${STAGE_DIR}/component.php"
|
||||||
|
|
||||||
if [[ "$PUBLISH_RELEASE" == "true" || "$PUBLISH_RELEASE" == "True" ]]; then
|
# Read version from manifest
|
||||||
PUBLISH_RELEASE="true"
|
VERSION="$(python - << 'PY'
|
||||||
else
|
import xml.etree.ElementTree as ET
|
||||||
PUBLISH_RELEASE="false"
|
root = ET.parse("dist/stage/templateDetails.xml").getroot()
|
||||||
fi
|
v = root.findtext("version") or ""
|
||||||
|
v = v.strip()
|
||||||
|
if not v:
|
||||||
|
raise SystemExit("ERROR: <version> not found in templateDetails.xml")
|
||||||
|
print(v)
|
||||||
|
PY
|
||||||
|
)"
|
||||||
|
|
||||||
if [[ "$PRERELEASE" == "true" || "$PRERELEASE" == "True" ]]; then
|
ZIP_NAME="${ZIP_BASENAME}-${VERSION}.zip"
|
||||||
PRERELEASE="true"
|
ZIP_PATH="${OUT_DIR}/${ZIP_NAME}"
|
||||||
else
|
|
||||||
PRERELEASE="false"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -d "$TARGET_FOLDER" ]]; then
|
(cd "${STAGE_DIR}" && zip -r "../${ZIP_NAME}" .)
|
||||||
echo "ERROR: Folder does not exist: $TARGET_FOLDER" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$VERSION_SUFFIX" ]] && [[ ! "$VERSION_SUFFIX" =~ ^[0-9]{2}\.[0-9]{2}\.[0-9]{2}$ ]]; then
|
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
|
||||||
echo "ERROR: version_suffix must match NN.NN.NN (example 01.02.03)" >&2
|
echo "zip_name=${ZIP_NAME}" >> "${GITHUB_OUTPUT}"
|
||||||
exit 1
|
echo "zip_path=${ZIP_PATH}" >> "${GITHUB_OUTPUT}"
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$ZIP_NAME_INPUT" ]]; then
|
- name: Compute effective release tag
|
||||||
ZIP_NAME_INPUT="$(echo "$ZIP_NAME_INPUT" | tr '[:upper:]' '[:lower:]')"
|
id: tag
|
||||||
fi
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
if [[ "$PUBLISH_RELEASE" == "true" ]] && [[ -z "$RELEASE_TAG" ]]; then
|
INPUT_TAG="${{ github.event.inputs.release_tag }}"
|
||||||
echo "ERROR: release_tag is required when publish_release=true" >&2
|
INPUT_TAG="$(echo "${INPUT_TAG}" | tr -d '[:space:]')"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "TARGET_FOLDER=$TARGET_FOLDER" >> "$GITHUB_ENV"
|
if [ -n "${INPUT_TAG}" ]; then
|
||||||
echo "INPUT_ZIP_NAME=$ZIP_NAME_INPUT" >> "$GITHUB_ENV"
|
EFFECTIVE_TAG="${INPUT_TAG}"
|
||||||
echo "INPUT_VERSION_SUFFIX=$VERSION_SUFFIX" >> "$GITHUB_ENV"
|
else
|
||||||
echo "PUBLISH_RELEASE=$PUBLISH_RELEASE" >> "$GITHUB_ENV"
|
EFFECTIVE_TAG="dev/${{ steps.pkg.outputs.version }}"
|
||||||
echo "RELEASE_TAG=$RELEASE_TAG" >> "$GITHUB_ENV"
|
fi
|
||||||
echo "PRERELEASE=$PRERELEASE" >> "$GITHUB_ENV"
|
|
||||||
|
|
||||||
- name: Prepare dist folder
|
echo "effective_tag=${EFFECTIVE_TAG}" >> "${GITHUB_OUTPUT}"
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
rm -rf dist
|
|
||||||
mkdir -p dist
|
|
||||||
|
|
||||||
- name: Resolve version
|
- name: Upload workflow artifact (temporary)
|
||||||
shell: bash
|
uses: actions/upload-artifact@v4
|
||||||
run: |
|
with:
|
||||||
set -euo pipefail
|
name: ${{ steps.pkg.outputs.zip_name }}
|
||||||
|
path: ${{ steps.pkg.outputs.zip_path }}
|
||||||
|
retention-days: 30
|
||||||
|
|
||||||
VERSION_SUFFIX="$INPUT_VERSION_SUFFIX"
|
- 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
|
||||||
|
|
||||||
if [[ -z "$VERSION_SUFFIX" ]]; then
|
TAG="${{ steps.tag.outputs.effective_tag }}"
|
||||||
XML_FILE=""
|
ZIP="${{ steps.pkg.outputs.zip_path }}"
|
||||||
if [[ -f "$TARGET_FOLDER/templateDetails.xml" ]]; then
|
|
||||||
XML_FILE="$TARGET_FOLDER/templateDetails.xml"
|
|
||||||
elif [[ -f "$TARGET_FOLDER/manifest.xml" ]]; then
|
|
||||||
XML_FILE="$TARGET_FOLDER/manifest.xml"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$XML_FILE" ]]; then
|
if [ -z "${TAG}" ]; then
|
||||||
VERSION_SUFFIX=$(grep -oPm1 '(?<=<version>)[^<]+' "$XML_FILE" || true)
|
echo "ERROR: release tag is empty."
|
||||||
VERSION_SUFFIX="${VERSION_SUFFIX//[[:space:]]/}"
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$VERSION_SUFFIX" ]] && [[ ! "$VERSION_SUFFIX" =~ ^[0-9]{2}\.[0-9]{2}\.[0-9]{2}$ ]]; then
|
# Ensure the tag exists locally for release creation (optional)
|
||||||
echo "ERROR: Version found in XML is invalid: $VERSION_SUFFIX" >&2
|
# GitHub will still allow creating a release for a tag name, but tagging is best practice.
|
||||||
exit 1
|
if ! git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null 2>&1; then
|
||||||
fi
|
echo "INFO: Tag ${TAG} not found locally. Creating lightweight tag on current commit."
|
||||||
|
git tag "${TAG}"
|
||||||
|
git push origin "${TAG}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -z "$VERSION_SUFFIX" ]]; then
|
# Create release if missing, then upload asset with clobber
|
||||||
VERSION_SUFFIX="$(echo "${GITHUB_REPOSITORY##*/}" | tr '[:upper:]' '[:lower:]')"
|
if ! gh release view "${TAG}" >/dev/null 2>&1; then
|
||||||
fi
|
gh release create "${TAG}" \
|
||||||
|
--title "${TAG}" \
|
||||||
|
--notes "Automated build artifact upload." \
|
||||||
|
--draft
|
||||||
|
fi
|
||||||
|
|
||||||
echo "VERSION_SUFFIX=$VERSION_SUFFIX" >> "$GITHUB_ENV"
|
# Upload asset
|
||||||
|
set +e
|
||||||
|
gh release upload "${TAG}" "${ZIP}" --clobber
|
||||||
|
RC=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
- name: Create ZIP archive and SHA256
|
if [ $RC -ne 0 ]; then
|
||||||
shell: bash
|
echo "ERROR: Failed to upload asset to release ${TAG}."
|
||||||
run: |
|
echo "NOTE: GitHub may reject uploads to an immutable release. If so, create a new draft release or a new tag and retry."
|
||||||
set -euo pipefail
|
exit $RC
|
||||||
|
fi
|
||||||
DEFAULT_REPO_NAME="$(echo "${GITHUB_REPOSITORY##*/}" | tr '[:upper:]' '[:lower:]')"
|
|
||||||
BASE_ZIP_NAME="$INPUT_ZIP_NAME"
|
|
||||||
|
|
||||||
if [[ -z "$BASE_ZIP_NAME" ]]; then
|
|
||||||
BASE_ZIP_NAME="$DEFAULT_REPO_NAME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
SAFE_FOLDER_NAME="$(echo "$TARGET_FOLDER" | tr '/' '-')"
|
|
||||||
|
|
||||||
ZIP_NAME="${BASE_ZIP_NAME}-${SAFE_FOLDER_NAME}-${VERSION_SUFFIX}.zip"
|
|
||||||
ZIP_PATH="dist/$ZIP_NAME"
|
|
||||||
|
|
||||||
cd "$TARGET_FOLDER"
|
|
||||||
|
|
||||||
zip -r "../$ZIP_PATH" . \
|
|
||||||
-x "*.DS_Store" \
|
|
||||||
-x "__MACOSX/*" \
|
|
||||||
-x "node_modules/*" \
|
|
||||||
-x "coverage/*" \
|
|
||||||
-x "*.log" \
|
|
||||||
-x "*.tmp"
|
|
||||||
|
|
||||||
cd - >/dev/null 2>&1
|
|
||||||
|
|
||||||
SHA_PATH="${ZIP_PATH}.sha256"
|
|
||||||
sha256sum "$ZIP_PATH" | awk '{print $1}' > "$SHA_PATH"
|
|
||||||
|
|
||||||
ZIP_ARTIFACT_NAME="${ZIP_NAME}"
|
|
||||||
echo "ZIP_NAME=$ZIP_NAME" >> "$GITHUB_ENV"
|
|
||||||
echo "ZIP_ARTIFACT_NAME=$ZIP_ARTIFACT_NAME" >> "$GITHUB_ENV"
|
|
||||||
echo "ZIP_PATH=$ZIP_PATH" >> "$GITHUB_ENV"
|
|
||||||
echo "SHA_PATH=$SHA_PATH" >> "$GITHUB_ENV"
|
|
||||||
|
|
||||||
- name: Export artifact metadata
|
|
||||||
id: meta
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
echo "zip_artifact_name=$ZIP_NAME" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "sha_artifact_name=${ZIP_NAME}.sha256" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "zip_file_name=$ZIP_NAME" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "sha_file_name=$(basename "$SHA_PATH")" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Upload ZIP artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ env.ZIP_ARTIFACT_NAME }}
|
|
||||||
path: ${{ env.ZIP_PATH }}
|
|
||||||
|
|
||||||
- name: Upload SHA256 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ env.ZIP_NAME }}.sha256
|
|
||||||
path: ${{ env.SHA_PATH }}
|
|
||||||
|
|
||||||
- name: Upload assets to GitHub Release
|
|
||||||
id: release_upload
|
|
||||||
if: ${{ env.PUBLISH_RELEASE == 'true' }}
|
|
||||||
uses: softprops/action-gh-release@v2
|
|
||||||
with:
|
|
||||||
tag_name: ${{ env.RELEASE_TAG }}
|
|
||||||
prerelease: ${{ env.PRERELEASE == 'true' }}
|
|
||||||
files: |
|
|
||||||
${{ env.ZIP_PATH }}
|
|
||||||
${{ env.SHA_PATH }}
|
|
||||||
|
|
||||||
- name: Export release upload status
|
|
||||||
id: release_status
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
if [[ "$PUBLISH_RELEASE" == "true" ]]; then
|
|
||||||
echo "release_uploaded=true" >> "$GITHUB_OUTPUT"
|
|
||||||
else
|
|
||||||
echo "release_uploaded=false" >> "$GITHUB_OUTPUT"
|
|
||||||
fi
|
|
||||||
|
|||||||
Reference in New Issue
Block a user