Table of contents
I wrote about using GitHub CLI to interact with the API to get mundane tasks done.
This quick follow-up demonstrates the use case with a different scenario for deleting old caches from GitHub Actions.
The Context
Every public repository gets 10 GiB worth of cache storage across all its workflows. Usually, this is fine because GitHub will automatically drop older caches. You will likely hit these limits often if you have a famous repository.
But what if you want to start over? What if you have multiple soiled caches that you want to remove? Or what if one of your caches gets soiled for some reason, and you want to remove it to avoid multiple PRs and workflow jobs referencing it?
Well, GitHub has a handy UI you can use:
You can click the delete button (trash can icon) and remove items one by one.
I know; keeping the tradition of this blog, we will not do that.
Are we?
Use the CLI to remove the orphaned entries
For starters, let's look at the API documentation and get the list of all the caches for a repository:
gh api \
-H "Accept: application/vnd.github+json" \
/repos/OWNER/REPO/actions/caches
And you get something along these lines:
{
"total_count": 42,
"actions_caches": [
{
"id": XXXXX,
"ref": "refs/heads/main",
"key": "npm-linux-x64-xxxxxxxxx",
"version": "04d00cc68e2xxxxxxx",
"last_accessed_at": "2022-11-02T13:32:08.323333300Z",
"created_at": "2022-10-31T13:03:43.376666700Z",
"size_in_bytes": 319315417
},
{
"id": XXXYZ,
"ref": "refs/heads/main",
"key": "cypress-linux-x64--xxxxxxxxx",
"version": "04d00cc68e2xxxxxxx",
"last_accessed_at": "2022-11-02T13:32:08.313333300Z",
"created_at": "2022-10-31T13:03:57.923333300Z",
"size_in_bytes": 165492002
},
...
Nice.
Next, we can use another API endpoint to delete a cache by its id:
gh api \
--method DELETE \
-H "Accept: application/vnd.github+json" \
/repos/OWNER/REPO/actions/caches/XXXXX
OK — how do we bring this together?
Let's introduce some jq
-style queries. If you remember from the previous post, GitHub CLI supports queries based on the popular jq
tool to help filter the output.
Instead of the output in the first command, you can filter on fewer parameters relevant to your needs.
I'll explain with an example.
gh api \
-H "Accept: application/vnd.github+json" \
/repos/freeCodeCamp/freeCodeCamp/actions/caches \
+ -q '.actions_caches[] | { id, last_accessed_at }'
Here this line -q' .actions_caches[] | { id, last_accessed_at }
essentially is the query where you ask GitHub CLI to filter on the parameters you care about. The result looks much minimal:
{ "id":XXXXX, "last_accessed_at":"2022-11-02T13:32:08.323333300Z" }
{ "id":XXXYY, "last_accessed_at":"2022-11-02T13:32:08.313333300Z" }
{ "id":XXXZZ, "last_accessed_at":"2022-11-02T12:12:46.446666700Z" }
...
Let's take it a step further. We want to filter the ids for the caches say that are older than two days and delete those. With that in mind, let's design a query to get an array of all the id
s and the last_accessed_at
properties.
.actions_caches[]
| { id, last_accessed_at }
+ | select(.last_accessed_at < "2022-11-02T00:00:00.000000000Z")
There are several ways to create a selector; I have demoed an approach that worked for me: finding anything older than a specific date. If you need to look up selectors, you should check out helpful tips on StackOverflow.
Let's put it all together:
gh api \
-H "Accept: application/vnd.github+json" \
/repos/OWNER/REPO/actions/caches \
-q '.actions_caches[]
| { id, last_accessed_at }
| select(.last_accessed_at < "2022-11-02T00:00:00.000000000Z")
| {id}
| .[]'
The above should give us a list of the ids we can use in a separate "delete-by-id" call to GitHub's API.
Using another favorite tool of mine — the mighty xargs
we can automate calling the delete endpoint like so:
gh api \
-H "Accept: application/vnd.github+json" \
/repos/OWNER/REPO/actions/caches \
-q '.actions_caches[]
| { id, last_accessed_at }
| select(.last_accessed_at < "2022-11-02T00:00:00.000000000Z")
| {id}
| .[]' \
--paginate | xargs -I {} \
gh api \
--method DELETE \
-H "Accept: application/vnd.github.v3+json" \
/repos/OWNER/REPO/actions/caches/{}
That's it.
You can refresh the action caches' dashboard page and check the results.
I hope you liked this story, until the next one.