release.yml 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. name: Auto Release
  2. on:
  3. push:
  4. tags:
  5. - 'v*'
  6. permissions:
  7. contents: write
  8. pull-requests: read
  9. issues: read
  10. jobs:
  11. build:
  12. runs-on: ubuntu-latest
  13. steps:
  14. - name: Checkout code
  15. uses: actions/checkout@v4
  16. with:
  17. fetch-depth: 0
  18. token: ${{ secrets.GITHUB_TOKEN }}
  19. - name: Install yq
  20. run: sudo snap install yq
  21. - name: Generate changelog
  22. id: changelog
  23. env:
  24. CONFIG_FILE: .github/release.yml
  25. run: |
  26. # 解析配置文件
  27. declare -A category_map
  28. while IFS=";" read -r title labels; do
  29. for label in $labels; do
  30. category_map[$label]="$title"
  31. done
  32. done < <(yq -o=tsv '.categories[] | [.title, (.labels | join(" "))] | join(";")' $CONFIG_FILE)
  33. # 获取版本范围
  34. mapfile -t tags < <(git tag -l --sort=-version:refname)
  35. current_tag=${tags[0]}
  36. previous_tag=${tags[1]:-}
  37. if [[ -z "$previous_tag" ]]; then
  38. commit_range="$current_tag"
  39. echo "首次发布版本: $current_tag"
  40. else
  41. commit_range="$previous_tag..$current_tag"
  42. echo "版本范围: $commit_range"
  43. fi
  44. # 获取所有符合规范的提交
  45. commits=$(git log --pretty=format:"%s|%h" "$commit_range")
  46. # 生成分类日志
  47. declare -A log_entries
  48. while IFS="|" read -r subject hash; do
  49. # type=$(echo "$subject" | cut -d':' -f1 | tr -d ' ')
  50. type=$(echo "$subject" | sed -E 's/^([[:alnum:]]+)(\(.*\))?:.*/\1/' | tr -d ' ')
  51. found=0
  52. for label in "${!category_map[@]}"; do
  53. if [[ "$type" == "$label" ]]; then
  54. entry="- ${subject} (${hash:0:7})"
  55. log_entries[${category_map[$label]}]+="$entry"$'\n'
  56. found=1
  57. break
  58. fi
  59. done
  60. if [[ $found -eq 0 ]]; then
  61. entry="- ${subject} (${hash:0:7})"
  62. log_entries["其他"]+="$entry"$'\n'
  63. fi
  64. done <<< "$commits"
  65. # 统计提交数量
  66. commit_count=$(git log --oneline "$commit_range" | wc -l)
  67. # 统计受影响的文件数量
  68. file_count=$(git diff --name-only "$commit_range" | wc -l)
  69. # 统计贡献者信息
  70. contributor_stats=$(git shortlog -sn "$commit_range")
  71. contributor_notes=""
  72. while IFS= read -r line; do
  73. commits=$(echo "$line" | awk '{print $1}')
  74. name=$(echo "$line" | awk '{$1=""; print $0}' | sed 's/^ //')
  75. contributor_notes+="- @${name} (${commits} commits)\n"
  76. done <<< "$contributor_stats"
  77. # 构建输出内容
  78. release_notes="## 版本更新日志 ($current_tag)\n\n"
  79. while IFS= read -r category; do
  80. if [[ -n "${log_entries[$category]}" ]]; then
  81. release_notes+="### $category\n${log_entries[$category]}\n"
  82. fi
  83. done < <(yq '.categories[].title' $CONFIG_FILE)
  84. # 构建输出内容
  85. release_notes="## 版本更新日志 ($current_tag)\n\n"
  86. current_date=$(date +"%Y-%m-%d")
  87. # 添加发布日期和下载统计信息
  88. release_notes+=" ### 📅 发布日期: ${current_date}\n"
  89. while IFS= read -r category; do
  90. if [[ -n "${log_entries[$category]}" ]]; then
  91. release_notes+="### $category\n${log_entries[$category]}\n"
  92. fi
  93. done < <(yq '.categories[].title' $CONFIG_FILE)
  94. # 添加统计信息
  95. release_notes+="### 📊 统计信息\n"
  96. release_notes+="- 本次发布包含 ${commit_count} 个提交\n"
  97. release_notes+="- 影响 ${file_count} 个文件\n\n"
  98. # 添加贡献者信息
  99. release_notes+="### 👥 贡献者\n"
  100. release_notes+="感谢这些优秀的贡献者(按提交次数排序):\n"
  101. release_notes+="${contributor_notes}\n"
  102. release_notes+="---\n"
  103. # 写入文件
  104. echo -e "$release_notes" > changelog.md
  105. echo "生成日志内容:"
  106. cat changelog.md
  107. - name: Create Release
  108. uses: ncipollo/release-action@v1
  109. with:
  110. generateReleaseNotes: false
  111. bodyFile: changelog.md
  112. tag: ${{ github.ref_name }}