Files
fscan/.github/workflows/test-build.yml
T
2025-07-17 21:33:36 +08:00

430 lines
18 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: 测试构建
on:
push:
branches:
- dev
- develop
- feature/*
pull_request:
branches:
- main
- master
- dev
workflow_dispatch:
inputs:
branch:
description: '测试分支'
required: false
default: 'dev'
skip_tests:
description: '跳过测试'
type: boolean
default: false
permissions:
contents: read
jobs:
test-build:
name: 测试构建
runs-on: ubuntu-latest
timeout-minutes: 30
# 设置作业级别的环境变量
env:
GITHUB_OWNER: ${{ github.repository_owner }}
GITHUB_REPO: ${{ github.event.repository.name }}
PROJECT_NAME: ${{ github.event.repository.name }}
steps:
- name: 📥 检出代码
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.inputs.branch || github.ref }}
- name: 🔍 获取项目信息
id: project
run: |
echo "owner=${GITHUB_REPOSITORY_OWNER}" >> $GITHUB_OUTPUT
echo "repo=${GITHUB_REPOSITORY#*/}" >> $GITHUB_OUTPUT
echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
echo "short_sha=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT
echo "full_sha=${GITHUB_SHA}" >> $GITHUB_OUTPUT
echo "build_time=$(date '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_OUTPUT
echo "build_timestamp=$(date +%s)" >> $GITHUB_OUTPUT
- name: 🐹 设置 Go 环境
uses: actions/setup-go@v5
with:
go-version: '1.20'
cache: true
- name: 📦 下载依赖
run: |
go mod download
go mod verify
- name: 🗜️ 安装 UPX 压缩工具
uses: crazy-max/ghaction-upx@v3
with:
install-only: true
- name: ️ 显示构建环境信息
run: |
echo "Go 版本: $(go version)"
echo "UPX 版本: $(upx --version)"
echo "分支: ${{ steps.project.outputs.branch }}"
echo "提交: ${{ steps.project.outputs.short_sha }}"
echo "仓库: ${{ steps.project.outputs.owner }}/${{ steps.project.outputs.repo }}"
echo "环境变量:"
echo "- GITHUB_OWNER: $GITHUB_OWNER"
echo "- GITHUB_REPO: $GITHUB_REPO"
echo "- PROJECT_NAME: $PROJECT_NAME"
- name: 🧪 运行测试
id: test_step
if: ${{ !inputs.skip_tests }}
run: |
echo "test_skipped=false" >> $GITHUB_OUTPUT
echo "构建开始时间: $(date)" > test_results.txt
# 运行测试并记录结果
if go test -v ./... 2>&1 | tee test_output.txt; then
echo "test_passed=true" >> $GITHUB_OUTPUT
echo "测试状态: ✅ 通过" >> test_results.txt
else
echo "test_passed=false" >> $GITHUB_OUTPUT
echo "测试状态: ❌ 失败" >> test_results.txt
fi
# 统计测试信息
if [ -f test_output.txt ]; then
test_count=$(grep -c "=== RUN" test_output.txt || echo "0")
pass_count=$(grep -c "--- PASS:" test_output.txt || echo "0")
fail_count=$(grep -c "--- FAIL:" test_output.txt || echo "0")
echo "test_count=$test_count" >> $GITHUB_OUTPUT
echo "pass_count=$pass_count" >> $GITHUB_OUTPUT
echo "fail_count=$fail_count" >> $GITHUB_OUTPUT
echo "测试总数: $test_count" >> test_results.txt
echo "通过测试: $pass_count" >> test_results.txt
echo "失败测试: $fail_count" >> test_results.txt
fi
continue-on-error: true
- name: 📝 记录跳过测试状态
if: ${{ inputs.skip_tests }}
run: |
echo "test_skipped=true" >> $GITHUB_OUTPUT
echo "test_passed=true" >> $GITHUB_OUTPUT
echo "test_count=0" >> $GITHUB_OUTPUT
echo "pass_count=0" >> $GITHUB_OUTPUT
echo "fail_count=0" >> $GITHUB_OUTPUT
echo "测试状态: ⏭️ 跳过" > test_results.txt
env:
GITHUB_OUTPUT: ${{ steps.test_step.outputs.GITHUB_OUTPUT }}
- name: 🔍 验证 GoReleaser 配置
id: config_check
run: |
echo "config_start_time=$(date +%s)" >> $GITHUB_OUTPUT
if docker run --rm -v "$(pwd):/workspace" -w /workspace goreleaser/goreleaser:latest check -f .github/conf/.goreleaser.yml; then
echo "config_valid=true" >> $GITHUB_OUTPUT
else
echo "config_valid=false" >> $GITHUB_OUTPUT
fi
echo "config_end_time=$(date +%s)" >> $GITHUB_OUTPUT
continue-on-error: true
- name: 🚀 测试构建 (Snapshot 模式)
id: build_step
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: latest
args: release --snapshot --clean -f .github/conf/.goreleaser.yml
workdir: .
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
- name: 📋 上传测试产物
uses: actions/upload-artifact@v4
with:
name: 测试构建-${{ steps.project.outputs.branch }}-${{ steps.project.outputs.short_sha }}
path: |
dist/
test_results.txt
test_output.txt
retention-days: 7
continue-on-error: true
- name: 🧪 测试生成的二进制文件
id: binary_test
run: |
echo "## 🧪 测试二进制文件" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
binary_count=0
tested_count=0
passed_count=0
failed_count=0
if [ -d "dist" ]; then
echo "| 平台 | 架构 | 文件大小 | 压缩 | 运行测试 | 版本信息 |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|----------|------|----------|----------|" >> $GITHUB_STEP_SUMMARY
for binary in dist/*; do
if [[ -f "$binary" && -x "$binary" ]]; then
binary_count=$((binary_count + 1))
# 获取文件信息
file_size=$(du -h "$binary" | cut -f1)
file_info=$(file "$binary")
# 提取平台和架构信息
platform="Unknown"
arch="Unknown"
if [[ "$binary" == *"linux"* ]]; then
platform="Linux"
elif [[ "$binary" == *"darwin"* ]]; then
platform="macOS"
elif [[ "$binary" == *"windows"* ]]; then
platform="Windows"
fi
if [[ "$binary" == *"amd64"* ]]; then
arch="AMD64"
elif [[ "$binary" == *"arm64"* ]]; then
arch="ARM64"
elif [[ "$binary" == *"386"* ]]; then
arch="i386"
fi
# 检查是否使用了UPX压缩
compressed="❌"
if [[ "$file_info" == *"UPX"* ]]; then
compressed="✅"
fi
# 测试运行(仅对当前平台的二进制文件)
run_test="⏭️"
version_info="N/A"
if [[ "$binary" == *"linux"* && "$binary" == *"amd64"* ]]; then
tested_count=$((tested_count + 1))
if timeout 10s "$binary" --version > version_output.txt 2>&1; then
run_test="✅"
passed_count=$((passed_count + 1))
version_info=$(head -n1 version_output.txt | cut -c1-20)
elif timeout 10s "$binary" --help > /dev/null 2>&1; then
run_test="✅"
passed_count=$((passed_count + 1))
version_info="Help OK"
else
run_test="❌"
failed_count=$((failed_count + 1))
version_info="Error"
fi
fi
echo "| $platform | $arch | $file_size | $compressed | $run_test | $version_info |" >> $GITHUB_STEP_SUMMARY
fi
done
echo "" >> $GITHUB_STEP_SUMMARY
echo "**统计信息:**" >> $GITHUB_STEP_SUMMARY
echo "- 总二进制文件数: $binary_count" >> $GITHUB_STEP_SUMMARY
echo "- 测试文件数: $tested_count" >> $GITHUB_STEP_SUMMARY
echo "- 测试通过数: $passed_count" >> $GITHUB_STEP_SUMMARY
echo "- 测试失败数: $failed_count" >> $GITHUB_STEP_SUMMARY
else
echo "❌ 未找到构建产物" >> $GITHUB_STEP_SUMMARY
binary_count=0
fi
echo "binary_count=$binary_count" >> $GITHUB_OUTPUT
echo "tested_count=$tested_count" >> $GITHUB_OUTPUT
echo "passed_count=$passed_count" >> $GITHUB_OUTPUT
echo "failed_count=$failed_count" >> $GITHUB_OUTPUT
continue-on-error: true
- name: 📊 生成测试报告
if: always()
run: |
# 计算构建时间
build_end_time=$(date +%s)
build_duration=$((build_end_time - ${{ steps.project.outputs.build_timestamp }}))
build_duration_formatted=$(printf "%02d:%02d" $((build_duration / 60)) $((build_duration % 60)))
# 生成报告头部
echo "# 🎯 测试构建报告" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 构建状态徽章
if [[ "${{ steps.build_step.outcome }}" == "success" ]]; then
build_status="![构建状态](https://img.shields.io/badge/构建-成功-brightgreen)"
else
build_status="![构建状态](https://img.shields.io/badge/构建-失败-red)"
fi
if [[ "${{ steps.test_step.outputs.test_skipped }}" == "true" ]]; then
test_status="![测试状态](https://img.shields.io/badge/测试-跳过-yellow)"
elif [[ "${{ steps.test_step.outputs.test_passed }}" == "true" ]]; then
test_status="![测试状态](https://img.shields.io/badge/测试-通过-brightgreen)"
else
test_status="![测试状态](https://img.shields.io/badge/测试-失败-red)"
fi
echo "$build_status $test_status" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 基本信息表格
echo "## 📋 基本信息" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 项目 | 信息 |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 🏷️ **仓库** | ${{ steps.project.outputs.owner }}/${{ steps.project.outputs.repo }} |" >> $GITHUB_STEP_SUMMARY
echo "| 🌿 **分支** | \`${{ steps.project.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| 📝 **提交** | \`${{ steps.project.outputs.short_sha }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| ⏰ **构建时间** | ${{ steps.project.outputs.build_time }} |" >> $GITHUB_STEP_SUMMARY
echo "| ⏱️ **构建耗时** | ${build_duration_formatted} |" >> $GITHUB_STEP_SUMMARY
echo "| 🏃 **运行环境** | Ubuntu Latest |" >> $GITHUB_STEP_SUMMARY
echo "| 🐹 **Go 版本** | $(go version | cut -d' ' -f3) |" >> $GITHUB_STEP_SUMMARY
echo "| 🗜️ **UPX 版本** | $(upx --version | head -n1 | cut -d' ' -f2) |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 测试结果
echo "## 🧪 测试结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "${{ steps.test_step.outputs.test_skipped }}" == "true" ]]; then
echo "⏭️ **测试已跳过**" >> $GITHUB_STEP_SUMMARY
else
test_count="${{ steps.test_step.outputs.test_count }}"
pass_count="${{ steps.test_step.outputs.pass_count }}"
fail_count="${{ steps.test_step.outputs.fail_count }}"
echo "| 测试项 | 数量 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 📊 **总测试数** | $test_count | - |" >> $GITHUB_STEP_SUMMARY
echo "| ✅ **通过测试** | $pass_count | $(if [ "$pass_count" -gt 0 ]; then echo "✅"; else echo ""; fi) |" >> $GITHUB_STEP_SUMMARY
echo "| ❌ **失败测试** | $fail_count | $(if [ "$fail_count" -gt 0 ]; then echo "❌"; else echo ""; fi) |" >> $GITHUB_STEP_SUMMARY
if [ "$fail_count" -gt 0 ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "⚠️ **发现测试失败,请检查测试输出**" >> $GITHUB_STEP_SUMMARY
fi
fi
echo "" >> $GITHUB_STEP_SUMMARY
# 构建结果
echo "## 🚀 构建结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "${{ steps.config_check.outputs.config_valid }}" == "true" ]]; then
config_status="✅ 配置有效"
else
config_status="❌ 配置无效"
fi
echo "| 构建阶段 | 状态 | 说明 |" >> $GITHUB_STEP_SUMMARY
echo "|----------|------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 🔍 **配置验证** | $config_status | GoReleaser配置文件检查 |" >> $GITHUB_STEP_SUMMARY
if [[ "${{ steps.build_step.outcome }}" == "success" ]]; then
echo "| 🏗️ **快照构建** | ✅ 成功 | 二进制文件已生成 |" >> $GITHUB_STEP_SUMMARY
else
echo "| 🏗️ **快照构建** | ❌ 失败 | 请检查构建日志 |" >> $GITHUB_STEP_SUMMARY
fi
binary_count="${{ steps.binary_test.outputs.binary_count }}"
tested_count="${{ steps.binary_test.outputs.tested_count }}"
passed_count="${{ steps.binary_test.outputs.passed_count }}"
failed_count="${{ steps.binary_test.outputs.failed_count }}"
echo "| 🧪 **二进制测试** | $(if [ "$failed_count" -eq 0 ]; then echo "✅ 通过"; else echo "❌ 部分失败"; fi) | $tested_count/$binary_count 已测试 |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 构建产物统计
if [ -d "dist" ]; then
echo "## 📦 构建产物" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
total_size=$(du -sh dist/ | cut -f1)
file_count=$(find dist/ -type f | wc -l)
echo "**📊 总体统计:**" >> $GITHUB_STEP_SUMMARY
echo "- 📁 总文件数: $file_count" >> $GITHUB_STEP_SUMMARY
echo "- 📏 总大小: $total_size" >> $GITHUB_STEP_SUMMARY
echo "- 🗜️ 平均大小: $(echo "scale=2; $(du -s dist/ | cut -f1) / $file_count" | bc 2>/dev/null || echo "N/A") KB" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "<details>" >> $GITHUB_STEP_SUMMARY
echo "<summary>📋 详细文件列表</summary>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
ls -lah dist/ | head -30 >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "</details>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "<details>" >> $GITHUB_STEP_SUMMARY
echo "<summary>📏 文件大小排序</summary>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
du -h dist/* | sort -hr | head -15 >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "</details>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
fi
# 环境信息
echo "## 🔧 环境信息" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "<details>" >> $GITHUB_STEP_SUMMARY
echo "<summary>🖥️ 系统信息</summary>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "操作系统: $(uname -a)" >> $GITHUB_STEP_SUMMARY
echo "CPU信息: $(nproc) cores" >> $GITHUB_STEP_SUMMARY
echo "内存信息: $(free -h | grep Mem | awk '{print $2}') total" >> $GITHUB_STEP_SUMMARY
echo "磁盘空间: $(df -h / | tail -1 | awk '{print $4}') available" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "</details>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 总结
echo "## 📋 构建总结" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# 确定整体状态
overall_status="success"
if [[ "${{ steps.build_step.outcome }}" != "success" ]]; then
overall_status="failure"
elif [[ "${{ steps.test_step.outputs.test_passed }}" == "false" ]]; then
overall_status="warning"
fi
case $overall_status in
"success")
echo "🎉 **构建成功!** 所有步骤都已完成,构建产物已生成并可供使用。" >> $GITHUB_STEP_SUMMARY
;;
"warning")
echo "⚠️ **构建完成但有警告!** 构建产物已生成,但测试存在问题,请检查测试结果。" >> $GITHUB_STEP_SUMMARY
;;
"failure")
echo "❌ **构建失败!** 请检查构建日志以了解失败原因。" >> $GITHUB_STEP_SUMMARY
;;
esac
echo "" >> $GITHUB_STEP_SUMMARY
echo "---" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "📎 **产物下载:** 构建产物已上传为 Artifact,可在 Actions 页面下载。" >> $GITHUB_STEP_SUMMARY
echo "🔗 **提交链接:** https://github.com/${{ steps.project.outputs.owner }}/${{ steps.project.outputs.repo }}/commit/${{ steps.project.outputs.full_sha }}" >> $GITHUB_STEP_SUMMARY