diff --git a/release/lts/README.md b/release/lts/README.md
index 8f7b6f0b87a..c95aecabe18 100644
--- a/release/lts/README.md
+++ b/release/lts/README.md
@@ -1,41 +1,18 @@
-This folder contains several scripts to smoothen the Blender LTS releases.
+This folder contains a script to generate release notes and download URLs
+for Blender LTS releases.
-create_download_urls.py
-=======================
+Ensure required Python modules are installed before running:
-This python script is used to generate the download urls which we can
-copy-paste directly into the CMS of www.blender.org.
+ pip3 install -r ./requirements.txt
-Usage: create_download_urls.py --version 2.83.7
+Then run for example:
-Arguments:
- --version VERSION Version string in the form of {major}.{minor}.{build}
- (eg 2.83.7)
+ ./create_release_notes.py --version 3.3.2 --format=html
-The resulting html will be printed to the console.
+Available arguments:
-create_release_notes.py
-=======================
-
-This python script is used to generate the release notes which we can
-copy-paste directly into the CMS of www.blender.org and stores.
-
-Usage: ./create_release_notes.py --task=T77348 --version=2.83.7
-
-Arguments:
- --version VERSION Version string in the form of {major}.{minor}.{build}
- (e.g. 2.83.7)
- --task TASK Phabricator ticket that is contains the release notes
- information (e.g. T77348)
- --format FORMAT Format the result in `text`, `steam`, `wiki` or `html`
-
-Requirements
-============
-
-* Python 3.8 or later
-* Python phabricator client version 0.7.0
- https://pypi.org/project/phabricator/
-
-For convenience the python modules can be installed using pip
-
- pip3 install -r ./requirements.txt
\ No newline at end of file
+ --version VERSION Version string in the form of {major}.{minor}.{build}
+ (e.g. 3.3.2)
+ --issue ISSUE Gitea issue that is contains the release notes
+ information (e.g. #77348)
+ --format FORMAT Format the result in `text`, `steam`, `wiki` or `html`
diff --git a/release/lts/create_release_notes.py b/release/lts/create_release_notes.py
index a51721057bb..cfab24c94ae 100755
--- a/release/lts/create_release_notes.py
+++ b/release/lts/create_release_notes.py
@@ -1,169 +1,46 @@
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
-#!/usr/bin/env python3
-
import argparse
-import phabricator
+import lts_issue
+import lts_download
-DESCRIPTION = ("This python script is used to generate the release notes "
- "which we can copy-paste directly into the CMS of "
+DESCRIPTION = ("This python script is used to generate the release notes and "
+ "download URLs which we can copy-paste directly into the CMS of "
"www.blender.org and stores.")
-USAGE = "./create_release_notes.py --task=T77348 --version=2.83.7"
+# Parse arguments
+parser = argparse.ArgumentParser(description=DESCRIPTION)
+parser.add_argument(
+ "--version",
+ required=True,
+ help="Version string in the form of {major}.{minor}.{patch} (e.g. 3.3.2)")
+parser.add_argument(
+ "--issue",
+ help="Task that is contains the release notes information (e.g. #77348)")
+parser.add_argument(
+ "--format",
+ help="Format the result in `text`, `steam`, `wiki` or `html`",
+ default="text")
+args = parser.parse_args()
-class ReleaseLogLine:
- """
- Class containing the information of a single line of the release log
+# Determine issue number
+version = args.version
+issue = args.issue
+if not issue:
+ if version.startswith("2.83."):
+ issue = "#77348"
+ elif version.startswith("2.93."):
+ issue = "#88449"
+ elif version.startswith("3.3."):
+ issue = "#100749"
+ else:
+ raise ValueError("Specify --issue or update script to include issue number for this version")
- Instance attributes:
+# Print
+if args.format == "html":
+ lts_download.print_urls(version=version)
+ print("")
- * line: (str) the original line used to create this log line
- * task_id: (int or None) the extracted task id associated with this log
- line. Can be None if the log line isn't associated with a task.
- * commit_id: (str or None) the extracted commit id associated with this log
- line. Only filled when no `task_id` could be found.
- * ref: (str) `task_id` or `commit_id` of this line, including `T` for tasks
- or `D` for diffs.
- * title: (str) title of this log line. When constructed this attribute is
- an empty string. The called needs to retrieve the title from the
- backend.
- * url: (str) url of the ticket task or commit.
- """
-
- def __init__(self, line: str):
- self.line = line
- items = line.split("|")
- self.task_id = None
- self.commit_id = None
- try:
- task_id = int(items[1].strip()[1:])
- self.task_id = task_id
- self.ref = f"T{self.task_id}"
- except ValueError:
- # no task
- commit_string = items[3].strip()
- commits = commit_string.split(",")
- commit_id = commits[0]
- commit_id = commit_id.replace("{", "").replace("}", "")
- if not commit_id.startswith("rB"):
- commit_id = f"rB{commit_id}"
- self.commit_id = commit_id
-
- self.ref = f"{self.commit_id}"
-
- self.title = ""
- self.url = f"https://developer.blender.org/{self.ref}"
-
- def __format_as_html(self) -> str:
- return f"
{self.title} [{self.ref}]"
-
- def __format_as_text(self) -> str:
- return f"* {self.title} [{self.ref}]"
-
- def __format_as_steam(self) -> str:
- return f"* {self.title} ([url={self.url}]{self.ref}[/url])"
-
- def __format_as_wiki(self) -> str:
- if self.task_id:
- return f"* {self.title} [{{{{BugReport|{self.task_id}}}}}]"
- else:
- return f"* {self.title} [{{{{GitCommit|{self.commit_id[2:]}}}}}]"
-
- def format(self, format: str) -> str:
- """
- Format this line
-
- :attr format: the desired format. Possible values are 'text', 'steam' or 'html'
- :type string:
- """
- if format == 'html':
- return self.__format_as_html()
- elif format == 'steam':
- return self.__format_as_steam()
- elif format == 'wiki':
- return self.__format_as_wiki()
- else:
- return self.__format_as_text()
-
-
-def format_title(title: str) -> str:
- title = title.strip()
- if not title.endswith("."):
- title = title + "."
- return title
-
-
-def extract_release_notes(version: str, task_id: int):
- """
- Extract all release notes logs
-
- # Process
-
- 1. Retrieval of description of the given `task_id`.
- 2. Find rows for the given `version` and convert to `ReleaseLogLine`.
- 3. based on the associated task or commit retrieves the title of the log
- line.
- """
- phab = phabricator.Phabricator()
- phab.update_interfaces()
- task = phab.maniphest.info(task_id=task_id)
- description = task["description"]
- lines = description.split("\n")
- start_index = lines.index(f"## Blender {version} ##")
- lines = lines[start_index + 1:]
- for line in lines:
- if not line.strip():
- continue
- if line.startswith("| **Report**"):
- continue
- if line.startswith("## Blender"):
- break
-
- log_line = ReleaseLogLine(line)
- if log_line.task_id:
- issue_task = phab.maniphest.info(task_id=log_line.task_id)
- log_line.title = format_title(issue_task.title)
- yield log_line
- elif log_line.commit_id:
- commits = phab.diffusion.commit.search(constraints={"identifiers": [log_line.commit_id]})
- commit = commits.data[0]
- commit_message = commit['fields']['message']
- commit_title = commit_message.split("\n")[0]
- log_line.title = format_title(commit_title)
- yield log_line
-
-
-def print_release_notes(version: str, format: str, task_id: int):
- """
- Generate and print the release notes to the console.
- """
- if format == 'html':
- print("")
- if format == 'steam':
- print("[ul]")
- for log_item in extract_release_notes(version=version, task_id=task_id):
- print(log_item.format(format=format))
- if format == 'html':
- print("
")
- if format == 'steam':
- print("[/ul]")
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description=DESCRIPTION, usage=USAGE)
- parser.add_argument(
- "--version",
- required=True,
- help="Version string in the form of {major}.{minor}.{build} (e.g. 2.83.7)")
- parser.add_argument(
- "--task",
- required=True,
- help="Phabricator ticket that is contains the release notes information (e.g. T77348)")
- parser.add_argument(
- "--format",
- help="Format the result in `text`, `steam`, `wiki` or `html`",
- default="text")
- args = parser.parse_args()
-
- print_release_notes(version=args.version, format=args.format, task_id=int(args.task[1:]))
+lts_issue.print_notes(version=version, format=args.format, issue=issue)
diff --git a/release/lts/create_download_urls.py b/release/lts/lts_download.py
old mode 100755
new mode 100644
similarity index 69%
rename from release/lts/create_download_urls.py
rename to release/lts/lts_download.py
index c6b01acdf60..6d0dd81397b
--- a/release/lts/create_download_urls.py
+++ b/release/lts/lts_download.py
@@ -1,14 +1,9 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
-import argparse
import datetime
-DESCRIPTION = ("This python script is used to generate the download urls "
- "which we can copy-paste directly into the CMS of "
- "www.blender.org")
-USAGE = "create_download_urls --version=2.83.7"
# Used date format: "September 30, 2020"
DATE_FORMAT = "%B %d, %Y"
@@ -62,19 +57,8 @@ def generate_html(version: Version) -> str:
return "\n".join(lines)
-def print_download_urls(version: Version):
+def print_urls(version: str):
"""
Generate the download urls and print them to the console.
"""
- print(generate_html(version))
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description=DESCRIPTION, usage=USAGE)
- parser.add_argument("--version",
- required=True,
- help=("Version string in the form of {major}.{minor}."
- "{build} (eg 2.83.7)"))
- args = parser.parse_args()
-
- print_download_urls(version=Version(args.version))
+ print(generate_html(Version(version)))
diff --git a/release/lts/lts_issue.py b/release/lts/lts_issue.py
new file mode 100644
index 00000000000..f84cfb29b15
--- /dev/null
+++ b/release/lts/lts_issue.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import requests
+
+class ReleaseLogLine:
+ """
+ Class containing the information of a single line of the release log
+
+ Instance attributes:
+
+ * line: (str) the original line used to create this log line
+ * issue_id: (int or None) the extracted issue id associated with this log
+ line. Can be None if the log line isn't associated with a issue.
+ * commit_id: (str or None) the extracted commit id associated with this log
+ line. Only filled when no `issue_id` could be found.
+ * ref: (str) `issue_id` or `commit_id` of this line, including `T` for issues
+ or `D` for diffs.
+ * title: (str) title of this log line. When constructed this attribute is
+ an empty string. The called needs to retrieve the title from the
+ backend.
+ * url: (str) url of the ticket issue or commit.
+ """
+
+ def __init__(self, line: str):
+ self.line = line
+ items = line.split("|")
+ self.issue_id = None
+ self.issue_repo = None
+ self.commit_id = None
+ self.commit_repo = None
+ base_url = "https://projects.blender.org"
+ try:
+ issue_tokens = items[1].strip().split("#")
+ if len(issue_tokens[0]) > 0:
+ self.issue_repo = issue_tokens[0]
+ self.issue_id = issue_tokens[1]
+ else:
+ self.issue_repo = "blender/blender"
+ self.issue_id = issue_tokens[1]
+
+ self.ref = f"#{self.issue_id}"
+ self.url = f"{base_url}/{self.issue_repo}/issues/{self.issue_id}"
+ except IndexError:
+ # no issue
+ commit_string = items[3].strip()
+ commit_string = commit_string.split(",")[0]
+ commit_string = commit_string.split("]")[0]
+ commit_string = commit_string.replace("[", "")
+
+ commit_tokens = commit_string.split("@")
+ if len(commit_tokens) > 1:
+ self.commit_repo = commit_tokens[0]
+ self.commit_id = commit_tokens[1]
+ else:
+ self.commit_repo = "blender/blender"
+ self.commit_id = commit_tokens[0]
+
+ self.ref = f"{self.commit_id}"
+ self.url = f"{base_url}/{self.commit_repo}/commit/{self.commit_id}"
+
+ self.title = ""
+
+ def __format_as_html(self) -> str:
+ return f" {self.title} [{self.ref}]"
+
+ def __format_as_text(self) -> str:
+ return f"* {self.title} [{self.ref}]"
+
+ def __format_as_steam(self) -> str:
+ return f"* {self.title} ([url={self.url}]{self.ref}[/url])"
+
+ def __format_as_wiki(self) -> str:
+ if self.issue_id:
+ return f"* {self.title} [{{{{BugReport|{self.issue_id}}}}}]"
+ else:
+ return f"* {self.title} [{{{{GitCommit|{self.commit_id[2:]}}}}}]"
+
+ def format(self, format: str) -> str:
+ """
+ Format this line
+
+ :attr format: the desired format. Possible values are 'text', 'steam' or 'html'
+ :type string:
+ """
+ if format == 'html':
+ return self.__format_as_html()
+ elif format == 'steam':
+ return self.__format_as_steam()
+ elif format == 'wiki':
+ return self.__format_as_wiki()
+ else:
+ return self.__format_as_text()
+
+
+def format_title(title: str) -> str:
+ title = title.strip()
+ if not title.endswith("."):
+ title = title + "."
+ return title
+
+
+def extract_release_notes(version: str, issue: str):
+ """
+ Extract all release notes logs
+
+ # Process
+
+ 1. Retrieval of description of the given `issue_id`.
+ 2. Find rows for the given `version` and convert to `ReleaseLogLine`.
+ 3. based on the associated issue or commit retrieves the title of the log
+ line.
+ """
+ base_url = "https://projects.blender.org/api/v1/repos"
+ issues_url = base_url + "/blender/blender/issues/"
+ headers = {'accept': 'application/json'}
+
+ response = requests.get(issues_url + issue[1:], headers=headers)
+ description = response.json()["body"]
+
+ lines = description.split("\n")
+ start_index = lines.index(f"## Blender {version}")
+ lines = lines[start_index + 1:]
+ for line in lines:
+ if not line.strip():
+ continue
+ if line.startswith("| **Report**"):
+ continue
+ if line.startswith("## Blender"):
+ break
+ if line.find("| -- |") != -1:
+ continue
+
+ log_line = ReleaseLogLine(line)
+ if log_line.issue_id:
+ issue_url = f"{base_url}/{log_line.issue_repo}/issues/{log_line.issue_id}"
+ response = requests.get(issue_url, headers=headers)
+ if response.status_code != 200:
+ raise ValueError("Issue not found: " + str(log_line.issue_id))
+
+ log_line.title = format_title(response.json()["title"])
+ yield log_line
+ elif log_line.commit_id:
+ commit_url = f"{base_url}/{log_line.commit_repo}/git/commits/{log_line.commit_id}"
+ response = requests.get(commit_url, headers=headers)
+ if response.status_code != 200:
+ raise ValueError("Commit not found: " + log_line.commit_id)
+
+ commit_message = response.json()['commit']['message']
+ commit_title = commit_message.split("\n")[0]
+ log_line.title = format_title(commit_title)
+ yield log_line
+
+
+def print_notes(version: str, format: str, issue: str):
+ """
+ Generate and print the release notes to the console.
+ """
+ if format == 'html':
+ print("")
+ if format == 'steam':
+ print("[ul]")
+ for log_item in extract_release_notes(version=version, issue=issue):
+ print(log_item.format(format=format))
+ if format == 'html':
+ print("
")
+ if format == 'steam':
+ print("[/ul]")
diff --git a/release/lts/requirements.txt b/release/lts/requirements.txt
index dc91ba85b01..f2293605cf1 100644
--- a/release/lts/requirements.txt
+++ b/release/lts/requirements.txt
@@ -1 +1 @@
-phabricator==0.7.0
\ No newline at end of file
+requests