Update updateserver.yml
This commit is contained in:
201
.github/workflows/updateserver.yml
vendored
201
.github/workflows/updateserver.yml
vendored
@@ -1,10 +1,155 @@
|
|||||||
- name: Update updates.xml (version, date, download URL only)
|
name: Update Joomla Update Server XML Feed
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [prereleased, released]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Version to publish (defaults to release tag on release events)"
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
|
asset_name:
|
||||||
|
description: "ZIP asset base name (without .zip). Defaults to <repo>-<version>."
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
EXT_NAME: "MokoWaaS-Brand"
|
||||||
|
EXT_ELEMENT: "mokowaasbrand"
|
||||||
|
EXT_TYPE: "plugin"
|
||||||
|
EXT_FOLDER: "system"
|
||||||
|
EXT_CLIENT: "site"
|
||||||
|
EXT_CATEGORY: "MokoWaaS-Brand"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-server:
|
||||||
|
name: Publish version to UpdateServer
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: UpdateServer
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# HARD PREFLIGHT CHECK
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
- name: Validate required UpdateServer environment variables
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ -z "${{ vars.UPDATESERVER_FILE_URL }}" ]; then
|
||||||
|
echo "ERROR: Required environment variable UPDATESERVER_FILE_URL is not defined."
|
||||||
|
echo "This workflow will not run without UpdateServer environment configuration."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Preflight validation passed."
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# VERSION + ASSET METADATA
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
- name: Resolve version and asset metadata
|
||||||
|
id: meta
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "${{ github.event_name }}" = "release" ]; then
|
||||||
|
VERSION="${{ github.event.release.tag_name }}"
|
||||||
|
else
|
||||||
|
VERSION="${{ github.event.inputs.version }}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${VERSION}" ]; then
|
||||||
|
echo "ERROR: Version is not defined."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if echo "${VERSION}" | grep -qiE "(^|[-.])rc([-.]|$)"; then
|
||||||
|
echo "RC version detected (${VERSION}). Publication skipped by policy."
|
||||||
|
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "skip=false" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ github.event.inputs.asset_name }}" ]; then
|
||||||
|
ASSET_NAME="${{ github.event.inputs.asset_name }}"
|
||||||
|
else
|
||||||
|
REPO_NAME="${GITHUB_REPOSITORY##*/}"
|
||||||
|
ASSET_NAME="${REPO_NAME}-${VERSION}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DOWNLOAD_URL="https://github.com/${GITHUB_REPOSITORY}/releases/download/${VERSION}/${ASSET_NAME}.zip"
|
||||||
|
|
||||||
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "asset_name=${ASSET_NAME}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "download_url=${DOWNLOAD_URL}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# PARSE UPDATE SERVER LOCATION (FROM ENV ONLY)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
- name: Parse UpdateServer URL from environment variable
|
||||||
|
if: steps.meta.outputs.skip != 'true'
|
||||||
|
id: parse
|
||||||
|
env:
|
||||||
|
UPDATESERVER_FILE_URL: ${{ vars.UPDATESERVER_FILE_URL }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
python << 'PY'
|
||||||
|
import os
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
url = os.environ["UPDATESERVER_FILE_URL"].strip()
|
||||||
|
|
||||||
|
parsed = urlparse(url)
|
||||||
|
parts = parsed.path.strip("/").split("/")
|
||||||
|
|
||||||
|
if len(parts) < 5 or parts[2] != "blob":
|
||||||
|
raise SystemExit(f"Invalid UPDATESERVER_FILE_URL format: {url}")
|
||||||
|
|
||||||
|
owner = parts[0]
|
||||||
|
repo = parts[1]
|
||||||
|
branch = parts[3]
|
||||||
|
file_path = "/".join(parts[4:])
|
||||||
|
|
||||||
|
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as fh:
|
||||||
|
fh.write(f"update_repo={owner}/{repo}\n")
|
||||||
|
fh.write(f"update_branch={branch}\n")
|
||||||
|
fh.write(f"update_file={file_path}\n")
|
||||||
|
PY
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# CHECKOUT UPDATE SERVER REPO
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
- name: Check out update server repository
|
||||||
|
if: steps.meta.outputs.skip != 'true'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: ${{ steps.parse.outputs.update_repo }}
|
||||||
|
ref: ${{ steps.parse.outputs.update_branch }}
|
||||||
|
token: ${{ secrets.MOKO_UPDATES_TOKEN }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# UPDATE XML (VERSION, DATE, DOWNLOAD URL ONLY)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
- name: Update updates.xml
|
||||||
if: steps.meta.outputs.skip != 'true'
|
if: steps.meta.outputs.skip != 'true'
|
||||||
env:
|
env:
|
||||||
VERSION: ${{ steps.meta.outputs.version }}
|
VERSION: ${{ steps.meta.outputs.version }}
|
||||||
DOWNLOAD_URL: ${{ steps.meta.outputs.download_url }}
|
DOWNLOAD_URL: ${{ steps.meta.outputs.download_url }}
|
||||||
UPDATE_FILE: ${{ steps.parse.outputs.update_file }}
|
UPDATE_FILE: ${{ steps.parse.outputs.update_file }}
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
python << 'PY'
|
python << 'PY'
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -13,20 +158,18 @@
|
|||||||
|
|
||||||
xml_path = Path(os.environ["UPDATE_FILE"])
|
xml_path = Path(os.environ["UPDATE_FILE"])
|
||||||
if not xml_path.exists():
|
if not xml_path.exists():
|
||||||
raise SystemExit(f"{xml_path} not found in update server repository")
|
raise SystemExit(f"{xml_path} not found")
|
||||||
|
|
||||||
tree = ET.parse(xml_path)
|
tree = ET.parse(xml_path)
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
|
|
||||||
version = os.environ["VERSION"].strip()
|
version = os.environ["VERSION"]
|
||||||
download_url = os.environ["DOWNLOAD_URL"].strip()
|
download_url = os.environ["DOWNLOAD_URL"]
|
||||||
today = datetime.utcnow().strftime("%Y-%m-%d")
|
today = datetime.utcnow().strftime("%Y-%m-%d")
|
||||||
|
|
||||||
# Find an existing update node for this version; if none exists, create one.
|
|
||||||
target = None
|
target = None
|
||||||
for upd in root.findall("update"):
|
for upd in root.findall("update"):
|
||||||
v_node = upd.find("version")
|
if (upd.findtext("version") or "").strip() == version:
|
||||||
if v_node is not None and (v_node.text or "").strip() == version:
|
|
||||||
target = upd
|
target = upd
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -34,19 +177,13 @@
|
|||||||
target = ET.SubElement(root, "update")
|
target = ET.SubElement(root, "update")
|
||||||
ET.SubElement(target, "version").text = version
|
ET.SubElement(target, "version").text = version
|
||||||
|
|
||||||
# Ensure version is set (only set the version field)
|
target.find("version").text = version
|
||||||
v_node = target.find("version")
|
|
||||||
if v_node is None:
|
|
||||||
v_node = ET.SubElement(target, "version")
|
|
||||||
v_node.text = version
|
|
||||||
|
|
||||||
# Ensure creationDate is set
|
cd = target.find("creationDate")
|
||||||
cd_node = target.find("creationDate")
|
if cd is None:
|
||||||
if cd_node is None:
|
cd = ET.SubElement(target, "creationDate")
|
||||||
cd_node = ET.SubElement(target, "creationDate")
|
cd.text = today
|
||||||
cd_node.text = today
|
|
||||||
|
|
||||||
# Ensure downloads/downloadurl exists; update text only, keep attributes as-is if present
|
|
||||||
downloads = target.find("downloads")
|
downloads = target.find("downloads")
|
||||||
if downloads is None:
|
if downloads is None:
|
||||||
downloads = ET.SubElement(target, "downloads")
|
downloads = ET.SubElement(target, "downloads")
|
||||||
@@ -59,3 +196,31 @@
|
|||||||
|
|
||||||
tree.write(xml_path, encoding="utf-8", xml_declaration=True)
|
tree.write(xml_path, encoding="utf-8", xml_declaration=True)
|
||||||
PY
|
PY
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# COMMIT AND PUSH
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
- name: Configure git user
|
||||||
|
if: steps.meta.outputs.skip != 'true'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
- name: Commit and push update server changes
|
||||||
|
if: steps.meta.outputs.skip != 'true'
|
||||||
|
env:
|
||||||
|
VERSION: ${{ steps.meta.outputs.version }}
|
||||||
|
UPDATE_FILE: ${{ steps.parse.outputs.update_file }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if git diff --quiet; then
|
||||||
|
echo "No changes to commit."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
git add "${UPDATE_FILE}"
|
||||||
|
git commit -m "Update server metadata for version ${VERSION}"
|
||||||
|
git push
|
||||||
|
|||||||
Reference in New Issue
Block a user