How to delete GitHub Actions Caches with GitHub CLI

How to delete GitHub Actions Caches with GitHub CLI

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:

image.png

You can click the delete button (trash can icon) and remove items one by one.

image.png

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 ids 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.

Did you find this article valuable?

Support Mrugesh Mohapatra by becoming a sponsor. Any amount is appreciated!