format-changelog.sh 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/bin/bash
  2. set -euo pipefail
  3. shopt -s nullglob
  4. export LANG=C.UTF-8
  5. [ "${DEBUG:-}" = 1 ] && set -x
  6. logerr() {
  7. echo "$(tput setaf 1)ERROR: $1$(tput sgr0)" 1>&2
  8. }
  9. usage() {
  10. cat <<EOF
  11. $0 [option]
  12. options:
  13. -h|--help: print this usages info
  14. -b|--base:
  15. The git tag of compare base to find included changes.
  16. e.g. v5.0.18, e5.0.0 etc.
  17. -v|--version:
  18. The tag to be released
  19. e.g. v5.0.19, e5.0.1-alpha.1 etc.
  20. EOF
  21. }
  22. while [ "$#" -gt 0 ]; do
  23. case $1 in
  24. -h|--help)
  25. usage
  26. exit 0
  27. ;;
  28. -b|--base)
  29. shift
  30. BASE_TAG="$1"
  31. shift
  32. ;;
  33. -v|--version)
  34. shift
  35. TEMPLATE_VSN_HEADING="$1"
  36. shift
  37. ;;
  38. *)
  39. logerr "Unknown option $1"
  40. exit 1
  41. ;;
  42. esac
  43. done
  44. LANGUAGE='en'
  45. case "${BASE_TAG:-}" in
  46. v*)
  47. PROFILE="emqx"
  48. ;;
  49. e*)
  50. PROFILE="emqx-enterprise"
  51. ;;
  52. *)
  53. logerr "Unsupported -b|--base option, must be v* or e*"
  54. exit 1
  55. ;;
  56. esac
  57. TEMPLATE_VSN_HEADING="${TEMPLATE_VSN_HEADING:-<VSN-TAG>}"
  58. top_dir="$(git rev-parse --show-toplevel)"
  59. declare -a PRS
  60. PRS=("")
  61. format_one_pr() {
  62. local filename pr_num indent
  63. filename="${1}"
  64. pr_num="$(echo "${filename}" | sed -E 's/.*-([0-9]+)\.[a-z]+\.md$/\1/')"
  65. re='^[0-9]+$'
  66. if ! [[ $pr_num =~ $re ]]; then
  67. logerr "bad filename format: $filename"
  68. fi
  69. indent="- [#${pr_num}](https://github.com/emqx/emqx/pull/${pr_num}) "
  70. while read -r line; do
  71. if [ "${line}" != '' ]; then
  72. echo "${indent}${line}"
  73. else
  74. echo ''
  75. fi
  76. indent=" "
  77. done < "${filename}"
  78. echo
  79. }
  80. section() {
  81. local prefix=$1
  82. for file in "${PRS[@]}"; do
  83. if [[ $file =~ .*$prefix-.*$LANGUAGE.md ]]; then
  84. format_one_pr "$file"
  85. fi
  86. done
  87. }
  88. changes_dir=("$top_dir/changes/ce")
  89. if [ "$PROFILE" == "emqx-enterprise" ]; then
  90. changes_dir+=("$top_dir/changes/ee")
  91. fi
  92. while read -r file; do
  93. PRS+=("$file")
  94. done < <(git diff --diff-filter=A --name-only "tags/${BASE_TAG}...HEAD" "${changes_dir[@]}")
  95. TEMPLATE_FEAT_CHANGES="$(section 'feat')"
  96. TEMPLATE_PERF_CHANGES="$(section 'perf')"
  97. TEMPLATE_FIX_CHANGES="$(section 'fix')"
  98. TEMPLATE_BREAKING_CHANGES="$(section 'breaking')"
  99. TEMPLATE_ENH_HEADING="Enhancements"
  100. TEMPLATE_FIX_HEADING="Bug Fixes"
  101. TEMPLATE_BREAKING_HEADING="Breaking Changes"
  102. cat <<EOF
  103. # ${TEMPLATE_VSN_HEADING}
  104. ## ${TEMPLATE_ENH_HEADING}
  105. ${TEMPLATE_FEAT_CHANGES}
  106. ${TEMPLATE_PERF_CHANGES}
  107. ## ${TEMPLATE_FIX_HEADING}
  108. ${TEMPLATE_FIX_CHANGES}
  109. ## ${TEMPLATE_BREAKING_HEADING}
  110. ${TEMPLATE_BREAKING_CHANGES}
  111. EOF