Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 5 additions & 83 deletions .github/workflows/update-fexcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,57 +22,8 @@ jobs:
- name: Find latest FEXCore .wcp
id: check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Fetch the file listing from the upstream repo via the GitHub API.
# Authenticate to avoid anonymous rate-limit (60 req/hr).
RESPONSE=$(curl -sf \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer $GH_TOKEN" \
"https://api.github.com/repos/StevenMXZ/Winlator-Contents/contents/FEXCore")

# Pick the file with the highest YYMM version.
# Only considers files whose names start with 4 digits (e.g. 2604.wcp, 2508.1.wcp).
LATEST=$(echo "$RESPONSE" | python3 - <<'EOF'
import sys, json, re

data = json.loads(sys.stdin.read())
files = [f["name"] for f in data if f["type"] == "file" and f["name"].endswith(".wcp")]

best = None
best_ver = (-1, -1)
for name in files:
m = re.match(r'^(\d{4})(?:\.(\d+))?\.wcp$', name)
if m:
ver = (int(m.group(1)), int(m.group(2) or 0))
if ver > best_ver:
best_ver = ver
best = name

print(best or "")
EOF
)

if [[ -z "$LATEST" ]]; then
echo "Could not determine latest .wcp file." >&2
exit 1
fi

# Extract the YYMM version (first four digits) for the output filename.
VERSION=$(echo "$LATEST" | grep -oP '^\d{4}')
TZST_PATH="app/src/main/assets/fexcore/fexcore-${VERSION}.tzst"

echo "LATEST_FILE=$LATEST" >> "$GITHUB_OUTPUT"
echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"
echo "TZST_PATH=$TZST_PATH" >> "$GITHUB_OUTPUT"

if [[ -f "$TZST_PATH" ]]; then
echo "ALREADY_EXISTS=true" >> "$GITHUB_OUTPUT"
echo "fexcore-${VERSION}.tzst already present — nothing to do."
else
echo "ALREADY_EXISTS=false" >> "$GITHUB_OUTPUT"
echo "New release found: $LATEST → $TZST_PATH"
fi
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python3 tools/check-latest-fexcore.py

- name: Download ${{ steps.check.outputs.LATEST_FILE }}
if: steps.check.outputs.ALREADY_EXISTS == 'false'
Expand All @@ -89,38 +40,9 @@ EOF
- name: Update arrays.xml
if: steps.check.outputs.ALREADY_EXISTS == 'false'
run: |
VERSION="${{ steps.check.outputs.VERSION }}"
ARRAYS_XML="app/src/main/res/values/arrays.xml"

# Check if this version is already listed in arrays.xml.
if grep -qF "<item>${VERSION}</item>" "$ARRAYS_XML"; then
echo "Version $VERSION already present in arrays.xml — skipping XML update."
else
# Insert the new version as the last <item> of fexcore_version_entries.
# We find the closing </string-array> that follows the fexcore_version_entries
# block and insert directly before it.
python3 - "$ARRAYS_XML" "$VERSION" <<'PYEOF'
import sys, re

path, version = sys.argv[1], sys.argv[2]
with open(path, "r", encoding="utf-8") as f:
content = f.read()

# Find the fexcore_version_entries block and append the new item before its closing tag.
pattern = r'(name="fexcore_version_entries".*?)(</string-array>)'
replacement = r'\g<1> <item>' + version + r'</item>\n \g<2>'
new_content, count = re.subn(pattern, replacement, content, count=1, flags=re.DOTALL)

if count == 0:
print("ERROR: fexcore_version_entries array not found in arrays.xml", file=sys.stderr)
sys.exit(1)

with open(path, "w", encoding="utf-8") as f:
f.write(new_content)

print(f"Appended <item>{version}</item> to fexcore_version_entries.")
PYEOF
fi
python3 tools/update-arrays-xml.py \
app/src/main/res/values/arrays.xml \
"${{ steps.check.outputs.VERSION }}"

- name: Create PR branch, commit, and open PR
if: steps.check.outputs.ALREADY_EXISTS == 'false'
Expand Down
112 changes: 112 additions & 0 deletions tools/check-latest-fexcore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/usr/bin/env python3
"""
check-latest-fexcore.py
Queries the StevenMXZ/Winlator-Contents FEXCore directory and prints the
latest .wcp filename (by YYMM version number).

Usage:
python3 tools/check-latest-fexcore.py [--token <github_token>]

A token is optional but recommended to avoid the 60 req/hr anonymous rate limit.
It can also be supplied via the GITHUB_TOKEN environment variable.
"""

import argparse
import json
import os
import re
import subprocess
import sys

API_URL = "https://api.github.com/repos/StevenMXZ/Winlator-Contents/contents/FEXCore"


def fetch_listing(token: str | None) -> list[dict]:
cmd = [
"curl", "-sf",
"-H", "Accept: application/vnd.github.v3+json",
]
if token:
cmd += ["-H", f"Authorization: Bearer {token}"]
cmd.append(API_URL)

result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"curl error: {result.stderr.strip()}", file=sys.stderr)
sys.exit(1)
return json.loads(result.stdout)


def pick_latest(entries: list[dict]) -> tuple[str | None, tuple[int, int]]:
best_name = None
best_ver: tuple[int, int] = (-1, -1)
for entry in entries:
if entry.get("type") != "file":
continue
name = entry["name"]
if not name.endswith(".wcp"):
continue
m = re.match(r"^(\d{4})(?:\.(\d+))?\.wcp$", name)
if m:
ver = (int(m.group(1)), int(m.group(2) or 0))
if ver > best_ver:
best_ver = ver
best_name = name
return best_name, best_ver


def main() -> None:
parser = argparse.ArgumentParser(description="Find the latest FEXCore .wcp release.")
parser.add_argument("--token", default=os.environ.get("GITHUB_TOKEN"), help="GitHub token (or set GITHUB_TOKEN)")
parser.add_argument(
"--gha-output",
metavar="FILE",
default=os.environ.get("GITHUB_OUTPUT"),
help="Append key=value pairs to this file (GitHub Actions $GITHUB_OUTPUT). "
"Automatically set when GITHUB_OUTPUT env var is present.",
)
args = parser.parse_args()

if not args.gha_output:
# Human-readable mode
print(f"Querying {API_URL} ...")

entries = fetch_listing(args.token)

all_wcp = [e["name"] for e in entries if e.get("type") == "file" and e["name"].endswith(".wcp")]

latest, ver = pick_latest(entries)
if not latest:
print("ERROR: Could not determine latest versioned .wcp file.", file=sys.stderr)
sys.exit(1)

version = latest[:4] # first four digits = YYMM
tzst_path = f"app/src/main/assets/fexcore/fexcore-{version}.tzst"
download_url = f"https://raw.githubusercontent.com/StevenMXZ/Winlator-Contents/main/FEXCore/{latest}"
already_exists = os.path.isfile(tzst_path)

if args.gha_output:
# GitHub Actions mode: write outputs, print minimal log to stdout
with open(args.gha_output, "a", encoding="utf-8") as f:
f.write(f"LATEST_FILE={latest}\n")
f.write(f"VERSION={version}\n")
f.write(f"TZST_PATH={tzst_path}\n")
f.write(f"ALREADY_EXISTS={'true' if already_exists else 'false'}\n")
if already_exists:
print(f"fexcore-{version}.tzst already present — nothing to do.")
else:
print(f"New release found: {latest} → {tzst_path}")
else:
# Human-readable mode
print(f"\nAll .wcp files found ({len(all_wcp)}):")
for name in sorted(all_wcp):
print(f" {name}")
print(f"\nLatest : {latest} (parsed version {ver[0]}.{ver[1]})")
print(f"VERSION: {version}")
print(f"Output : {tzst_path}")
print(f"Already exists: {already_exists}")
print(f"Download URL: {download_url}")


if __name__ == "__main__":
main()
46 changes: 46 additions & 0 deletions tools/update-arrays-xml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env python3
"""
update-arrays-xml.py
Appends a new version entry to the fexcore_version_entries array in arrays.xml.

Usage:
python3 tools/update-arrays-xml.py <arrays.xml path> <version>
e.g. python3 tools/update-arrays-xml.py app/src/main/res/values/arrays.xml 2604
"""

import re
import sys


def main() -> None:
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <arrays.xml> <version>", file=sys.stderr)
sys.exit(1)

path, version = sys.argv[1], sys.argv[2]

with open(path, "r", encoding="utf-8") as f:
content = f.read()

# Idempotency check
if f"<item>{version}</item>" in content:
print(f"Version {version} already present in arrays.xml — nothing to do.")
sys.exit(0)

# Find the fexcore_version_entries block and append the new item before its closing tag.
pattern = r'(name="fexcore_version_entries".*?)(</string-array>)'
replacement = r'\g<1> <item>' + version + r'</item>\n \g<2>'
new_content, count = re.subn(pattern, replacement, content, count=1, flags=re.DOTALL)

if count == 0:
print("ERROR: fexcore_version_entries array not found in arrays.xml", file=sys.stderr)
sys.exit(1)

with open(path, "w", encoding="utf-8") as f:
f.write(new_content)

print(f"Appended <item>{version}</item> to fexcore_version_entries.")


if __name__ == "__main__":
main()
Loading