From a74a1080e0f2ba1821e5f27af2d0a915cb2ae6df Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Wed, 20 May 2026 04:42:03 -0700 Subject: [PATCH] Move uninstall scripts into scripts/ and fix references (#5644) * Move uninstall scripts into scripts/ and fix all references Relocates `uninstall.sh` and `uninstall.ps1` from the repo root into the existing `scripts/` directory, alongside the other helper scripts. Reference fixes: * `README.md`: Studio uninstall instructions now point at the raw GitHub URLs under `scripts/`. The previous `unsloth.ai/uninstall.*` short URLs currently 404 (unlike `unsloth.ai/install.sh`, which 301s to the raw github URL), so the raw URL is the working entry point until that redirect is configured. * `scripts/uninstall.sh` header `Usage:` example updated to the new raw GitHub path. * `scripts/uninstall.ps1` header `Usage:` example updated to the new raw GitHub path. * `.github/workflows/studio-update-smoke.yml`: `paths:` trigger and round-trip exec/exists checks now use `scripts/uninstall.sh`. * `.github/workflows/studio-mac-update-smoke.yml`: same. * `.github/workflows/studio-windows-update-smoke.yml`: `paths:` trigger and round-trip exec/exists checks now use `scripts/uninstall.ps1`. The in-script help hints (e.g. `sh uninstall.sh`, `.\uninstall.ps1`) are left unchanged because they are user-facing examples shown after the user already has the file locally, and the basename form works regardless of which directory the user downloaded the script into. Follow-up note for unsloth.ai: once this lands, please add the `unsloth.ai/uninstall.sh` and `unsloth.ai/uninstall.ps1` short-URL redirects to `raw.githubusercontent.com/unslothai/unsloth/main/scripts/...` (matching the existing `unsloth.ai/install.sh` redirect pattern). * Update remaining uninstall script help hints for new scripts/ path Three user-facing strings inside the uninstall scripts still showed the old basename form, which became misleading after the move: * `scripts/uninstall.ps1` header `# Local:` example: now references `.\scripts\uninstall.ps1` (the actual path from the cloned repo root). * `scripts/uninstall.sh` env-var re-run hint: now shows the canonical curl-pipe form documented in README, since callers who came via `curl -fsSL ... | sh` never had a local `uninstall.sh` to invoke. * `scripts/uninstall.ps1` env-var re-run hint: same, switched to the `irm ... | iex` form documented in README. Pure string changes, no behavior change. --------- Co-authored-by: Lee Jackson <130007945+Imagineer99@users.noreply.github.com> --- .github/workflows/studio-mac-update-smoke.yml | 18 ++++++------- .github/workflows/studio-update-smoke.yml | 20 +++++++-------- .../workflows/studio-windows-update-smoke.yml | 25 ++++++++++--------- README.md | 4 +-- uninstall.ps1 => scripts/uninstall.ps1 | 6 ++--- uninstall.sh => scripts/uninstall.sh | 4 +-- 6 files changed, 39 insertions(+), 38 deletions(-) rename uninstall.ps1 => scripts/uninstall.ps1 (99%) rename uninstall.sh => scripts/uninstall.sh (97%) diff --git a/.github/workflows/studio-mac-update-smoke.yml b/.github/workflows/studio-mac-update-smoke.yml index cfa192b470..b65439f174 100644 --- a/.github/workflows/studio-mac-update-smoke.yml +++ b/.github/workflows/studio-mac-update-smoke.yml @@ -21,7 +21,7 @@ on: pull_request: paths: - 'install.sh' - - 'uninstall.sh' + - 'scripts/uninstall.sh' - 'studio/setup.sh' - 'studio/install_python_stack.py' - 'studio/install_llama_prebuilt.py' @@ -139,20 +139,20 @@ jobs: echo "post-update Studio /api/health OK" - name: Uninstall and verify clean - # Round-trip through uninstall.sh on real macOS. As a side effect - # this exercises the macOS-only .app bundle + Launch Services + # Round-trip through scripts/uninstall.sh on real macOS. As a side + # effect this exercises the macOS-only .app bundle + Launch Services # removal path (~/Applications/Unsloth Studio.app, lsregister -u) # which is not testable from a Linux runner. Skips gracefully if - # uninstall.sh has not landed yet (lets this workflow merge + # scripts/uninstall.sh has not landed yet (lets this workflow merge # before #5497). run: | set -o pipefail - if [ ! -f uninstall.sh ]; then - echo "uninstall.sh not present in this tree; skipping round-trip" + if [ ! -f scripts/uninstall.sh ]; then + echo "scripts/uninstall.sh not present in this tree; skipping round-trip" : > logs/uninstall.log exit 0 fi - sh uninstall.sh 2>&1 | tee logs/uninstall.log + sh scripts/uninstall.sh 2>&1 | tee logs/uninstall.log leak=0 for p in \ "$HOME/.unsloth/studio" \ @@ -166,8 +166,8 @@ jobs: fi done [ "$leak" -eq 0 ] || exit 1 - sh uninstall.sh 2>&1 | tail -5 - sh uninstall.sh 2>&1 | tail -5 + sh scripts/uninstall.sh 2>&1 | tail -5 + sh scripts/uninstall.sh 2>&1 | tail -5 echo "PASS: mac install -> update -> uninstall round-trip clean" - name: Upload update logs diff --git a/.github/workflows/studio-update-smoke.yml b/.github/workflows/studio-update-smoke.yml index b28e2bf0bd..057aeacbd4 100644 --- a/.github/workflows/studio-update-smoke.yml +++ b/.github/workflows/studio-update-smoke.yml @@ -15,7 +15,7 @@ on: pull_request: paths: - 'install.sh' - - 'uninstall.sh' + - 'scripts/uninstall.sh' - 'studio/setup.sh' - 'studio/install_python_stack.py' - 'studio/install_llama_prebuilt.py' @@ -141,22 +141,22 @@ jobs: echo "post-update Studio /api/health OK" - name: Uninstall and verify clean - # Round-trip the installer through uninstall.sh: confirms the + # Round-trip the installer through scripts/uninstall.sh: confirms the # uninstaller actually finds and removes everything install.sh + # update wrote. Safety-guard scenarios (refuse-$HOME etc.) belong # in a separate fast smoke job; this is the happy-path cleanup # assertion that catches regressions where install.sh starts - # writing to a new location and uninstall.sh hasn't caught up. - # Skips gracefully if uninstall.sh has not landed yet (lets this - # workflow merge before #5497). + # writing to a new location and scripts/uninstall.sh hasn't caught up. + # Skips gracefully if scripts/uninstall.sh has not landed yet (lets + # this workflow merge before #5497). run: | set -o pipefail - if [ ! -f uninstall.sh ]; then - echo "uninstall.sh not present in this tree; skipping round-trip" + if [ ! -f scripts/uninstall.sh ]; then + echo "scripts/uninstall.sh not present in this tree; skipping round-trip" : > logs/uninstall.log exit 0 fi - sh uninstall.sh 2>&1 | tee logs/uninstall.log + sh scripts/uninstall.sh 2>&1 | tee logs/uninstall.log leak=0 for p in \ "$HOME/.unsloth/studio" \ @@ -171,8 +171,8 @@ jobs: done [ "$leak" -eq 0 ] || exit 1 # Idempotent: re-runs exit 0 on an empty $HOME. - sh uninstall.sh 2>&1 | tail -5 - sh uninstall.sh 2>&1 | tail -5 + sh scripts/uninstall.sh 2>&1 | tail -5 + sh scripts/uninstall.sh 2>&1 | tail -5 echo "PASS: install -> update -> uninstall round-trip clean" - name: Upload update logs diff --git a/.github/workflows/studio-windows-update-smoke.yml b/.github/workflows/studio-windows-update-smoke.yml index b412d60921..b477b3fa11 100644 --- a/.github/workflows/studio-windows-update-smoke.yml +++ b/.github/workflows/studio-windows-update-smoke.yml @@ -23,7 +23,7 @@ on: pull_request: paths: - 'install.ps1' - - 'uninstall.ps1' + - 'scripts/uninstall.ps1' - 'studio/setup.ps1' - 'studio/setup.bat' - 'studio/install_python_stack.py' @@ -268,21 +268,22 @@ jobs: echo "post-update Studio /api/health OK" - name: Uninstall and verify clean - # Round-trip through uninstall.ps1 against the default install - # tree at %USERPROFILE%\.unsloth\studio. Catches regressions - # where install.ps1 starts writing under a new key (registry, - # Start Menu, %APPDATA%) and uninstall.ps1 has not been updated - # to match. Skips gracefully if uninstall.ps1 has not landed yet - # (lets this workflow merge before #5513). + # Round-trip through scripts/uninstall.ps1 against the default + # install tree at %USERPROFILE%\.unsloth\studio. Catches + # regressions where install.ps1 starts writing under a new key + # (registry, Start Menu, %APPDATA%) and scripts/uninstall.ps1 has + # not been updated to match. Skips gracefully if + # scripts/uninstall.ps1 has not landed yet (lets this workflow + # merge before #5513). shell: pwsh run: | New-Item -ItemType Directory -Force -Path logs | Out-Null - if (-not (Test-Path "$PWD\uninstall.ps1")) { - Write-Host "uninstall.ps1 not present in this tree; skipping round-trip" + if (-not (Test-Path "$PWD\scripts\uninstall.ps1")) { + Write-Host "scripts/uninstall.ps1 not present in this tree; skipping round-trip" "" | Set-Content logs/uninstall.log exit 0 } - pwsh -NoProfile -File "$PWD\uninstall.ps1" *>&1 | Tee-Object -FilePath logs/uninstall.log + pwsh -NoProfile -File "$PWD\scripts\uninstall.ps1" *>&1 | Tee-Object -FilePath logs/uninstall.log $leak = 0 foreach ($p in @( "$env:USERPROFILE\.unsloth\studio", @@ -296,8 +297,8 @@ jobs: } if ($leak -gt 0) { exit 1 } # Idempotency. - pwsh -NoProfile -File "$PWD\uninstall.ps1" *>&1 | Select-Object -Last 5 - pwsh -NoProfile -File "$PWD\uninstall.ps1" *>&1 | Select-Object -Last 5 + pwsh -NoProfile -File "$PWD\scripts\uninstall.ps1" *>&1 | Select-Object -Last 5 + pwsh -NoProfile -File "$PWD\scripts\uninstall.ps1" *>&1 | Select-Object -Last 5 Write-Host "PASS: windows install -> update -> uninstall round-trip clean" - name: Upload update logs diff --git a/README.md b/README.md index 9e0bdb4dda..dc22804074 100644 --- a/README.md +++ b/README.md @@ -220,8 +220,8 @@ unsloth studio -p 8888 #### Uninstall The recommended way to fully remove Unsloth Studio is the matching uninstall script for your OS. It stops any running servers, removes the install dir, the launcher data dir, the desktop shortcut, and any platform-specific entries (macOS `.app` bundle + Launch Services on Mac; Start Menu, `HKCU\Software\Unsloth` registry key and user `PATH` entries on Windows): -* ​ **MacOS, WSL, Linux:** `curl -fsSL https://unsloth.ai/uninstall.sh | sh` -* ​ **Windows (PowerShell):** `irm https://unsloth.ai/uninstall.ps1 | iex` +* ​ **MacOS, WSL, Linux:** `curl -fsSL https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.sh | sh` +* ​ **Windows (PowerShell):** `irm https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.ps1 | iex` If you only want to drop the install dir and keep the launcher/shortcut for a later reinstall, you can instead run `rm -rf ~/.unsloth/studio` (Mac/Linux/WSL) or `Remove-Item -Recurse -Force "$HOME\.unsloth\studio"` (Windows). The model cache at `~/.cache/huggingface` is not touched by any of these. diff --git a/uninstall.ps1 b/scripts/uninstall.ps1 similarity index 99% rename from uninstall.ps1 rename to scripts/uninstall.ps1 index 9dfe1bd83c..6174e7e494 100644 --- a/uninstall.ps1 +++ b/scripts/uninstall.ps1 @@ -4,8 +4,8 @@ # registry key. Honors custom roots set via UNSLOTH_STUDIO_HOME / STUDIO_HOME # at install time (read back from share\studio.conf). # -# Usage: irm https://raw.githubusercontent.com/unslothai/unsloth/main/uninstall.ps1 | iex -# Local: Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass; .\uninstall.ps1 +# Usage: irm https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.ps1 | iex +# Local: Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass; .\scripts\uninstall.ps1 function Uninstall-UnslothStudio { $ErrorActionPreference = "Continue" @@ -345,7 +345,7 @@ function Uninstall-UnslothStudio { Write-Host "If you installed Unsloth Studio with UNSLOTH_STUDIO_HOME or STUDIO_HOME" Write-Host "pointing at a custom directory, re-run this script with the same variable" Write-Host "set to also remove that install tree, e.g.:" - Write-Host " `$env:UNSLOTH_STUDIO_HOME = 'C:\your\path'; .\uninstall.ps1" + Write-Host " `$env:UNSLOTH_STUDIO_HOME = 'C:\your\path'; irm https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.ps1 | iex" } } diff --git a/uninstall.sh b/scripts/uninstall.sh similarity index 97% rename from uninstall.sh rename to scripts/uninstall.sh index 7fbdc8dfac..94ca04b204 100755 --- a/uninstall.sh +++ b/scripts/uninstall.sh @@ -5,7 +5,7 @@ # Honors custom roots set via UNSLOTH_STUDIO_HOME / STUDIO_HOME at # install time (read back from studio.conf). # -# Usage: curl -fsSL https://unsloth.ai/uninstall.sh | sh +# Usage: curl -fsSL https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.sh | sh set -e @@ -279,5 +279,5 @@ if [ -z "${UNSLOTH_STUDIO_HOME:-}" ] && [ -z "${STUDIO_HOME:-}" ]; then echo "If you installed Unsloth Studio with UNSLOTH_STUDIO_HOME or STUDIO_HOME" echo "pointing at a custom directory, re-run this script with the same variable" echo "set to also remove that install tree, e.g.:" - echo " UNSLOTH_STUDIO_HOME=/your/path sh uninstall.sh" + echo " UNSLOTH_STUDIO_HOME=/your/path sh -c \"\$(curl -fsSL https://raw.githubusercontent.com/unslothai/unsloth/main/scripts/uninstall.sh)\"" fi