Forecast your GHES Actions Minutes Usage - A GitHub CLI extension
npm install gh-forecast> š Forecast your GitHub Actions minutes usage for GHES (GitHub Enterprise Server) organizations
A GitHub CLI extension that analyzes workflow run history and calculates estimated GitHub Actions costs based on job durations and OS multipliers.
GHES self-hosted runners don't report "billable minutes" the same way GitHub.com does. This tool reconstructs the job history and applies GitHub's billing multipliers to give you a cost estimate if you were to migrate to GitHub-hosted runners.
``bashSet your token
export GH_TOKEN="ghp_xxxxxxxxxxxx"
That's it! The tool will analyze the last 30 days of workflow runs and show you cost estimates.
Installation
$3
`bash
npx gh-forecast --org my-org
`$3
`bash
npm install -g gh-forecast
gh-forecast --org my-org
`$3
`bash
gh extension install austenstone/gh-ghes-actions-forecast
gh ghes-actions-forecast --org my-org
`Usage
`bash
Basic usage - analyze the last 30 days
gh-forecast --org my-orgAnalyze a different time period
gh-forecast --org my-org --days 90Custom date range
gh-forecast --org my-org --start 2024-01-01 --end 2024-03-31Connect to GitHub Enterprise Server
gh-forecast --org my-org --host github.mycompany.comCustom label-to-OS mappings for self-hosted runners
gh-forecast --org my-org --map "runner-*:linux,mac-builder:macos"Output as JSON for further processing
gh-forecast --org my-org --output jsonOutput as CSV for spreadsheets
gh-forecast --org my-org --output csvGroup by week or month
gh-forecast --org my-org --group-by week
gh-forecast --org my-org --group-by monthShow workflow and job breakdown
gh-forecast --org my-org --show-workflows --show-jobsClear cached data
gh-forecast --clear-cache --org my-orgDisable caching for fresh data
gh-forecast --org my-org --no-cache
`Options
| Flag | Description | Default |
|------|-------------|---------|
|
-o, --org | GitHub organization name (required) | - |
| -d, --days | Number of days to analyze | 30 |
| --start | Start date (YYYY-MM-DD) | - |
| --end | End date (YYYY-MM-DD) | today |
| -H, --host | GitHub Enterprise Server hostname | github.com |
| -c, --concurrency | API request concurrency limit | 5 |
| -m, --map | Custom label-to-OS mappings | - |
| --output | Output format: table, json, csv | table |
| --group-by | Group results: day, week, month | day |
| --top-repos | Show top N repositories by usage | 10 |
| --show-workflows | Show workflow-level breakdown | false |
| --show-jobs | Show individual job details | false |
| --no-cache | Disable caching | - |
| --clear-cache | Clear all cached data and exit | - |
| --cache-ttl | Cache TTL in minutes | 30 |
| --verbose | Show detailed progress | false |Authentication
The extension uses authentication in this priority order:
1.
GH_TOKEN environment variable
2. GH_ENTERPRISE_TOKEN environment variable
3. gh auth token (from the gh CLI's stored credentials)For GHES, make sure you've authenticated:
`bash
Using environment variable (recommended for npx)
export GH_TOKEN="ghp_xxxxxxxxxxxx"Or authenticate with gh CLI
gh auth login --hostname github.mycompany.com
`Example Output
`
š GitHub Actions Forecast
Organization: my-org
Date range: 2024-11-08 to 2024-12-08 (30 days)
Cache: 3 files (6.0 KB) Authenticating... ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā | Fetching repos | 50/50 | ETA: 0s
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā | Fetching runs | 50/50 | ETA: 0s
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā | Fetching jobs | 234/234 | ETA: 0s
Completed in 4.2s: 50 repos, 234 runs, 1,456 jobs
š Results for my-org
Period: Nov 8, 2024 - Dec 8, 2024
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāā
ā Metric ā Value ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāā¤
ā Total Workflow Runs ā 234 ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāā¤
ā Total Jobs ā 1,456 ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāā¤
ā Total Minutes ā 45,230 ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāā¤
ā Billable Minutes (weighted) ā 67,845 ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāā¤
ā Estimated Cost (period) ā $543.60 ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāā
š„ļø Usage by Operating System:
āāāāāāāāāāā¬āāāāāāāāā¬āāāāāāāāāā¬āāāāāāāāāāāāā¬āāāāāāāāāāāāāāā
ā OS ā Jobs ā Minutes ā Multiplier ā Billable Min ā
āāāāāāāāāāā¼āāāāāāāāā¼āāāāāāāāāā¼āāāāāāāāāāāāā¼āāāāāāāāāāāāāāā¤
ā Linux ā 1,234 ā 38,500 ā 1x ā 38,500 ā
āāāāāāāāāāā¼āāāāāāāāā¼āāāāāāāāāā¼āāāāāāāāāāāāā¼āāāāāāāāāāāāāāā¤
ā Windows ā 192 ā 5,230 ā 2x ā 10,460 ā
āāāāāāāāāāā¼āāāāāāāāā¼āāāāāāāāāā¼āāāāāāāāāāāāā¼āāāāāāāāāāāāāāā¤
ā macOS ā 30 ā 1,500 ā 10x ā 15,000 ā
āāāāāāāāāāā“āāāāāāāāā“āāāāāāāāāā“āāāāāāāāāāāāā“āāāāāāāāāāāāāāā
š° Cost Projections (based on GitHub.com pricing):
āāāāāāāāāāā¬āāāāāāāāāāāāāāā¬āāāāāāāāāāāā
ā Period ā Billable Min ā Est. Cost ā
āāāāāāāāāāā¼āāāāāāāāāāāāāāā¼āāāāāāāāāāāā¤
ā Daily ā 2,262 ā $18.12 ā
āāāāāāāāāāā¼āāāāāāāāāāāāāāā¼āāāāāāāāāāāā¤
ā Weekly ā 15,834 ā $126.84 ā
āāāāāāāāāāā¼āāāāāāāāāāāāāāā¼āāāāāāāāāāāā¤
ā Monthly ā 67,860 ā $543.60 ā
āāāāāāāāāāā“āāāāāāāāāāāāāāā“āāāāāāāāāāāā
`Custom Label Mappings
Self-hosted runners often have custom labels like
runner-01-prod or build-agent-linux. Use the --map flag to specify how these should be categorized:`bash
gh-forecast --org my-org --map "runner-:linux,mac-:macos,win-*:windows"
`Format:
pattern:os,pattern:os- Patterns support
* wildcards
- OS must be one of: linux, windows, macos
- Custom mappings take precedence over default detectionBilling Multipliers
GitHub Actions bills different runner types at different rates:
| OS | Multiplier | Rate/min |
|----|------------|----------|
| Linux | 1x | $0.008 |
| Windows | 2x | $0.016 |
| macOS | 10x | $0.080 |
> Note: These are GitHub.com public rates. Actual GHES costs depend on your enterprise agreement.
How It Works
1. Discovery: Lists all repositories in the target organization
2. History Extraction: Fetches completed workflow runs for the specified time period
3. Job Drill-down: For each run, fetches job details including runner labels and timing
4. OS Detection: Analyzes
runs-on labels to determine the OS (or uses custom mappings)
5. Cost Calculation: Applies GitHub's billing multipliers and rounds up to the nearest minute
6. Aggregation: Groups data by OS, repository, workflow, and date
7. Caching: Results are cached locally for 30 minutes to speed up subsequent runsCaching
Results are cached in
~/.gh-forecast-cache to avoid redundant API calls:`bash
View cache status (shown in header when running)
gh-forecast --org my-orgClear cache when you need fresh data
gh-forecast --clear-cache --org my-orgDisable caching entirely
gh-forecast --org my-org --no-cacheCustom cache TTL (in minutes)
gh-forecast --org my-org --cache-ttl 60
`Development
`bash
Clone the repo
git clone https://github.com/austenstone/gh-ghes-actions-forecast.git
cd gh-ghes-actions-forecastInstall dependencies
npm installBuild
npm run buildRun locally
node dist/index.js --org my-orgOr link globally for testing
npm link
gh-forecast --org my-org
`Publishing
`bash
Build and publish to npm
npm publishUsers can then run with npx
npx gh-forecast --org my-org
``MIT