Skip to content

Code Statistics

Code Statistics #132

Workflow file for this run

name: Code Statistics
on:
workflow_dispatch: # 手动触发
inputs:
output_branch:
description: '输出结果的分支名称(默认:code-stats-results)'
required: false
default: 'code-stats-results'
schedule:
# 每天凌晨 2 点执行
- cron: '0 2 * * *'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
code-stats:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout StarryOS
uses: actions/checkout@v4
with:
submodules: 'recursive'
- name: Checkout test harness
uses: actions/checkout@v4
with:
repository: kylin-x-kernel/starry-test-harness
path: starry-test-harness
- name: Install dependencies
run: |
# 安装 tokei
cargo install --locked tokei
# 安装 yq
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq
# 验证安装
tokei --version
yq --version
- name: Clone whitelist repositories
run: |
# 白名单仓库会克隆到 local_crates/ 目录
# 格式: 分支名|仓库URL|目录名
cat > repos.txt << 'EOF'
master|https://github.com/kylin-x-kernel/starry-ptrace|starry-ptrace
master|https://github.com/kylin-x-kernel/starry-test-harness|starry-test-harness
master|https://gitee.com/openkylin/rust-libutee|rust-libutee
master|https://gitee.com/openkylin/microkylin_manager|microkylin_manager
main|https://github.com/kylin-x-kernel/meta-starry.git|meta-starry
main|https://github.com/kylin-x-kernel/aarch64-pmuv3.git|aarch64-pmuv3
dev|https://github.com/kylin-x-kernel/page_table_multiarch.git|page_table_multiarch
EOF
# 添加更多仓库示例:
# main|https://github.com/org/repo|repo
# 批量克隆到 local_crates
while IFS='|' read -r branch repo name; do
[[ -z "$branch" ]] && continue
target="local_crates/$name"
if [[ -d "$target" ]]; then
echo "[skip] $target already exists"
else
echo "[clone] $repo ($branch) → $target"
git clone -b "$branch" --depth 1 "$repo" "$target"
fi
done < repos.txt
- name: Run code statistics
run: |
# 统计主仓库(排除 local_crates)和 local_crates 下所有子目录
python3 starry-test-harness/scripts/generate_loc_report.py \
--workspace "${{ github.workspace }}" \
--clone-dir local_crates \
--output ./code-stats
- name: Generate timestamp
id: timestamp
run: echo "date=$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_OUTPUT
- name: Upload statistics as artifact
uses: actions/upload-artifact@v4
with:
name: code-statistics-${{ steps.timestamp.outputs.date }}
path: |
code-stats/loc.json
code-stats/loc.md
retention-days: 90
- name: Commit and push to results branch
env:
OUTPUT_BRANCH: ${{ github.event.inputs.output_branch || 'code-stats-results' }}
TIMESTAMP: ${{ steps.timestamp.outputs.date }}
run: |
# 配置 git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# 备份统计结果到临时目录
mkdir -p /tmp/code-stats-backup
cp -r code-stats/* /tmp/code-stats-backup/
# 创建或切换到结果分支
git fetch origin ${OUTPUT_BRANCH} || true
# 检查分支是否存在
if git show-ref --verify --quiet refs/remotes/origin/${OUTPUT_BRANCH}; then
# 分支存在,切换
git checkout ${OUTPUT_BRANCH}
# 检查是否有非 reports 的文件/目录(说明分支被污染了)
shopt -s dotglob nullglob
needs_cleanup=false
for item in *; do
if [ "$item" != ".git" ] && [ "$item" != "reports" ]; then
needs_cleanup=true
break
fi
done
if [ "$needs_cleanup" = true ]; then
echo "Branch contains non-report files. Performing cleanup..."
# 备份旧的 reports 目录(如果存在)
if [ -d "reports" ]; then
echo "Backing up old reports..."
cp -r reports /tmp/old-reports-backup
fi
# 清理工作区(保留 .git)
for item in *; do
if [ "$item" != ".git" ]; then
rm -rf "$item"
fi
done
# 清空 git 索引
git rm -rf --cached . 2>/dev/null || true
# 恢复旧的 reports 目录
if [ -d "/tmp/old-reports-backup" ]; then
echo "Restoring old reports..."
cp -r /tmp/old-reports-backup reports
fi
else
echo "Branch is clean. Skipping cleanup."
fi
else
# 分支不存在,创建孤立分支
git checkout --orphan ${OUTPUT_BRANCH}
# 清空暂存区
git rm -rf . 2>/dev/null || true
fi
# 确保 reports 目录存在
mkdir -p reports/${TIMESTAMP}
# 从临时目录复制统计结果
cp /tmp/code-stats-backup/loc.json reports/${TIMESTAMP}/
cp /tmp/code-stats-backup/loc.md reports/${TIMESTAMP}/
cp /tmp/code-stats-backup/loc.json reports/latest.json
cp /tmp/code-stats-backup/loc.md reports/latest.md
# 创建索引文件
cat > reports/README.md << 'EOF'
# StarryOS 代码统计历史报告
## 最新报告
- [最新统计 (JSON)](./latest.json)
- [最新统计 (Markdown)](./latest.md)
## 历史报告
EOF
# 列出所有历史报告
for dir in reports/*/; do
if [ -d "$dir" ]; then
dirname=$(basename "$dir")
echo "- [\`${dirname}\`](./${dirname}/loc.md)" >> reports/README.md
fi
done
# 添加元信息
cat > reports/latest-info.json << EOF
{
"timestamp": "${TIMESTAMP}",
"commit": "${{ github.sha }}",
"branch": "${{ github.ref_name }}",
"workflow_run": "${{ github.run_id }}"
}
EOF
# 提交更改
git add reports/
git commit -m " 代码统计报告 - ${TIMESTAMP}" || echo "No changes to commit"
# 推送到远程
git push -f origin ${OUTPUT_BRANCH}
echo " 统计结果已推送到分支: ${OUTPUT_BRANCH}"
echo " 查看报告: https://github.com/${{ github.repository }}/tree/${OUTPUT_BRANCH}/reports"
- name: Display statistics summary
if: always()
run: |
echo "## 代码统计摘要" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ -f code-stats/loc.md ]; then
cat code-stats/loc.md >> $GITHUB_STEP_SUMMARY
else
echo "统计文件未生成" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "---" >> $GITHUB_STEP_SUMMARY
echo " 统计结果已保存到分支: \`${{ github.event.inputs.output_branch || 'code-stats-results' }}\`" >> $GITHUB_STEP_SUMMARY
echo " [查看历史报告](https://github.com/${{ github.repository }}/tree/${{ github.event.inputs.output_branch || 'code-stats-results' }}/reports)" >> $GITHUB_STEP_SUMMARY