Skip to content

构建扫描与分析 ​

源:Gradle Build Scans | Develocity

Build Scan 是 Gradle 提供的交互式构建报告,详细记录构建过程的每个细节,帮助诊断问题和优化性能。

Build Scan 概念 ​

什么是 Build Scan ​

Build Scan 是一份上传到 Gradle 服务器的详细构建报告,包含:

构建元数据:

  • 构建时间和结果
  • Gradle 版本和环境
  • 插件版本

任务信息:

  • 任务执行时间
  • 任务依赖关系
  • 任务输入输出

性能数据:

  • 配置阶段耗时
  • 执行阶段耗时
  • 依赖解析耗时

依赖信息:

  • 依赖树
  • 依赖冲突
  • 依赖下载

生成 Build Scan ​

命令行生成 ​

bash
./gradlew build --scan

流程:

  1. 构建完成后提示
Publishing build scan...
https://gradle.com/s/abc123xyz
  1. 首次使用需要接受协议
Do you accept the Gradle Cloud Services license agreement (https://gradle.com/terms-of-service)? [yes, no]
yes
  1. 打开链接查看报告

自动启用 ​

gradle.properties:

properties
# 始终生成 Build Scan
org.gradle.caching=true

settings.gradle.kts:

kotlin
plugins {
    id("com.gradle.enterprise") version "3.16"
}

gradleEnterprise {
    buildScan {
        termsOfServiceUrl = "https://gradle.com/terms-of-service"
        termsOfServiceAgree = "yes"
        
        // 自动发布
        publishAlways()
    }
}

Build Scan 内容 ​

Performance 性能 ​

Timeline 时间线:

  • 配置阶段
  • 依赖解析
  • 任务执行
  • 输出上传

Task Execution 任务执行:

  • 任务列表(按耗时排序)
  • 任务状态(执行/缓存/UP-TO-DATE)
  • 任务输入输出

Build Cache 构建缓存:

  • 缓存命中率
  • 缓存保存/加载
  • 节省的时间

Configuration 配置:

  • 脚本编译时间
  • 插件配置时间
  • 项目配置时间

Dependencies 依赖 ​

Dependency Tree 依赖树:

  • 完整依赖图
  • 传递依赖
  • 依赖版本

Dependency Resolution 依赖解析:

  • 解析时间
  • 仓库访问
  • 依赖冲突

Downloaded Dependencies 下载:

  • 下载的库
  • 下载大小
  • 下载时间

Infrastructure 基础设施 ​

Environment 环境:

  • Gradle 版本
  • JVM 版本
  • 操作系统
  • CPU 和内存

Build Configuration 构建配置:

  • gradle.properties
  • 环境变量
  • JVM 参数

Plugins 插件:

  • 应用的插件
  • 插件版本
  • 插件耗时

使用场景 ​

场景1:诊断慢构建 ​

步骤:

  1. 生成 Build Scan
bash
./gradlew build --scan
  1. 查看 Performance → Task Execution

  2. 识别最慢的任务

:app:compileDebugKotlin - 12.5s
:app:kaptDebugKotlin - 8.3s
:app:processDebugResources - 3.2s
  1. 优化慢任务
  • compileDebugKotlin:考虑模块化
  • kaptDebugKotlin:迁移到 KSP
  • processDebugResources:减少资源

场景2:分析依赖冲突 ​

步骤:

  1. 查看 Dependencies → Dependency Resolution

  2. 查找冲突

com.squareup.okhttp3:okhttp
├── 4.12.0 (requested: 4.9.0)
└── 4.12.0 (requested: 4.12.0)
  1. 查看冲突原因

  2. 修复冲突

场景3:缓存效率分析 ​

步骤:

  1. 查看 Performance → Build Cache

  2. 检查指标

Cacheable tasks: 150
From cache: 120 (80%)
Not from cache: 30 (20%)
Time saved: 45.3s
  1. 优化缓存命中率

对比构建 ​

对比功能 ​

对比两次构建:

  1. 保存第一次构建的 URL
  2. 运行第二次构建
  3. 在 Build Scan 中选择 "Compare with another build"
  4. 输入第一次构建的 URL

对比内容:

  • 构建时间差异
  • 任务执行差异
  • 缓存命中差异
  • 依赖变化

性能趋势 ​

跟踪性能:

Build 1: 45.3s
Build 2: 38.2s (↓ 15.7%)
Build 3: 36.9s (↓ 3.4%)
Build 4: 37.5s (↑ 1.6%)

团队协作 ​

分享 Build Scan ​

生成可分享链接:

bash
./gradlew build --scan

分享给团队:

  • 复制 URL
  • 发送给同事
  • 讨论问题

自定义标签 ​

添加标签:

kotlin
gradleEnterprise {
    buildScan {
        tag("CI")
        tag("feature-branch")
        value("Git Branch", "feature/login")
        value("Git Commit", "abc123")
    }
}

按标签筛选:

  • 查看所有 CI 构建
  • 查看特定分支构建
  • 分析趋势

隐私和安全 ​

数据上传 ​

上传内容:

  • 构建元数据(公开)
  • 任务信息(公开)
  • 环境信息(公开)
  • 源代码(不上传)

隐私设置:

kotlin
gradleEnterprise {
    buildScan {
        // 仅在 CI 上传
        publishOnDemand()
        
        // 或条件发布
        if (System.getenv("CI") == "true") {
            publishAlways()
        }
    }
}

私有 Build Scan 服务器 ​

Gradle Enterprise(企业版):

kotlin
gradleEnterprise {
    server = "https://gradle-enterprise.company.com"
    
    buildScan {
        publishAlways()
    }
}

优势:

  • 数据不离开内网
  • 更多功能
  • 团队协作

实战案例 ​

案例1:CI 性能监控 ​

GitHub Actions:

yaml
name: Build with Scan

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          gradle-home-cache-cleanup: true
      
      - name: Build with Scan
        run: ./gradlew build --scan
        env:
          GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}

案例2:性能回归检测 ​

脚本:

bash
#!/bin/bash

# 基线构建
./gradlew build --scan > baseline.txt
BASELINE_URL=$(grep "https://gradle.com/s/" baseline.txt | awk '{print $1}')

# 当前构建
./gradlew build --scan > current.txt
CURRENT_URL=$(grep "https://gradle.com/s/" current.txt | awk '{print $1}')

echo "Baseline: $BASELINE_URL"
echo "Current: $CURRENT_URL"
echo "Compare: ${CURRENT_URL}/compare/${BASELINE_URL##*/}"

案例3:依赖审计 ​

步骤:

  1. 生成 Build Scan
  2. 导出依赖列表
  3. 检查安全漏洞
  4. 生成报告

Build Scan vs 其他工具 ​

对比 ​

特性Build ScanProfile 报告Build Analyzer
详细程度⭐⭐⭐⭐⭐⭐⭐
交互性⭐⭐⭐⭐⭐⭐⭐
分享能力⭐⭐⭐⭐❌
依赖分析⭐⭐⭐⭐⭐
趋势分析⭐⭐⭐❌❌

组合使用 ​

推荐组合:

  • Build Scan:全面诊断
  • Profile 报告:快速查看
  • Build Analyzer:IDE 集成
  • Gradle Profiler:基准测试

最佳实践 ​

CI 自动生成:

kotlin
if (System.getenv("CI") == "true") {
    gradleEnterprise.buildScan.publishAlways()
}

添加有用标签:

kotlin
buildScan {
    tag(System.getenv("BRANCH_NAME") ?: "local")
    value("Git Commit", gitCommit)
    value("PR Number", prNumber)
}

定期审查:

  • 每周查看构建趋势
  • 识别性能退化
  • 及时优化

团队分享:

  • 分享慢构建链接
  • 讨论优化方案
  • 记录最佳实践

隐私保护:

  • 评估数据敏感性
  • 考虑私有部署
  • 配置上传策略