format-changelog.sh 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. -l|--lang: en | zh
  21. EOF
  22. }
  23. while [ "$#" -gt 0 ]; do
  24. case $1 in
  25. -h|--help)
  26. usage
  27. exit 0
  28. ;;
  29. -b|--base)
  30. shift
  31. BASE_TAG="$1"
  32. shift
  33. ;;
  34. -v|--version)
  35. shift
  36. TEMPLATE_VSN_HEADING="$1"
  37. shift
  38. ;;
  39. -l|--lang)
  40. shift
  41. LANGUAGE="$1"
  42. shift
  43. ;;
  44. *)
  45. logerr "Unknown option $1"
  46. exit 1
  47. ;;
  48. esac
  49. done
  50. case "${LANGUAGE:-}" in
  51. en|zh)
  52. true
  53. ;;
  54. *)
  55. logerr "-l|--lang must be 'en' or 'zh'"
  56. exit 1
  57. ;;
  58. esac
  59. case "${BASE_TAG:-}" in
  60. v*)
  61. PROFILE="emqx"
  62. ;;
  63. e*)
  64. PROFILE="emqx-enterprise"
  65. ;;
  66. *)
  67. logerr "Unsupported -b|--base option, must be v* or e*"
  68. exit 1
  69. ;;
  70. esac
  71. TEMPLATE_VSN_HEADING="${TEMPLATE_VSN_HEADING:-<VSN-TAG>}"
  72. top_dir="$(git rev-parse --show-toplevel)"
  73. declare -a PRS
  74. PRS=("")
  75. format_one_pr() {
  76. local filename pr_num indent
  77. filename="${1}"
  78. pr_num="$(echo "${filename}" | sed -E 's/.*-([0-9]+)\.[a-z]+\.md$/\1/')"
  79. re='^[0-9]+$'
  80. if ! [[ $pr_num =~ $re ]]; then
  81. logerr "bad filename format: $filename"
  82. fi
  83. indent="- [#${pr_num}](https://github.com/emqx/emqx/pull/${pr_num}) "
  84. while read -r line; do
  85. if [ "${line}" != '' ]; then
  86. echo "${indent}${line}"
  87. else
  88. echo ''
  89. fi
  90. indent=" "
  91. done < "${filename}"
  92. echo
  93. }
  94. section() {
  95. local prefix=$1
  96. for file in "${PRS[@]}"; do
  97. if [[ $file =~ .*$prefix-.*$LANGUAGE.md ]]; then
  98. format_one_pr "$file"
  99. fi
  100. done
  101. }
  102. changes_dir=("$top_dir/changes/ce")
  103. if [ "$PROFILE" == "emqx-enterprise" ]; then
  104. changes_dir+=("$top_dir/changes/ee")
  105. fi
  106. while read -r file; do
  107. PRS+=("$file")
  108. done < <(git diff --diff-filter=A --name-only "tags/${BASE_TAG}...HEAD" "${changes_dir[@]}")
  109. TEMPLATE_FEAT_CHANGES="$(section 'feat')"
  110. TEMPLATE_PERF_CHANGES="$(section 'perf')"
  111. TEMPLATE_FIX_CHANGES="$(section 'fix')"
  112. case "$LANGUAGE" in
  113. en)
  114. TEMPLATE_ENH_HEADING="Enhancements"
  115. TEMPLATE_FIX_HEADING="Bug Fixes"
  116. ;;
  117. zh)
  118. TEMPLATE_ENH_HEADING="增强"
  119. TEMPLATE_FIX_HEADING="修复"
  120. ;;
  121. esac
  122. cat <<EOF
  123. # ${TEMPLATE_VSN_HEADING}
  124. ## ${TEMPLATE_ENH_HEADING}
  125. ${TEMPLATE_FEAT_CHANGES}
  126. ${TEMPLATE_PERF_CHANGES}
  127. ## ${TEMPLATE_FIX_HEADING}
  128. ${TEMPLATE_FIX_CHANGES}
  129. EOF