Przeglądaj źródła

优化pre-release主体信息 (#5063)

* :octocat: improve the body of release information https://github.com/siyuan-note/siyuan/issues/5062

* :octocat: not match `Widget` milestone https://github.com/siyuan-note/siyuan/issues/5062
飘尘 3 lat temu
rodzic
commit
e85f7a55cf
2 zmienionych plików z 92 dodań i 26 usunięć
  1. 5 2
      .github/workflows/ci.yml
  2. 87 24
      scripts/parse-changelog.py

+ 5 - 2
.github/workflows/ci.yml

@@ -24,17 +24,20 @@ jobs:
         uses: actions/setup-python@v3
         with:
           python-version: "3.10"
+      - run: pip install PyGithub
 
       - name: Gather Release Information
         id: release_info
         run: |
           echo "::set-output name=release_title::$(git show --format=%s --no-patch | head -1)"
           echo "::set-output name=release_version::$(TZ=Asia/Shanghai date +'v%Y%m%d%H%M')"
-          changelog=$(python scripts/parse-changelog.py CHANGE_LOGS.md)
+          changelog=$(python scripts/parse-changelog.py -t ${{ github.ref }} siyuan-note/siyuan)
           changelog="${changelog//'%'/'%25'}"
           changelog="${changelog//$'\n'/'%0A'}"
           changelog="${changelog//$'\r'/'%0D'}"
           echo "::set-output name=release_body::$changelog"
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Extract version from package.json
         uses: sergeysova/jq-action@v2
@@ -50,7 +53,7 @@ jobs:
         with:
           release_name: ${{ steps.release_info.outputs.release_version }}
           tag_name: ${{ github.ref }}
-          body: ${{ github.ref }}
+          body: ${{ steps.release_info.outputs.release_body }}
           draft: false
           prerelease: true
 

+ 87 - 24
scripts/parse-changelog.py

@@ -1,32 +1,95 @@
-#!/usr/bin/env python3
-from pathlib import Path
+import os
+import re
 from argparse import ArgumentParser
+from collections import defaultdict
 
+import github
 
-def parse_latest_changelog(text: str) -> str:
-    """Read the contents between the first `##` and the second `##`"""
-    recording = False
-    contents: list[str] = []
-    for line in text.splitlines():
-        if line.strip().startswith("## ") and recording is False:
-            recording = True
-        elif line.strip().startswith("## ") and recording is True:
-            break
-        if recording:
-            contents.append(line)
+docmap = {
+    "Enhancement": "改进功能",
+    "Document": "文档相关",
+    "Refactor": "开发重构",
+    "Bug": "修复缺陷",
+    "Features": "引入特性",
+    "Abolishments": "移除功能"
+}
 
-    return "\n".join(contents[1:])
 
+def generate_msg_from_repo(repo_name, tag_name):
+    """Generate changelog messages from repository and tag name.
 
-def get_changelog() -> str:
-    parser = ArgumentParser(description="Get the latest change log from CHANG_LOGS.md")
-    parser.add_argument("changelog_file", help="The path of CHANGE_LOGS.md")
-    args = parser.parse_args()
-    with Path(args.changelog_file).open() as f:
-        return f.read()
+    Envs:
+        GITHUB_HOST: the custom github host.
+        GITHUB_TOKEN: the github access token.
+
+    Args:
+        repo_name (str): The repository name
+        tag_name (str): the tag name
+    """
+    hostname = os.getenv("GITHUB_HOST") or "api.github.com"
+    token = os.getenv("GITHUB_TOKEN")
+    desc_mapping = defaultdict(list)
+
+    gh = github.Github(token, base_url=f"https://{hostname}")
+    repo = gh.get_repo(repo_name)
+    milestone = find_milestone(repo, tag_name)
+
+    for issue in repo.get_issues(state="closed", milestone=milestone):
+        desc_mapping[get_issue_first_label(issue)].append(
+            {"title": issue.title, "url": issue.url}
+        )
+    generate_msg(desc_mapping)
+
+
+def find_milestone(repo, title):
+    """Find the milestone in a repository that is similar to milestone title
+
+    Args:
+        repo (github.repository.Repository): The repository to search
+        title (str): the title to match
 
+    Returns:
+        The milestone which title matches the given argument.
+        If no milestone matches, it will return None
+    """
+    pat = re.search("v([0-9.]+)", title)
+    if not pat:
+        return None
+    version = pat.group(1)
+    for milestone in repo.get_milestones():
+        if version in milestone.title:
+            return milestone
+
+
+def get_issue_first_label(issue):
+    """Get the first label from issue, if no labels, return empty string."""
+    for label in issue.get_labels():
+        if label.name in docmap:
+            return label.name
+    return ""
+
+
+def generate_msg(desc_mapping):
+    """Print changelogs from direction."""
+    print()
+    for header in docmap:
+        if not desc_mapping[header]:
+            continue
+        print(f"### {docmap[header]}\n")
+        for item in desc_mapping[header]:
+            print(f"* [{item['title']}]({item['url']})")
+        print()
+
+
+if __name__ == "__main__":
+    parser = ArgumentParser(
+        description="Automaticly generate information from issues by tag."
+    )
+    parser.add_argument("-t", "--tag", help="the tag to filter issues.")
+    parser.add_argument("repo", help="The repository name")
+    args = parser.parse_args()
 
-if __name__ == '__main__':
-    changelog = get_changelog()
-    latest_changelog = parse_latest_changelog(changelog)
-    print(latest_changelog)
+    try:
+        generate_msg_from_repo(args.repo, args.tag)
+    except AssertionError:
+        print(args.tag)