- Notifications
You must be signed in to change notification settings - Fork14
Project that checks the billable minutes of GitHub actions by repo and workflow, then outputs to the console.
License
fergusmacd/github-actions-usage
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This GitHub Action can:
- fails when remaining minutes drop below a defined number
- print out monthly action minutes budget
- print out action usage per organization repo
- print out action usage per organization repo and workflow
- show totals for both of the above
- print out the number of remaining days in the billing cycle
- be run locally with Docker or python
This action came about because a project I was working on kept running out of free minutes very quickly. As an admin Iwas asking teams to reduce usage, but they had no idea which repos and workflows were clocking up the minutes. Worse,the billing user was away for a day, the free minutes ran out, and we had no buffer set up. Development and deploymentcame to a virtual standstill. So I started investigating ways to make usage more transparent.
With the use of GitHub Actions (GHA) in build and deploy pipelines, usage adda up very quickly. Once the monthly limithas been reached, as we found out, the workflows will just stop running thereby causing huge disruption in the build anddelivery pipeline. If the billing user is on holiday, this is pretty disastrous. Better to be forewarned and so extracredits can be added by the billing owner.
However, the usage minutes total is hidden away in the admin section and so repo owners cannot even see GHA usage. Evenif they could, the usage CSV that GitHub sends out contains too much information making it hard to isolate heavy usageworkflows and repos.
Furthermore, MacOS usage is charged at 10x, Windows 2x the rate of Ubuntu machines. This means that a 7 second actionruntime will be consume 1 minute of the allowance on Ubuntu, 10 minutes on MacOS, and 2 minutes on Windows. MacOS buildscan take 20-30 minutes and the free minutes soon dry up. It turned out, this was the cause of our high usage. Top tip:don't build MacOS machines in GitHub.
So I wrote this action to address the problems above, in the following way:
- fails the workflow if the minutes remaining drops below 100, or a user defined value meaning a notification will besent out to watchers
- show remaining minutes left in billing period
- give clear visibility of GitHub Action usage to all users
- show total usage per repo
- show total usage per repo and workflow
- show usage by machine type, i.e. Ubuntu, MacOS and Windows
To do this, the GHA prints out two tables:
- total usage per repo
- usage per repo and workflow
in the prettyprint formatted ASCII tables like this:
+--------------------------------+--------+-------+---------+| Repo Name | Ubuntu | MacOS | Windows |+------------------------------- +--------+-------+---------+| aws-infra | 0 | 0 | 0 || cicd-images | 12 | 0 | 0 || terraform-github-repository | 39 | 0 | 0 || --------- | ---- | ---- | ---- || Usage Minutes 2022-06-13 13:59 | 51 | 0 | 0 || --------- | ---- | ---- | ---- || Stats From GitHub | | | || Monthly Allowance: 2000 | | | || Usage Minutes: 51 | 51 | 0 | 0 || Remaining Minutes: 1949 | | | || Alarm Triggered at: 150 | | | || Paid Minutes: 0 | | | || Days Left in Cycle: 13 | | | |+--------------------------------+--------+-------+---------++--------------------------------+---------------------+--------+-------+---------+| Repo Name | Workflow | Ubuntu | MacOS | Windows |+--------------------------------+---------------------+--------+-------+---------+| aws-infra | automerge.yml | 0 | 0 | 0 || | close-stale-prs.yml | 0 | 0 | 0 || | enforce-labels.yml | 0 | 0 | 0 || | labeler.yml | 0 | 0 | 0 || | release.yml | 0 | 0 | 0 || | setup-terraform.yml | 0 | 0 | 0 || -------- | -------- | ----- | ----- | ----- || -------- | -------- | ----- | ----- | ----- || github-audit | automerge.yml | 0 | 0 | 0 || | close-stale-prs.yml | 15 | 0 | 0 || | enforce-labels.yml | 0 | 0 | 0 || | labeler.yml | 0 | 0 | 0 || | release.yml | 0 | 0 | 0 || | setup-terraform.yml | 0 | 0 | 0 || -------- | -------- | ----- | ----- | ----- || terraform-github-repository | No workflows | | | || -------- | -------- | ----- | ----- | ----- || Usage Minutes 2022-06-13 13:59 | | 15 | 0 | 0 || -------- | -------- | ----- | ----- | ----- || Stats From GitHub | | | | || Monthly Allowance: 2000 | | | | || Usage Minutes: 15 | | 15 | 0 | 0 || Remaining Minutes: 1985 | | | | || Alarm Triggered at: 150 | | | | || Paid Minutes: 0 | | | | || Days Left in Cycle: 13 | | | | |+--------------------------------+---------------------+--------+-------+---------+
The action calls GitHub REST API endpoints to get the required information, and then prettyprint for formatting.
To get the number of repos, itcallsGitHub Organisation API. For information on eachrepo, itcallsGitHub List Organisational Repos API. For repository workflows, itcallsGitHub List Repository Workflow API. For workflow usage, itcallsGitHub Get Workflow Usage API.
For days left in the billing cycle , itcallsGitHub Get Actions billing for an organization API.
Finally for monthly allowance, paid minutes and what GitHub think has been used itcallsGitHub Get shared storage billing for an organization API
- an organisation or repo secret called
ORGANISATION
with the value of your organisation - a secret called
GITHUBAPIKEY
with the value being a personal access token (PAT) with scoperead:org
for readingpublic repos andrepo:full
for reading private repos.
Create a file calledgha-audit.yml
in yourworkflows
directory, paste the following as the contents and you are goodtogo.GHA best practicesrecommend using a commit SHA, rather than a version. The example below runs on a schedule at 3AM every day. This waywhen the remaining allowance drops below the threshold (100 or user defined) a notification will be triggered.
name: GHA Usage Auditon: schedule: - cron: "0 3 * * *" # Runs at 03:00 AM (UTC) every dayjobs: gha-usage-minutes-report: runs-on: ubuntu-latest steps: - name: GitHub Actions Usage Audit uses: fergusmacd/github-action-usage@daff7e5517914546a1e39fcc22f476e1471853f6 # use a commit SHA # pass user input as arguments with: organisation: ${{secrets.ORGANISATION}} gitHubAPIKey: ${{secrets.GITHUBAPIKEY}} # default token in GitHub Workflow loglevel: error # not required, change to debug if misbehaving raisealarmremainingminutes: 100 # not required, defaults to 100 skipReposWithoutUsage: false
The docker file and python script can both be run locally in the following ways.
For python, from the python directory:
pip install -r requirements.txt# default is warning, see the action.yaml for further details# GHA environment variables prepend INPUT_ to values passed inexport INPUT_LOGLEVEL=debug|info|warning|errorexport INPUT_ORGANISATION="myorg"export INPUT_GITHUBAPIKEY="***"export INPUT_RAISEALARMREMAININGMINUTES="150"export INPUT_SKIPREPOSWITHOUTUSAGE="false"export# from python directory you can runpython main.py
For Docker, run from the root directory:
# from root directorydocker build -t gha-billable-usage.# GHA environment variables prepend INPUT_ to values passed inexport INPUT_LOGLEVEL=debug|info|warning|errorexport INPUT_ORGANISATION="myorg"export INPUT_GITHUBAPIKEY="***"export INPUT_RAISEALARMREMAININGMINUTES="150"export INPUT_SKIPREPOSWITHOUTUSAGE="false"docker run -v$PWD:/app/results -e INPUT_RAISEALARMREMAININGMINUTES=${INPUT_RAISEALARMREMAININGMINUTES} -e INPUT_LOGLEVEL=${INPUT_LOGLEVEL} -e INPUT_ORGANISATION=${INPUT_ORGANISATION} -e INPUT_GITHUBAPIKEY=${INPUT_GITHUBAPIKEY} -e INPUT_SKIPREPOSWITHOUTUSAGE=${INPUT_SKIPREPOSWITHOUTUSAGE} -it gha-billable-usage
When problems happen, the best thing to do is set the log level todebug
like this locally:
export LOGLEVEL="debug"
Or change the loglevel input in the GHA.
The following one happens when running locally and theINPUT_GITHUBAPIKEY
environment variable has not been exported:
python3 main.pyTraceback (most recent call last): File"/github-action-usage/python/main.py", line 5,in<module> from ghaworkflows import* File"/github-action-usage/python/ghaworkflows.py", line 9,in<module> github_api_key =getgithubapikey() File"/github-action-usage/python/common.py", line 24,in getgithubapikeyreturn os.environ['INPUT_GITHUBAPIKEY'] File"/usr/local/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/os.py", line 679,in __getitem__ raise KeyError(key) from NoneKeyError:'INPUT_GITHUBAPIKEY'
This error happens when the PAT has expired or does not have sufficient permissions:
python3 main.py Traceback (most recent call last): File"/github-action-usage/python/main.py", line 92,in<module>main() File"/github-action-usage/python/main.py", line 30,in main repoNames = getreposfromorganisation(org) File"/github-action-usage/python/ghorg.py", line 27,in getreposfromorganisation totalPrivateRepos = json_data["total_private_repos"]KeyError:'total_private_repos'
The following APIs are used:
- GitHub Organisation API - to get the number of repos
- GitHub List Organisational Repos API -to get the repo information
- GitHub List Repository Workflow API -to get the repository workflows
- GitHub Get Workflow Usage API - for workflowusage
- GitHub Get shared storage billing for an organization API
- for days left in billing cycle
There are plenty of tutorials on prettyprint, I used this one:
- alerts when limits are closed to being reached
- export to excel and upload to packages
- sorting by different criteria, e.g. tags or ownership
- test coverage
- test scripts
- colouring console
- any requests?
About
Project that checks the billable minutes of GitHub actions by repo and workflow, then outputs to the console.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors6
Uh oh!
There was an error while loading.Please reload this page.