Last active
January 7, 2026 22:08
-
-
Save viperadnan-git/5968c1dc3756427c83c69a8a71a41a2a to your computer and use it in GitHub Desktop.
GitHub Actions Cleanup Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # GitHub Actions Cleanup Script | |
| # Cancels running workflows and deletes ALL runs (including cancelled ones) | |
| set -e | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| CYAN='\033[0;36m' | |
| NC='\033[0m' # No Color | |
| # Check if gh is installed | |
| if ! command -v gh &> /dev/null; then | |
| echo -e "${RED}Error: gh CLI is not installed. Install it from https://cli.github.com/${NC}" | |
| exit 1 | |
| fi | |
| # Check if jq is installed | |
| if ! command -v jq &> /dev/null; then | |
| echo -e "${RED}Error: jq is not installed. Install it with 'apt install jq' or 'brew install jq'${NC}" | |
| exit 1 | |
| fi | |
| # Check if authenticated | |
| if ! gh auth status &> /dev/null; then | |
| echo -e "${RED}Error: Not authenticated with gh. Run 'gh auth login' first.${NC}" | |
| exit 1 | |
| fi | |
| # Get repository (use current repo or specify one) | |
| REPO="${1:-}" | |
| REPO_FLAG="" | |
| if [ -n "$REPO" ]; then | |
| REPO_FLAG="--repo $REPO" | |
| echo -e "${BLUE}Working on repository: $REPO${NC}" | |
| else | |
| echo -e "${BLUE}Working on current repository${NC}" | |
| fi | |
| echo "" | |
| iteration=1 | |
| # Process runs in batches until none remain | |
| while true; do | |
| echo -e "${CYAN}=== Iteration $iteration ===${NC}" | |
| # Fetch batch of runs (max 1000 per request) | |
| runs=$(gh run list $REPO_FLAG --limit 1000 --json databaseId,status,conclusion,displayTitle,workflowName 2>/dev/null) | |
| if [ -z "$runs" ] || [ "$runs" == "[]" ]; then | |
| echo -e "${GREEN}No more workflow runs found.${NC}" | |
| break | |
| fi | |
| batch_count=$(echo "$runs" | jq length) | |
| echo -e "${BLUE}Found $batch_count workflow runs in this batch${NC}" | |
| echo "----------------------------------------" | |
| # Process each run | |
| echo "$runs" | jq -c '.[]' | while read -r run; do | |
| run_id=$(echo "$run" | jq -r '.databaseId') | |
| status=$(echo "$run" | jq -r '.status') | |
| conclusion=$(echo "$run" | jq -r '.conclusion') | |
| title=$(echo "$run" | jq -r '.displayTitle') | |
| workflow=$(echo "$run" | jq -r '.workflowName') | |
| # Truncate title if too long | |
| if [ ${#title} -gt 40 ]; then | |
| title="${title:0:37}..." | |
| fi | |
| echo -ne "Run #$run_id [$workflow] \"$title\" - " | |
| # Check if running (in_progress, queued, waiting, pending, requested) | |
| if [[ "$status" == "in_progress" || "$status" == "queued" || "$status" == "waiting" || "$status" == "pending" || "$status" == "requested" ]]; then | |
| echo -ne "${YELLOW}$status${NC} -> " | |
| # Cancel first | |
| if gh run cancel "$run_id" $REPO_FLAG 2>/dev/null; then | |
| echo -ne "${GREEN}CANCELLED${NC} -> " | |
| # Wait a moment for the cancellation to process | |
| sleep 1 | |
| # Then delete | |
| if gh run delete "$run_id" $REPO_FLAG 2>/dev/null; then | |
| echo -e "${GREEN}DELETED${NC}" | |
| else | |
| echo -e "${YELLOW}DELETE PENDING (will retry)${NC}" | |
| fi | |
| else | |
| echo -e "${RED}CANCEL FAILED${NC}" | |
| fi | |
| else | |
| # Run is completed, just delete it | |
| echo -ne "${BLUE}$status${NC}" | |
| [ -n "$conclusion" ] && [ "$conclusion" != "null" ] && echo -ne " ($conclusion)" | |
| echo -ne " -> " | |
| if gh run delete "$run_id" $REPO_FLAG 2>/dev/null; then | |
| echo -e "${GREEN}DELETED${NC}" | |
| else | |
| echo -e "${RED}DELETE FAILED${NC}" | |
| fi | |
| fi | |
| done | |
| echo "" | |
| ((iteration++)) | |
| # Small delay between iterations to avoid rate limiting | |
| sleep 2 | |
| done | |
| echo "" | |
| echo "========================================" | |
| echo -e "${GREEN}Cleanup complete!${NC}" | |
| echo "========================================" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
GitHub Actions Cleanup Script
A bash script to bulk cancel and delete all GitHub Actions workflow runs from a repository.
What it does
Prerequisites
gh) installed and authenticatedjqfor JSON parsingInstallation
macOS:
Ubuntu/Debian:
Authenticate with GitHub:
Usage
Example Output
How it works
Notes