Skip to content

PatilParas05/buildpulse-android

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

29 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

⚑ BuildPulse Android

Gradle Plugin Portal License: MIT Kotlin

A powerful Gradle Plugin for Android projects that tracks, compares, and reports build performance metrics β€” including total build time, per-module durations, per-task durations, and regressions between builds.

Never let your build times creep up again. πŸš€

BuildPulse Report


🧠 What is a Gradle Plugin?

A Gradle Plugin is a build-time tool β€” it runs during your build process, not inside your app. It never becomes part of your APK. It hooks into Gradle's lifecycle to observe, measure, or modify how your project is built.

This is fundamentally different from a regular Android library:

Regular Library (e.g. Retrofit) Gradle Plugin (e.g. BuildPulse)
Added via implementation(...) in module's build.gradle.kts id(...) in root plugins {} block
Runs Inside your app, on a device During the build, on your machine
Part of APK? βœ… Yes ❌ No
Examples Coil, Room, OkHttp Hilt, KSP, BuildPulse

✨ Features

  • ⏱️ Total build time tracking β€” measures how long your entire build takes
  • πŸ“¦ Module-level breakdown β€” see which modules (:app, :feature-login, :core-network) are slowest
  • πŸ”§ Task-level breakdown β€” drill down into individual Gradle tasks
  • πŸ“Š Regression detection β€” compares current build vs previous build and flags slowdowns
  • 🚨 CI enforcement β€” optionally fail the build if a regression exceeds your threshold
  • 🌐 HTML report β€” generates a beautiful visual report at buildpulse/build-metrics.html
  • πŸ’Ύ Metrics persistence β€” saves metrics to buildpulse/build-metrics.json for comparison across builds
  • 🎯 Zero dependencies β€” pure Gradle + Kotlin stdlib, no external libraries

πŸ“¦ Installation

Using Gradle Plugin Portal (Recommended)

Add the plugin to your root build.gradle.kts:

plugins {
    id("io.github.PatilParas05.buildpulse-android") version "1.0.0"   // ← Add this
}

That's it! Sync your project and run a build.

Check Latest Version

Always use the latest version from the Gradle Plugin Portal.


πŸš€ Usage

BuildPulse runs automatically every time you build your project. No special commands needed.

First Build (Creates Baseline)

./gradlew assembleDebug

Console Output:

╔═══════════════════════════════════════════════════╗
β•‘          πŸ“Š  BuildPulse β€” Metrics Summary         β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Total build time: 25.3s (first run)

Module Breakdown (sorted by time ↓)
  ─────────────────────────────────────
    app                    40,056 ms   
    core-network           22,347 ms   
    feature-login          16,987 ms   

═══════════════════════════════════════════════════════

Second Build (Shows Diffs)

./gradlew assembleDebug

Console Output:

╔═══════════════════════════════════════════════════╗
β•‘          πŸ“Š  BuildPulse β€” Metrics Summary         β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Total build time: 18.2s (-7.1s βœ…)

Module Breakdown (sorted by time ↓)
  ─────────────────────────────────────
    app                    28,120 ms   (-11,936 ms βœ…)
    core-network           15,230 ms   (-7,117 ms  βœ…)
    feature-login          12,450 ms   (-4,537 ms  βœ…)

  βœ…  BuildPulse CI Check: no regressions detected.

═══════════════════════════════════════════════════════

View HTML Report

Open buildpulse/build-metrics.html in your browser for an interactive dashboard:

buildpulse/
  β”œβ”€β”€ build-metrics.json   ← raw metrics data
  └── build-metrics.html   ← open this in browser βœ…

In Android Studio:

  1. Find the file in Project panel
  2. Right-click β†’ Open In β†’ Browser

βš™οΈ Configuration Options

All options are configured in the buildPulse { } block in your root build.gradle.kts:

Option Type Default Description
enabled Boolean true Enable or disable the plugin entirely
trackTasks Boolean true Track individual task durations
trackModules Boolean true Roll up task times into module totals
failOnRegression Boolean false Fail the build if a regression is detected
maxAllowedIncreaseMs Long 500L Threshold in ms above which a slowdown is a regression
outputDir String "buildpulse" Directory where JSON and HTML reports are written
generatedHtmlReport Boolean true Whether to generate the HTML visual report

πŸ€– CI Integration

Enable Enforcement Mode

buildPulse {
    failOnRegression     = true   // ← Fail builds on regression
    maxAllowedIncreaseMs = 500L   // ← Max allowed slowdown
}

Now if any module gets slower by more than 500ms, the build fails:

❌  BuildPulse CI Check FAILED β€” regression detected!

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Regressions  (threshold exceeded)                  β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚  [Module]  app                              +720 ms
  β”‚           prev: 28,120 ms  β†’  now: 28,840 ms
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

BUILD FAILED

πŸ—οΈ Project Structure

buildpulse-android/
β”œβ”€β”€ plugin/                        # The Gradle plugin source
β”‚   └── src/main/kotlin/
β”‚       └── dev/paraspatil/buildpulse/
β”‚           β”œβ”€β”€ BuildPulsePlugin.kt        # Plugin entry point
β”‚           β”œβ”€β”€ BuildPulseExtension.kt     # DSL configuration
β”‚           β”œβ”€β”€ TaskTimingListener.kt      # Hooks into Gradle task lifecycle
β”‚           β”œβ”€β”€ MetricsCollector.kt        # Aggregates timing data
β”‚           β”œβ”€β”€ MetricsStore.kt            # Saves/loads metrics as JSON
β”‚           β”œβ”€β”€ MetricsComparator.kt       # Diffs current vs previous build
β”‚           β”œβ”€β”€ ReportGenerator.kt         # Console report
β”‚           β”œβ”€β”€ HtmlReportGenerator.kt     # HTML report
β”‚           β”œβ”€β”€ CIEnforcer.kt              # Fails build on regression
β”‚           └── model/
β”‚               └── BuildMetrics.kt        # Data models
β”œβ”€β”€ app/                           # Sample Android app
β”œβ”€β”€ feature-login/                 # Sample feature module
β”œβ”€β”€ core-network/                  # Sample core module
└── buildpulse/                    # Generated output (after build)
    β”œβ”€β”€ build-metrics.json
    └── build-metrics.html

βš™οΈ How It Works

  1. Plugin Registration: BuildPulsePlugin registers a TaskExecutionListener via TaskTimingListener
  2. Task Tracking: Before each task runs, it records a start timestamp; after completion, it calculates elapsed time
  3. Build Finished: When gradle.buildFinished fires, MetricsCollector aggregates task times into module totals
  4. Load Previous: MetricsStore loads the previous build's metrics from JSON (if it exists)
  5. Comparison: MetricsComparator diffs the two builds to find regressions and improvements
  6. Console Report: ReportGenerator prints a summary to the console
  7. HTML Report: HtmlReportGenerator writes a visual dashboard to disk
  8. CI Enforcement: CIEnforcer optionally throws a GradleException if regressions exceed the threshold

πŸ“š What I Learned Building This

  • How Gradle plugins work internally and how they differ from Android libraries
  • How TaskExecutionListener hooks into the build lifecycle
  • How composite builds (includeBuild) allow local plugin development without publishing
  • How plugin marker artifacts work and the Gradle Plugin Portal submission process
  • How to serialize/deserialize build metrics manually (without a JSON library)
  • How to generate HTML reports from Kotlin string templates
  • How to enforce build quality gates in CI/CD pipelines

🀝 Contributing

Contributions are welcome! Please:

  1. Fork the repo
  2. Create a feature branch (git checkout -b feature/amazing)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing)
  5. Open a Pull Request

πŸ“ License

MIT License - see LICENSE file for details.


πŸ‘¨β€πŸ’» Author

Paras Patil


πŸ™ Acknowledgments

Built with ❀️ to solve a real pain point in Android development.

If BuildPulse helped you catch a build regression, give it a ⭐!


πŸ“ž Support


⭐ Show Your Support

If you find BuildPulse useful:

  • ⭐ Star this repo
  • 🐦 Share on Twitter
  • πŸ“ Write a blog post about it
  • πŸ’¬ Tell your teammates

πŸ”— Quick Links


Made with β˜• and Kotlin

BuildPulse β€’ Keep Your Builds Fast πŸš€

About

⚑ A custom Gradle plugin to track and report Android build performance. Monitor module/task timings and catch regressions with automated HTML reports! πŸ“ŠπŸš€πŸ› οΈ

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors