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