1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/mediawiki_ynh.git synced 2024-09-03 19:46:05 +02:00
mediawiki_ynh/.github/workflows/update_extensions.py
2023-09-15 17:01:53 +02:00

132 lines
3.8 KiB
Python
Executable file

#!/usr/bin/env python3
"""
Download extensions for the current mediawiki version, and update the conf files.
"""
import datetime
import hashlib
from typing import Any, List, Optional
import requests
import tomlkit
from packaging import version
GITHUB_API_URL = "https://api.github.com/repos"
GITHUB_API_TOKEN = False
# Update this after updating mediawiki version.
ACCEPTABLE_BRANCHES = [
"REL1_40",
"REL1_39",
]
def github_get(path: str, *args, **kwargs) -> Any:
headers = kwargs.get("headers", {})
if GITHUB_API_TOKEN:
headers["Authorization"] = f"Bearer {GITHUB_API_TOKEN}"
kwargs["headers"] = headers
result = requests.get(
f"{GITHUB_API_URL}/{path}",
timeout=10,
*args,
**kwargs
)
if result.status_code == requests.codes["forbidden"]:
raise RuntimeError(result.json().get("message"), result.json().get("documentation_url"))
return result.json()
def sha256sum_of_url(url: str) -> str:
"""Compute checksum without saving the file"""
checksum = hashlib.sha256()
for chunk in requests.get(url, stream=True, timeout=10).iter_content():
checksum.update(chunk)
return checksum.hexdigest()
def find_valid_version(all_versions: List[str], max_version: version.Version) -> Optional[str]:
"""Find the valid extensions for the current mediawiki version"""
def version_of(ext):
try:
return version.parse(ext.replace("_", ".").replace("REL", ""))
except version.InvalidVersion:
# print(f"Invalid version (this might be normal): {ext}")
return version.parse("0.0")
def compatible(ext_version: str) -> bool:
return version_of(ext_version) <= max_version
compatible_versions = filter(compatible, all_versions)
if compatible_versions:
return max(compatible_versions, key=version_of)
if "master" in all_versions:
return "master"
return None
def get_repo(url: str) -> str:
return "/".join(url.split("://")[1].split("/")[1:3])
def get_branches(repo: str) -> List[str]:
branches = github_get(f"{repo}/branches")
names = [branch["name"] for branch in branches]
return names
def get_last_commit_of(repo: str, branch: str) -> str:
commit = github_get(f"{repo}/commits/{branch}")
return commit["sha"]
def timestamp_of_commit(repo: str, sha: str) -> datetime.datetime:
commit = github_get(f"{repo}/commits/{sha}")
date = commit["commit"]["author"]["date"]
return datetime.datetime.strptime(date, "%Y-%m-%dT%H:%M:%SZ")
def main():
print('Updating extensions source files...')
with open("manifest.toml", "r", encoding="utf-8") as file:
manifest = tomlkit.loads(file.read())
# mediawiki_version = version.Version(manifest["version"].value.split("~")[0])
for name, descr in manifest["resources"]["sources"].items():
if "extension" not in descr["url"]:
# not an extension
continue
print(f'Updating source file for {name}')
repo = get_repo(descr["url"])
branches = get_branches(repo)
commits = [
get_last_commit_of(repo, branch)
for branch in branches
if branch in ACCEPTABLE_BRANCHES
]
if not commits:
print("Could not find any valid branch")
continue
# Sort by commit date…
commits = sorted(commits, key=lambda x, r=repo: timestamp_of_commit(r, x), reverse=True)
commit = commits[0]
url = f"https://github.com/{repo}/archive/{commit}.tar.gz"
manifest["resources"]["sources"][name]["url"] = url
manifest["resources"]["sources"][name]["sha256"] = sha256sum_of_url(url)
with open("manifest.toml", "w", encoding="utf-8") as manifest_file:
manifest_file.write(tomlkit.dumps(manifest))
if __name__ == "__main__":
main()