Blog.

Use Python To Clean Up Your Github Actions Workflows

Cover Image for Use Python To Clean Up Your Github Actions Workflows
Wayne / Devscover
Wayne / Devscover

This is a guide for writing a Python script on how to delete workflows in Github actions.

Why did I decide to write this?

Well I work in a rather large team. We have CI running in Github actions on every push, pr and merge. There are a lot due to the fact we use a monorepo.

It got to the point at which there were 130,000 previous workflow runs, and I could not see a way of clearing them without manually going through each.

The main issue it causes is on the left hand side, you have a list of all the workflows. However even if you delete or rename the workflow, the name stays there. That means it was very time conusimning to find the correct workflow that was still active.

The way around this is to delete any workflow runs associated with an old or renamed workflow.

So here's the code:

import requests

ploads = {'per_page': 100, 'page': 100}
headers = {'Authorization': 'token abc123'}

while 1==1:
try:
r = requests.get('https://api.github.com/repos/YOUR_REPO/YOUR_PROJECT/actions/runs', params=ploads, headers=headers)
except requests.exceptions.RequestException as e:
raise SystemExit(e)

    print(r.status_code)
    if r.status_code == 200:
        j = r.json()

        try:
            for item in j['workflow_runs']:
                id = str(item['id'])
                print('Deleting ' + id)
                r2 = requests.delete('https://api.github.com/repos/YOUR_REPO/YOUR_PROJECT/actions/runs/'+id, headers=headers)
        except Exception as e:
            print(e)
            break

Now this isn't perfect by any means, but it worked for us. Just replace the YOUR_REPO and YOUR_PROJECT bit with yours so like /facebook/react or something.

You'll want to get an API key from GitHub.

The only other thing to do is play about with the pages and items per page feature. You can specify a maximum of 100 items per page, so you can work out where this script will start. We did it this way because we wanted to keep the 10,000 latest runs, but delete everything older