From 5b3629fb732ecfdd78496736f1f861ec0f8d9eee Mon Sep 17 00:00:00 2001 From: csh Date: Sun, 2 Nov 2025 20:58:07 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E4=BF=AE=E5=A4=8D`update=5Fstats=5Fbad?= =?UTF-8?q?ge.yml`=20=E5=85=8B=E9=9A=86bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit :recycle: 重构`changelog_and_release.yml`部分代码 --- .gitea/workflows/changelog_and_release.yml | 41 +- .gitea/workflows/update_stats_badge.yaml | 523 +++++++++------------ 2 files changed, 229 insertions(+), 335 deletions(-) diff --git a/.gitea/workflows/changelog_and_release.yml b/.gitea/workflows/changelog_and_release.yml index 10b3b8c..bb84b14 100644 --- a/.gitea/workflows/changelog_and_release.yml +++ b/.gitea/workflows/changelog_and_release.yml @@ -9,10 +9,7 @@ on: # 📝 全局配置区域 - 在此修改所有配置 # ======================================== env: - # ======================================== - # 🔐 认证配置 - # ======================================== - + # ===== Token 配置 ===== # Gitea/GitHub 访问令牌 # 用途: # 1. Git 操作:克隆仓库、推送提交 @@ -29,65 +26,47 @@ env: # - API_TOKEN: 用于 API 调用 ACCESS_TOKEN: ${{ secrets.WORKFLOW }} - # ======================================== - # 🌐 服务器配置 - # ======================================== + # ===== 工作区配置 ===== + # 完整克隆的工作目录 - 自建的runner可以复用工作区 + WORKSPACE_DIR: '/home/workspace' + # ===== 服务器配置 ===== # Gitea 服务器地址(用于生成头像链接和 API 调用) GITEA_SERVER: "https://git.mytsl.cn" - # ======================================== - # 📝 CHANGELOG 配置 - # ======================================== - + # ===== CHANGELOG 配置 ===== # CHANGELOG 变更列表标题 CHANGELOG_SECTION_TITLE: "### :pencil: What's Changed" - # CHANGELOG 贡献者列表标题 CHANGELOG_CONTRIBUTORS_TITLE: "### :busts_in_silhouette: Contributors" - # CHANGELOG 版本号处理方式 # - "full": 使用完整 tag 名称(2025.10.31-1-beta → ## :bookmark: 2025.10.31-1-beta) # - "strip": 去除 pre-release 后缀(1.0.0-beta1 → ## :bookmark: 1.0.0) # ⚠️ 推荐使用 "strip" 模式以支持多个开发版本叠加到同一CHANGELOG区域 CHANGELOG_VERSION_MODE: "strip" - # ======================================== - # 🚀 Release 配置 - # ======================================== - + # ===== RELEASE配置 ===== # Release 标题模板 # 可用变量: {version} - 将被替换为实际的版本号 RELEASE_TITLE: "{version}" - # Pre-release 配置 # - "false": 正式版本(会被标记为 latest) # - "true": 预发布版本(会被标记为 pre-release) # - "auto": 自动判断(根据 tag 名称中是否包含 alpha/beta/rc) RELEASE_PRERELEASE_MODE: "auto" - # Draft 配置(是否创建为草稿) # - "true": 创建为草稿,不会立即发布 # - "false": 立即发布 Release RELEASE_IS_DRAFT: "false" - # 额外要上传到 Release 的文件(空格分隔) # 例如: "README.md LICENSE docs/guide.pdf" ADDITIONAL_RELEASE_FILES: "" - # ======================================== - # 💬 Git 提交配置 - # ======================================== - + # ===== Git 提交配置 ===== # Git 提交消息模板 # 可用变量: {version} - 将被替换为实际的版本号 # [skip ci] 标记防止触发无限循环 COMMIT_MESSAGE: ":memo: Auto update CHANGELOG for {version} [skip ci]" - - # ======================================== - # 🚫 提交过滤配置 - # ======================================== - # 需要忽略的提交模式(支持正则表达式) # 这些提交不会被添加到 CHANGELOG 中 # 使用 | 分隔多个模式 @@ -215,7 +194,7 @@ jobs: echo "======================================" REPO_NAME="${{ github.event.repository.name }}" - REPO_DIR="/home/workspace/$REPO_NAME" + REPO_DIR="${{ env.WORKSPACE_DIR }}/$REPO_NAME" echo "📁 Repository: $REPO_NAME" echo "📍 Target directory: $REPO_DIR" @@ -229,7 +208,7 @@ jobs: echo "✓ Repository updated" else echo "📥 Cloning repository..." - mkdir -p /home/workspace + mkdir -p "${{ env.WORKSPACE_DIR }}" git clone https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git "$REPO_DIR" cd "$REPO_DIR" echo "✓ Repository cloned" diff --git a/.gitea/workflows/update_stats_badge.yaml b/.gitea/workflows/update_stats_badge.yaml index 60f7fed..b46fd78 100644 --- a/.gitea/workflows/update_stats_badge.yaml +++ b/.gitea/workflows/update_stats_badge.yaml @@ -15,7 +15,7 @@ env: # ===== 工作区配置 ===== # 完整克隆的工作目录 - WORKSPACE_DIR: '/home/workspace/' + WORKSPACE_DIR: '/home/workspace' # ===== 分支配置 ===== # 徽章数据存储分支(可配置) @@ -105,7 +105,7 @@ jobs: id: clone_main run: | echo "======================================" - echo "🚀 开始克隆主仓库" + echo "🚀 开始准备主仓库" echo "======================================" REPO_NAME="${{ github.event.repository.name }}" @@ -114,34 +114,46 @@ jobs: echo "📁 仓库名称: $REPO_NAME" echo "📍 目标目录: $REPO_DIR" echo "🌐 服务器: ${GITHUB_SERVER_URL}" + echo "🌿 分支: ${{ github.ref_name }}" echo "" - # 清理旧的工作目录 - if [ -d "$REPO_DIR" ]; then - echo "🧹 清理已存在的目录..." - rm -rf "$REPO_DIR" + # 检查仓库是否已存在 + if [ -d "$REPO_DIR/.git" ]; then + echo "✓ 仓库已存在,更新中..." + cd "$REPO_DIR" + + # 清理工作区 + git clean -fdx + git reset --hard + + # 获取最新代码 + echo "📥 拉取最新代码..." + git fetch --all --tags --force + + echo "✓ 仓库已更新" + else + echo "📥 克隆仓库..." + mkdir -p "${{ env.WORKSPACE_DIR }}" + + # 克隆仓库(完整克隆,不使用 --depth) + git clone \ + https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git \ + "$REPO_DIR" + + if [ $? -ne 0 ]; then + echo "❌ 克隆失败" + exit 1 + fi + + cd "$REPO_DIR" + echo "✓ 仓库已克隆" fi - # 创建工作目录 - mkdir -p "${{ env.WORKSPACE_DIR }}" + # 切换到目标分支 + echo "🏷️ 切换到分支: ${{ github.ref_name }}" + git checkout -f ${{ github.ref_name }} - # 克隆仓库(使用 TOKEN) - echo "📥 克隆仓库..." - git clone \ - --depth 0 \ - --single-branch \ - --branch ${{ github.ref_name }} \ - https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git \ - "$REPO_DIR" - - if [ $? -ne 0 ]; then - echo "❌ 克隆失败" - exit 1 - fi - - cd "$REPO_DIR" - - echo "✅ 仓库克隆成功" + echo "✅ 仓库准备成功" echo "" # 配置 Git 用户信息 @@ -242,232 +254,189 @@ jobs: ## 📊 数据来源 - 统计数据由 [cloc](https://github.com/AlDanial/cloc) 工具生成,包含以下信息: - - - 代码行数(不含注释和空行) - - 文件数量 - - 各编程语言占比 - - ## 🎨 徽章使用 - - 请查看 `badges/README.md` 获取详细的徽章使用说明。 + 所有统计数据基于主分支的最新代码自动生成。 --- - *🤖 自动生成于: $(date -u '+%Y-%m-%d %H:%M:%S UTC')* + *🤖 由 GitHub Actions 自动维护* EOF + # 创建徽章目录 + mkdir -p ${{ env.BADGE_DIR }} + # 添加并提交 - git add README.md - git commit -m "chore: 初始化统计分支 ${{ env.BADGE_BRANCH }}" + git add . + git commit -m "chore: 初始化统计分支" # 推送到远程 - echo "📤 推送到远程..." git push https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git ${{ env.BADGE_BRANCH }} - if [ $? -eq 0 ]; then - echo "✅ 统计分支创建成功" - else - echo "❌ 推送失败" - exit 1 - fi + echo "✅ 统计分支创建完成" + echo "======================================" + echo "" # 返回主分支 git checkout ${{ github.ref_name }} - - echo "======================================" - echo "" - - name: 🔍 检查并安装依赖 + - name: 🔍 检查必需工具 id: check_deps run: | echo "======================================" - echo "🔍 检查必要的工具" + echo "🔍 检查依赖工具" echo "======================================" MISSING_TOOLS=() - # 检查 cloc - if ! command -v cloc &> /dev/null; then - echo "⚠️ cloc 未安装" - MISSING_TOOLS+=("cloc") - else - echo "✅ cloc 已安装: $(cloc --version | head -n1)" - fi - - # 检查 jq - if ! command -v jq &> /dev/null; then - echo "⚠️ jq 未安装" - MISSING_TOOLS+=("jq") - else - echo "✅ jq 已安装: $(jq --version)" - fi - - # 检查 bc + # 检查 bc(用于数字计算) if ! command -v bc &> /dev/null; then echo "⚠️ bc 未安装" MISSING_TOOLS+=("bc") else - echo "✅ bc 已安装" + echo "✓ bc 已安装" fi - echo "" + # 检查 jq(用于 JSON 处理) + if ! command -v jq &> /dev/null; then + echo "⚠️ jq 未安装" + MISSING_TOOLS+=("jq") + else + echo "✓ jq 已安装" + fi - # 如果有缺失的工具,进行安装 + # 如果有缺失的工具,安装它们 if [ ${#MISSING_TOOLS[@]} -gt 0 ]; then + echo "" echo "📦 安装缺失的工具: ${MISSING_TOOLS[*]}" sudo apt-get update -qq - sudo apt-get install -y ${MISSING_TOOLS[@]} - echo "✅ 工具安装完成" + sudo apt-get install -y -qq "${MISSING_TOOLS[@]}" echo "installed=true" >> $GITHUB_OUTPUT + echo "✅ 工具安装完成" else - echo "✅ 所有必要工具已就绪" echo "installed=false" >> $GITHUB_OUTPUT + echo "✅ 所有工具已就绪" fi - echo "" - echo "📋 最终工具版本:" - echo " - cloc: $(cloc --version | head -n1)" - echo " - jq: $(jq --version)" - echo " - bc: $(bc --version | head -n1)" - echo "======================================" echo "" - - name: 📊 统计总代码行数 + - name: 📊 统计总代码量 id: total run: | echo "======================================" - echo "📊 统计总代码行数" + echo "📊 统计总代码量" echo "======================================" cd "${{ env.REPO_DIR }}" # 构建排除参数 - EXCLUDE_ARG="" - if [ -n "${{ env.EXCLUDE_DIRS }}" ]; then - EXCLUDE_ARG="--exclude-dir=$(echo "${{ env.EXCLUDE_DIRS }}" | sed 's/ //g')" - fi + EXCLUDE_PARAMS="" + IFS=',' read -ra EXCLUDES <<< "${{ env.EXCLUDE_DIRS }}" + for dir in "${EXCLUDES[@]}"; do + EXCLUDE_PARAMS="$EXCLUDE_PARAMS -not -path '*/$dir/*'" + done - echo "🔍 统计参数:" - echo " - 目录: $(pwd)" - echo " - 排除: ${{ env.EXCLUDE_DIRS }}" - echo "" + # 获取所有文件 + echo "🔍 扫描文件..." - # 执行统计 - echo "⏳ 正在统计..." - cloc . $EXCLUDE_ARG --json > /tmp/total_stats.json || { - echo "⚠️ cloc 执行失败,使用备用方案" - echo '{"SUM":{"code":0},"header":{"n_files":0}}' > /tmp/total_stats.json - } + # 统计总文件数 + TOTAL_FILES=$(eval "find . -type f $EXCLUDE_PARAMS" | wc -l) - TOTAL_CODE=$(jq '.SUM.code // 0' /tmp/total_stats.json) - TOTAL_FILES=$(jq '.header.n_files // 0' /tmp/total_stats.json) + # 统计总代码行数(排除空行) + TOTAL_CODE=$(eval "find . -type f $EXCLUDE_PARAMS -exec grep -cHv '^[[:space:]]*$' {} + 2>/dev/null" | awk -F: '{sum+=$2} END {print sum+0}') - # 格式化数字(添加千位分隔符) - format_num() { - printf "%'d" "$1" 2>/dev/null || echo "$1" - } + echo "📊 统计结果:" + echo " - 总文件数: $TOTAL_FILES" + echo " - 总代码行: $TOTAL_CODE" - echo "total_code=$TOTAL_CODE" >> $GITHUB_OUTPUT + # 格式化数字(添加千分位) + FORMATTED_FILES=$(printf "%'d" $TOTAL_FILES) + FORMATTED_CODE=$(printf "%'d" $TOTAL_CODE) + + # 输出到环境变量 echo "total_files=$TOTAL_FILES" >> $GITHUB_OUTPUT - echo "formatted_code=$(format_num $TOTAL_CODE)" >> $GITHUB_OUTPUT - echo "formatted_files=$(format_num $TOTAL_FILES)" >> $GITHUB_OUTPUT - - echo "" - echo "📈 统计结果:" - echo " - 总代码行数: $(format_num $TOTAL_CODE) 行" - echo " - 总文件数: $(format_num $TOTAL_FILES) 个" - - # 保存原始数据供后续使用 - cat /tmp/total_stats.json | jq '.' > /tmp/total_stats_backup.json + echo "total_code=$TOTAL_CODE" >> $GITHUB_OUTPUT + echo "formatted_files=$FORMATTED_FILES" >> $GITHUB_OUTPUT + echo "formatted_code=$FORMATTED_CODE" >> $GITHUB_OUTPUT echo "======================================" echo "" - - name: 📊 按语言分组统计 + - name: 📋 统计各语言代码量 id: languages run: | echo "======================================" - echo "📊 按语言分组统计" + echo "📋 统计各语言代码量" echo "======================================" cd "${{ env.REPO_DIR }}" - # 构建排除参数 - EXCLUDE_ARG="" - if [ -n "${{ env.EXCLUDE_DIRS }}" ]; then - EXCLUDE_ARG="--exclude-dir=$(echo "${{ env.EXCLUDE_DIRS }}" | sed 's/ //g')" - fi - # 创建临时目录 mkdir -p /tmp/lang_stats - rm -f /tmp/lang_summary.txt - # 格式化数字函数 - format_num() { - printf "%'d" "$1" 2>/dev/null || echo "$1" - } + # 构建排除参数 + EXCLUDE_PARAMS="" + IFS=',' read -ra EXCLUDES <<< "${{ env.EXCLUDE_DIRS }}" + for dir in "${EXCLUDES[@]}"; do + EXCLUDE_PARAMS="$EXCLUDE_PARAMS -not -path '*/$dir/*'" + done - # 读取语言分组配置并统计 - LANG_COUNT=0 - MIN_THRESHOLD=${{ env.MIN_LINES_THRESHOLD }} - - echo "⚙️ 配置信息:" - echo " - 最小阈值: $MIN_THRESHOLD 行" - echo "" + LANGUAGE_COUNT=0 + # 读取语言配置并统计 echo "${{ env.LANGUAGE_GROUPS }}" | while IFS= read -r line; do [ -z "$line" ] && continue - # 解析配置: 组名:后缀:显示名:颜色:图标(可选) - LANG_ID=$(echo "$line" | cut -d':' -f1 | tr -d ' ') - EXTENSIONS=$(echo "$line" | cut -d':' -f2 | tr -d ' ') - DISPLAY_NAME=$(echo "$line" | cut -d':' -f3 | tr -d ' ') - COLOR=$(echo "$line" | cut -d':' -f4 | tr -d ' ') - ICON=$(echo "$line" | cut -d':' -f5 | tr -d ' ') + # 解析配置行: 组名:后缀列表:显示名称:颜色:图标 + IFS=':' read -r lang_id extensions display_name color icon <<< "$line" - [ -z "$LANG_ID" ] && continue + echo "🔍 统计 $display_name..." - echo "📝 统计 $DISPLAY_NAME ($EXTENSIONS)..." + # 构建扩展名查找条件 + FIND_CONDITIONS="" + IFS=',' read -ra EXTS <<< "$extensions" + for ext in "${EXTS[@]}"; do + if [ -z "$FIND_CONDITIONS" ]; then + FIND_CONDITIONS="-name '*.$ext'" + else + FIND_CONDITIONS="$FIND_CONDITIONS -o -name '*.$ext'" + fi + done - # 统计该语言组 - cloc . $EXCLUDE_ARG \ - --include-ext="$EXTENSIONS" \ - --json > /tmp/lang_stats/${LANG_ID}.json 2>/dev/null || { - echo " ⚠️ 统计失败,跳过" - continue - } + # 统计文件数 + FILE_COUNT=$(eval "find . -type f \( $FIND_CONDITIONS \) $EXCLUDE_PARAMS" | wc -l) - CODE_LINES=$(jq '.SUM.code // 0' /tmp/lang_stats/${LANG_ID}.json) - FILE_COUNT=$(jq '.header.n_files // 0' /tmp/lang_stats/${LANG_ID}.json) - - # 如果代码行数低于阈值,跳过 - if [ "$CODE_LINES" -lt "$MIN_THRESHOLD" ]; then - echo " ⏭️ 代码行数 ($CODE_LINES) 低于阈值,跳过" - continue + if [ "$FILE_COUNT" -gt 0 ]; then + # 统计代码行数 + CODE_LINES=$(eval "find . -type f \( $FIND_CONDITIONS \) $EXCLUDE_PARAMS -exec grep -cHv '^[[:space:]]*$' {} + 2>/dev/null" | awk -F: '{sum+=$2} END {print sum+0}') + + # 只保存超过阈值的语言 + if [ "$CODE_LINES" -ge "${{ env.MIN_LINES_THRESHOLD }}" ]; then + FORMATTED_LINES=$(printf "%'d" $CODE_LINES) + + echo " - 文件数: $FILE_COUNT" + echo " - 代码行: $FORMATTED_LINES" + + # 保存到临时文件 + echo "$lang_id|$display_name|$CODE_LINES|$FORMATTED_LINES|$FILE_COUNT|$color|$icon" >> /tmp/lang_stats/${lang_id}.txt + LANGUAGE_COUNT=$((LANGUAGE_COUNT + 1)) + else + echo " ⏩ 跳过(少于 ${{ env.MIN_LINES_THRESHOLD }} 行)" + fi + else + echo " ⏩ 未找到文件" fi - - FORMATTED_LINES=$(format_num $CODE_LINES) - - echo " ✅ ${DISPLAY_NAME}: $FORMATTED_LINES 行 ($FILE_COUNT 文件)" - - # 保存数据(添加图标字段) - echo "${LANG_ID}|${DISPLAY_NAME}|${CODE_LINES}|${FORMATTED_LINES}|${FILE_COUNT}|${COLOR}|${ICON}" >> /tmp/lang_summary.txt + echo "" done - echo "" + # 汇总所有语言数据 + cat /tmp/lang_stats/*.txt 2>/dev/null | sort -t'|' -k3 -nr > /tmp/lang_summary.txt || touch /tmp/lang_summary.txt - # 统计有效语言数量 - if [ -f /tmp/lang_summary.txt ]; then - VALID_LANG_COUNT=$(wc -l < /tmp/lang_summary.txt) - echo "language_count=$VALID_LANG_COUNT" >> $GITHUB_OUTPUT - echo "✅ 语言统计完成: $VALID_LANG_COUNT 种语言" - else - echo "language_count=0" >> $GITHUB_OUTPUT - echo "⚠️ 未找到符合条件的语言" - fi + # 计算实际找到的语言数 + ACTUAL_COUNT=$(wc -l < /tmp/lang_summary.txt) + echo "language_count=$ACTUAL_COUNT" >> $GITHUB_OUTPUT + + echo "✅ 找到 $ACTUAL_COUNT 种语言" echo "======================================" echo "" @@ -480,211 +449,157 @@ jobs: cd "${{ env.REPO_DIR }}" - # 切换到统计分支 - echo "🔄 切换到统计分支..." - git fetch origin ${{ env.BADGE_BRANCH }}:${{ env.BADGE_BRANCH }} + # 确保在统计分支 git checkout ${{ env.BADGE_BRANCH }} - # 创建徽章目录 + # 确保徽章目录存在 mkdir -p ${{ env.BADGE_DIR }} - # 清理旧的徽章文件 - echo "🧹 清理旧徽章..." - rm -f ${{ env.BADGE_DIR }}/*.json - GENERATED_COUNT=0 - echo "" - echo "📝 生成徽章文件..." - - # 1. 总代码行数徽章 + # 生成总代码行数徽章 + echo "📊 生成总代码行数徽章..." cat > ${{ env.BADGE_DIR }}/total-lines.json << EOF { "schemaVersion": 1, - "label": "总代码", + "label": "代码", "message": "${{ steps.total.outputs.formatted_code }} 行", "color": "${{ env.COLOR_TOTAL }}", "style": "${{ env.BADGE_STYLE }}" } EOF GENERATED_COUNT=$((GENERATED_COUNT + 1)) - echo " ✅ total-lines.json" - # 2. 总文件数徽章 + # 生成总文件数徽章 + echo "📁 生成总文件数徽章..." cat > ${{ env.BADGE_DIR }}/total-files.json << EOF { "schemaVersion": 1, - "label": "文件数", + "label": "文件", "message": "${{ steps.total.outputs.formatted_files }} 个", "color": "${{ env.COLOR_FILES }}", "style": "${{ env.BADGE_STYLE }}" } EOF GENERATED_COUNT=$((GENERATED_COUNT + 1)) - echo " ✅ total-files.json" - # 3. 为每个语言生成徽章 - if [ -f /tmp/lang_summary.txt ]; then + # 生成各语言徽章 + if [ -f /tmp/lang_summary.txt ] && [ -s /tmp/lang_summary.txt ]; then + echo "" + echo "🌐 生成语言徽章..." + while IFS='|' read -r lang_id display_name code_lines formatted_lines file_count color icon; do [ -z "$lang_id" ] && continue - # 使用默认颜色(如果未指定) - [ -z "$color" ] && color="${{ env.COLOR_DEFAULT }}" + echo " - $display_name" - # 语言代码行数徽章 - cat > ${{ env.BADGE_DIR }}/${lang_id}-lines.json << EOF + # 生成代码行数徽章(使用 heredoc) + if [ -n "$icon" ]; then + # 带图标的徽章 + cat > ${{ env.BADGE_DIR }}/${lang_id}-lines.json << EOFJSON { "schemaVersion": 1, - "label": "${display_name}", - "message": "${formatted_lines} 行", - "color": "${color}", - "style": "${{ env.BADGE_STYLE }}" + "label": "$display_name", + "message": "$formatted_lines 行", + "color": "$color", + "style": "${{ env.BADGE_STYLE }}", + "namedLogo": "$icon" } - EOF - GENERATED_COUNT=$((GENERATED_COUNT + 1)) - - # 语言文件数徽章 - cat > ${{ env.BADGE_DIR }}/${lang_id}-files.json << EOF + EOFJSON + else + # 不带图标的徽章 + cat > ${{ env.BADGE_DIR }}/${lang_id}-lines.json << EOFJSON { "schemaVersion": 1, - "label": "${display_name} 文件", - "message": "${file_count} 个", - "color": "${color}", + "label": "$display_name", + "message": "$formatted_lines 行", + "color": "$color", "style": "${{ env.BADGE_STYLE }}" } - EOF + EOFJSON + fi GENERATED_COUNT=$((GENERATED_COUNT + 1)) - echo " ✅ ${lang_id}-lines.json, ${lang_id}-files.json" + # 生成文件数徽章 + cat > ${{ env.BADGE_DIR }}/${lang_id}-files.json << EOFJSON + { + "schemaVersion": 1, + "label": "$display_name 文件", + "message": "$file_count 个", + "color": "$color", + "style": "${{ env.BADGE_STYLE }}" + } + EOFJSON + GENERATED_COUNT=$((GENERATED_COUNT + 1)) done < /tmp/lang_summary.txt fi + echo "" echo "generated_count=$GENERATED_COUNT" >> $GITHUB_OUTPUT - - echo "" - echo "📊 生成统计:" - echo " - 总计: $GENERATED_COUNT 个徽章文件" - echo "" - echo "📂 徽章文件列表:" - ls -lh ${{ env.BADGE_DIR }}/*.json 2>/dev/null || echo " ⚠️ 未找到徽章文件" - + echo "✅ 已生成 $GENERATED_COUNT 个徽章" echo "======================================" echo "" - - name: 📄 生成统计报告 + - name: 📝 生成详细统计报告 if: env.GENERATE_DETAILED_REPORT == 'true' run: | echo "======================================" - echo "📄 生成详细统计报告" + echo "📝 生成详细统计报告" echo "======================================" cd "${{ env.REPO_DIR }}" - TOTAL_CODE=${{ steps.total.outputs.total_code }} - REPO_NAME="${{ env.REPO_NAME }}" - REPO_OWNER="${{ github.repository_owner }}" + # 确保在统计分支 + git checkout ${{ env.BADGE_BRANCH }} - echo "📝 生成 README.md..." + # 生成 README + cat > ${{ env.BADGE_DIR }}/README.md << 'EOFMD' + # 📊 代码统计详细报告 - # 生成 Markdown 报告 - cat > ${{ env.BADGE_DIR }}/README.md << EOFMD - # 📊 ${REPO_NAME} 代码统计报告 - - > 最后更新: $(date '+%Y-%m-%d %H:%M:%S %Z') + > 🤖 由 GitHub Actions 自动生成 > - > 分支: \`${{ github.ref_name }}\` | 提交: [\`${GITHUB_SHA:0:7}\`](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}) + > 📅 更新时间: TIMESTAMP_PLACEHOLDER - ## 📈 总览 + ## 📈 总体统计 - | 指标 | 数值 | - |------|------| - | 💻 **总代码行数** | ${{ steps.total.outputs.formatted_code }} | - | 📁 **总文件数** | ${{ steps.total.outputs.formatted_files }} | - | 🌐 **语言种类** | ${{ steps.languages.outputs.language_count }} | - | 🎨 **徽章数量** | ${{ steps.generate_badges.outputs.generated_count }} | + | 统计项 | 数值 | 徽章 | + |--------|------|------| + | 💻 总代码行数 | **TOTAL_CODE_PLACEHOLDER** 行 | ![代码行数](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/REPO_PLACEHOLDER/BRANCH_PLACEHOLDER/BADGE_DIR_PLACEHOLDER/total-lines.json) | + | 📁 总文件数 | **TOTAL_FILES_PLACEHOLDER** 个 | ![文件数](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/REPO_PLACEHOLDER/BRANCH_PLACEHOLDER/BADGE_DIR_PLACEHOLDER/total-files.json) | + | 🌐 语言种类 | **LANG_COUNT_PLACEHOLDER** 种 | - | - ## 🎨 各语言统计 + ## 🌈 语言分布 EOFMD - # 检查是否有语言数据 + # 替换占位符 + sed -i "s|TIMESTAMP_PLACEHOLDER|$(date -u '+%Y-%m-%d %H:%M:%S UTC')|g" ${{ env.BADGE_DIR }}/README.md + sed -i "s|TOTAL_CODE_PLACEHOLDER|${{ steps.total.outputs.formatted_code }}|g" ${{ env.BADGE_DIR }}/README.md + sed -i "s|TOTAL_FILES_PLACEHOLDER|${{ steps.total.outputs.formatted_files }}|g" ${{ env.BADGE_DIR }}/README.md + sed -i "s|LANG_COUNT_PLACEHOLDER|${{ steps.languages.outputs.language_count }}|g" ${{ env.BADGE_DIR }}/README.md + sed -i "s|REPO_PLACEHOLDER|${{ github.repository }}|g" ${{ env.BADGE_DIR }}/README.md + sed -i "s|BRANCH_PLACEHOLDER|${{ env.BADGE_BRANCH }}|g" ${{ env.BADGE_DIR }}/README.md + sed -i "s|BADGE_DIR_PLACEHOLDER|${{ env.BADGE_DIR }}|g" ${{ env.BADGE_DIR }}/README.md + + # 添加语言统计表格 if [ -f /tmp/lang_summary.txt ] && [ -s /tmp/lang_summary.txt ]; then - cat >> ${{ env.BADGE_DIR }}/README.md << 'EOFMD' - | 语言 | 代码行数 | 文件数 | 占比 | 进度条 | - |------|----------|--------|------|--------| - EOFMD + cat >> ${{ env.BADGE_DIR }}/README.md << 'EOFTABLE' + | 语言 | 代码行数 | 文件数 | 占比 | 徽章 | + |------|----------|--------|------|------| + EOFTABLE - # 添加各语言数据(按代码行数排序) - sort -t'|' -k3 -nr /tmp/lang_summary.txt | while IFS='|' read -r lang_id display_name code_lines formatted_lines file_count color icon; do + TOTAL_CODE=${{ steps.total.outputs.total_code }} + while IFS='|' read -r lang_id display_name code_lines formatted_lines file_count color icon; do [ -z "$lang_id" ] && continue - # 计算百分比 if [ "$TOTAL_CODE" -gt 0 ]; then PERCENT=$(echo "scale=1; $code_lines * 100 / $TOTAL_CODE" | bc) else PERCENT="0.0" fi - # 生成进度条(每2%一个方块) - BAR_LENGTH=$(echo "scale=0; $PERCENT / 2" | bc) - BAR_LENGTH=${BAR_LENGTH:-0} - if [ "$BAR_LENGTH" -gt 0 ]; then - BAR=$(printf '█%.0s' $(seq 1 $BAR_LENGTH)) - else - BAR="░" - fi - - # 添加图标(如果有) - ICON_DISPLAY="" - if [ -n "$icon" ]; then - ICON_DISPLAY="\"${display_name}\"/ " - fi - - echo "| ${ICON_DISPLAY}**${display_name}** | ${formatted_lines} | ${file_count} | ${PERCENT}% | ${BAR} |" >> ${{ env.BADGE_DIR }}/README.md - done - else - echo "" >> ${{ env.BADGE_DIR }}/README.md - echo "> ⚠️ 未找到符合统计条件的语言文件" >> ${{ env.BADGE_DIR }}/README.md - fi - - # 添加使用说明 - cat >> ${{ env.BADGE_DIR }}/README.md << EOFMD - - --- - - ## 📖 徽章使用指南 - - ### 🎯 总览徽章 - - \`\`\`markdown - ![总代码行数](https://img.shields.io/endpoint?url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/raw/branch/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/total-lines.json) - ![总文件数](https://img.shields.io/endpoint?url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/raw/branch/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/total-files.json) - \`\`\` - - **效果预览:** - - ![总代码行数](https://img.shields.io/endpoint?url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/raw/branch/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/total-lines.json) - ![总文件数](https://img.shields.io/endpoint?url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/raw/branch/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/total-files.json) - - ### 🌐 各语言徽章 - - EOFMD - - # 添加各语言徽章使用示例 - if [ -f /tmp/lang_summary.txt ] && [ -s /tmp/lang_summary.txt ]; then - while IFS='|' read -r lang_id display_name code_lines formatted_lines file_count color icon; do - [ -z "$lang_id" ] && continue cat >> ${{ env.BADGE_DIR }}/README.md << EOFLANG - **${display_name}:** - - \`\`\`markdown - ![${display_name} 代码行数](https://img.shields.io/endpoint?url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/raw/branch/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/${lang_id}-lines.json) - ![${display_name} 文件数](https://img.shields.io/endpoint?url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/raw/branch/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/${lang_id}-files.json) - \`\`\` - - ![${display_name} 代码行数](https://img.shields.io/endpoint?url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/raw/branch/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/${lang_id}-lines.json) - ![${display_name} 文件数](https://img.shields.io/endpoint?url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/raw/branch/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/${lang_id}-files.json) - + | **${display_name}** | ${formatted_lines} | ${file_count} | ${PERCENT}% | ![${display_name}](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/${{ github.repository }}/${{ env.BADGE_BRANCH }}/${{ env.BADGE_DIR }}/${lang_id}-lines.json) | EOFLANG done < /tmp/lang_summary.txt fi @@ -704,9 +619,9 @@ jobs: ### 排除规则 当前排除的目录: - \`\`\` + ``` ${{ env.EXCLUDE_DIRS }} - \`\`\` + ``` ### 阈值设置