diff --git a/.github/workflows/changelog.py b/.github/workflows/changelog.py index aaa51abff..abae7a176 100644 --- a/.github/workflows/changelog.py +++ b/.github/workflows/changelog.py @@ -1,82 +1,55 @@ import os -import re import sys -import json -from urllib.error import HTTPError -main_repo_url = "https://github.com/eried/portapack-mayhem.git" -main_repo_identifier = "eried/portapack-mayhem" -# ^^&^ change these if main repo changed +import requests +from datetime import datetime, timedelta, timezone -os.system('gh repo set-default ' + main_repo_url) - -raw_git = os.popen('git log next --since="24 hours" --pretty=format:"- ^%h^ - {USERNAME}*_%al_%an*: %s"').read() +# Set up your personal access token and the repository details +token = os.environ.get('GH_TOKEN') +repo_owner = "eried" +repo_name = "portapack-mayhem" -# ^ as github's rule, a real username can contains "-" but not "_" and "*", so use these two to seperate things. -# ^ during test at 2023-07-10, %al could return 3 different types of values: -# : 123+abc <<<< abc is real username -# : def <<<< def is 3rd level domain of unhidden email, drop this, fetch info from github cli client -# : note that github will probably change in the future +def print_stable_changelog(previous_sha): + url = f"compare/{previous_sha}...next" + commits = handle_get_request(url) + for commit in commits["commits"]: + # Print the commit details + print(format_output(commit)) -def compute_username(line): - line_org = line - stripped = re.search(r'(?<=\*)(.*?)(?=\*)', line).group(0) # get the string between "*" and "*" - now_item_hash = re.search(r'(?<=\^)(.*?)(?=\^)', line).group(0) # get the string between "*" and "*" - stripped_org = stripped - stripped = re.search(r'(?<=\_)(.*?)(?=\_)', stripped).group(0) # get the string between "_" and "_" - stripped_fallback = stripped - # now it's like "123+abc" or "def" - - if ("+" in stripped): # 123+abc - stripped = re.sub(r'^.*?\+', "", stripped) - elif not ("+" in stripped): # maybe not real username, dropped, fetch from github cli client - fetched_now_item_json = os.popen( - 'gh search commits repo:' + main_repo_identifier + ' --json author --hash ' + now_item_hash).read() - stripped = extract_first_login(fetched_now_item_json) - if stripped is False: # 403 - return "@" + stripped_fallback - elif stripped == "app/": # user did their commit with github app - return "@" + stripped_fallback - else: # exception and edge cases - return "@" + stripped_fallback - - if stripped is None: # if commit hash can't find AKA commit is only in fork - return "@" + stripped_fallback - - return "@" + stripped +def print_nightly_changelog(): + # Calculate the date and time 24 hours ago + since_time = (datetime.now(timezone.utc) - timedelta(hours=24)).isoformat() # Check that this is UTC + url = "commits" + commits = handle_get_request(url, since_time) + for commit in commits: + # Print the commit details + print(format_output(commit)) -def compile_line(line): - username = compute_username(line) - line = re.sub(r'[*].*[*]', "", line) - line = line.replace("{USERNAME}", username) - line = re.sub(r'\^', '', line, count=2) - - return line - - -def extract_first_login(json_data): - if not json_data: # if returned null - return None - - try: - data = json.loads(json_data) - - if isinstance(data, list) and len(data) > 0: - first_object = data[0] - if 'author' in first_object and 'login' in first_object['author']: - return first_object['author']['login'] - - except HTTPError as e: - if e.code == 403 and "API rate limit exceeded" in str(e): - return False - except json.decoder.JSONDecodeError: - return None +def handle_get_request(path, offset=None): + headers = {"Authorization": f"Bearer {token}"} + params = {"since": offset} + url_base = f"https://api.github.com/repos/{repo_owner}/{repo_name}/" + response = requests.get(url_base + path, headers=headers, params=params) + # Check if the request was successful (status code 200) + if response.status_code == 200: + return response.json() + else: + print(f"Request failed with status code: {response.status_code}") return None -for row in raw_git.splitlines(): - print(compile_line(row)) +def format_output(commit): + message_lines = commit["commit"]["message"].split("\n") + author = commit["author"]["login"] if commit["author"] and "login" in commit["author"] else commit["commit"]["author"]["name"] + return '- ' + commit["sha"][:8] + ' - @' + author + ': ' + message_lines[0] + + +if len(sys.argv) < 2: + print_nightly_changelog() +else: + past_version = sys.argv[1] + print_stable_changelog(past_version) diff --git a/.github/workflows/create_stable_release.yml b/.github/workflows/create_stable_release.yml index 9a81e9a04..bf22fe303 100644 --- a/.github/workflows/create_stable_release.yml +++ b/.github/workflows/create_stable_release.yml @@ -50,7 +50,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GH_TOKEN }} run: | - CHANGELOG=$(python3 .github/workflows/stable_changelog.py ${{ steps.past_version.outputs.past_version }}) + CHANGELOG=$(python3 .github/workflows/changelog.py ${{ steps.past_version.outputs.past_version }}) CHANGELOG="${CHANGELOG//'%'/'%25'}" CHANGELOG="${CHANGELOG//$'\n'/'%0A'}" CHANGELOG="${CHANGELOG//$'\r'/'%0D'}" diff --git a/.github/workflows/stable_changelog.py b/.github/workflows/stable_changelog.py deleted file mode 100644 index 438becb94..000000000 --- a/.github/workflows/stable_changelog.py +++ /dev/null @@ -1,84 +0,0 @@ -import os -import re -import sys -import json -from urllib.error import HTTPError - -past_version = sys.argv[1] - -main_repo_url = "https://github.com/eried/portapack-mayhem.git" -main_repo_identifier = "eried/portapack-mayhem" -# ^^&^ change these if main repo changed - -os.system('gh repo set-default ' + main_repo_url) - -raw_git = os.popen('git log ' + past_version + '..next --pretty=format:"- ^%h^ - {USERNAME}*_%al_%an*: %s"').read() - - -# ^ as github's rule, a real username can contains "-" but not "_" and "*", so use these two to seperate things - -# during test at 2023-07-10, %al could return 3 different types of values: -# 123+abc <<<< abc is real username -# def <<<< def is 3rd level domain of unhidden email, drop this, fetch info from github cli client -# note that github will probably change in the future - -def compute_username(line): - line_org = line - stripped = re.search(r'(?<=\*)(.*?)(?=\*)', line).group(0) # get the string between "*" and "*" - now_item_hash = re.search(r'(?<=\^)(.*?)(?=\^)', line).group(0) # get the string between "*" and "*" - stripped_org = stripped - stripped = re.search(r'(?<=\_)(.*?)(?=\_)', stripped).group(0) # get the string between "_" and "_" - stripped_fallback = stripped - # now it's like "123+abc" or "def" - - if ("+" in stripped): # 123+abc - stripped = re.sub(r'^.*?\+', "", stripped) - elif not ("+" in stripped): # maybe not real username, dropped, fetch from github cli client - fetched_now_item_json = os.popen( - 'gh search commits repo:' + main_repo_identifier + ' --json author --hash ' + now_item_hash).read() - stripped = extract_first_login(fetched_now_item_json) - if stripped is False: # 403 - return "@" + stripped_fallback - elif stripped == "app/": - return "@" + stripped_fallback - else: # exception and edge cases - return "@" + stripped_fallback - - if stripped is None: # if commit hash can't find AKA commit is only in fork - return "@" + stripped_fallback - - return "@" + stripped - - -def compile_line(line): - username = compute_username(line) - line = re.sub(r'[*].*[*]', "", line) - line = line.replace("{USERNAME}", username) - line = re.sub(r'\^', '', line, count=2) - - return line - - -def extract_first_login(json_data): - if not json_data: # if returned null - return None - - try: - data = json.loads(json_data) - - if isinstance(data, list) and len(data) > 0: - first_object = data[0] - if 'author' in first_object and 'login' in first_object['author']: - return first_object['author']['login'] - - except HTTPError as e: - if e.code == 403 and "API rate limit exceeded" in str(e): - return False - except json.decoder.JSONDecodeError: - return None - - return None - - -for row in raw_git.splitlines(): - print(compile_line(row))