1+ #! /usr/bin/env bash
2+ set -euo pipefail
3+
4+ # -------------------------------------------------------------------
5+ # ⚙️ Configuration
6+ # -------------------------------------------------------------------
7+ USER=" helmhubio"
8+
9+ DOCKER_USER=" ${DOCKER_USER:- } "
10+ DOCKER_PASS=" ${DOCKER_PASS:- } "
11+
12+ if [ -z " $DOCKER_USER " ] || [ -z " $DOCKER_PASS " ]; then
13+ echo " ❌ Missing Docker credentials!"
14+ echo " Please export DOCKER_USER and DOCKER_PASS before running this script."
15+ echo " Example:"
16+ echo " export DOCKER_USER='helmhubio'"
17+ echo " export DOCKER_PASS='your-docker-access-token'"
18+ exit 1
19+ fi
20+
21+ # -------------------------------------------------------------------
22+ # 🔁 Retry Helper
23+ # -------------------------------------------------------------------
24+ retry () {
25+ local cmd=$1
26+ local max_retries=${2:- 3}
27+ local delay=${3:- 5}
28+ local count=0
29+ until eval " $cmd " ; do
30+ count=$(( count + 1 ))
31+ if [ $count -ge $max_retries ]; then
32+ echo " ❌ Command failed after ${max_retries} attempts: $cmd "
33+ return 1
34+ fi
35+ echo " ⚠️ Retry ${count} /${max_retries} for: $cmd (waiting ${delay} s)"
36+ sleep " $delay "
37+ done
38+ }
39+
40+ # -------------------------------------------------------------------
41+ # 🔑 Authenticate to Docker Hub API
42+ # -------------------------------------------------------------------
43+ echo " 🔑 Authenticating to Docker Hub API..."
44+ AUTH_PAYLOAD=$( curl -s -X POST " https://hub.docker.com/v2/users/login" \
45+ -H " Content-Type: application/json" \
46+ -d " {\" username\" : \" ${DOCKER_USER} \" , \" password\" : \" ${DOCKER_PASS} \" }" )
47+
48+ TOKEN=$( echo " $AUTH_PAYLOAD " | jq -r ' .token // empty' )
49+
50+ if [ -z " $TOKEN " ] || [ " $TOKEN " == " null" ]; then
51+ echo " ❌ Failed to obtain Docker Hub API token."
52+ echo " $AUTH_PAYLOAD " | jq .
53+ exit 1
54+ fi
55+ echo " ✅ Authenticated successfully."
56+
57+ # -------------------------------------------------------------------
58+ # 📦 Fetch all repositories
59+ # -------------------------------------------------------------------
60+ echo " 🔍 Fetching repositories for ${USER} ..."
61+ REPOS=()
62+ URL=" https://hub.docker.com/v2/repositories/${USER} /?page_size=100"
63+
64+ while [ -n " $URL " ] && [ " $URL " != " null" ]; do
65+ RESP=$( retry " curl -s -H \" Authorization: JWT ${TOKEN} \" \" $URL \" " 3 5)
66+ NAMES=$( echo " $RESP " | jq -r ' .results[].name' )
67+ REPOS+=($NAMES )
68+ URL=$( echo " $RESP " | jq -r ' .next' )
69+ done
70+
71+ if [ ${# REPOS[@]} -eq 0 ]; then
72+ echo " ❌ No repositories found for ${USER} ."
73+ exit 0
74+ fi
75+
76+ echo " ✅ Found ${# REPOS[@]} repositories total."
77+
78+ # -------------------------------------------------------------------
79+ # 🧹 Identify archived repos
80+ # -------------------------------------------------------------------
81+ ARCHIVED_REPOS=()
82+ for REPO in " ${REPOS[@]} " ; do
83+ if [[ " $REPO " == * " -archived" ]]; then
84+ ARCHIVED_REPOS+=(" $REPO " )
85+ fi
86+ done
87+
88+ if [ ${# ARCHIVED_REPOS[@]} -eq 0 ]; then
89+ echo " ✅ No '-archived' repositories found. Nothing to delete."
90+ exit 0
91+ fi
92+
93+ echo " "
94+ echo " ⚠️ The following repositories will be deleted:"
95+ for REPO in " ${ARCHIVED_REPOS[@]} " ; do
96+ echo " - ${USER} /${REPO} "
97+ done
98+
99+ echo " "
100+ read -p " ❓ Are you sure you want to delete these repositories? (y/N): " CONFIRM
101+ if [[ ! " $CONFIRM " =~ ^[Yy]$ ]]; then
102+ echo " 🚫 Operation cancelled."
103+ exit 0
104+ fi
105+
106+ # -------------------------------------------------------------------
107+ # 🧨 Delete archived repos
108+ # -------------------------------------------------------------------
109+ for REPO in " ${ARCHIVED_REPOS[@]} " ; do
110+ echo " "
111+ echo " 🧨 Deleting ${USER} /${REPO} ..."
112+
113+ DELETE_URL=" https://hub.docker.com/v2/repositories/${USER} /${REPO} /"
114+ STATUS=$( curl -s -o /dev/null -w " %{http_code}" -X DELETE " $DELETE_URL " \
115+ -H " Authorization: JWT ${TOKEN} " )
116+
117+ if [ " $STATUS " -eq 204 ]; then
118+ echo " ✅ Successfully deleted ${USER} /${REPO} "
119+ elif [ " $STATUS " -eq 404 ]; then
120+ echo " ⚠️ ${USER} /${REPO} not found (may have been deleted already)"
121+ else
122+ echo " ❌ Failed to delete ${USER} /${REPO} (status: ${STATUS} )"
123+ fi
124+ done
125+
126+ echo " "
127+ echo " 🎉 Deletion complete! Total deleted: ${# ARCHIVED_REPOS[@]} "
0 commit comments