refactor: 精简fscan-lab目录结构 #108
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 测试构建 | |
| on: | |
| push: | |
| branches: | |
| - dev | |
| - develop | |
| - feature/* | |
| paths-ignore: | |
| - '*.md' | |
| - '*.txt' | |
| - 'README*' | |
| - 'LICENSE*' | |
| - 'image/**' | |
| - 'TestDocker/**' | |
| - '**/*.png' | |
| - '**/*.jpg' | |
| - '**/*.jpeg' | |
| pull_request: | |
| branches: | |
| - main | |
| - master | |
| - dev | |
| paths-ignore: | |
| - '*.md' | |
| - '*.txt' | |
| - 'README*' | |
| - 'LICENSE*' | |
| - 'image/**' | |
| - 'TestDocker/**' | |
| - '**/*.png' | |
| - '**/*.jpg' | |
| - '**/*.jpeg' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| name: 代码检查 | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: 检出代码 | |
| uses: actions/checkout@v4 | |
| - name: 设置 Go 环境 | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.20' | |
| cache: true | |
| - name: 运行 golangci-lint | |
| run: | | |
| # 下载预编译的 golangci-lint (兼容 Go 1.20) | |
| curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.61.0 | |
| # 运行检查并灵活处理结果 | |
| set +e | |
| golangci-lint run --timeout=5m > lint_output.txt 2>&1 | |
| LINT_EXIT_CODE=$? | |
| cat lint_output.txt | |
| set -e | |
| # 只关注真正的 bug,忽略风格警告和代码质量建议 | |
| # 过滤规则: | |
| # - gocognit/gocyclo: 复杂度警告 | |
| # - revive: 代码风格 | |
| # - QF/S1: staticcheck 的代码质量改进建议(非bug) | |
| if [ $LINT_EXIT_CODE -ne 0 ]; then | |
| # 过滤掉可接受的警告,只关注真正的错误 | |
| CRITICAL_ISSUES=$(grep -E "\.go:[0-9]+:[0-9]+:" lint_output.txt | grep -v "gocognit" | grep -v "gocyclo" | grep -v "revive" | grep -v "QF[0-9]" | grep -v " S[0-9]" || true) | |
| if [ -n "$CRITICAL_ISSUES" ]; then | |
| echo "❌ Linting failed with critical issues (NOT just style warnings):" | |
| echo "$CRITICAL_ISSUES" | head -20 | |
| exit 1 | |
| else | |
| echo "⚠️ Only acceptable warnings (complexity/style/quality suggestions) - PASSING" | |
| exit 0 | |
| fi | |
| fi | |
| echo "✅ No lint issues found" | |
| - name: 检查代码复杂度(质量门禁) | |
| run: | | |
| echo "### 🚦 复杂度质量门禁" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # 检查认知复杂度>80的函数 | |
| COMPLEX_FUNCS=$(golangci-lint run --disable-all --enable=gocognit --out-format=line-number 2>&1 | grep "cognitive complexity" | grep -v "typechecking" || true) | |
| if [ -n "$COMPLEX_FUNCS" ]; then | |
| HIGH_COMPLEX=$(echo "$COMPLEX_FUNCS" | awk '{print $NF}' | sed 's/[()]//g' | awk -F'>' '{if ($1 > 80) print}' | wc -l) | |
| if [ "$HIGH_COMPLEX" -gt 0 ]; then | |
| echo "❌ **发现 $HIGH_COMPLEX 个复杂度>80的函数**" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "$COMPLEX_FUNCS" | awk '{print $NF}' | sed 's/[()]//g' | awk -F'>' '{if ($1 > 80) print "复杂度:", $1, "- 必须重构"}' >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "⚠️ 请重构复杂度>80的函数后再提交" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi | |
| fi | |
| echo "✅ 代码复杂度检查通过(所有函数≤80)" >> $GITHUB_STEP_SUMMARY | |
| test: | |
| name: 单元测试和构建 | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| needs: lint | |
| steps: | |
| - name: 检出代码 | |
| uses: actions/checkout@v4 | |
| - name: 设置 Go 环境 | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.20' | |
| cache: true | |
| - name: 下载依赖 | |
| run: | | |
| go mod download | |
| go mod verify | |
| - name: 运行测试 | |
| run: | | |
| # 排除第三方grdp库测试(存在环境依赖问题) | |
| go test -vet=off -race -coverprofile=coverage.out -covermode=atomic $(go list ./... | grep -v '/mylib/grdp/') | |
| - name: 上传覆盖率 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: coverage.out | |
| retention-days: 7 | |
| - name: 显示覆盖率 | |
| run: | | |
| echo "### 测试覆盖率报告" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| go tool cover -func=coverage.out >> $GITHUB_STEP_SUMMARY | |
| - name: 检查覆盖率(质量门禁) | |
| run: | | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### 🚦 覆盖率质量门禁" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # 提取总体覆盖率 | |
| TOTAL_COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//') | |
| echo "总体覆盖率: ${TOTAL_COVERAGE}%" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # 检查核心模块覆盖率(core, common/parsers必须>50%) | |
| CORE_COVERAGE=$(go tool cover -func=coverage.out | grep "^github.com/shadow1ng/fscan/core/" | grep -v "_test.go" | awk '{sum+=$3; count++} END {if(count>0) print sum/count; else print 0}') | |
| PARSERS_COVERAGE=$(go tool cover -func=coverage.out | grep "^github.com/shadow1ng/fscan/common/parsers/" | grep -v "_test.go" | awk '{sum+=$3; count++} END {if(count>0) print sum/count; else print 0}') | |
| # 警告阈值:总体<40%, 核心模块<50% | |
| if (( $(echo "$TOTAL_COVERAGE < 40" | bc -l) )); then | |
| echo "⚠️ **警告**: 总体覆盖率 ${TOTAL_COVERAGE}% < 40%,建议补充测试" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # 检查是否有新增的未测试文件(0%覆盖率) | |
| ZERO_COVERAGE_FILES=$(go tool cover -func=coverage.out | awk '$3 == "0.0%" && $1 !~ /_test\.go/' | wc -l) | |
| if [ "$ZERO_COVERAGE_FILES" -gt 0 ]; then | |
| echo "⚠️ **警告**: 发现 $ZERO_COVERAGE_FILES 个文件覆盖率为0%" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "请为新代码补充单元测试" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "✅ 覆盖率检查通过" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| build: | |
| name: 构建测试 | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: test | |
| steps: | |
| - name: 检出代码 | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: 快照构建 | |
| uses: ./.github/actions/build-release | |
| with: | |
| mode: snapshot | |
| go-version: '1.20' | |
| retention-days: '7' |