#!/usr/bin/env bash # =========================================================================== # Stage 01: Third-Party Repositories # Adds external package repos. Completely different per distro family. # # Debian/Ubuntu/Pop: uses PPAs and .list/.sources files in # /etc/apt/sources.list.d/ # Fedora: uses .repo files in /etc/yum.repos.d/ and COPRs # =========================================================================== # ================================================================== # COMMON: Add GPG keys (shared helper) # ================================================================== add_gpg_key() { local url="$1" local dest="$2" if [ ! -f "$dest" ]; then sudo curl -fsSL "$url" -o "$dest" 2>/dev/null || { warn "Failed to download GPG key: $url" return 1 } sudo chmod 644 "$dest" fi } # ================================================================== # DEBIAN / UBUNTU / POP — APT-based # ================================================================== if [ "$DISTRO_FAMILY" = "debian" ]; then info "Configuring APT repositories..." # ---- VS Code ---- info " Adding VS Code repo..." if [ ! -f /etc/apt/sources.list.d/vscode.sources ]; then add_gpg_key "https://packages.microsoft.com/keys/microsoft.asc" \ "/usr/share/keyrings/microsoft.gpg" cat << 'EOF' | sudo tee /etc/apt/sources.list.d/vscode.sources > /dev/null Types: deb URIs: https://packages.microsoft.com/repos/code Suites: stable Components: main Architectures: amd64 Signed-By: /usr/share/keyrings/microsoft.gpg EOF ok " VS Code repo added." fi # ---- Google Chrome ---- info " Adding Google Chrome repo..." if [ ! -f /etc/apt/sources.list.d/google-chrome.sources ]; then add_gpg_key "https://dl.google.com/linux/linux_signing_key.pub" \ "/usr/share/keyrings/google-chrome.gpg" cat << 'EOF' | sudo tee /etc/apt/sources.list.d/google-chrome.sources > /dev/null Types: deb URIs: https://dl.google.com/linux/chrome/deb/ Suites: stable Components: main Architectures: amd64 Signed-By: /usr/share/keyrings/google-chrome.gpg EOF ok " Google Chrome repo added." fi # ---- Docker CE ---- info " Adding Docker CE repo..." if [ ! -f /etc/apt/sources.list.d/docker.list ]; then add_gpg_key "https://download.docker.com/linux/${DISTRO_ID}/gpg" \ "/etc/apt/keyrings/docker.asc" echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${DISTRO_ID} ${DISTRO_VERSION_CODENAME:-$(. /etc/os-release && echo "$VERSION_CODENAME")} stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ok " Docker CE repo added." fi # ---- Tailscale ---- info " Adding Tailscale repo..." if [ ! -f /etc/apt/sources.list.d/tailscale.list ]; then add_gpg_key "https://pkgs.tailscale.com/stable/${DISTRO_ID}/$(. /etc/os-release && echo "$VERSION_CODENAME").gz" \ "/usr/share/keyrings/tailscale-archive-keyring.gpg" 2>/dev/null || \ add_gpg_key "https://pkgs.tailscale.com/stable/${DISTRO_ID}/repo.gpg" \ "/usr/share/keyrings/tailscale-archive-keyring.gpg" echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${DISTRO_ID} $(. /etc/os-release && echo "$VERSION_CODENAME") main" | \ sudo tee /etc/apt/sources.list.d/tailscale.list > /dev/null ok " Tailscale repo added." fi # ---- Signal Desktop ---- info " Adding Signal repo..." if [ ! -f /etc/apt/sources.list.d/signal-desktop.sources ]; then add_gpg_key "https://updates.signal.org/desktop/apt/keys.asc" \ "/usr/share/keyrings/signal-desktop-keyring.gpg" cat << 'EOF' | sudo tee /etc/apt/sources.list.d/signal-desktop.sources > /dev/null Types: deb URIs: https://updates.signal.org/desktop/apt Suites: xenial Components: main Architectures: amd64 Signed-By: /usr/share/keyrings/signal-desktop-keyring.gpg EOF ok " Signal repo added." fi # ---- Papirus icon theme (PPA) ---- info " Adding Papirus PPA..." if [ ! -f /etc/apt/sources.list.d/papirus-ubuntu-papirus-*.sources ]; then $REPO_ADD_PPA papirus/papirus 2>/dev/null && ok " Papirus PPA added." || warn " Papirus PPA failed." fi # ---- Solaar (Logitech) PPA ---- info " Adding Solaar PPA..." if [ ! -f /etc/apt/sources.list.d/solaar-unifying-ubuntu-stable-*.sources ]; then $REPO_ADD_PPA solaar-unifying/stable 2>/dev/null && ok " Solaar PPA added." || warn " Solaar PPA failed." fi # ---- Ghostty terminal PPA ---- info " Adding Ghostty PPA..." $REPO_ADD_PPA ghostty/ghostty 2>/dev/null && ok " Ghostty PPA added." || warn " Ghostty PPA failed." # ---- Zotero repo ---- info " Adding Zotero repo..." if [ ! -f /etc/apt/sources.list.d/zotero.list ]; then add_gpg_key "https://zotero.retorque.re/file/apt-package-archive/pubkey.gpg" \ "/usr/share/keyrings/zotero-archive-keyring.gpg" echo "deb [signed-by=/usr/share/keyrings/zotero-archive-keyring.gpg by-hash=force] https://zotero.retorque.re/file/apt-package-archive ./" | \ sudo tee /etc/apt/sources.list.d/zotero.list > /dev/null ok " Zotero repo added." fi # ---- Yubico PPA ---- info " Adding Yubico PPA..." $REPO_ADD_PPA yubico/stable 2>/dev/null && ok " Yubico PPA added." || warn " Yubico PPA failed." # ================================================================== # FEDORA / RHEL — DNF-based # ================================================================== elif [ "$DISTRO_FAMILY" = "fedora" ]; then info "Configuring DNF repositories..." # ---- RPM Fusion (free + nonfree) ---- info " Enabling RPM Fusion..." $PKG_INSTALL \ "https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm" \ "https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm" \ 2>/dev/null && ok " RPM Fusion configured." || warn " RPM Fusion install failed." # ---- VS Code ---- info " Adding VS Code repo..." sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc 2>/dev/null || true cat << 'EOF' | sudo tee /etc/yum.repos.d/vscode.repo > /dev/null [code] name=Visual Studio Code baseurl=https://packages.microsoft.com/yumrepos/vscode enabled=1 gpgcheck=1 gpgkey=https://packages.microsoft.com/keys/microsoft.asc EOF ok " VS Code repo added." # ---- Google Chrome ---- info " Adding Google Chrome repo..." cat << 'EOF' | sudo tee /etc/yum.repos.d/google-chrome.repo > /dev/null [google-chrome] name=Google Chrome baseurl=https://dl.google.com/linux/chrome/rpm/stable/x86_64 enabled=1 gpgcheck=1 gpgkey=https://dl.google.com/linux/linux_signing_key.pub EOF ok " Google Chrome repo added." # ---- Docker CE ---- info " Adding Docker CE repo..." repo_add_rpm https://download.docker.com/linux/fedora/docker-ce.repo && \ ok " Docker repo added." || warn " Docker repo add failed." # ---- Tailscale ---- info " Adding Tailscale repo..." repo_add_rpm https://pkgs.tailscale.com/stable/fedora/tailscale.repo && \ ok " Tailscale repo added." || warn " Tailscale repo add failed." # ---- Signal Desktop ---- # Signal does not provide an official RPM repo. Install via Flatpak (handled in stage 12). info " Note: Signal will be installed via Flatpak in stage 12." # ---- COPRs for extra packages ---- # Papirus icon theme is in RPM Fusion nonfree. # Solaar is in RPM Fusion. # Yubico tools: use COPR info " Adding COPR repos..." # Ghostty terminal emulator $REPO_ADD_COPR scottames/ghostty 2>/dev/null && ok " Ghostty COPR added." || warn " Ghostty COPR failed." # $REPO_ADD_COPR atim/papirus-icon-theme 2>/dev/null || true # $REPO_ADD_COPR sergiomb/Solaar 2>/dev/null || true # ---- Zotero — no DNF repo, use Flatpak (handled in stage 13) ---- info " Note: Zotero will be installed via Flatpak or tarball in stage 13." fi # ---- Update package cache after adding repos ---- info "Updating package cache..." $PKG_UPDATE 2>/dev/null || warn "Package cache update had issues." ok "Stage 01 complete: repositories configured."