Skip to content

Commit

Permalink
Add announce_mod_update workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander01998 committed Dec 20, 2024
1 parent 3ea3c70 commit 6e72e4a
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 0 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/announce_mod_update.yml
Original file line number Diff line number Diff line change
@@ -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: <https://wurstforum.net/d/${{ steps.announce.outputs.discussion_id }}>" >> $GITHUB_STEP_SUMMARY
113 changes: 113 additions & 0 deletions scripts/announce_mod_update.py
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
requests
ruamel.yaml
tomli
6 changes: 6 additions & 0 deletions scripts/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import os
import tomli
from dataclasses import dataclass
from io import StringIO
from pathlib import Path
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 6e72e4a

Please sign in to comment.