ci(forgejo): group release notes by prefix and fork vs merges
Bucket commits into New/Fix/Improve/Other from conventional-style subjects. When upstream main is available, split direct fork commits from merge commits under separate headings. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
7fab10c8ef
commit
9ce3f0ba29
1 changed files with 126 additions and 12 deletions
|
|
@ -112,18 +112,138 @@ jobs:
|
||||||
git fetch --no-tags --depth=1 "https://github.com/${upstream_repo}.git" "$upstream_base" || true
|
git fetch --no-tags --depth=1 "https://github.com/${upstream_repo}.git" "$upstream_base" || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
use_fork_merge_split=0
|
||||||
|
log_range=""
|
||||||
if [ -n "$upstream_base" ] && git cat-file -e "${upstream_base}^{commit}" 2>/dev/null; then
|
if [ -n "$upstream_base" ] && git cat-file -e "${upstream_base}^{commit}" 2>/dev/null; then
|
||||||
commit_logs="$(git log --pretty=format:'- %s (@%an)' "${upstream_base}..HEAD")"
|
use_fork_merge_split=1
|
||||||
elif [ -n "$previous_tag" ]; then
|
elif [ -n "$previous_tag" ]; then
|
||||||
commit_logs="$(git log --pretty=format:'- %s (@%an)' "${previous_tag}..HEAD")"
|
log_range="${previous_tag}..HEAD"
|
||||||
|
fi
|
||||||
|
|
||||||
|
commit_log_file="$(mktemp /tmp/komikku-commit-logs.XXXXXX)"
|
||||||
|
declare -a new_lines fix_lines improve_lines other_lines
|
||||||
|
|
||||||
|
bucket_for_subject() {
|
||||||
|
local s="$1"
|
||||||
|
local b=other
|
||||||
|
shopt -s nocasematch
|
||||||
|
local r_feat r_feature r_add r_fix r_perf r_refactor r_chore r_docs r_style r_test r_ci r_build r_improve
|
||||||
|
r_feat='^feat\([^)]*\):'
|
||||||
|
r_feature='^feature\([^)]*\):'
|
||||||
|
r_add='^add\([^)]*\):'
|
||||||
|
r_fix='^fix\([^)]*\):'
|
||||||
|
r_perf='^perf\([^)]*\):'
|
||||||
|
r_refactor='^refactor\([^)]*\):'
|
||||||
|
r_chore='^chore\([^)]*\):'
|
||||||
|
r_docs='^docs\([^)]*\):'
|
||||||
|
r_style='^style\([^)]*\):'
|
||||||
|
r_test='^test\([^)]*\):'
|
||||||
|
r_ci='^ci\([^)]*\):'
|
||||||
|
r_build='^build\([^)]*\):'
|
||||||
|
r_improve='^improve\([^)]*\):'
|
||||||
|
if [[ "$s" =~ ^feat: ]] || [[ "$s" =~ $r_feat ]]; then b=new
|
||||||
|
elif [[ "$s" =~ ^feature: ]] || [[ "$s" =~ $r_feature ]]; then b=new
|
||||||
|
elif [[ "$s" =~ ^add: ]] || [[ "$s" =~ $r_add ]]; then b=new
|
||||||
|
elif [[ "$s" =~ ^fix: ]] || [[ "$s" =~ $r_fix ]]; then b=fix
|
||||||
|
elif [[ "$s" =~ ^perf: ]] || [[ "$s" =~ $r_perf ]]; then b=improve
|
||||||
|
elif [[ "$s" =~ ^refactor: ]] || [[ "$s" =~ $r_refactor ]]; then b=improve
|
||||||
|
elif [[ "$s" =~ ^chore: ]] || [[ "$s" =~ $r_chore ]]; then b=improve
|
||||||
|
elif [[ "$s" =~ ^docs: ]] || [[ "$s" =~ $r_docs ]]; then b=improve
|
||||||
|
elif [[ "$s" =~ ^style: ]] || [[ "$s" =~ $r_style ]]; then b=improve
|
||||||
|
elif [[ "$s" =~ ^test: ]] || [[ "$s" =~ $r_test ]]; then b=improve
|
||||||
|
elif [[ "$s" =~ ^ci: ]] || [[ "$s" =~ $r_ci ]]; then b=improve
|
||||||
|
elif [[ "$s" =~ ^build: ]] || [[ "$s" =~ $r_build ]]; then b=improve
|
||||||
|
elif [[ "$s" =~ ^improve: ]] || [[ "$s" =~ $r_improve ]]; then b=improve
|
||||||
|
fi
|
||||||
|
shopt -u nocasematch
|
||||||
|
printf '%s' "$b"
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_buckets() {
|
||||||
|
new_lines=() fix_lines=() improve_lines=() other_lines=()
|
||||||
|
}
|
||||||
|
|
||||||
|
fill_buckets_from_git() {
|
||||||
|
local rev_range="$1"
|
||||||
|
shift
|
||||||
|
while IFS= read -r line || [ -n "${line:-}" ]; do
|
||||||
|
[ -z "${line:-}" ] && continue
|
||||||
|
subject="${line%%$'\x1f'*}"
|
||||||
|
author="${line#*$'\x1f'}"
|
||||||
|
entry="- ${subject} (@${author})"
|
||||||
|
case "$(bucket_for_subject "$subject")" in
|
||||||
|
new) new_lines+=("$entry") ;;
|
||||||
|
fix) fix_lines+=("$entry") ;;
|
||||||
|
improve) improve_lines+=("$entry") ;;
|
||||||
|
*) other_lines+=("$entry") ;;
|
||||||
|
esac
|
||||||
|
done < <(git log "$@" --pretty=tformat:'%s%x1f%an' "$rev_range")
|
||||||
|
}
|
||||||
|
|
||||||
|
emit_buckets_from_arrays() {
|
||||||
|
local any=0
|
||||||
|
if [ ${#new_lines[@]} -gt 0 ]; then
|
||||||
|
printf '%s\n' "##### New" ""
|
||||||
|
printf '%s\n' "${new_lines[@]}"
|
||||||
|
printf '\n'
|
||||||
|
any=1
|
||||||
|
fi
|
||||||
|
if [ ${#fix_lines[@]} -gt 0 ]; then
|
||||||
|
printf '%s\n' "##### Fix" ""
|
||||||
|
printf '%s\n' "${fix_lines[@]}"
|
||||||
|
printf '\n'
|
||||||
|
any=1
|
||||||
|
fi
|
||||||
|
if [ ${#improve_lines[@]} -gt 0 ]; then
|
||||||
|
printf '%s\n' "##### Improve" ""
|
||||||
|
printf '%s\n' "${improve_lines[@]}"
|
||||||
|
printf '\n'
|
||||||
|
any=1
|
||||||
|
fi
|
||||||
|
if [ ${#other_lines[@]} -gt 0 ]; then
|
||||||
|
printf '%s\n' "##### Other" ""
|
||||||
|
printf '%s\n' "${other_lines[@]}"
|
||||||
|
printf '\n'
|
||||||
|
any=1
|
||||||
|
fi
|
||||||
|
[ "$any" -eq 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$use_fork_merge_split" -eq 1 ]; then
|
||||||
|
{
|
||||||
|
printf '%s\n' "#### Fork changes" ""
|
||||||
|
clear_buckets
|
||||||
|
fill_buckets_from_git "${upstream_base}..HEAD" --no-merges
|
||||||
|
if [ ${#new_lines[@]} -eq 0 ] && [ ${#fix_lines[@]} -eq 0 ] && [ ${#improve_lines[@]} -eq 0 ] && [ ${#other_lines[@]} -eq 0 ]; then
|
||||||
|
printf '%s\n' "_No direct commits in this range._" ""
|
||||||
|
else
|
||||||
|
emit_buckets_from_arrays
|
||||||
|
fi
|
||||||
|
|
||||||
|
clear_buckets
|
||||||
|
fill_buckets_from_git "${upstream_base}..HEAD" --merges
|
||||||
|
if [ ${#new_lines[@]} -gt 0 ] || [ ${#fix_lines[@]} -gt 0 ] || [ ${#improve_lines[@]} -gt 0 ] || [ ${#other_lines[@]} -gt 0 ]; then
|
||||||
|
printf '%s\n' "#### Merge commits" ""
|
||||||
|
emit_buckets_from_arrays
|
||||||
|
printf '\n'
|
||||||
|
fi
|
||||||
|
} > "${commit_log_file}"
|
||||||
|
elif [ -n "$log_range" ]; then
|
||||||
|
clear_buckets
|
||||||
|
fill_buckets_from_git "$log_range"
|
||||||
|
{
|
||||||
|
if emit_buckets_from_arrays; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
printf '%s\n' "##### Other" "" "- Initial release" ""
|
||||||
|
fi
|
||||||
|
} > "${commit_log_file}"
|
||||||
else
|
else
|
||||||
commit_logs='- Initial release'
|
printf '%s\n' "##### Other" "" "- Initial release" "" > "${commit_log_file}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Do not pass multiline commit text via step outputs / env (breaks some Forgejo/act_runner
|
# Do not pass multiline commit text via step outputs / env (breaks some Forgejo/act_runner
|
||||||
# runners before the shell starts — empty logs). Only pass a temp file path.
|
# runners before the shell starts — empty logs). Only pass a temp file path.
|
||||||
commit_log_file="$(mktemp /tmp/komikku-commit-logs.XXXXXX)"
|
|
||||||
printf '%s\n' "$commit_logs" > "${commit_log_file}"
|
|
||||||
echo "COMMIT_LOG_FILE=${commit_log_file}" >> "${GITHUB_ENV}"
|
echo "COMMIT_LOG_FILE=${commit_log_file}" >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
- name: Set up Gradle
|
- name: Set up Gradle
|
||||||
|
|
@ -395,7 +515,7 @@ jobs:
|
||||||
fi
|
fi
|
||||||
commit_logs="$(printf '%s' "$commit_logs" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
commit_logs="$(printf '%s' "$commit_logs" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
||||||
if [ -z "$commit_logs" ]; then
|
if [ -z "$commit_logs" ]; then
|
||||||
commit_logs="- Initial release"
|
commit_logs=$'##### Other\n\n- Initial release\n'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
full_changelog=""
|
full_changelog=""
|
||||||
|
|
@ -412,12 +532,6 @@ jobs:
|
||||||
printf '%s\n' \
|
printf '%s\n' \
|
||||||
"#### What's Changed" \
|
"#### What's Changed" \
|
||||||
"" \
|
"" \
|
||||||
"##### New" \
|
|
||||||
"" \
|
|
||||||
"##### Improve" \
|
|
||||||
"" \
|
|
||||||
"##### Fix" \
|
|
||||||
"" \
|
|
||||||
"${commit_logs}" \
|
"${commit_logs}" \
|
||||||
"" \
|
"" \
|
||||||
"##### Based on" \
|
"##### Based on" \
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue