178

I created a couple workflows in the .github/workflows folder of my repository to experiment with GitHub Actions. I have since learned quite a bit and deleted said experimental workflows from my repo. After deleting the experimental workflow YAML files and committing the deletions, when I go to the Actions tab of my repository, I STILL see the workflows that I have since deleted.

I see no option to delete and start from scratch! Is this not possible? Is it possible through GitHub API?

3
  • 5
    I made this tool to easily delete workflow runs from bash: github.com/jv-k/delete-workflow-runs
    – jv-k
    Commented Jun 28, 2022 at 15:33
  • 5
    The issue is that that workflow, even if deleted from ~/.github/workflows still has runs under it. GitHub's feature is to preserve the workflow as long as it has some run metadata in it. So you need to delete all the runs under the workflow and it'll disappear from your Worflows tab. Commented Jul 23, 2022 at 9:59
  • 1
    👍 you can vote here github.com/community/community/discussions/26256 for this feature on UI
    – pbaranski
    Commented Oct 27, 2022 at 3:08

33 Answers 33

134
Answer recommended by CI/CD Collective

As of July 7, 2020, you can now delete the results of individual workflow runs. To do this, navigate to your workflow, find the workflow run that you want to delete, and select the "..." menu. In this menu, select "Delete workflow run".

The workflow run and its logs will be removed.

Delete workflow run

Currently, you must do this for each workflow run individually.

edit: As of 2021 Feb it seems that after all workflow runs are deleted the workflow it self disappears. One comment below also seems to confirm this.

9
  • 93
    I'm looking forward to that feature. In the meantime, when getting Actions set up, I recommend doing it in another repo so that all the detritus you create experimenting doesn't haunt you. Sadly, for anyone reading this, it's likely too late. Commented Sep 14, 2019 at 23:12
  • 1
    A feature no one complains about is likely useless:) Actions seem useful, but workflow runs seem weirdly implemented. Wouldn't the normal actions available for a top level user data object like this be "Create, Read, Update, Destroy"? Workflow runs only seem to support read and update (re-run) at this time. Apparently creating them or deleting them only happens automatically and can not be done manually. Commented Nov 16, 2019 at 22:45
  • 4
    it is important that it is possible to delete action logs, to prevent spreading of credentials and/or confidential information when a logging error is done in one of the actions/code being tested... Commented Mar 4, 2020 at 9:47
  • 4
    Just did this and it removed the workflow label from the sidebar too. I first disabled the workflow, then deleted all its runs from the UI. Workflow is now gone :)
    – mattwad
    Commented Jan 7, 2021 at 18:00
  • 2
    but if the workflow is empty, then file remove from repo. There will be no way to remove the workflow. because cannot remove any run in the workflow
    – Xin Meng
    Commented Jul 15, 2021 at 13:45
87

It doesn't seem that there is currently a way to delete those workflows - this makes no sense - but it appears that once one makes the mistake of creating one they are stuck with it forever. The only solution so far I found is to disable these workflows.

So if I go to the Actions tab (edit the url to match your repo), I can then click on a workflow and disable it via [...] in the right top corner of that tab as in the snapshot below:

enter image description here

To delete all workflow results at once

To delete the records here is the solution I found here with slight modifications from the original:

user=GH_USERNAME repo=REPO_NAME; gh api repos/$user/$repo/actions/runs \
--paginate -q '.workflow_runs[] | select(.head_branch != "master") | "\(.id)"' | \
xargs -n1 -I % gh api repos/$user/$repo/actions/runs/% -X DELETE

Replace GH_USERNAME and REPO_NAME with the desired github username and repo name correspondingly.

This will delete all the old workflows that aren't on the master branch. You can further tweak this to do what you need.

Prerequisites:

  • You will find the latest gh version here.

Notes:

  • You may have to gh auth login if this is your first time using it
  • You may further change the command to gh api --silent if you prefer not to see the verbose output.
  • For the final xargs part of the command chain - the original used -J instead of -I, which is not supported by GNU xargs. -J results in a single command, and -I will execute the command for each records, so it's a bit slower.

Thank you to the OP on the community forum for sharing this in first place.

14
  • 5
    you should add a --silent modifier to the delete action like so: gh api --silent repos/$user/$repo/actions/runs/% -X DELETE
    – jaecktec
    Commented Dec 2, 2020 at 18:17
  • 2
    For starters: you need to install the jq package too. And probably the latest gh version as the link above. The one coming from apt-get doesn't have the 'api' command, for now. After that, you need to login, using gh auth login. One more note: you may have to run this several times because of API limit. Commented Mar 3, 2021 at 21:40
  • 1
    I don't really wnat to leave old/unneeded info in the answer, but it looks like it was since March github.com/cli/cli/releases/tag/v1.7.0
    – Worthy7
    Commented Jun 15, 2021 at 9:27
  • 1
    Amazing Answer ;)
    – Omar Hasan
    Commented Jun 27, 2021 at 8:28
  • 1
    Thank you very much, detailed and working instruction to remove all workflow Commented Jul 22, 2021 at 8:59
72

Based on @Giampaolo Rodolà's answer (which worked for me), I created this simple shell script that does the job.

Note:

  1. Disable the workflow you want to delete (via GitHub console) before executing this script.
  2. Ensure to have GitHub client installed and required token permissions in GitHub.
org=<your org>
repo=<your repo>

# Get workflow IDs with status "disabled_manually"
workflow_ids=($(gh api repos/$org/$repo/actions/workflows --paginate | jq '.workflows[] | select(.["state"] | contains("disabled_manually")) | .id'))

for workflow_id in "${workflow_ids[@]}"
do
  echo "Listing runs for the workflow ID $workflow_id"
  run_ids=( $(gh api repos/$org/$repo/actions/workflows/$workflow_id/runs --paginate | jq '.workflow_runs[].id') )
  for run_id in "${run_ids[@]}"
  do
    echo "Deleting Run ID $run_id"
    gh api repos/$org/$repo/actions/runs/$run_id -X DELETE >/dev/null
  done
done

Outcome:

Listing runs for the workflow ID 5261185
Deleting Run ID 507553125
Deleting Run ID 507548002
Listing runs for the workflow ID 5261568
Deleting Run ID 525274011
Deleting Run ID 525264327
Deleting Run ID 525247443
12
  • 2
    Worked perfectly (after a multiple runs, to get around the batch limit of the API only returning a subset of runs for each workflow). Thank you!
    – Mitch Ware
    Commented May 17, 2021 at 21:04
  • 3
    Exactly @MitchWare, for these cases, we can do something like while :; do clear; source script.sh; sleep 10; done.
    – Ribeiro
    Commented May 20, 2021 at 11:56
  • 2
    Awesome solution. 👍🏻 Commented Jul 28, 2021 at 20:49
  • 5
    You can add --paginate to the run_ids line which will save you from having to run it multiple times. From the gh help documentation: ``` --paginate Make additional HTTP requests to fetch all pages of results ``` So the updated line in the script would be: run_ids=( $(gh api repos/$org/$repo/actions/workflows/$workflow_id/runs --paginate | jq '.workflow_runs[].id') ) Commented Aug 11, 2021 at 13:37
  • 2
    @TerrySposato adding --paginate works perfectly, thank you.
    – mturatti
    Commented Aug 14, 2021 at 8:57
58

Here's a few commands to quickly clean up your workflows.

You'll need the xargs, gh and jq CLI tools.

OWNER=<your user/org name>
REPO=<repo name>

# list workflows
gh api -X GET /repos/$OWNER/$REPO/actions/workflows | jq '.workflows[] | .name,.id'

# copy the ID of the workflow you want to clear and set it
WORKFLOW_ID=<workflow id>

# list runs
gh api -X GET /repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/runs --paginate | jq '.workflow_runs[] | .id'

# delete runs
gh api -X GET /repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/runs --paginate | jq '.workflow_runs[] | .id' | xargs -I{} gh api -X DELETE /repos/$OWNER/$REPO/actions/runs/{} --silent
6
  • 1
    jq download
    – greg
    Commented Aug 15, 2021 at 22:26
  • 2
    also use homebrew to download jq brew install jq Commented Feb 14, 2022 at 16:09
  • 4
    Why not adding --paginate to gh commands ? Commented Feb 22, 2022 at 15:12
  • 3
    The listing and delete step needs --paginate to list all results like gh api --paginate -X
    – Joël
    Commented Mar 23, 2022 at 9:36
  • 4
    Thanks! I was able to run this much faster by adding -P 30 to xargs options: we can send many requests at once to github - there's no need to wait for the deletion of one run to move on to the next one.
    – silviot
    Commented Jun 28, 2022 at 8:20
23

Delete all runs from a certain workflow

An improved version of @Sheece Gardazi's answer that supports selecting a certain workflow:

export OWNER="my-user"
export REPOSITORY="my-repo"
export WORKFLOW="My Workflow"

gh api -X GET /repos/$OWNER/$REPOSITORY/actions/runs --paginate \
  | jq '.workflow_runs[] | select(.name == '\"$WORKFLOW\"') | .id' \
  | xargs -t -I{} gh api -X DELETE /repos/$OWNER/$REPOSITORY/actions/runs/{}

(The -t option to xargs prints each workflow run deletion request to the terminal.)

It requires GitHub CLI:

brew install gh
gh auth login

and jq:

brew install jq

*Note: don't forget to remove the the workflow file from the main branch after running the script if you want to completely get rid of it.

5
  • 6
    why isn't this an accepted answer? this works exaclty as expected
    – dark_ruby
    Commented Jan 8, 2022 at 21:24
  • This is spot on. It can take a minute or two before the deletions start, so be patient.
    – Roly
    Commented Aug 9, 2022 at 10:19
  • 1
    Option to add --silent to the DELETE call to continue execution of the script otherwise it gets stuck on the first one. Commented Feb 27, 2023 at 7:20
  • Only improvement would be to add -P 30 before gh api in order to send 30 requests in parallel, instead of 1 deletion at a time.
    – Rishav
    Commented Aug 18, 2023 at 23:55
  • 1
    If your workflows have a consistent naming pattern, you can use select(.name | contains('\"$WORKFLOW\"')) to match with contains rather than exact matches. Commented Dec 17, 2023 at 5:04
19

I managed to fix this (currently not possible via UI) by using "gh" CLI tool and reading REST API docs.

First, get all your workflows (these are the ones shown in the web UI -> Actions -> left column):

$ gh api repos/$YOUR_USER/$YOUR_REPO/actions/workflows
{
  "total_count": 2,
  "workflows": [
    {
      "id": 3611607,
      "name": "FreeBSD",
      ...
    },
    {
      "id": 4336318,
      "name": "MacOS",
      ...
    }
  ]
}

Use the ID of the workflow you want to delete (say 3611607) to get all of its individual runs:

$ gh api repos/$YOUR_USER/$YOUR_REPO/actions/workflows/3611607/runs
{
  "total_count": 17,
  "workflow_runs": [
    {
      "id": 363876785,
      "name": "FreeBSD",
      ...
    },
    {
      "id": 363876786,
      "name": "FreeBSD",
      ...
    },
    {
      "id": 363876787,
      "name": "FreeBSD",
      ...
    },
}

For each run id (let's say 363876785), delete it with:

$ gh api repos/$YOUR_USER/$YOUR_REPO/actions/runs/363876785 -X DELETE

After this, the undeletable Action in the left column of the web UI should disappear.

3
  • 1
    Didn't work for me; already had 0 runs against the action. Also, the individual runs are deletable directly in the web ui, so no need to do it via api calls unless you have a lot to loop through.
    – jarekwg
    Commented Dec 20, 2020 at 21:25
  • In my case for some reason they were not displayed in the UI Commented Dec 21, 2020 at 22:23
  • Thanks, worked for me! The UI reflected no runs since they had been deleted but inspecting the workflow via API showed 2 runs. Deleting those made the stuck workflow disappear Commented Jan 21, 2021 at 18:40
10

Until GitHub implements a "Delete all workflow runs", you have to rely on the API. With the CLI tools gh and jq installed on your workstation, you can run the following commands to delete all runs of that workflow. Once all runs are removed, it won't show up anymore in the UI.

cd /path/to/your/repo

gh workflow list # Pick-up the workflow ID for which you want to delete all runs
WORKFLOW_ID=<the workflow id> # Change this line!

# List last 10 runs of the workflow you picked to double check the id
gh run list -L 10 -w $WORKFLOW_ID

# Some set up
REPO_INFO=$(gh repo view --json name,owner)
REPO_FULL_NAME="$(echo $REPO_INFO | jq '.owner.login' -r)/$(echo $REPO_INFO | jq '.name' -r)"

# Ready? Let's delete some runs!
gh api -X GET "/repos/$REPO_FULL_NAME/actions/workflows/$WORKFLOW_ID/runs?per_page=100" | jq '.workflow_runs[] | .id' -r | xargs -t -I{} gh api --silent -X DELETE /repos/$REPO_FULL_NAME/actions/runs/{}

The last command will delete the last 100 runs (limit from GitHub API). If you have more, run it multiple times to delete all.

9

Delete all the jobs belonging to your workflow and your workflow will be gone.

enter image description here

P.S. in case you have thousands of jobs to delete, using API is a good way to go with.

1
  • this answer should have more up votes :)
    – ThaiPD
    Commented Sep 17, 2021 at 11:12
6

I made some minor adjustments to @David Miguel's answer which offloads the filtering to GitHub's API instead of doing it locally.

#!/bin/sh

OWNER="user-name|org-name"
REPOSITORY="repository-name"
WORKFLOW="workflow-human-friendly-name"

gh run list --repo "$OWNER/$REPOSITORY" -w "$WORKFLOW" --json databaseId \
    | jq '.[].databaseId' \
    | xargs -I{} gh api -X DELETE /repos/$OWNER/$REPOSITORY/actions/runs/{}
2
  • I haven't tried this with a large workflow so it's possible his answer which has pagination might work better. I found it took a long time to run because it was iterating through all the runs from other workflows and skipping them. My update only iterates through the specified workflow. Commented Jul 26, 2022 at 0:18
  • This is indeed faster in most cases, however, when I ran it, I found that only successful workflows were deleted, while the other script above was able to remove all workflows of the name.
    – Eric Chen
    Commented Aug 3, 2022 at 5:21
5

And a PowerShell implementation (thanks to the other respondents), which also requires the gh cli.

$user = "your user"
$repo = "repo"

(gh api repos/$user/$repo/actions/runs | ConvertFrom-Json).workflow_runs |
 %{ $_.id } |
 %{ gh api repos/$user/$repo/actions/runs/$_ -X DELETE }

Re-run the "one-liner" until you have no more; it currently pages to 30 results.

4

Following the GitHub Actions Docs, it should be easy to delete a workflow which you don't need any more, as shown here:

Screenshot "Build project in daily mode"

If you don't see the delete option but the disable workflow instead, it's because that workflow still has some workflow runs. You need to delete those workflow runs and then the delete option will appea.

Screenshot "Build project in daily mode"

1
  • yup, that worked for me although after deleting all the runs the workflow disappeared as well. I guess it's because that workflow no longer existed in the repo.
    – matzar
    Commented Nov 28, 2022 at 13:34
2

I had 600+ actions that I wanted deleted so there were multiple pages. I had to run the command in for loop:

# install following packages 
sudo snap install jq gh
# To authenticate github cli
gh auth login

# for reference path to your code repository: https://github.com/$OWNER/$REPOSITORY
export OWNER=<OWNER_NAME/ORGANIZATIONS_NAME>
export REPOSITORY=<REPOSITORY_NAME>

# repeat command 30 times, if there are 30 pages of workflow history 
for i in {1..30}; do gh api -X GET /repos/$OWNER/$REPOSITORY/actions/runs | jq '.workflow_runs[] | .id' | xargs -I{} gh api -X DELETE /repos/$OWNER/$REPOSITORY/actions/runs/{}; done
1
  • 2
    use the --paginate option
    – David S.
    Commented Dec 16, 2021 at 6:16
2

I wasn't able to delete the workflow in spite of following all the answers in this post. What worked for me was that I first authenticated myself using gh auth login and the used the below command to get the details of the workflow that you want to delete.

If you do not know the workflow ID, just run gh api repos/$org/$repo/actions/workflows/ to see all the workflows. Once you run this, you will know the branch where you need to delete the workflow from. In our case, the work flow existed in the develop branch. You can see this in the html_url.

Once I deleted the workflow file from the develop branch, the workflow vanished from everywhere. Also, when you run gh api repos/$org/$repo/actions/workflows/$workflow_id, you will notice that the state will be changed to "deleted".

$> gh api repos/$org/$repo/actions/workflows/$workflow_id

{
  "id": 6,
  "node_id": "blah",
  "name": "Run Unit Tests",
  "path": ".github/workflows/unittests.yml",
  "state": "active",
  "created_at": "2021-05-15T00:25:19.000-07:00",
  "updated_at": "2022-03-10T13:02:43.000-08:00",
  "url": "blah",
  "html_url": "https://company-name/workspace/project/blob/develop/.github/workflows/unittests.yml",
  "badge_url": "blah"
}
1

For anyone wondering, deleting the workflow.yml files within .github/workflows works BUT you need to make sure it is deleted in all branches. If master/main still has the workflow files then GitHub will hold onto them.

1
  • Surprised this is downvoted so much given its an extension to the top voted answer. You can delete all runs and the workflow will disappear but that's not very feasible with 100+ runs. Its easier just to go to each branch and delete the workflow.yaml file. Ewerton's solution also works as long as you do this for all branches in the repository. Commented Apr 27, 2021 at 12:27
1

It should be automatically be removed once you remove all related workflow runs.

0
1

Deleting the workflows runs via the CLI was only part of the solution in my case. GitHub still refused to show any workflows I tried to add again afterwards.

I solved it by using the "New workflow" button in GH and to create a workflow from template. I pasted the content of my original YML file and renamed the file so that everything looked like before. Lastly, I committed via web - and GitHub showed again my workflow.

1

Here is another option to delete all logs from a Github actions workflow automatically, using Ritchie CLI.

All you need to do is:

  • run rit github delete workflow-logs
  • inform your github username and token
  • inform the repo owner and name
  • select the repo workflow to clean

An example can be seen here. Note that you need to import this repository using the Ritchie CLI tool for the command to work.

1

A quick update on this. The below bash script should do the job:

TOKEN="github-token" #make sure token has access to read/write on actions
REPO="username/repo"

# Get all workflow runs
RUNS=$(curl -s -H "Authorization: token $TOKEN" https://api.github.com/repos/$REPO/actions/runs)

# Extract run IDs
IDS=$(echo $RUNS | jq -r '.workflow_runs[].id')

# Delete each run
for ID in $IDS; do
  curl -X DELETE -H "Authorization: token $TOKEN" https://api.github.com/repos/$REPO/actions/runs/$ID
done
1
  • Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation? Commented Jan 9 at 2:05
1

If you want to delete multiple workflow runs, you should use the GitHub Action API to get the run IDs you want to delete, then send DELETE request with a header containing personal access token to delete the workflow run.

Try this Python script to delete all workflow runs. It uses grequests to make multiple requests at once, and doesn't require gh and jq.

2
1
  1. Install the Ritchie CLI

  2. Run rit add repo

? Select your provider: Github
? Repository name: formulas-github
? Repository URL: https://github.com/GuillaumeFalourd/formulas-github
? Is a private repository? no
? Select a tag version: {latest}
? Set the priority: 1
  1. Run rit set formula-runner
? Select a default formula run type: docker
The default formula runner has been successfully configured!
  1. Start Docker Desktop

  2. Go to tokens in GitHub settings, and generate a GitHub Personal Access Token (use the "workflow" scope)

  3. Run rit github delete workflow-logs

  4. Enter your GitHub username, token, owner, repository name and select the workflow for which you want the runs to be deleted

  5. Revoke your PAT

1
  • 1
    Didn't work for me Error: the selected repository has no formulas Commented May 17, 2022 at 19:08
0
  1. Remove the workflow file from the default branch.

  2. Delete the workflow runs:

owner=exampleowner
repo=examplerepo
workflow=exampleworkflow.yml
gh api repos/"$owner"/"$repo"/actions/workflows/"$workflow"/runs --paginate -q .workflow_runs[].id | while read -r id; do
    echo "$id"
    gh api -X DELETE repos/"$owner"/"$repo"/actions/runs/"$id"
done
0

I had some issues where I deleted the workflow .yml file before deleting the workflow runs which left workflows with no runs still dangling.

I was able to remove these by re-adding a workflow .yml file with the same name in one commit and following up with delete in another commit

0

If you are looking for a shell script to delete all the workflow_runs histories from all the repositories in org/user, you can use the below script

org=<your-org/user-name>
repos=($(gh repo list $org --json name -q '.[].name'))

for repo in "${repos[@]}"
do
  echo "Removing runs for the repo => $repo"
  $(gh api repos/$org/$repo/actions/runs --paginate | jq 
  '.workflow_runs[] | .id' | xargs -t -I{} gh api -X DELETE 
  /repos/$org/$repo/actions/runs/{})
  echo "Done removing for repo => $repo"
  echo "-------------------------------------"
done
0

Update 1/3/2023

I found something new, if I add test.yml back, the history will be back.

To truly delete the workflow history, please refer to other answers.


As of Dec 31, 2022

Assume you have a workflow .github/workflows/test.yml. Once you delete this workflow file and merge into main branch, the workflow on the side menu plus all workflow run history will be gone.

You can verify by manually going to the old workflow link: https://github.com/[username]/[repo]/actions/workflows/test.yml.

This is the current result:

enter image description here

0

Here is an answer that just uses the GitHub CLI (you need to install and authenticate) and AWK:

OWNER="repoOwner"
REPO="repoName"

gh run list --repo <[HOST/]OWNER/REPO> -workflow <string> | \
  awk -F '\t' '{ if ($2 == "failure") { print $7 } }' | \
  while read id; do gh api repos/$OWNER/$REPO/runs/$id -X DELETE; done
0

For the people who deleted the workflow and can't delete the workflow run (404)?

After finding this thread, I still did spent quite some time to make my workflows run fade away...

The answer provided by @ribeiro is correct. However, for people that have DELETED their workflows, they won't be able to delete the runs: it will resolve into a 404!

How to delete workflows run that doesn't have workflows anymore:

I've tried many things, in the end, only this worked for me:

  1. For each workflows you deleted, create the yml file with the same name that the previous one(filename.yml and the name property in the workflow must be the same as the previous one). This way GitHub will see them as 'existing'.
  2. Create a .sh file and input the following (I will use the answer provided by @ribeiro, however, I will remove the state filter because I wish to delete them all.)
OWNER="aOwner"
REPO="aRepo"

workflow_ids=($(gh api repos/$OWNER/$REPO/actions/workflows | jq '.workflows[] | .id'))

for workflow_id in "${workflow_ids[@]}"
do
  echo "Listing runs for the workflow ID $workflow_id"
  run_ids=( $(gh api repos/$OWNER/$REPO/actions/workflows/$workflow_id/runs --paginate | jq '.workflow_runs[].id') )
  for run_id in "${run_ids[@]}"
  do
    echo "Deleting Run ID $run_id"
    gh api repos/$OWNER/$REPO/actions/runs/$run_id -X DELETE >/dev/null
  done
done
  1. Run the sh file.

You should see workflows run deleted (it does take some time though).

0

For deleting all the runs of a specific workflow using gh CLI on Mac, you can put your workflow name or workflow filename to replace ${action.yml}.

You should run the command when you are in the same git repo folder locally.

for id in $(gh run list --workflow ${action.yml} --json databaseId --jq '.[].databaseId'); do gh run delete "$id"; done
0

Working simple script to delete all workflow runs (2024).

# Change "Workflow Name", MAXIMUM_RUNS (ex: 300) and USERNAME/REPONAME

gh run list -w "Workflow Name" -L MAXIMUM_RUNS --json databaseId -q '.[].databaseId' | xargs -IID gh api -X DELETE /repos/USERNAME/REPONAME/actions/runs/ID --silent
-2

I did find a way of doing this. You can go to .github/workflows or wherever your workflow is set and then commit deleting of the file(workflow file) which will finally delete it.

-3

Update your local branch from to sync with master , then delete the github/workflows. Commit and push your changes . Wokflow should be deleted in master

1
  • 2
    I have an old workflow stuck in there. It doesn't exist as an actual file. I can't figure out how to get rid of it! Commented Jun 27, 2020 at 7:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.