name: 📊 代码统计徽章 on: push: branches: [main, master] workflow_dispatch: # ========================================== # 🔧 配置区域 - 根据你的项目修改 # ========================================== env: # ===== Token 配置 ===== # 建议在 Settings -> Secrets 中配置 STATS_TOKEN 以获得更好的权限控制 ACCESS_TOKEN: ${{ secrets.WORKFLOW }} # ===== 工作区配置 ===== # 完整克隆的工作目录 WORKSPACE_DIR: "/home/workspace" # ===== 分支配置 ===== # 徽章数据存储分支(可配置) BADGE_BRANCH: "stats" # 徽章文件存储目录 BADGE_DIR: "badges" # ===== 排除配置 ===== # 全局排除的目录(这些目录会被完全忽略) EXCLUDE_DIRS: "node_modules,dist,build,out,target,vendor,.venv,venv,__pycache__,.git,.github" # 特殊包含规则(即使在排除目录中,也统计这些扩展名的文件) # 格式: 目录:扩展名列表 # 例如: 'dist:js,css' 表示即使 dist 被排除,也统计其中的 .js 和 .css 文件 SPECIAL_INCLUDES: "" # 示例: 'dist:js,css|vendor:go,mod' # ===== 徽章颜色配置 ===== COLOR_TOTAL: "blue" COLOR_FILES: "green" COLOR_DEFAULT: "brightgreen" # ===== 徽章样式配置 ===== BADGE_STYLE: "flat" # 可选: flat, flat-square, plastic, for-the-badge, social # ===== 输出配置 ===== # 是否生成详细报告 GENERATE_DETAILED_REPORT: "true" # 是否输出到 workflow summary OUTPUT_TO_SUMMARY: "true" # 最小代码行数阈值(低于此值的语言不生成徽章) MIN_LINES_THRESHOLD: "10" # ===== Git 配置 ===== GIT_USER_NAME: "github-actions[bot]" GIT_USER_EMAIL: "github-actions[bot]@users.noreply.github.com" # ===== 平台配置 ===== # 平台类型: github 或 gitea PLATFORM: "gitea" # Git 服务器 URL(Gitea 示例: https://gitea.example.com) GIT_SERVER_URL: "https://git.mytsl.cn" # 仓库路径(格式: owner/repo) REPO_PATH: "${{ github.repository }}" # Raw 文件基础 URL # GitHub: https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{path} # Gitea: https://gitea.example.com/{owner}/{repo}/raw/branch/{branch}/{path} RAW_URL_BASE: 'https://git.mytsl.cn/${{ github.repository }}/raw/branch' # ========================================== # 🎨 语言分组配置 # 格式: 组名:后缀列表:显示名称:颜色:图标(可选) # 图标使用 simple-icons 的名称,如 cplusplus, typescript 等 # ========================================== LANGUAGE_GROUPS: | cpp:hpp,cpp,cxx,cc,h,c:C/C++:00599C:cplusplus python:py:Python:3572A5:python typescript:ts,tsx:TypeScript:3178c6:typescript javascript:js,jsx:JavaScript:F7DF1E:javascript java:java:Java:007396:java go:go:Go:00ADD8:go rust:rs:Rust:CE412B:rust shell:sh,bash:Shell:4EAA25:gnubash yaml:yml,yaml:YAML:CB171E tsf:tsl,tsf:TSF:9945FF jobs: update-stats: runs-on: ubuntu-22.04 permissions: contents: write steps: - name: 🔍 验证 Token 配置 id: validate_token run: | echo "🔐 验证访问令牌..." if [ -z "${{ env.ACCESS_TOKEN }}" ]; then echo "❌ 错误: 未配置访问令牌" echo "请在 Settings -> Secrets 中配置 STATS_TOKEN 或确保 GITHUB_TOKEN 可用" exit 1 fi # 检测使用的是哪个 token if [ -n "${{ secrets.STATS_TOKEN }}" ]; then echo "✅ 使用自定义 STATS_TOKEN" echo "token_type=STATS_TOKEN" >> $GITHUB_OUTPUT else echo "✅ 使用默认 GITHUB_TOKEN" echo "token_type=GITHUB_TOKEN" >> $GITHUB_OUTPUT fi echo "🔗 仓库: ${{ github.repository }}" echo "🌿 分支: ${{ github.ref_name }}" echo "📝 提交: ${GITHUB_SHA:0:7}" - name: 🔧 检查必需工具 id: check_deps run: | echo "======================================" echo "🔍 检查依赖工具" echo "======================================" MISSING_TOOLS=() # 检查 bc(用于数字计算) if ! command -v bc &> /dev/null; then echo "⚠️ bc 未安装" MISSING_TOOLS+=("bc") else echo "✓ bc 已安装" fi # 检查 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 # Docker 环境通常以 root 运行,不需要 sudo if [ "$EUID" -eq 0 ] || [ "$(id -u)" -eq 0 ]; then # 当前是 root 用户,直接执行 echo "🔑 检测到 root 权限,直接安装" apt-get update -qq apt-get install -y -qq "${MISSING_TOOLS[@]}" elif command -v sudo &> /dev/null; then # 有 sudo 命令,使用 sudo echo "🔑 使用 sudo 安装" sudo apt-get update -qq sudo apt-get install -y -qq "${MISSING_TOOLS[@]}" else # 既不是 root 也没有 sudo echo "❌ 错误:没有足够权限安装工具" echo "请在 Docker 镜像中预装以下工具:" echo " ${MISSING_TOOLS[*]}" echo "" echo "方案1: 使用包含这些工具的镜像" echo "方案2: 在 Dockerfile 中添加:" echo " RUN apt-get update && apt-get install -y bc jq" exit 1 fi echo "installed=true" >> $GITHUB_OUTPUT echo "✅ 工具安装完成" else echo "installed=false" >> $GITHUB_OUTPUT echo "✅ 所有工具已就绪" fi echo "======================================" echo "" - name: 📥 克隆主仓库 id: clone_main run: | echo "======================================" echo "🚀 开始准备主仓库" echo "======================================" REPO_NAME="${{ github.event.repository.name }}" REPO_DIR="${{ env.WORKSPACE_DIR }}/$REPO_NAME" echo "📁 仓库名称: $REPO_NAME" echo "📍 目标目录: $REPO_DIR" echo "🌐 服务器: ${GITHUB_SERVER_URL}" echo "🌿 分支: ${{ github.ref_name }}" echo "" # 检查仓库状态 if [ -d "$REPO_DIR" ]; then echo "📂 目录已存在,检查 Git 仓库状态..." if [ -d "$REPO_DIR/.git" ]; then # 目录存在且是有效的 Git 仓库 echo "✓ 发现有效的 Git 仓库,执行增量更新..." cd "$REPO_DIR" # 清理工作区 git clean -fdx git reset --hard # 获取最新代码 echo "📥 拉取最新代码..." git fetch --all --tags --force echo "✓ 仓库已更新" else # 目录存在但不是 Git 仓库(可能之前运行失败) echo "⚠️ 目录存在但不是有效的 Git 仓库" echo "🧹 清理损坏的目录..." rm -rf "$REPO_DIR" echo "✓ 已清理" # 重新克隆 echo "📥 克隆仓库..." mkdir -p "${{ env.WORKSPACE_DIR }}" 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 else # 目录不存在,首次克隆 echo "📥 克隆仓库(首次)..." mkdir -p "${{ env.WORKSPACE_DIR }}" 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 # 切换到目标分支 echo "🏷️ 切换到分支: ${{ github.ref_name }}" git checkout -f ${{ github.ref_name }} echo "✅ 仓库准备成功" echo "" # 配置 Git 用户信息 echo "⚙️ 配置 Git 用户信息..." git config user.name "${{ env.GIT_USER_NAME }}" git config user.email "${{ env.GIT_USER_EMAIL }}" # 显示仓库信息 echo "📊 仓库信息:" echo " - 当前分支: $(git branch --show-current)" echo " - 最新提交: $(git log -1 --oneline)" echo " - 远程地址: $(git remote get-url origin | sed 's/oauth2:.*@/oauth2:***@/')" echo "" # 导出环境变量 echo "REPO_DIR=$REPO_DIR" >> $GITHUB_ENV echo "REPO_NAME=$REPO_NAME" >> $GITHUB_ENV echo "✅ 主仓库准备完成" echo "======================================" echo "" - name: ⚙️ 准备统计分支 id: prepare_stats_branch run: | echo "======================================" echo "🔧 准备统计分支" echo "======================================" cd "${{ env.REPO_DIR }}" # 获取所有远程分支 git fetch origin --prune # 检查统计分支是否存在 if git ls-remote --heads origin ${{ env.BADGE_BRANCH }} | grep -q ${{ env.BADGE_BRANCH }}; then echo "✅ 统计分支 '${{ env.BADGE_BRANCH }}' 已存在" # 检出统计分支 git fetch origin ${{ env.BADGE_BRANCH }}:${{ env.BADGE_BRANCH }} git checkout ${{ env.BADGE_BRANCH }} echo "📂 当前分支内容:" ls -la # 返回主分支 git checkout ${{ github.ref_name }} echo "branch_exists=true" >> $GITHUB_OUTPUT else echo "🆕 统计分支 '${{ env.BADGE_BRANCH }}' 不存在,将创建" echo "branch_exists=false" >> $GITHUB_OUTPUT fi echo "======================================" echo "" - name: 🌱 创建统计分支 if: steps.prepare_stats_branch.outputs.branch_exists == 'false' run: | echo "======================================" echo "🆕 创建新的统计分支" echo "======================================" cd "${{ env.REPO_DIR }}" # 🔴 安全检查:确认在正确的目录 echo "🔍 当前目录: $(pwd)" echo "🔍 .git 状态: $([ -d .git ] && echo '✓ 存在' || echo '✗ 不存在')" if [ ! -d .git ]; then echo "❌ 错误:.git 目录不存在,无法创建分支" exit 1 fi # 创建孤立分支(orphan branch) # 📝 说明:孤立分支与主分支没有共同的提交历史,适合存储独立的数据 echo "🌱 创建孤立分支..." git checkout --orphan ${{ env.BADGE_BRANCH }} # 🔴 再次确认 .git 仍然存在 if [ ! -d .git ]; then echo "❌ 严重错误:.git 目录丢失!" exit 1 fi # 🧹 清空所有文件(但保留 .git 目录) # ❓ 为什么要删除? # - stats 分支是独立的数据存储分支,不需要主分支的代码文件 # - 只需要存储徽章 JSON 文件和统计报告 # - 保持分支干净,避免混淆 # # ✅ 能否复用仓库? # - 可以!.git 目录包含所有分支的完整信息 # - 切换到主分支时,主分支的文件会恢复 # - 各分支独立,互不影响 echo "🧹 清理文件(保护 .git 和 .gitea)..." # 步骤 1: 使用 git rm 清理已跟踪的文件 git rm -rf . 2>/dev/null || true # 步骤 2: 安全地删除剩余文件 # 使用更严格的保护,确保不会误删 .git echo "🔍 查找需要删除的文件..." find . -maxdepth 1 -type f ! -name '.gitignore' -delete 2>/dev/null || true find . -maxdepth 1 -type d ! -name '.' ! -name '..' ! -name '.git' ! -name '.gitea' -exec rm -rf {} + 2>/dev/null || true # 🔴 最终检查:确认 .git 仍然完好 echo "🔍 最终检查..." if [ ! -d .git ]; then echo "❌ 致命错误:.git 目录在清理过程中被删除!" echo "这不应该发生,请检查 find 命令" exit 1 fi echo "✓ .git 目录完好" echo "✓ 文件清理完成" echo "" # 创建初始 README cat > README.md << 'EOF' # 📊 代码统计徽章数据 > 此分支由 GitHub Actions 自动生成和维护 > > ⚠️ **请勿手动修改此分支的内容!** ## 📁 目录结构 ``` badges/ ├── total-lines.json # 总代码行数徽章 ├── total-files.json # 总文件数徽章 ├── {language}-lines.json # 各语言代码行数徽章 ├── {language}-files.json # 各语言文件数徽章 └── README.md # 详细统计报告 ``` ## 🔄 更新机制 - ✅ 每次 push 到主分支时自动更新 - ✅ 可通过 workflow_dispatch 手动触发 ## 📊 数据来源 所有统计数据基于主分支的最新代码自动生成。 --- *🤖 由 GitHub Actions 自动维护* EOF # 创建徽章目录 mkdir -p ${{ env.BADGE_DIR }} # 添加并提交 git add . git commit -m "chore: 初始化统计分支" # 推送到远程 git push https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git ${{ env.BADGE_BRANCH }} echo "✅ 统计分支创建完成" echo "======================================" echo "" # 🔴 重要:返回主分支,后续统计需要在主分支进行 echo "🔄 切换回主分支: ${{ github.ref_name }}" git checkout ${{ github.ref_name }} echo "✓ 已切换回主分支" echo "" - name: 📊 统计总代码量 id: total run: | echo "======================================" echo "📊 统计总代码量" echo "======================================" cd "${{ env.REPO_DIR }}" # 🔴 重要:确保在主分支进行统计(不要统计 stats 分支) echo "🔍 确认当前分支..." CURRENT_BRANCH=$(git branch --show-current) if [ "$CURRENT_BRANCH" != "${{ github.ref_name }}" ]; then echo "⚠️ 当前在分支: $CURRENT_BRANCH,切换到主分支: ${{ github.ref_name }}" git checkout ${{ github.ref_name }} else echo "✓ 已在主分支: $CURRENT_BRANCH" fi echo "" # 构建排除参数 EXCLUDE_PARAMS="" IFS=',' read -ra EXCLUDES <<< "${{ env.EXCLUDE_DIRS }}" for dir in "${EXCLUDES[@]}"; do EXCLUDE_PARAMS="$EXCLUDE_PARAMS -not -path '*/$dir/*'" done # 获取所有文件 echo "🔍 扫描文件..." # 统计总文件数 TOTAL_FILES=$(eval "find . -type f $EXCLUDE_PARAMS" | wc -l) # 统计总代码行数(排除空行) TOTAL_CODE=$(eval "find . -type f $EXCLUDE_PARAMS -exec grep -cHv '^[[:space:]]*$' {} + 2>/dev/null" | awk -F: '{sum+=$2} END {print sum+0}') echo "📊 统计结果:" echo " - 总文件数: $TOTAL_FILES" echo " - 总代码行: $TOTAL_CODE" # 格式化数字(添加千分位) FORMATTED_FILES=$(printf "%'d" $TOTAL_FILES) FORMATTED_CODE=$(printf "%'d" $TOTAL_CODE) # 输出到环境变量 echo "total_files=$TOTAL_FILES" >> $GITHUB_OUTPUT echo "total_code=$TOTAL_CODE" >> $GITHUB_OUTPUT echo "formatted_files=$FORMATTED_FILES" >> $GITHUB_OUTPUT echo "formatted_code=$FORMATTED_CODE" >> $GITHUB_OUTPUT echo "======================================" echo "" - name: 📋 统计各语言代码量 id: languages run: | echo "======================================" echo "📋 统计各语言代码量" echo "======================================" cd "${{ env.REPO_DIR }}" # 🔴 重要:确保在主分支进行统计 echo "🔍 确认当前分支..." CURRENT_BRANCH=$(git branch --show-current) if [ "$CURRENT_BRANCH" != "${{ github.ref_name }}" ]; then echo "⚠️ 当前在分支: $CURRENT_BRANCH,切换到主分支: ${{ github.ref_name }}" git checkout ${{ github.ref_name }} else echo "✓ 已在主分支: $CURRENT_BRANCH" fi echo "" # 创建临时目录 mkdir -p /tmp/lang_stats # 构建排除参数 EXCLUDE_PARAMS="" IFS=',' read -ra EXCLUDES <<< "${{ env.EXCLUDE_DIRS }}" for dir in "${EXCLUDES[@]}"; do EXCLUDE_PARAMS="$EXCLUDE_PARAMS -not -path '*/$dir/*'" done LANGUAGE_COUNT=0 # 读取语言配置并统计 echo "${{ env.LANGUAGE_GROUPS }}" | while IFS= read -r line; do [ -z "$line" ] && continue # 解析配置行: 组名:后缀列表:显示名称:颜色:图标 IFS=':' read -r lang_id extensions display_name color icon <<< "$line" echo "🔍 统计 $display_name..." # 构建扩展名查找条件 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 # 统计文件数 FILE_COUNT=$(eval "find . -type f \( $FIND_CONDITIONS \) $EXCLUDE_PARAMS" | wc -l) 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 echo "" done # 汇总所有语言数据 cat /tmp/lang_stats/*.txt 2>/dev/null | sort -t'|' -k3 -nr > /tmp/lang_summary.txt || touch /tmp/lang_summary.txt # 计算实际找到的语言数 ACTUAL_COUNT=$(wc -l < /tmp/lang_summary.txt) echo "language_count=$ACTUAL_COUNT" >> $GITHUB_OUTPUT echo "✅ 找到 $ACTUAL_COUNT 种语言" echo "======================================" echo "" - name: 🎨 生成徽章数据 id: generate_badges run: | echo "======================================" echo "🎨 生成徽章数据" echo "======================================" cd "${{ env.REPO_DIR }}" # 确保在统计分支 git checkout ${{ env.BADGE_BRANCH }} # 确保徽章目录存在 mkdir -p ${{ env.BADGE_DIR }} GENERATED_COUNT=0 # 生成总代码行数徽章 echo "📊 生成总代码行数徽章..." cat > ${{ env.BADGE_DIR }}/total-lines.json << EOF { "schemaVersion": 1, "label": "代码", "message": "${{ steps.total.outputs.formatted_code }} 行", "color": "${{ env.COLOR_TOTAL }}", "style": "${{ env.BADGE_STYLE }}" } EOF GENERATED_COUNT=$((GENERATED_COUNT + 1)) # 生成总文件数徽章 echo "📁 生成总文件数徽章..." cat > ${{ env.BADGE_DIR }}/total-files.json << EOF { "schemaVersion": 1, "label": "文件", "message": "${{ steps.total.outputs.formatted_files }} 个", "color": "${{ env.COLOR_FILES }}", "style": "${{ env.BADGE_STYLE }}" } EOF GENERATED_COUNT=$((GENERATED_COUNT + 1)) # 生成各语言徽章 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 echo " - $display_name" # 生成代码行数徽章(使用 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 }}", "namedLogo": "$icon" } EOFJSON else # 不带图标的徽章 cat > ${{ env.BADGE_DIR }}/${lang_id}-lines.json << EOFJSON { "schemaVersion": 1, "label": "$display_name", "message": "$formatted_lines 行", "color": "$color", "style": "${{ env.BADGE_STYLE }}" } EOFJSON fi GENERATED_COUNT=$((GENERATED_COUNT + 1)) # 生成文件数徽章 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 "✅ 已生成 $GENERATED_COUNT 个徽章" echo "======================================" echo "" - name: 📝 生成详细统计报告 if: env.GENERATE_DETAILED_REPORT == 'true' run: | echo "======================================" echo "📝 生成详细统计报告" echo "======================================" cd "${{ env.REPO_DIR }}" # 确保在统计分支 git checkout ${{ env.BADGE_BRANCH }} # 生成 README cat > ${{ env.BADGE_DIR }}/README.md << 'EOFMD' # 📊 代码统计详细报告 > 🤖 由 GitHub Actions 自动生成 > > 📅 更新时间: TIMESTAMP_PLACEHOLDER ## 📈 总体统计 | 统计项 | 数值 | 徽章 | |--------|------|------| | 💻 总代码行数 | **TOTAL_CODE_PLACEHOLDER** 行 |  | | 📁 总文件数 | **TOTAL_FILES_PLACEHOLDER** 个 |  | | 🌐 语言种类 | **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 sed -i "s|RAW_URL_PLACEHOLDER|${{ env.RAW_URL_BASE }}|g" ${{ env.BADGE_DIR }}/README.md # 添加语言统计表格 if [ -f /tmp/lang_summary.txt ] && [ -s /tmp/lang_summary.txt ]; then cat >> ${{ env.BADGE_DIR }}/README.md << 'EOFTABLE' | 语言 | 代码行数 | 文件数 | 占比 | 徽章 | |------|----------|--------|------|------| EOFTABLE 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 cat >> ${{ env.BADGE_DIR }}/README.md << EOFLANG | **${display_name}** | ${formatted_lines} | ${file_count} | ${PERCENT}% |  | EOFLANG done < /tmp/lang_summary.txt fi # 添加配置说明 cat >> ${{ env.BADGE_DIR }}/README.md << 'EOFMD' --- ## ⚙️ 配置说明 ### Token 配置 - 当前使用: **${{ steps.validate_token.outputs.token_type }}** - 推荐配置自定义 `STATS_TOKEN` 以获得更好的权限控制 ### 排除规则 当前排除的目录: ``` ${{ env.EXCLUDE_DIRS }} ``` ### 阈值设置 - 最小代码行数阈值: **${{ env.MIN_LINES_THRESHOLD }}** 行 - 低于此阈值的语言将不会生成徽章 ### 徽章样式 - 当前样式: **${{ env.BADGE_STYLE }}** - 可选样式: flat, flat-square, plastic, for-the-badge, social ---