Skip to content

Instantly share code, notes, and snippets.

@exetico
Last active August 12, 2025 08:45
Show Gist options
  • Select an option

  • Save exetico/db141c08ca5f09be0f8899f9ee689e92 to your computer and use it in GitHub Desktop.

Select an option

Save exetico/db141c08ca5f09be0f8899f9ee689e92 to your computer and use it in GitHub Desktop.
Automated GitHub Deployment Cleanup Script: Reads a JSON file of deployments (or fetch from GitHub), filters by creation date, and deletes old deployments using the GitHub CLI. Includes interactive prompts for fetching, deleting, and file cleanup. Handles encoding issues and guides the user through safe deletion.
# This script reads a JSON file containing deployment data and deletes deployments created before a specific date using the GitHub CLI.
# The jobs was fetched with:
# gh api --method GET -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/<owner>/<repo>/deployments | Out-File -FilePath .\deployments.json
# Remember to adjust the encoding if needed: encoding="utf-16"
import json
import subprocess
import time
import os
threshold_date = "2025-07-25T08:00:00Z" # Will replace with your desired threshold date in ISO 8601 format, e.g., "YYYY-MM-DDTHH:MM:SSZ" like "2025-07-25T08:00:00Z"
github_repo = "<owner>/<repo" # Replace with your GitHub repository in the format "owner/repo"
exclude_ids = [12345, 67890] # Replace with the IDs you want to exclude, e.g., [12345, 67890]. As the script will not continue before you give the required prompt, you can check out the json file and add the IDs you want to exclude, terminate the script, and then run it again with the updated exclude_ids.
if not github_repo or github_repo == "<owner>/<repo>":
print("Please set the GitHub repository in the format 'owner/repo'.")
exit(1)
print(f"Using GitHub repository: {github_repo}")
print(f"Using threshold date: {threshold_date}")
# Check if the GitHub CLI is installed
try:
subprocess.run(["gh", "version"], check=True)
except subprocess.CalledProcessError:
print("GitHub CLI (gh) is not installed or not found in PATH.")
exit(1)
# Ask the user if they want to fetch jobs before starting
answer = input("Get jobs before start? (will overwrite existing file) [y/N]: ").strip().lower()
if answer == "y":
print("Fetching deployments and overwriting deployments.json...")
subprocess.run([
"gh", "api", "--method", "GET",
"-H", "Accept: application/vnd.github+json",
"-H", "X-GitHub-Api-Version: 2022-11-28",
f"/repos/{github_repo}/deployments"
], stdout=open("deployments.json", "w", encoding="utf-8"), check=True)
# Check if the file exists before reading
if not os.path.exists("deployments.json"):
print("deployments.json file does not exist. Please run the fetch command first.")
exit(1)
# Load the JSON data from the file
with open("deployments.json", "r", encoding="utf-8") as f:
data = json.load(f)
# Ensure threshold_date is in ISO format and compare correctly
# If you want to change the threshold_date, uncomment below:
# threshold_date = input("Enter threshold date (YYYY-MM-DDTHH:MM:SSZ): ").strip() or threshold_date
items_marked_for_deletion = [
item for item in data
if item['created_at'] < threshold_date and item['id'] not in exclude_ids
]
for item in items_marked_for_deletion:
print(f"id: {item['id']}, created_at: {item['created_at']}")
print(f"Deployment {item['id']} is before {threshold_date}, and will be deleted.")
# Ask if the user wants to delete the deployments.json file
if not items_marked_for_deletion:
print("No deployments to delete.")
else:
confirm_delete = input("Do you want to delete these deployments? [y/N]: ").strip().lower()
if confirm_delete != "y":
print("Deletion cancelled.")
exit(0)
for item in items_marked_for_deletion:
print(f"Deleting deployment {item['id']} created at {item['created_at']}...")
# Run the GitHub CLI command to delete the deployment
cmd = [
"gh", "api",
"--method", "DELETE",
"-H", "Accept: application/vnd.github+json",
"-H", "X-GitHub-Api-Version: 2022-11-28",
f"/repos/{github_repo}/deployments/{item['id']}"
]
print(f"Running: {' '.join(cmd)}")
subprocess.run(cmd, check=True)
time.sleep(1)
delete_file = input("Do you want to delete the deployments.json file? [y/N]: ").strip().lower()
if delete_file == "y":
# Check if the file exists before attempting to delete
if not os.path.exists("deployments.json"):
print("deployments.json file does not exist. Nothing to delete.")
exit(0)
import os
os.remove("deployments.json")
print("deployments.json file deleted.")
else:
print("deployments.json file retained.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment