-
Notifications
You must be signed in to change notification settings - Fork 45
feat: include past 3 versions in Google Play release notes #181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -612,7 +612,10 @@ jobs: | |||||||||||||||
| run: | | ||||||||||||||||
| mkdir -p whatsnew | ||||||||||||||||
|
|
||||||||||||||||
| # Define shared functions (duplicated from release job since jobs run in isolation) | ||||||||||||||||
| # Google Play whatsnew character limit | ||||||||||||||||
| MAX_CHARS=500 | ||||||||||||||||
|
|
||||||||||||||||
| # Define shared functions | ||||||||||||||||
| cat > /tmp/release_functions.sh << 'FUNCTIONS_EOF' | ||||||||||||||||
| # Function to categorize commit message | ||||||||||||||||
| categorize_commit() { | ||||||||||||||||
|
|
@@ -652,221 +655,169 @@ jobs: | |||||||||||||||
| echo "$category:$cleaned_msg" | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| # Function to get GitHub username from commit | ||||||||||||||||
| get_github_username() { | ||||||||||||||||
| local commit_sha="$1" | ||||||||||||||||
| local github_repo="${GITHUB_REPOSITORY}" | ||||||||||||||||
| # Try to get the GitHub username from the commit using gh api | ||||||||||||||||
| local username=$(gh api "repos/${github_repo}/commits/${commit_sha}" --jq '.author.login // empty' 2>/dev/null || echo "") | ||||||||||||||||
| if [ -n "$username" ]; then | ||||||||||||||||
| echo "@$username" | ||||||||||||||||
| else | ||||||||||||||||
| # Fallback: try to get committer login if author login is not available | ||||||||||||||||
| local committer=$(gh api "repos/${github_repo}/commits/${commit_sha}" --jq '.committer.login // empty' 2>/dev/null || echo "") | ||||||||||||||||
| if [ -n "$committer" ]; then | ||||||||||||||||
| echo "@$committer" | ||||||||||||||||
| else | ||||||||||||||||
| # Last resort: use hardcoded mapping for known authors | ||||||||||||||||
| local git_author=$(git show -s --format='%an' $commit_sha) | ||||||||||||||||
| case "$git_author" in | ||||||||||||||||
| "Gray Zhang" | "gray" | "Gray") | ||||||||||||||||
| echo "@graycreate" | ||||||||||||||||
| ;; | ||||||||||||||||
| "github-actions[bot]") | ||||||||||||||||
| echo "@github-actions[bot]" | ||||||||||||||||
| ;; | ||||||||||||||||
| *) | ||||||||||||||||
| # If no mapping found, use git author name without @ | ||||||||||||||||
| echo "$git_author" | ||||||||||||||||
| ;; | ||||||||||||||||
| esac | ||||||||||||||||
| fi | ||||||||||||||||
| fi | ||||||||||||||||
| } | ||||||||||||||||
| FUNCTIONS_EOF | ||||||||||||||||
| # Function to collect commits for a version range | ||||||||||||||||
| collect_version_commits() { | ||||||||||||||||
| local range="$1" | ||||||||||||||||
| local -n feat_ref=$2 | ||||||||||||||||
| local -n bug_ref=$3 | ||||||||||||||||
| local -n improve_ref=$4 | ||||||||||||||||
| local -n perf_ref=$5 | ||||||||||||||||
|
|
||||||||||||||||
| # Source the shared functions | ||||||||||||||||
| source /tmp/release_functions.sh | ||||||||||||||||
| while IFS= read -r line; do | ||||||||||||||||
| [ -z "$line" ] && continue | ||||||||||||||||
| sha=$(echo "$line" | cut -d' ' -f1) | ||||||||||||||||
| msg=$(echo "$line" | cut -d' ' -f2-) | ||||||||||||||||
|
|
||||||||||||||||
| # Get commits since last tag for categorization | ||||||||||||||||
| LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | ||||||||||||||||
| # Skip version bump and merge commits | ||||||||||||||||
| if [[ "$msg" =~ "bump version" ]] || [[ "$msg" =~ "Merge pull request" ]] || [[ "$msg" =~ "Merge branch" ]]; then | ||||||||||||||||
| continue | ||||||||||||||||
| fi | ||||||||||||||||
|
|
||||||||||||||||
| # Collect and categorize commits | ||||||||||||||||
| declare -A features | ||||||||||||||||
| declare -A bugs | ||||||||||||||||
| declare -A improvements | ||||||||||||||||
| declare -A performance | ||||||||||||||||
| declare -A contributors | ||||||||||||||||
| categorized=$(categorize_commit "$msg") | ||||||||||||||||
| category=$(echo "$categorized" | cut -d':' -f1) | ||||||||||||||||
| clean_msg=$(echo "$categorized" | cut -d':' -f2-) | ||||||||||||||||
|
|
||||||||||||||||
| if [ -n "$LAST_TAG" ]; then | ||||||||||||||||
| RANGE="$LAST_TAG..HEAD" | ||||||||||||||||
| else | ||||||||||||||||
| RANGE="HEAD~5..HEAD" | ||||||||||||||||
| fi | ||||||||||||||||
| case "$category" in | ||||||||||||||||
| feature) feat_ref["$clean_msg"]=1 ;; | ||||||||||||||||
| bug) bug_ref["$clean_msg"]=1 ;; | ||||||||||||||||
| improvement) improve_ref["$clean_msg"]=1 ;; | ||||||||||||||||
| performance) perf_ref["$clean_msg"]=1 ;; | ||||||||||||||||
| esac | ||||||||||||||||
| done < <(git log --oneline --no-merges $range 2>/dev/null) | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| # Process commits | ||||||||||||||||
| while IFS= read -r line; do | ||||||||||||||||
| sha=$(echo "$line" | cut -d' ' -f1) | ||||||||||||||||
| msg=$(echo "$line" | cut -d' ' -f2-) | ||||||||||||||||
| # Function to generate version notes (compact format for Google Play) | ||||||||||||||||
| generate_version_notes() { | ||||||||||||||||
| local -n feat=$1 | ||||||||||||||||
| local -n bugs=$2 | ||||||||||||||||
| local -n improve=$3 | ||||||||||||||||
| local -n perf=$4 | ||||||||||||||||
| local output="" | ||||||||||||||||
|
|
||||||||||||||||
| # Skip version bump and merge commits | ||||||||||||||||
| if [[ "$msg" =~ "bump version" ]] || [[ "$msg" =~ "Merge pull request" ]] || [[ "$msg" =~ "Merge branch" ]]; then | ||||||||||||||||
| continue | ||||||||||||||||
| if [ ${#feat[@]} -gt 0 ]; then | ||||||||||||||||
| for msg in "${!feat[@]}"; do | ||||||||||||||||
| output+="• $msg"$'\n' | ||||||||||||||||
| done | ||||||||||||||||
| fi | ||||||||||||||||
|
|
||||||||||||||||
| categorized=$(categorize_commit "$msg") | ||||||||||||||||
| category=$(echo "$categorized" | cut -d':' -f1) | ||||||||||||||||
| clean_msg=$(echo "$categorized" | cut -d':' -f2-) | ||||||||||||||||
|
|
||||||||||||||||
| # Get author for this commit | ||||||||||||||||
| author=$(get_github_username "$sha") | ||||||||||||||||
| if [ -n "$author" ]; then | ||||||||||||||||
| contributors["$author"]="1" | ||||||||||||||||
| if [ ${#bugs[@]} -gt 0 ]; then | ||||||||||||||||
| for msg in "${!bugs[@]}"; do | ||||||||||||||||
| output+="• $msg"$'\n' | ||||||||||||||||
| done | ||||||||||||||||
| fi | ||||||||||||||||
| if [ ${#improve[@]} -gt 0 ]; then | ||||||||||||||||
| for msg in "${!improve[@]}"; do | ||||||||||||||||
| output+="• $msg"$'\n' | ||||||||||||||||
| done | ||||||||||||||||
| fi | ||||||||||||||||
| if [ ${#perf[@]} -gt 0 ]; then | ||||||||||||||||
| for msg in "${!perf[@]}"; do | ||||||||||||||||
| output+="• $msg"$'\n' | ||||||||||||||||
| done | ||||||||||||||||
| fi | ||||||||||||||||
| echo "$output" | ||||||||||||||||
|
||||||||||||||||
| echo "$output" | |
| if [ -z "$output" ]; then | |
| # Explicitly handle the case where there are no version notes | |
| echo "" | |
| else | |
| echo "$output" | |
| fi |
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The associative arrays are redeclared inside the loop without being cleared between iterations. In bash, when you declare -A an existing associative array, it doesn't clear its contents. This means commits from previous iterations will accumulate in the arrays, leading to duplicate entries in the release notes for version i=1.
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The associative arrays are redeclared inside the loop without being cleared between iterations. In bash, when you declare -A an existing associative array, it doesn't clear its contents. This means commits from previous iterations will accumulate in the arrays, leading to duplicate entries in the release notes for version i=1.
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loop logic for handling the last tag (when i+1 >= number of tags) uses ${TAGS[$i]}~5..${TAGS[$i]} which gets commits leading up to the tag, not commits between tags. This will show the wrong commits for the oldest version in the release notes. The range should be from the previous tag (or an appropriate earlier reference) to ${TAGS[$i]}.
| # Last tag - get commits before it | |
| declare -A prev_features prev_bugs prev_improvements prev_performance | |
| collect_version_commits "${TAGS[$i]}~5..${TAGS[$i]}" prev_features prev_bugs prev_improvements prev_performance | |
| # Last tag - get commits from repository root to this tag | |
| declare -A prev_features prev_bugs prev_improvements prev_performance | |
| collect_version_commits "$(git rev-list --max-parents=0 ${TAGS[$i]})..${TAGS[$i]}" prev_features prev_bugs prev_improvements prev_performance |
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loop iterates over indices 0 and 1 to collect previous versions, but the condition checks if i < ${#TAGS[@]} which may cause issues. When TAGS has only 1 element (index 0), the loop will try to access TAGS[1] in the first condition branch, which doesn't exist. The loop should handle the case where there are fewer than 3 tags more carefully.
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The character counting logic is incorrect. wc -c counts bytes, not characters. For multi-byte UTF-8 characters (like Chinese characters in the feedback header "唯一问题反馈渠道"), this will count multiple bytes per character. However, ${#notes} counts characters correctly. This mismatch means the character limit enforcement may be inaccurate - the initial length calculation uses byte count while the subsequent additions use character count.
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The character limit check adds 2 to account for newlines, but this is inconsistent. When writing to the file with echo "$notes", bash adds a single newline character (1 byte), not 2. This will cause the actual file size to be smaller than the calculated CURRENT_LEN, leading to inaccurate character limit enforcement.
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The character counting logic is incorrect. wc -c counts bytes, not characters. For multi-byte UTF-8 characters (like Chinese characters in the feedback header "唯一问题反馈渠道"), this will count multiple bytes per character. However, ${#notes} counts characters correctly. This mismatch means the character limit enforcement may be inaccurate - the initial length calculation uses byte count while the subsequent additions use character count.
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The character limit check adds 2 to account for newlines, but this is inconsistent. When writing to the file with echo "$notes", bash adds a single newline character (1 byte), not 2. This will cause the actual file size to be smaller than the calculated CURRENT_LEN, leading to inaccurate character limit enforcement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable naming is inconsistent. In
generate_version_notes, the parameter references usebugs(line 692) but in the function body it's referenced as${#bugs[@]}(line 702). The array is passed asbug_refincollect_version_commits(line 662) and assigned fromcurr_bugs,prev_bugs, etc. The naming should be consistent - either usebugseverywhere orbugeverywhere to match the pattern offeat/improve/perf.