From 6e72e4ac770909fec9dd383b7a94d15cd2e24e87 Mon Sep 17 00:00:00 2001 From: Alexander01998 Date: Fri, 20 Dec 2024 15:48:07 +0100 Subject: [PATCH] Add announce_mod_update workflow --- .github/workflows/announce_mod_update.yml | 43 ++++++++ scripts/announce_mod_update.py | 113 ++++++++++++++++++++++ scripts/requirements.txt | 1 + scripts/util.py | 6 ++ 4 files changed, 163 insertions(+) create mode 100644 .github/workflows/announce_mod_update.yml create mode 100644 scripts/announce_mod_update.py diff --git a/.github/workflows/announce_mod_update.yml b/.github/workflows/announce_mod_update.yml new file mode 100644 index 0000000..bb156dd --- /dev/null +++ b/.github/workflows/announce_mod_update.yml @@ -0,0 +1,43 @@ +name: Announce Mod Update +run-name: Announce ${{ github.event.inputs.mod }} ${{ github.event.inputs.mod_version }} update on WurstForum + +on: + workflow_dispatch: + inputs: + mod: + description: "Mod ID (as it appears in config.toml)" + required: true + mod_version: + description: "Mod version (without v or -MC)" + required: true + +jobs: + announce: + runs-on: ubuntu-latest + steps: + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: "pip" + cache-dependency-path: _scripts/requirements.txt + + - name: Install dependencies + run: | + pip install -r _scripts/requirements.txt + + - name: Run announce_mod_update.py + id: announce + env: + WURSTFORUM_TOKEN: ${{ secrets.WF_BOT_TOKEN }} + run: | + python _scripts/announce_mod_update.py "${{ github.event.inputs.mod }}" "${{ github.event.inputs.mod_version }}" + + - name: Write summary + run: | + echo "Discussion ID: ${{ steps.announce.outputs.discussion_id }}" >> $GITHUB_STEP_SUMMARY + echo "Link: " >> $GITHUB_STEP_SUMMARY diff --git a/scripts/announce_mod_update.py b/scripts/announce_mod_update.py new file mode 100644 index 0000000..25e67de --- /dev/null +++ b/scripts/announce_mod_update.py @@ -0,0 +1,113 @@ +import argparse +import json +import os +import requests +import util +from dataclasses import dataclass +from pathlib import Path +from util import JekyllPost + + +@dataclass +class WurstForumDiscussion: + title: str + tags: list[int] + content: str + + +announcement_template = """ +@"Everyone"#g7 {mod_name} {mod_version} is now available. Download it here: <{update_url}> + +[![{title}]({image_url})]({update_url}) + +{changelog} +""".strip() + + +def parse_changelog(content: str) -> str: + """Parse the changelog from the content of a Wurst update post.""" + changelog_lines = [] + for line in content[content.find("## Changelog") :].splitlines(): + stripped = line.strip() + if not stripped or stripped.startswith("-") or stripped.startswith("## Changelog"): + changelog_lines.append(line) + continue + break + return "\n".join(changelog_lines).strip() + + +def create_announcement(mod_update: JekyllPost) -> WurstForumDiscussion: + """Create an announcement from a mod update post.""" + # Title + title = mod_update.front_matter["title"] + + # Tag IDs - check these at https://wurstforum.net/api/tags + tags = { + "Announcements": 3, + "Other Mods": 27, + } + + # Content + mod = mod_update.front_matter["mod"] + config = util.read_toml_file(Path("config.toml")) + mod_name = config["Params"]["modnames"][mod] + mod_version = mod_update.front_matter["modversion"] + content = announcement_template.format( + title=title, + mod_name=mod_name, + mod_version=mod_version, + update_url=f"https://www.wimods.net/{mod}/{mod}-{mod_version.replace('.', '-')}/", + image_url=mod_update.front_matter["image"], + changelog=parse_changelog(mod_update.content), + ) + + return WurstForumDiscussion(title, list(tags.values()), content) + + +def upload_discussion(discussion: WurstForumDiscussion) -> int: + """Upload a new discussion to WurstForum and return its ID.""" + url = "https://wurstforum.net/api/discussions" + headers = {"Authorization": f"Token {os.getenv('WURSTFORUM_TOKEN')}"} + data = { + "data": { + "type": "discussions", + "attributes": { + "title": discussion.title, + "content": discussion.content, + }, + "relationships": { + "tags": { + "data": [{"type": "tags", "id": tag_id} for tag_id in discussion.tags], + }, + }, + }, + } + + print(f"Request data: {json.dumps(data, indent=2)}") + response = requests.post(url, headers=headers, json=data) + if not response.ok: + raise requests.HTTPError(f"Request failed (code {response.status_code}): {response.text}") + discussion_id = response.json().get("data", {}).get("id") + if not discussion_id: + raise ValueError(f"No discussion ID in response: {response.text}") + return discussion_id + + +def main(mod, mod_version): + hugo_post = util.find_mod_update_post(mod, mod_version) + + announcement = create_announcement(hugo_post) + print(f"Title: {announcement.title}") + print(f"Content: {announcement.content}") + + discussion_id = upload_discussion(announcement) + print(f"https://wurstforum.net/d/{discussion_id}") + util.set_github_output("discussion_id", discussion_id) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Announces a new mod update on WurstForum") + parser.add_argument("mod", help="Mod ID (as it appears in config.toml)") + parser.add_argument("mod_version", help="Mod version (without v or -MC)") + args = parser.parse_args() + main(args.mod, args.mod_version) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 9d48c4b..f1343e2 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,2 +1,3 @@ requests ruamel.yaml +tomli diff --git a/scripts/util.py b/scripts/util.py index 6e468fe..5865e79 100644 --- a/scripts/util.py +++ b/scripts/util.py @@ -1,5 +1,6 @@ import json import os +import tomli from dataclasses import dataclass from io import StringIO from pathlib import Path @@ -77,6 +78,11 @@ def write_json_file(path: Path, data: dict): path.write_text(json.dumps(data, indent=2), encoding="utf-8", newline="\n") +def read_toml_file(path: Path) -> dict: + """Read a TOML data file.""" + return tomli.loads(path.read_text(encoding="utf-8")) + + def set_github_output(key: str, value: str): """Set a key-value pair in the GitHub Actions output.""" if "GITHUB_OUTPUT" not in os.environ: