mirror of
https://github.com/WeblateOrg/weblate.git
synced 2026-07-26 14:23:58 +08:00
179 lines
4.9 KiB
Python
Executable file
Vendored
179 lines
4.9 KiB
Python
Executable file
Vendored
#!/usr/bin/env python
|
|
|
|
# Copyright © Michal Čihař <michal@weblate.org>
|
|
#
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from __future__ import annotations
|
|
|
|
# ruff: ignore[suspicious-subprocess-import]
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
import requests
|
|
from ruamel.yaml import YAML
|
|
from update_version import VERSION_FILES, replace_file, update_version
|
|
|
|
REPO_API = "https://api.github.com/repos/WeblateOrg/weblate"
|
|
ACTIVITY_API = f"{REPO_API}/stats/commit_activity"
|
|
FALLBACK_STATS_FILE = "weblate/trans/views/about.py"
|
|
|
|
if len(sys.argv) != 2:
|
|
print("Usage: ./scripts/set-version.py VERSION")
|
|
sys.exit(1)
|
|
|
|
version = version_full = sys.argv[1]
|
|
if version.count(".") == 1:
|
|
version_full = f"{version}.0"
|
|
package_version = f"{version}.dev0"
|
|
|
|
|
|
def prepend_file(name: str, content: str) -> None:
|
|
content += Path(name).read_text(encoding="utf-8")
|
|
Path(name).write_text(content, encoding="utf-8")
|
|
|
|
|
|
def fetch_commit_activity(request_headers: dict[str, str]) -> list[dict[str, int]]:
|
|
"""Fetch commit activity, retrying while GitHub prepares the stats."""
|
|
for _attempt in range(5):
|
|
activity_response = requests.get(
|
|
ACTIVITY_API, headers=request_headers, timeout=5
|
|
)
|
|
if activity_response.status_code != 202:
|
|
activity_response.raise_for_status()
|
|
return activity_response.json()
|
|
time.sleep(1)
|
|
activity_response.raise_for_status()
|
|
msg = "GitHub commit activity is not ready"
|
|
raise RuntimeError(msg)
|
|
|
|
|
|
def fetch_fallback_stats(request_headers: dict[str, str]) -> dict[str, int]:
|
|
repo_response = requests.get(REPO_API, headers=request_headers, timeout=5)
|
|
repo_response.raise_for_status()
|
|
repo = repo_response.json()
|
|
activity = sorted(
|
|
fetch_commit_activity(request_headers), key=lambda item: -item["week"]
|
|
)
|
|
return {
|
|
"stars": repo["stargazers_count"],
|
|
"issues": repo["open_issues_count"],
|
|
"commits": sum(item["total"] for item in activity[:8]),
|
|
}
|
|
|
|
|
|
def update_fallback_stats(stats: dict[str, int]) -> None:
|
|
replace_file(
|
|
FALLBACK_STATS_FILE,
|
|
r"^FALLBACK_STATS = \{\n"
|
|
r' "stars": \d+,\n'
|
|
r' "issues": \d+,\n'
|
|
r' "commits": \d+,\n'
|
|
r"\}",
|
|
"FALLBACK_STATS = {\n"
|
|
f' "stars": {stats["stars"]},\n'
|
|
f' "issues": {stats["issues"]},\n'
|
|
f' "commits": {stats["commits"]},\n'
|
|
"}",
|
|
)
|
|
|
|
|
|
yaml = YAML()
|
|
config = yaml.load(Path("~/.config/hub").expanduser().read_text(encoding="utf-8"))
|
|
|
|
# Get/create milestone
|
|
milestones_api = f"{REPO_API}/milestones"
|
|
api_auth = f"token {config['github.com'][0]['oauth_token']}"
|
|
headers = {"Authorization": api_auth, "Accept": "application/vnd.github.v3+json"}
|
|
response = requests.get(
|
|
milestones_api, headers=headers, timeout=1, params={"state": "open"}
|
|
)
|
|
response.raise_for_status()
|
|
milestone_url = None
|
|
for milestone in response.json():
|
|
if milestone["title"] == version:
|
|
milestone_url = milestone["html_url"]
|
|
|
|
if milestone_url is None:
|
|
response = requests.post(
|
|
milestones_api, headers=headers, json={"title": version}, timeout=1
|
|
)
|
|
payload = response.json()
|
|
try:
|
|
milestone_url = payload["html_url"]
|
|
except KeyError:
|
|
print(payload)
|
|
raise
|
|
|
|
fallback_stats = fetch_fallback_stats(headers)
|
|
|
|
# Set version in the files
|
|
update_version(package_version, version)
|
|
replace_file(
|
|
"client/package.json", ' "version": ".*",', f' "version": "{version_full}",'
|
|
)
|
|
update_fallback_stats(fallback_stats)
|
|
|
|
# Update changelog
|
|
title = f"Weblate {version}"
|
|
underline = "-" * len(title)
|
|
header = f"""{title}
|
|
{underline}
|
|
|
|
*Not yet released.*
|
|
|
|
.. rubric:: New features
|
|
|
|
.. rubric:: Improvements
|
|
|
|
.. rubric:: Bug fixes
|
|
|
|
.. rubric:: Compatibility
|
|
|
|
.. rubric:: Upgrading
|
|
|
|
Please follow :ref:`generic-upgrade-instructions` in order to perform update.
|
|
|
|
.. rubric:: Contributors
|
|
|
|
.. include:: /changes/contributors/{version}.rst
|
|
|
|
`All changes in detail <{milestone_url}?closed=1>`__.
|
|
|
|
"""
|
|
prepend_file("docs/changes.rst", header)
|
|
version_contributors = Path("docs") / "changes" / "contributors" / f"{version}.rst"
|
|
version_contributors.write_text("""..
|
|
DO NOT EDIT! Automatically generated by scripts/prepare-release upon release.
|
|
""")
|
|
|
|
files = [
|
|
*VERSION_FILES,
|
|
"docs/changes.rst",
|
|
"client/package.json",
|
|
FALLBACK_STATS_FILE,
|
|
version_contributors.as_posix(),
|
|
]
|
|
# ruff: ignore[start-process-with-partial-path]
|
|
subprocess.run(["git", "add", version_contributors.as_posix()], check=True)
|
|
subprocess.run(
|
|
# ruff: ignore[start-process-with-partial-path]
|
|
[
|
|
"uv",
|
|
"run",
|
|
"--only-group",
|
|
"pre-commit",
|
|
"prek",
|
|
"run",
|
|
"--files",
|
|
*files,
|
|
],
|
|
check=False,
|
|
)
|
|
subprocess.run(
|
|
# ruff: ignore[start-process-with-partial-path]
|
|
["git", "commit", "-m", f"chore: setting version to {version}", *files],
|
|
check=True,
|
|
)
|