| 1 | #!/usr/bin/env bash |
| 2 | # Installs a named set of Debian packages, from the job's cache when it has |
| 3 | # them. CI's desktop job spent 110 s of its 175 s here on every run: 21 s |
| 4 | # on `apt-get update`, 35 s downloading 335 MB, the rest unpacking. |
| 5 | # |
| 6 | # bash scripts/apt-install.sh tauri # Tauri's build on Linux |
| 7 | # bash scripts/apt-install.sh tauri-windows # its Windows cross build |
| 8 | # |
| 9 | # apt's package lists and downloaded .debs are kept in ~/.cache/apt/<set>, |
| 10 | # which the workflow restores and saves with actions/cache under |
| 11 | # apt-<os>-<set>-<hash of this file>, so changing a set here starts a new |
| 12 | # entry. With them restored, the install runs offline (--no-download); when |
| 13 | # that fails (a list out of date for a package the image already has newer, |
| 14 | # say) or nothing was restored, it updates the lists and downloads as |
| 15 | # before, tried three times, since the mirror has answered with a |
| 16 | # mismatched package before. An entry lives at most 28 days, so the lists |
| 17 | # are never older than that. |
| 18 | set -euo pipefail |
| 19 | |
| 20 | set_name="${1:-}" |
| 21 | case "$set_name" in |
| 22 | tauri) |
| 23 | packages=(libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev) |
| 24 | ;; |
| 25 | tauri-windows) |
| 26 | packages=(build-essential curl wget file libssl-dev libayatana-appindicator3-dev nsis clang lld llvm) |
| 27 | ;; |
| 28 | *) |
| 29 | echo "usage: bash scripts/apt-install.sh tauri|tauri-windows" >&2 |
| 30 | exit 2 |
| 31 | ;; |
| 32 | esac |
| 33 | |
| 34 | dir="$HOME/.cache/apt/$set_name" |
| 35 | mkdir -p "$dir/archives/partial" "$dir/lists/partial" |
| 36 | apt=(sudo apt-get -o "Dir::Cache::Archives=$dir/archives" -o "Dir::State::Lists=$dir/lists" -y) |
| 37 | |
| 38 | # The cache's files go back into it as this user, and apt leaves its |
| 39 | # partial folders readable by root alone. |
| 40 | mine() { sudo chown -R "$(id -u):$(id -g)" "$dir"; } |
| 41 | trap mine EXIT |
| 42 | |
| 43 | if compgen -G "$dir/lists/*_Packages*" >/dev/null && "${apt[@]}" install --no-download "${packages[@]}"; then |
| 44 | echo "Installed ${#packages[@]} packages from the cache." |
| 45 | exit 0 |
| 46 | fi |
| 47 | |
| 48 | for try in 1 2 3; do |
| 49 | if "${apt[@]}" update && "${apt[@]}" install "${packages[@]}"; then |
| 50 | # Only what this install used is kept. |
| 51 | "${apt[@]}" autoclean >/dev/null 2>&1 || true |
| 52 | exit 0 |
| 53 | fi |
| 54 | sudo rm -rf "$dir/archives/partial/"* |
| 55 | sleep 15 |
| 56 | done |
| 57 | exit 1 |