Skip to content

Instantly share code, notes, and snippets.

@pckilgore
Last active May 10, 2023 07:24
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pckilgore/827bafd1bbda456b30ebd32ff652f9b6 to your computer and use it in GitHub Desktop.
Save pckilgore/827bafd1bbda456b30ebd32ff652f9b6 to your computer and use it in GitHub Desktop.
Batch Delete Github Workflow Runs Shell Script
#!/bin/bash
ORG_NAME=$1
REPO_NAME=$2
WORKFLOW_NAME=$3
if [[ -z $WORKFLOW_NAME || -z REPO_NAME || -z ORG_NAME ]]; then
echo "Usage: bash remove_workflow_runs.sh <USER/ORG NAME> <REPO NAME> <WORKFLOW NAME>"
exit 1
fi
if ! gh auth status 2>&1 >/dev/null | grep "Logged in to github.com"; then
echo "Script requires logged-in gh CLI user."
echo "Install gh with \`brew install gh\`"
exit 1
fi
JQ_SEARCH=".workflows[] | select(.name == \"$WORKFLOW_NAME\") | \"\\(.id)\""
echo "Searching for workflow..."
WORKFLOW_ID=$(gh api "repos/$ORG_NAME/$REPO_NAME/actions/workflows?per_page=100" | jq -r "$JQ_SEARCH")
if [ -z $WORKFLOW_ID ]; then
echo "Workflow not found!\nCheck your spelling!"
exit 1;
else
echo "...done!"
fi
echo "Retreiving runs..."
WORKFLOW_RUNS=$(gh api "repos/$ORG_NAME/$REPO_NAME/actions/workflows/$WORKFLOW_ID/runs?per_page=100")
echo "done!"
RUN_COUNT=$(echo $WORKFLOW_RUNS | jq -r ".total_count")
read -r -p "Are you sure you want to delete all $RUN_COUNT runs? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
DELETED=0
LEFT=1
while [[ $LEFT -gt "0" ]]; do
# Be lazy and try to avoid fetching stale results
sleep 1
BATCH=$(gh api "repos/$ORG_NAME/$REPO_NAME/actions/workflows/$WORKFLOW_ID/runs?per_page=100")
LEFT=$(echo $BATCH | jq -r ".total_count")
echo "Deleting up to 100 of $LEFT"
echo $BATCH \
| jq -r '.workflow_runs[] | "\(.id)"' \
| xargs -n1 -I % gh api repos/$ORG_NAME/$REPO_NAME/actions/runs/% -X DELETE
((DELETED=DELETED+LEFT))
echo "done!"
done;
echo ""
echo "All Done! Deleted $DELETED runs from \"$WORKFLOW_NAME\""
else
echo "Writing preliminary data to /tmp/workflow_info.json and aborting!"
echo $WORKFLOW_RUNS > /tmp/workflow_info.json
fi
@kmorozov
Copy link

Thanks! This was super useful.
A suggestion: It looks like workflow names are not unique. I had 3 with the same name differentiated by the .yml file there were in. Also, a per-page of 100 timed out when it tried to retrieve the runs at 31. I did have 5k runs though 😄

@pckilgore
Copy link
Author

Ha, glad it was helpful to someone else! I think I only had a few hundred to delete when I wrote this.

Feel free to suggest a change and I'll update it.

@e8-HongJunLiu
Copy link

@pckilgore when i run it,"Script requires logged-in gh CLI user.Install gh with brew install gh".How to install brew & gh for windows 11?

@e8-HongJunLiu
Copy link

parse "https://api.github.com/repos/orgName/repo/actions/runs/4181100411\r": net/url: invalid control character in URL

@e8-HongJunLiu
Copy link

For windows, I have fixed this problem.
echo $BATCH
| jq -r '.workflow_runs[] | "(.id)"'
| awk -F '' '{print $1}'
| xargs -n1 -I % gh api --method DELETE -H "Accept: application/vnd.github+json" repos/$ORG_NAME/$REPO_NAME/actions/runs/%

@pckilgore
Copy link
Author

If you’re using windows you’re going to be better off translating this to powershell not some unholy invocation of bash outside a posix environment. Looks like the line endings are causing issues.. Not surprising. Hope it helped but this isn’t intended for and I have zero interest in making this cross platform.

@e8-HongJunLiu
Copy link

Thank you for your reply!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment