[FEATURE Request] - Delete workflow runs (runs/:run_id)


I know there are some other posts about this in the forum

e.g :

- Delete-old-workflow-results 

So my feature request is the following :

May github add a DELETE method to the following secured endpoint ?


It could be so helpfull because then we could use this endpoint to cleanup our runs when we want to. (Using whatever we want like postman workspace, script or even action, etc…)

IMHO, it’s the easiest way to allow users to clean runs, because there is no impact on the actual github action UI and general process.

What do you think about it ?



Hi @grzi,

Thanks for this feedback! We’re always working to improve GitHub and the GitHub Community Forum, and we consider every suggestion we receive. I’ve logged your feature request in our internal feature request list. Though I can’t guarantee anything or share a timeline for this, I can tell you that it’s been shared with the appropriate teams for consideration.


Today this option is not on github :frowning:

Thats the reason I developed a python-script (using PyGithub):

def cleanup_workflow_runs(self, repo, workflow_selection = None, run_selection = None, interactive: bool = True):

        ''' Delete workflow runs.

        Actual you have to do this manual... This is lame. This function will help you and saves your time.


            repo: Repository with type 'Github.get_repo()' or as str.

            workflow_selection: default = None, e.g. 'Self Hosted CI'

            run_selection: default = None, e.g. 'all', 'cancelled', 'failure' or 'success'

            interactive: default = True. If True the function will expact yout input/selection. If False all workflow-runs will be deleted.


        # input management

        if isinstance(repo, str):

            repo = self.get_repo(repo)

        # get a list of all workflows in the repo

        workflowList = repo.get_workflows()

        if workflowList.totalCount == 0:

            print("There are no workflows in your selected repository: '{}'".format(repo.name))


        # print list

        print("List of all workflows of your selected repository: '{}'".format(repo.name))

        for workflow in workflowList:

            print(" ID: '{}', Name: '{}', State: '{}'".format(workflow.id, workflow.name, workflow.state))

        # if no selection of a workflow is initiated by function-call

        if workflow_selection == None and interactive:

            workflow_selection = input("Please select a workflow by Name:")

        # if no interactive and no selection is done: choose the first workflow of the list

        elif workflow_selection == None and not interactive:

            print("First workflow chosen automatically: '{}'".format(workflowList[0].name))

            workflow_selection = workflowList[0].name

        # search workflow in list

        found = False

        for workflow in workflowList:

            if workflow.name == workflow_selection:

                print("Workflow found in list above: {}".format(workflow_selection))

                found = True


        # if workflow found

        if found:

            # get runs

            runList = workflow.get_runs()

            print("Run List: ")

            for run in runList:

                print(" Run Number: '{}', Satus: '{}', Conclusion: '{}', ID: '{}'".format(run.run_number, run.status, run.conclusion, run.id))

            # get input

            if run_selection == None and interactive:

                ans = input("Select a special run number (e.g. 123), a list of workflow run numbers seperated by comma (e.g. 123, 111, 112) or type >all<, >cancelled<, >failure< or >success<:")

            # choose all if no selection is done an not interaction is used

            elif run_selection == None and not interactive:

                ans = 'all'

            # choose selection if special run is selected


                ans = run_selection

            # manage input: choose selection

            selectedRuns = []

            if ans not in ['all', 'cancelled', 'failure', 'success']:

                ansSplit = ans.split(',')

                for id in ansSplit:



                for run in runList:

                    if ans == 'all':


                    elif ans in ['cancelled', 'failure', 'success'] and run.conclusion == ans:


            # interate over list and 

            for run in runList:

                if run.run_number in selectedRuns:

                    # delete completed workflow run

                    if run.status == 'completed':

                        print("delete run with number: '{}'".format(run.run_number))

                        repo._requester.requestJson("DELETE", run.url)

                    # ask for cancel workflow run


                        print("It is not possible to delete run: '{}'. This is not completed.".format(run.run_number))

                        if interactive:

                            ans = input("Do you want to cancel it? Yes [default] or No:")

                            if ans in ['y', 'Y', 'yes', 'YES', 'Yes', '']:


                                print("Pleas rerun cleanup")

                            elif ans in ['n', 'N', 'no', 'NO', 'No']:

                                print("No cancel selected!")


                                print("Unkown input!")


            print("Workflow '{}' not found in list above.".format(workflow_selection))