From b8c70bf2e16dbc19dbd185ab82065943b530171b Mon Sep 17 00:00:00 2001 From: Michael Otto Date: Mon, 2 Mar 2026 14:10:08 +0100 Subject: [PATCH] v2 --- .gitea/workflows/update-plugins-xml.yml | 48 ++++++++ .../.gitea/workflows/update-plugins-xml.yml | 46 -------- scripts/update_plugins_xml.py | 107 ------------------ 3 files changed, 48 insertions(+), 153 deletions(-) create mode 100644 .gitea/workflows/update-plugins-xml.yml delete mode 100644 scripts/.gitea/workflows/update-plugins-xml.yml delete mode 100644 scripts/update_plugins_xml.py diff --git a/.gitea/workflows/update-plugins-xml.yml b/.gitea/workflows/update-plugins-xml.yml new file mode 100644 index 0000000..91c825a --- /dev/null +++ b/.gitea/workflows/update-plugins-xml.yml @@ -0,0 +1,48 @@ +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 + token: ${{ secrets.GITEA_TOKEN }} + + - name: Select target XML file + id: target + run: | + case "${{ github.event.client_payload.channel }}" in + stable) echo "file=plugins.xml" >> $GITHUB_OUTPUT ;; + beta) echo "file=plugins-beta.xml" >> $GITHUB_OUTPUT ;; + dev) echo "file=plugins-dev.xml" >> $GITHUB_OUTPUT ;; + esac + + - name: Remove existing entry for this plugin + run: | + PLUGIN="${{ github.event.client_payload.plugin }}" + FILE="${{ steps.target.outputs.file }}" + sed -i "//d" "$FILE" + + - name: Insert new XML block + run: | + FILE="${{ steps.target.outputs.file }}" + BLOCK=$(printf '${{ github.event.client_payload.xml_block }}' | sed 's/\\n/\n/g') + sed -i "s||${BLOCK}\n|" "$FILE" + + - 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 "[${{ github.event.client_payload.channel }}] ${{ github.event.client_payload.plugin }}" \ + || echo "Keine Änderungen" + git push origin feature/release \ No newline at end of file diff --git a/scripts/.gitea/workflows/update-plugins-xml.yml b/scripts/.gitea/workflows/update-plugins-xml.yml deleted file mode 100644 index 8755924..0000000 --- a/scripts/.gitea/workflows/update-plugins-xml.yml +++ /dev/null @@ -1,46 +0,0 @@ -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 deleted file mode 100644 index fe70248..0000000 --- a/scripts/update_plugins_xml.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/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