11#! /bin/bash
2+ set  -euo pipefail
23
34#  Free disk space on Linux GitHub action runners
45#  Script inspired by https://github.com/jlumbroso/free-disk-space
56
7+ #  When updating to a new ubuntu version (e.g. from ubuntu-24.04):
8+ #  - Check that there are no docker images preinstalled with `docker image ls`
9+ #  - Check that there are no big packages preinstalled that we aren't using
10+ #  - Check that all directores we are removing are still present (look at the warnings)
11+ 
612#  print a line of the specified character
713printSeparationLine () {
814    for  (( i =  0 ; i <  80 ; i++ )) ;  do 
@@ -14,11 +20,15 @@ printSeparationLine() {
1420#  compute available space
1521#  REF: https://unix.stackexchange.com/a/42049/60849
1622#  REF: https://stackoverflow.com/a/450821/408734
17- getAvailableSpace () { echo  $( df -a |  awk ' NR > 1 {avail+=$4} END {print avail}' ) ;  }
23+ getAvailableSpace () {
24+     df -a |  awk ' NR > 1 {avail+=$4} END {print avail}' 
25+ }
1826
1927#  make Kb human readable (assume the input is Kb)
2028#  REF: https://unix.stackexchange.com/a/44087/60849
21- formatByteCount () { echo  $( numfmt --to=iec-i --suffix=B --padding=7 $1 ' 000' ) ;  }
29+ formatByteCount () {
30+     numfmt --to=iec-i --suffix=B --padding=7 " $1 " ' 000' 
31+ }
2232
2333#  macro to output saved space
2434printSavedSpace () {
@@ -54,15 +64,93 @@ printDF() {
5464    printSeparationLine " =" 
5565}
5666
57- removeDir () {
58-     dir =${1} 
67+ removeRecursive () {
68+     element =${1} 
5969
6070    local  before
61-     before=$( getAvailableSpace) 
71+     if  [ !  -e  " $element " ;  then 
72+         echo  " ::warning::Directory or file $element  does not exist, skipping." 
73+     else 
74+         before=$( getAvailableSpace) 
75+         sudo rm -rf " $element " 
76+         printSavedSpace " $before " " Removed $element " 
77+     fi 
78+ }
6279
63-     sudo rm -rf " $dir " ||  true 
80+ removeUnusedDirsAndFiles () {
81+     local  to_remove=(
82+         " /etc/mysql" 
83+         " /usr/local/aws-sam-cli" 
84+         " /usr/local/doc/cmake" 
85+         " /usr/local/julia" * 
86+         " /usr/local/lib/android" 
87+         " /usr/local/share/chromedriver-" * 
88+         " /usr/local/share/chromium" 
89+         " /usr/local/share/cmake-" * 
90+         " /usr/local/share/edge_driver" 
91+         " /usr/local/share/gecko_driver" 
92+         " /usr/local/share/icons" 
93+         " /usr/local/share/vim" 
94+         " /usr/local/share/emacs" 
95+         " /usr/local/share/powershell" 
96+         " /usr/local/share/vcpkg" 
97+         " /usr/share/apache-maven-" * 
98+         " /usr/share/gradle-" * 
99+         " /usr/share/java" 
100+         " /usr/share/kotlinc" 
101+         " /usr/share/miniconda" 
102+         " /usr/share/php" 
103+         " /usr/share/ri" 
104+         " /usr/share/swift" 
105+ 
106+         #  binaries
107+         " /usr/local/bin/azcopy" 
108+         " /usr/local/bin/bicep" 
109+         " /usr/local/bin/ccmake" 
110+         " /usr/local/bin/cmake-" * 
111+         " /usr/local/bin/cmake" 
112+         " /usr/local/bin/cpack" 
113+         " /usr/local/bin/ctest" 
114+         " /usr/local/bin/helm" 
115+         " /usr/local/bin/kind" 
116+         " /usr/local/bin/kustomize" 
117+         " /usr/local/bin/minikube" 
118+         " /usr/local/bin/packer" 
119+         " /usr/local/bin/phpunit" 
120+         " /usr/local/bin/pulumi-" * 
121+         " /usr/local/bin/pulumi" 
122+         " /usr/local/bin/stack" 
123+ 
124+         #  Haskell runtime
125+         " /usr/local/.ghcup" 
126+ 
127+         #  Azure
128+         " /opt/az" 
129+         " /usr/share/az_" * 
130+ 
131+         #  Environemnt variable set by GitHub Actions
132+         " $AGENT_TOOLSDIRECTORY " 
133+     )
134+ 
135+     for  element  in  " ${to_remove[@]} " ;  do 
136+         removeRecursive " $element " 
137+     done 
138+ }
64139
65-     printSavedSpace " $before " " $dir " 
140+ removeNodeModules () {
141+     sudo npm uninstall -g \
142+         " @bazel/bazelisk" 
143+         " bazel" 
144+         " grunt" 
145+         " gulp" 
146+         " lerna" 
147+         " n" 
148+         " newman" 
149+         " parcel" 
150+         " typescript" 
151+         " webpack-cli" 
152+         " webpack" 
153+         " yarn" 
66154}
67155
68156execAndMeasureSpaceChange () {
@@ -79,58 +167,70 @@ execAndMeasureSpaceChange() {
79167#  Remove large packages
80168#  REF: https://github.com/apache/flink/blob/master/tools/azure-pipelines/free_disk_space.sh
81169cleanPackages () {
82-     sudo apt-get -qq remove -y --fix-missing \
83-         ' ^aspnetcore-.*' 
84-         ' ^dotnet-.*' 
85-         ' ^llvm-.*' 
86-         ' php.*' 
87-         ' ^mongodb-.*' 
88-         ' ^mysql-.*' 
89-         ' azure-cli' 
90-         ' google-chrome-stable' 
91-         ' firefox' 
92-         ' powershell' 
93-         ' mono-devel' 
94-         ' libgl1-mesa-dri' 
95-         ' google-cloud-sdk' 
96-         ' google-cloud-cli' 
97- 
170+     sudo apt-get purge -y --autoremove --fix-missing \
171+         ' .*-icon-theme$' 
172+         ' ^aspnetcore-.*' 
173+         ' ^dotnet-.*' 
174+         ' ^java-*' 
175+         ' ^libllvm.*' 
176+         ' ^llvm-.*' 
177+         ' ^mercurial.*' 
178+         ' ^mysql-.*' 
179+         ' ^vim.*' 
180+         ' ^fonts-.*' 
181+         ' azure-cli' 
182+         ' buildah' 
183+         ' cpp-13' 
184+         ' firefox' 
185+         ' gcc-12' 
186+         ' gcc-13' 
187+         ' gcc-14' 
188+         ' gcc' 
189+         ' g++-14' 
190+         ' gfortran-14' 
191+         ' google-chrome-stable' 
192+         ' google-cloud-cli' 
193+         ' groff-base' 
194+         ' kubectl' 
195+         ' libgl1-mesa-dri' 
196+         ' microsoft-edge-stable' 
197+         ' php.*' 
198+         ' podman' 
199+         ' powershell' 
200+         ' skopeo' 
201+         ' snapd' 
202+         ' tmux' 
203+ 
204+     echo  " => apt-get autoremove" 
98205    sudo apt-get autoremove -y ||  echo  " ::warning::The command [sudo apt-get autoremove -y] failed" 
206+     echo  " => apt-get clean" 
99207    sudo apt-get clean ||  echo  " ::warning::The command [sudo apt-get clean] failed failed" 
100208}
101209
102- #  Remove Docker images
103- cleanDocker () {
104-     echo  " Removing the following docker images:" 
105-     sudo docker image ls
106-     echo  " Removing docker images..." 
107-     sudo docker image prune --all --force ||  true 
108- }
109- 
110210#  Remove Swap storage
111211cleanSwap () {
112212    sudo swapoff -a ||  true 
113213    sudo rm -rf /mnt/swapfile ||  true 
114214    free -h
115215}
116216
217+ removePythonPackages () {
218+     sudo pipx uninstall ansible-core
219+ }
220+ 
117221#  Display initial disk space stats
118222
119223AVAILABLE_INITIAL=$( getAvailableSpace) 
120224
121225printDF " BEFORE CLEAN-UP:" 
122226echo  " " 
123227
124- removeDir /usr/local/lib/android
125- removeDir /usr/share/dotnet
126- 
127- #  Haskell runtime
128- removeDir /opt/ghc
129- removeDir /usr/local/.ghcup
130- 
131- execAndMeasureSpaceChange cleanPackages " Large misc. packages" 
132- execAndMeasureSpaceChange cleanDocker " Docker images" 
228+ execAndMeasureSpaceChange cleanPackages " Unused packages" 
133229execAndMeasureSpaceChange cleanSwap " Swap storage" 
230+ execAndMeasureSpaceChange removeNodeModules " Node modules" 
231+ execAndMeasureSpaceChange removePythonPackages " Python Packages" 
232+ 
233+ removeUnusedDirsAndFiles
134234
135235#  Output saved space statistic
136236echo  " " 
0 commit comments