diff --git a/plugins-beta.xml b/plugins-beta.xml new file mode 100644 index 0000000..ad499ac --- /dev/null +++ b/plugins-beta.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins-dev.xml b/plugins-dev.xml new file mode 100644 index 0000000..ad499ac --- /dev/null +++ b/plugins-dev.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins.xml b/plugins.xml index 505a83c..ad499ac 100644 --- a/plugins.xml +++ b/plugins.xml @@ -1,83 +1,3 @@ - + - - 25.11.4 - QGIS Plugin mit Basisfunktionen LNO Sachsen - Weitere Informationen über das Plugin - Max Mustermann - https://example.com/mein_plugin - https://entwicklung.vln-sn.de/AG_QGIS/Plugin_SN_Basis/releases/download/25.11.4/sn_basis.zip - Geometrie, Analyse - Analysis - https://example.com/repo/mein_plugin/icon.png - true - false - 3.22 - 4.99 - https://example.com/issues - https://example.com/repo - Initiale Version - 2025-11-17 - 2025-11-18 - - - 25.11.3 - QGIS Plugin mit Funktionen für Plan - Weitere Informationen über das Plugin - Max Mustermann - https://example.com/mein_plugin - https://entwicklung.vln-sn.de/AG_QGIS/Plugin_SN_Plan41/releases/download/25.11.3/sn_plan41.zip - Geometrie, Analyse - Analysis - https://example.com/repo/mein_plugin/icon.png - true - false - 3.22 - 4.99 - https://example.com/issues - https://example.com/repo - Initiale Version - 2025-11-17 - 2025-11-17 - - - 25.11.4 - QGIS Plugin mit Funktionen für das Verfahrensgebiet - Weitere Informationen über das Plugin - Max Mustermann - https://example.com/mein_plugin - https://entwicklung.vln-sn.de/AG_QGIS/Plugin_SN_Verfahrensgebiet/releases/download/25.11.4/sn_verfahrensgebiet.zip - Geometrie, Analyse - Analysis - https://example.com/repo/mein_plugin/icon.png - true - false - 3.22 - 4.99 - https://example.com/issues - https://example.com/repo - Initiale Version - 2025-11-17 - 2025-11-18 - - - 25.11.3 - QGIS Plugin mit Funktionen zum Erstellen von Widmungskarten - Weitere Informationen über das Plugin - Max Mustermann - https://example.com/mein_plugin - https://entwicklung.vln-sn.de/AG_QGIS/Plugin_SN_Widmung/releases/download/25.11.3/sn_widmung.zip - Geometrie, Analyse - Analysis - https://example.com/repo/mein_plugin/icon.png - true - false - 3.22 - 4.99 - https://example.com/issues - https://example.com/repo - Initiale Version - 2025-11-17 - 2025-11-17 - - + \ No newline at end of file diff --git a/scripts/.gitea/workflows/update-plugins-xml.yml b/scripts/.gitea/workflows/update-plugins-xml.yml new file mode 100644 index 0000000..8755924 --- /dev/null +++ b/scripts/.gitea/workflows/update-plugins-xml.yml @@ -0,0 +1,46 @@ +name: Update plugins.xml + +on: + repository_dispatch: + types: [plugin-released] + +jobs: + update: + runs-on: alpine-latest + steps: + - uses: actions/checkout@v3 + with: + ref: feature/release # Während Testphase auf feature/release arbeiten + token: ${{ secrets.GITEA_TOKEN }} + + - name: Install dependencies + run: apk add --no-cache python3 py3-lxml py3-requests + + - name: Update plugins.xml + env: + GITEA_URL: ${{ vars.GITEA_URL }} + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + PLUGIN_NAME: ${{ github.event.client_payload.plugin }} + VERSION: ${{ github.event.client_payload.version }} + CHANNEL: ${{ github.event.client_payload.channel }} + DOWNLOAD_URL: ${{ github.event.client_payload.download_url }} + run: | + python3 scripts/update_plugins_xml.py \ + --plugin "$PLUGIN_NAME" \ + --version "$VERSION" \ + --channel "$CHANNEL" \ + --download-url "$DOWNLOAD_URL" + + - name: Commit and push + env: + GITEA_URL: ${{ vars.GITEA_URL }} + run: | + git config user.name "Gitea Actions" + git config user.email "actions@gitea.local" + git remote set-url origin \ + https://oauth2:${{ secrets.GITEA_TOKEN }}@${GITEA_URL#https://}/${{ github.repository }}.git + git add plugins.xml plugins-beta.xml plugins-dev.xml + git commit -m "chore: [${{ github.event.client_payload.channel }}] \ + ${{ github.event.client_payload.plugin }} \ + ${{ github.event.client_payload.version }}" || echo "No changes to commit" + git push origin feature/release \ No newline at end of file diff --git a/scripts/update_plugins_xml.py b/scripts/update_plugins_xml.py new file mode 100644 index 0000000..fe70248 --- /dev/null +++ b/scripts/update_plugins_xml.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +"""Aktualisiert die passende plugins.xml anhand des Channels.""" + +import argparse +import os +import sys +import zipfile +import io +import configparser +import requests +from lxml import etree +from pathlib import Path + +CHANNEL_FILES = { + "stable": "plugins.xml", + "beta": "plugins-beta.xml", + "dev": "plugins-dev.xml", +} + + +def fetch_metadata_from_zip(download_url: str, token: str) -> dict: + """Lädt die ZIP und extrahiert metadata.txt.""" + headers = {"Authorization": f"token {token}"} + print(f"→ Lade ZIP von {download_url}") + response = requests.get(download_url, headers=headers) + response.raise_for_status() + + with zipfile.ZipFile(io.BytesIO(response.content)) as z: + meta_path = next( + (n for n in z.namelist() if n.endswith("metadata.txt")), None + ) + if not meta_path: + print("FEHLER: metadata.txt nicht in ZIP gefunden!", file=sys.stderr) + sys.exit(1) + meta_content = z.read(meta_path).decode("utf-8") + + return parse_metadata(meta_content) + + +def parse_metadata(content: str) -> dict: + cfg = configparser.ConfigParser() + cfg.read_string("[plugin]\n" + content) + p = cfg["plugin"] + return { + "name": p.get("name", ""), + "qgisMinimumVersion": p.get("qgisminimumversion", "3.0"), + "qgisMaximumVersion": p.get("qgismaximumversion", "3.99"), + "description": p.get("description", ""), + "version": p.get("version", ""), + "author": p.get("author", ""), + "email": p.get("email", ""), + "homepage": p.get("homepage", ""), + "tracker": p.get("tracker", ""), + "repository": p.get("repository", ""), + "experimental": p.get("experimental", "False"), + "deprecated": p.get("deprecated", "False"), + } + + +def update_xml(xml_file: str, metadata: dict, download_url: str): + xml_path = Path(xml_file) + + if xml_path.exists(): + tree = etree.parse(xml_path) + root = tree.getroot() + else: + root = etree.Element("plugins") + tree = etree.ElementTree(root) + + # Bestehenden Eintrag gleichen Namens entfernen + plugin_name = metadata["name"] + for old in root.findall(f"pyqgis_plugin[@name='{plugin_name}']"): + root.remove(old) + + # Neuen Eintrag anlegen + el = etree.SubElement(root, "pyqgis_plugin", + name=plugin_name, + version=metadata["version"]) + + field_order = [ + "qgisMinimumVersion", "qgisMaximumVersion", "description", + "author", "email", "homepage", "tracker", "repository", + "download_url", "experimental", "deprecated", + ] + for key in field_order: + child = etree.SubElement(el, key) + child.text = metadata.get(key, "") if key != "download_url" else download_url + + etree.indent(tree, space=" ") + tree.write(xml_path, xml_declaration=True, + encoding="UTF-8", pretty_print=True) + print(f"✓ {xml_file} aktualisiert: {plugin_name} {metadata['version']}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--plugin", required=True) + parser.add_argument("--version", required=True) + parser.add_argument("--channel", required=True, choices=["stable", "beta", "dev"]) + parser.add_argument("--download-url", required=True) + args = parser.parse_args() + + token = os.environ.get("GITEA_TOKEN", "") + + metadata = fetch_metadata_from_zip(args.download_url, token) + xml_file = CHANNEL_FILES[args.channel] + update_xml(xml_file, metadata, args.download_url) \ No newline at end of file