mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-02 22:21:28 +08:00
🎨 更新 parse-changelog 工作流 (#11289)
This commit is contained in:
parent
291a083378
commit
5095d836c0
10
.github/workflows/cd.yml
vendored
10
.github/workflows/cd.yml
vendored
@ -29,10 +29,10 @@ jobs:
|
|||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.11"
|
||||||
- run: pip install PyGithub
|
- run: pip install PyGithub
|
||||||
|
|
||||||
- id: thislatestR
|
- id: thisLatestRelease
|
||||||
uses: pozetroninc/github-action-get-latest-release@master
|
uses: pozetroninc/github-action-get-latest-release@master
|
||||||
with:
|
with:
|
||||||
# owner: siyuan-note
|
# owner: siyuan-note
|
||||||
@ -46,9 +46,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "release_title=$(git show --format=%s --no-patch | head -1)" >> $GITHUB_OUTPUT
|
echo "release_title=$(git show --format=%s --no-patch | head -1)" >> $GITHUB_OUTPUT
|
||||||
echo "release_version=$(TZ=Asia/Shanghai date +'v%Y%m%d%H%M')" >> $GITHUB_OUTPUT
|
echo "release_version=$(TZ=Asia/Shanghai date +'v%Y%m%d%H%M')" >> $GITHUB_OUTPUT
|
||||||
changelog=$(python scripts/parse-changelog.py -t ${{ github.ref }} -b ${{ steps.thislatestR.outputs.release }} ${{ env.repo_owner }}/${{ env.repo_name }})
|
changelog_header=$(python scripts/parse-changelog-HEAD.py -t ${{ github.ref }} -b ${{ steps.thisLatestRelease.outputs.release }} ${{ env.repo_owner }}/${{ env.repo_name }})
|
||||||
|
changelog=$(python scripts/parse-changelog.py -t ${{ github.ref }} ${{ env.repo_owner }}/${{ env.repo_name }})
|
||||||
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
|
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
|
||||||
echo "release_body<<$EOF" >> $GITHUB_ENV
|
echo "release_body<<$EOF" >> $GITHUB_ENV
|
||||||
|
echo "$changelog_header" >> $GITHUB_ENV
|
||||||
echo "$changelog" >> $GITHUB_ENV
|
echo "$changelog" >> $GITHUB_ENV
|
||||||
echo "$EOF" >> $GITHUB_ENV
|
echo "$EOF" >> $GITHUB_ENV
|
||||||
env:
|
env:
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -38,3 +38,6 @@ lerna-debug.log*
|
|||||||
# NPM Package
|
# NPM Package
|
||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
|
# workflows
|
||||||
|
**/__pycache__
|
||||||
|
19
scripts/_pkg/Const.py
Normal file
19
scripts/_pkg/Const.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
docmap_siyuan = {
|
||||||
|
"Feature": "Feature",
|
||||||
|
"Enhancement": "Enhancement",
|
||||||
|
"Bug": "Bugfix",
|
||||||
|
"Document": "Document",
|
||||||
|
"Refactor": "Refactor",
|
||||||
|
"Abolishment": "Abolishment",
|
||||||
|
"Development": "Development",
|
||||||
|
}
|
||||||
|
|
||||||
|
repo_siyuan = "siyuan-note/siyuan"
|
||||||
|
hostname = "api.github.com"
|
||||||
|
|
||||||
|
HEADER_siyuan = '''
|
||||||
|
'''
|
||||||
|
|
||||||
|
HEADER = {
|
||||||
|
"siyuan-note/siyuan": HEADER_siyuan,
|
||||||
|
}
|
61
scripts/_pkg/Utils.py
Normal file
61
scripts/_pkg/Utils.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
def find_milestone(repo, title, len=0):
|
||||||
|
"""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
|
||||||
|
len: 版本号长度限制,默认 0 不限制
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The milestone which title matches the given argument.
|
||||||
|
If no milestone matches, it will return None
|
||||||
|
"""
|
||||||
|
thisRelease = title.split("/")[-1]
|
||||||
|
pat = re.search("v([0-9.]+)", thisRelease)
|
||||||
|
if not pat:
|
||||||
|
return None
|
||||||
|
if len > 0:
|
||||||
|
version = ".".join(pat.group(1).split(".")[:len])
|
||||||
|
else:
|
||||||
|
version = ".".join(pat.group(1).split(".")[:])
|
||||||
|
|
||||||
|
# REF https://docs.github.com/en/rest/issues/milestones?apiVersion=2022-11-28#list-milestones
|
||||||
|
for milestone in repo.get_milestones(state="all"):
|
||||||
|
if version in milestone.title:
|
||||||
|
return milestone
|
||||||
|
|
||||||
|
def generate_msg(desc_mapping, docmap):
|
||||||
|
"""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()
|
||||||
|
|
||||||
|
def get_issue_first_label(issue, docmap):
|
||||||
|
"""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_header_from_repo(repo_name, tag_name, lastestRelease, action_file, HEADER=''):
|
||||||
|
thisRelease = tag_name.split("/")[-1]
|
||||||
|
pat = re.search("v([0-9.]+)", thisRelease)
|
||||||
|
if not pat:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return f'''
|
||||||
|
---
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/{repo_name}/actions/workflows/{action_file}"><img src="https://img.shields.io/github/actions/workflow/status/{repo_name}/{action_file}?logo=github&label={action_file}%20Action" style="cursor:pointer;height: 30px;margin: 3px auto;"/></a>
|
||||||
|
<a href="https://github.com/{repo_name}/releases/{thisRelease}/"><img src="https://img.shields.io/github/downloads/{repo_name}/{thisRelease}/total?logo=github" style="cursor:pointer;height: 30px;margin: 3px auto;"/></a>
|
||||||
|
<img alt="GitHub commits difference between two branches/tags/commits" src="https://img.shields.io/github/commits-difference/{repo_name}?base={lastestRelease}&head={thisRelease}&logo=git" style="cursor:pointer;height: 30px;margin: 3px auto;"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{HEADER}'''
|
8
scripts/_pkg/__init__.py
Normal file
8
scripts/_pkg/__init__.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import os,sys
|
||||||
|
if os.path.abspath(os.path.dirname(__file__)) not in sys.path:
|
||||||
|
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
|
||||||
|
PY_DIR = os.path.abspath(os.path.dirname(sys.executable))
|
||||||
|
PYSPP = os.path.abspath(os.path.join(PY_DIR,'Lib', 'site-packages'))
|
||||||
|
if PY_DIR not in sys.path:
|
||||||
|
sys.path.append(PY_DIR)
|
||||||
|
sys.path.append(PYSPP)
|
29
scripts/parse-changelog-HEAD.py
Normal file
29
scripts/parse-changelog-HEAD.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from _pkg import Const as C
|
||||||
|
from _pkg import Utils as U
|
||||||
|
|
||||||
|
def generate_msg_from_repo(repo_name, tag_name, lastestRelease):
|
||||||
|
thisRelease = tag_name.split("/")[-1]
|
||||||
|
pat = re.search("v([0-9.]+)", thisRelease)
|
||||||
|
if not pat:
|
||||||
|
return None
|
||||||
|
|
||||||
|
action_file = "cd.yml"
|
||||||
|
print(U.generate_header_from_repo(repo_name, tag_name, lastestRelease, action_file, C.HEADER[repo_name]))
|
||||||
|
|
||||||
|
|
||||||
|
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("-b", "--lastestRelease", help="lastest Release")
|
||||||
|
parser.add_argument("repo", help="The repository name")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
generate_msg_from_repo(args.repo, args.tag, args.lastestRelease)
|
||||||
|
except AssertionError:
|
||||||
|
print(args.tag)
|
@ -2,21 +2,11 @@ import os
|
|||||||
import re
|
import re
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from _pkg import Const as C
|
||||||
|
from _pkg import Utils as U
|
||||||
|
import github # type: ignore # pip install PyGithub
|
||||||
|
|
||||||
import github # pip install PyGithub
|
def generate_msg_from_repo(repo_name, tag_name):
|
||||||
# ensure the milestone is open before run this
|
|
||||||
docmap = {
|
|
||||||
"Feature": "Feature",
|
|
||||||
"Enhancement": "Enhancement",
|
|
||||||
"Bug": "Bugfix",
|
|
||||||
"Document": "Document",
|
|
||||||
"Refactor": "Refactor",
|
|
||||||
"Abolishment": "Abolishment",
|
|
||||||
"Development": "Development",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def generate_msg_from_repo(repo_name, tag_name, lastestRelease):
|
|
||||||
"""Generate changelog messages from repository and tag name.
|
"""Generate changelog messages from repository and tag name.
|
||||||
|
|
||||||
Envs:
|
Envs:
|
||||||
@ -27,81 +17,30 @@ def generate_msg_from_repo(repo_name, tag_name, lastestRelease):
|
|||||||
repo_name (str): The repository name
|
repo_name (str): The repository name
|
||||||
tag_name (str): the tag name
|
tag_name (str): the tag name
|
||||||
"""
|
"""
|
||||||
hostname = os.getenv("GITHUB_HOST") or "api.github.com"
|
hostname = os.getenv("GITHUB_HOST") or C.hostname
|
||||||
token = os.getenv("GITHUB_TOKEN")
|
token = os.getenv("GITHUB_TOKEN")
|
||||||
desc_mapping = defaultdict(list)
|
desc_mapping = defaultdict(list)
|
||||||
|
|
||||||
gh = github.Github(token, base_url=f"https://{hostname}")
|
gh = github.Github(token, base_url=f"https://{hostname}")
|
||||||
repo = gh.get_repo(repo_name)
|
repo = gh.get_repo(repo_name)
|
||||||
milestone = find_milestone(repo, tag_name, lastestRelease)
|
|
||||||
|
|
||||||
|
milestone = U.find_milestone(repo, tag_name)
|
||||||
for issue in repo.get_issues(state="closed", milestone=milestone): # type: ignore
|
for issue in repo.get_issues(state="closed", milestone=milestone): # type: ignore
|
||||||
# REF https://pygithub.readthedocs.io/en/latest/github_objects/Issue.html#github.Issue.Issue
|
# REF https://pygithub.readthedocs.io/en/latest/github_objects/Issue.html#github.Issue.Issue
|
||||||
desc_mapping[get_issue_first_label(issue)].append(
|
desc_mapping[U.get_issue_first_label(issue, C.docmap_siyuan)].append(
|
||||||
{"title": issue.title, "url": issue.html_url}
|
{"title": issue.title, "url": issue.html_url}
|
||||||
)
|
)
|
||||||
generate_msg(desc_mapping)
|
U.generate_msg(desc_mapping, C.docmap_siyuan)
|
||||||
|
|
||||||
|
|
||||||
def find_milestone(repo, title, lastestRelease):
|
|
||||||
"""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)
|
|
||||||
thisRelease = title.split("/")[-1]
|
|
||||||
if not pat:
|
|
||||||
return None
|
|
||||||
version = pat.group(1)
|
|
||||||
print(f'''
|
|
||||||
<p>
|
|
||||||
<a href="https://github.com/siyuan-note/siyuan/actions/workflows/cd.yml"><img src="https://img.shields.io/github/actions/workflow/status/siyuan-note/siyuan/cd.yml?event=push&label=cd.yml%20Action&logo=github" style="cursor:pointer;height: 30px;margin: 3px auto;"/></a>
|
|
||||||
<a href="https://github.com/siyuan-note/siyuan/releases/{thisRelease}/"><img src="https://img.shields.io/github/downloads/siyuan-note/siyuan/{thisRelease}/total?logo=github" style="cursor:pointer;height: 30px;margin: 3px auto;"/></a>
|
|
||||||
<img alt="GitHub commits difference between two branches/tags/commits" src="https://img.shields.io/github/commits-difference/siyuan-note/siyuan?base={lastestRelease}&head={thisRelease}&logo=git" style="cursor:pointer;height: 30px;margin: 3px auto;"/>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
''')
|
|
||||||
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__":
|
if __name__ == "__main__":
|
||||||
parser = ArgumentParser(
|
parser = ArgumentParser(
|
||||||
description="Automaticly generate information from issues by tag."
|
description="Automaticly generate information from issues by tag."
|
||||||
)
|
)
|
||||||
parser.add_argument("-t", "--tag", help="the tag to filter issues.")
|
parser.add_argument("-t", "--tag", help="the tag to filter issues.")
|
||||||
parser.add_argument("-b", "--lastestRelease", help="lastest Release")
|
|
||||||
parser.add_argument("repo", help="The repository name")
|
parser.add_argument("repo", help="The repository name")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
generate_msg_from_repo(args.repo, args.tag, args.lastestRelease)
|
generate_msg_from_repo(args.repo, args.tag)
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
print(args.tag)
|
print(args.tag)
|
||||||
|
Loading…
Reference in New Issue
Block a user