Community health analytics for GitHub organizations and repositories. devpulse imports contribution data from the GitHub API, enriches it with developer affiliations, and surfaces project health insights through a local dashboard.
Motivation and the drivers behind this project are covered in the blog post here
Features
Project Health
- Bus factor / pony factor -- minimum developers or organizations producing 50% of contributions
- Repository Status -- stars, forks, open issues, language, license with 30-day sparkline
- Stars & forks trends -- daily star and fork counts over the last 30 days with historical backfill
- Community Profile -- badges for README, Contributing, Code of Conduct, and issue/PR templates
Activity & Code
- Activity trends -- monthly event volume (PRs, reviews, issues, comments, forks) with total and 3-month moving average
- PR size distribution -- pull requests bucketed by lines changed (S/M/L/XL) per month
- Forks & activity -- monthly fork count vs total event activity
- Issue Open/Close Ratio -- monthly opened vs closed issues
Velocity
- Lead time (PR to merge) -- average days from PR creation to merge
- Change failure rate -- percentage of deployments causing failures (bug issues near releases + revert PRs)
- Release cadence -- monthly release counts (total, stable, deployments) with merge-to-main fallback
- Release downloads -- monthly download trends and top releases by download count
- Time to First Response -- average hours to first review or comment on PRs
Quality
- PR review ratio -- PRs to reviews per month with ratio trend line
- Review latency -- average hours from PR creation to first review
- Time to close -- average days to close all issues vs bug issues near releases
- Contributor reputation -- two-tier scoring (shallow local, deep GitHub API) with known bot filtering
Community
- Contributor retention -- new vs returning contributors per month
- Contributor momentum -- rolling 3-month active contributor count with month-over-month delta
- First-time contributor funnel -- new contributor milestones per month (first comment, first PR, first merge)
- Entity affiliations -- top contributing companies/orgs with drill-down to individual developers (GitHub profile + CNCF gitdm)
Dashboard
- Global summary banner -- organizations, repositories, events, contributors, and last import timestamp (GMT) at a glance
- Tabbed layout -- Health, Activity, Velocity, Quality, Community, and Events tabs with lazy-loaded charts
- Event search filters -- filter by type, date range, username, or entity from the Events tab
- Adjustable time period -- dropdown adapts to available data range per search scope
- Unified search --
org:nameorrepo:nameprefix syntax; all panels respect scope
Install
DevPulse with even more powerful analytics, AI-powered insights, and less data access limits is available as SaaS offering at https://devpulse.thingz.io/
Homebrew (macOS / Linux)
brew tap mchmarny/tap brew install devpulse
Binary releases
Visit latest releases page.
Build from source
Requires Go 1.26+.
git clone https://github.com/mchmarny/devpulse.git
cd devpulse
make buildSee DEVELOPMENT.md for details.
Quick start
1. Authentication
devpulse uses GitHub's device flow for OAuth. By default the token requests the repo scope for private repository access. Use --public to skip the repo scope when you only work with public repos. The token is stored in your OS keychain.
devpulse auth # private + public repo access (default) devpulse auth --public # public repo access only
Alternatively, set GITHUB_TOKEN to skip the auth command entirely:
export GITHUB_TOKEN=ghp_...2. Data import
Import events, affiliations, metadata, releases, and reputation for an org:
devpulse import --org <org>
Or target specific repos:
devpulse import --org <org> --repo <repo1> --repo <repo2>
Use --fresh to clear pagination state and re-import from scratch:
devpulse import --org <org> --fresh
Update all previously imported data (no flags needed):
Control how many repos import in parallel (default: 3):
devpulse import --concurrency 2
See docs/IMPORT.md for all import options.
3. Reputation score
Import computes basic reputation scores automatically. For deeper scoring using GitHub API signals (profile age, org membership, PR history, etc.):
devpulse score --org <org> # deep-score 5 lowest in org (default) devpulse score --org <org> --repo <repo> # scope to a specific repo devpulse score --org <org> --count 20 # deep-score 20 lowest
Run incrementally — each invocation scores the next batch of lowest-reputation contributors. See docs/SCORE.md for details.
4. Scheduled sync
For automated, scheduled imports, sync reads a config file and imports + scores one repo per run using hour-based round-robin rotation:
devpulse sync --config sync.yaml devpulse sync --config https://raw.githubusercontent.com/org/repo/main/config/sync.yaml # Override round-robin to sync a specific repo devpulse sync --config sync.yaml --org mchmarny --repo devpulse # Sync a specific repo without a config file (uses hardcoded defaults) devpulse sync --org mchmarny --repo devpulse
Config format (all reputation fields are optional with sensible defaults):
repos: - name: repo1 org: myorg reputation: scoreCount: 50 # contributors to deep-score per run (default: 50) staleAfter: "3d" # re-score after this duration (default: 3d) - name: repo2 org: myorg - name: devpulse org: mchmarny
The --config flag (or DEVPULSE_SYNC_CONFIG env var) accepts a local file path or HTTP(S) URL. Each run picks one repo from the list based on UTC hour % total repos, runs a full import, then deep-scores the lowest-reputation contributors. With 9 repos on an hourly schedule, each repo is imported 2-3 times per day while staying within GitHub's 5,000 requests/hour API rate limit. Reputation thresholds are configured per-repo in the YAML file.
5. Dashboard view
Opens your browser to http://127.0.0.1:8080. Use --port to change the port or --no-browser to suppress auto-open.
The dashboard shows a global summary banner (orgs, repos, events, contributors, last import timestamp in GMT) and organizes insights into six tabs: Health, Activity, Velocity, Quality, Community, and Events. Charts load lazily per tab.
You can run devpulse import in a separate terminal or cron job while the server is running — the dashboard picks up new data immediately after each import transaction commits. See docs/SERVER.md for details.
Use the search bar with prefix syntax to scope the dashboard:
| Prefix | Example | Scope |
|---|---|---|
org: |
org:myorg |
All repos in an organization |
repo: |
repo:devpulse |
Single repository |
No prefix defaults to org search.
6. Programmatic query
devpulse also exposes data as JSON for scripting:
devpulse query events --org mchmarny --repo devpulse --type pr --since 2024-01-01 devpulse query developer list --like mark devpulse query entity detail --name GOOGLE
See docs/QUERY.md for all query options.
7. Data deletion
Remove imported data for a specific org or repo:
devpulse delete --org <org> # delete all data for org devpulse delete --org <org> --repo <repo> # delete data for specific repo devpulse delete --org <org> --repo <repo> --force # skip confirmation prompt
8. Full reset
Delete all imported data and start fresh:
Prompts for confirmation before deleting the database.
Data sources
| Source | Data |
|---|---|
| GitHub API | PRs, issues, comments, reviews, forks, repo metadata, releases |
| cncf/gitdm | Developer-to-company affiliations |
Entity names are normalized automatically. Use devpulse substitute to correct misattributions:
devpulse substitute --type entity --old "INTERNATIONAL BUSINESS MACHINES" --new "IBM"
Database
Data is stored locally in SQLite (~/.devpulse/data.db). No external services required.
Architecture
See docs/ARCHITECTURE.md for details.
Verification
Release binaries are signed and attested in CI. No private keys — everything uses keyless Sigstore OIDC via GitHub Actions.
Verify checksum signature
cosign verify-blob \
--bundle checksums-sha256.txt.sigstore.json \
--certificate-identity-regexp 'github.com/mchmarny/devpulse' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums-sha256.txtVerify build provenance
gh attestation verify <binary> -R mchmarny/devpulse
Inspect SBOM
Each binary has a corresponding SBOM (SPDX JSON) attached to the release.
Contributing
Contributions are welcome. Please open an issue before submitting large changes. See CONTRIBUTING.md for guidelines and DEVELOPMENT.md for setup.
- Fork and clone the repository
- Create a feature branch
- Run
make qualify(tests, lint, vulnerability scan) - Submit a pull request





