-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
## Type of change - [ ] Bug fix - [ ] New feature development - [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc) - [x] Build/deploy pipeline (DevOps) - [x] Other ## Objective Allow easy installation of `bws` on most systems with: `curl <script-url> | sh` on Linux and macOS or `iwr <script-url> | iex` on Windows ## Code changes - **crates/bws/scripts/install.(sh|ps1):** added install scripts that will download `bws` from GitHub Releases, validate the checksums, and install it. I am unsure if this is the _best_ place to house these scripts and would welcome suggestions for other places these might belong. - **.github/workflows/version-bump.yml:** added version bumps for the install scripts ## Before you submit - Please add **unit tests** where it makes sense to do so
- Loading branch information
1 parent
05475f1
commit 56547d7
Showing
4 changed files
with
313 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
param ( | ||
[switch]$Uninstall | ||
) | ||
|
||
$ErrorActionPreference = "Stop" | ||
|
||
$defaultBwsVersion = "0.5.0" | ||
$bwsVersion = if ($env:bwsVersion) { $env:bwsVersion } else { $defaultBwsVersion } | ||
$installDir = [Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData) | Join-Path -ChildPath "Programs" | Join-Path -ChildPath "Bitwarden" | ||
|
||
# https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor#properties | ||
$processorArch = (Get-CimInstance -ClassName Win32_Processor).Architecture | ||
if ($processorArch -eq 9) { | ||
$arch = "x86_64" | ||
} elseif ($processorArch -eq 12) { | ||
$arch = "aarch64" | ||
} else { | ||
throw "Unsupported architecture: $processorArch" | ||
} | ||
|
||
function Test-BwsInstallation { | ||
$existingBws = Get-Command bws -ErrorAction SilentlyContinue | ||
if ($null -ne $existingBws) { | ||
$userInput = Read-Host "bws is already installed at $($existingBws.Source). Do you want to overwrite it? (Y/N)" | ||
if ($userInput -ne "Y") { | ||
Write-Host "Installation cancelled by user." | ||
exit | ||
} | ||
} | ||
} | ||
|
||
function Invoke-BwsDownload { | ||
Write-Host "Detected architecture: $arch" | ||
|
||
$bwsUrl = "https://github.com/bitwarden/sdk/releases/download/bws-v$bwsVersion/bws-$arch-pc-windows-msvc-$bwsVersion.zip" | ||
Write-Host "Downloading bws from: $bwsUrl" | ||
$outputPath = Join-Path $env:TEMP "bws.zip" | ||
Invoke-WebRequest -Uri $bwsUrl -OutFile $outputPath | ||
return $outputPath | ||
} | ||
|
||
function Test-Checksum { | ||
param($zipPath) | ||
Write-Host "Validating checksum..." | ||
|
||
$checksumUrl = "https://github.com/bitwarden/sdk/releases/download/bws-v$bwsVersion/bws-sha256-checksums-$bwsVersion.txt" | ||
$checksumFile = Join-Path $env:TEMP "bws-checksums.txt" | ||
Invoke-WebRequest -Uri $checksumUrl -OutFile $checksumFile | ||
|
||
$expectedChecksum = (Get-Content $checksumFile | Where-Object { $_ -match "bws-$arch-pc-windows-msvc-$bwsVersion.zip" }).Split(" ")[0] | ||
$actualChecksum = (Get-FileHash -Algorithm SHA256 -Path $zipPath).Hash | ||
|
||
if ($actualChecksum -ne $expectedChecksum) { | ||
throw "Checksum validation failed. Expected: $expectedChecksum, Actual: $actualChecksum" | ||
} else { | ||
Write-Host "Checksum validation successful." | ||
} | ||
} | ||
|
||
function Install-Bws { | ||
param($zipPath) | ||
Write-Host "Installing bws..." | ||
New-Item -ItemType Directory -Force -Path $installDir | Out-Null | ||
Expand-Archive -Force $zipPath -DestinationPath $installDir | ||
Write-Host "bws installed to $installDir" | ||
setx PATH "$env:PATH;$installDir" | ||
Write-Host "$installDir has been added to your PATH" | ||
Write-Host "Please restart your shell to use bws" | ||
} | ||
|
||
function Test-Bws { | ||
Write-Host "Checking bws..." | ||
$bwsPath = Join-Path $installDir "bws.exe" | ||
if (Test-Path $bwsPath) { | ||
Write-Host "bws is installed at $bwsPath" | ||
} else { | ||
throw "bws is not installed" | ||
} | ||
} | ||
|
||
function Remove-Bws { | ||
Write-Host "Uninstalling bws..." | ||
|
||
if (Test-Path $installDir) { | ||
Remove-Item -Path $installDir -Recurse -Force | ||
Write-Host "bws uninstalled from $installDir" | ||
} else { | ||
Write-Host "bws installation directory not found at $installDir. Skipping removal." | ||
} | ||
|
||
$configDir = "$env:USERPROFILE\.bws" | ||
if (Test-Path $configDir -PathType Container) { | ||
Remove-Item -Path $configDir -Recurse -Force | ||
Write-Host "bws config directory removed from $configDir" | ||
} else { | ||
Write-Host "bws config directory not found at $configDir. Skipping removal." | ||
} | ||
} | ||
|
||
if ($Uninstall) { | ||
Remove-Bws | ||
} else { | ||
Test-BwsInstallation | ||
$zipPath = Invoke-BwsDownload | ||
Test-Checksum -zipPath $zipPath | ||
Install-Bws -zipPath $zipPath | ||
Test-Bws | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
#!/bin/sh | ||
|
||
################################################## | ||
# An installer for the bws command line utility. # | ||
################################################## | ||
|
||
DEFAULT_BWS_VERSION="0.5.0" | ||
BWS_VERSION="${BWS_VERSION:-$DEFAULT_BWS_VERSION}" | ||
|
||
main() { | ||
case "$1" in | ||
-u | --uninstall) | ||
uninstall_bws | ||
;; | ||
*) | ||
check_required | ||
platform_detect | ||
arch_detect | ||
download_bws | ||
validate_checksum | ||
install_bws | ||
;; | ||
esac | ||
} | ||
|
||
error() { | ||
echo "$1" >&2 | ||
echo "Exiting..." >&2 | ||
exit 1 | ||
} | ||
|
||
check_required() { | ||
if ! command -v curl >/dev/null && ! command -v wget >/dev/null; then | ||
error "curl or wget is required to download bws." | ||
fi | ||
|
||
if ! command -v unzip >/dev/null; then | ||
error "unzip is required to install bws." | ||
fi | ||
} | ||
|
||
can_sudo() { | ||
if command -v sudo >/dev/null; then | ||
echo "Attempting to install bws with sudo. Please enter your password if prompted." | ||
if sudo -v 2>/dev/null; then | ||
echo "sudo is available and we have the necessary permissions." | ||
echo "Installing bws to /usr/local/bin..." | ||
return 0 | ||
else | ||
echo "sudo is available, but we failed to authenticate." | ||
return 1 | ||
fi | ||
else | ||
echo "sudo is not available." | ||
return 1 | ||
fi | ||
} | ||
|
||
platform_detect() { | ||
if [ "$(uname -s)" = "Linux" ]; then | ||
PLATFORM="unknown-linux-gnu" | ||
elif [ "$(uname -s)" = "Darwin" ]; then | ||
PLATFORM="apple-darwin" | ||
else | ||
error "Unsupported platform: $(uname -s)" | ||
fi | ||
} | ||
|
||
arch_detect() { | ||
if [ "$(uname -m)" = "x86_64" ]; then | ||
ARCH="x86_64" | ||
elif [ "$(uname -m)" = "aarch64" ]; then # Linux uname output | ||
ARCH="aarch64" | ||
elif [ "$(uname -m)" = "arm64" ]; then # Darwin uname output | ||
ARCH="aarch64" | ||
else | ||
error "Unsupported architecture: $(uname -m)" | ||
fi | ||
} | ||
|
||
checksum() { | ||
if command -v sha256sum >/dev/null; then | ||
sha256sum "$1" | ||
else | ||
shasum -a 256 "$1" | ||
fi | ||
} | ||
|
||
downloader() { | ||
if command -v curl >/dev/null; then | ||
curl -L -o "$2" "$1" | ||
else | ||
wget -O "$2" "$1" | ||
fi | ||
} | ||
|
||
extract() { | ||
unzip -o "$1" -d "$2" | ||
} | ||
|
||
download_bws() { | ||
bws_url="https://github.com/bitwarden/sdk/releases/download/bws-v${BWS_VERSION}/bws-${ARCH}-${PLATFORM}-${BWS_VERSION}.zip" | ||
echo "Downloading bws from: $bws_url" | ||
tmp_dir="$(mktemp -d)" | ||
downloader "$bws_url" "$tmp_dir/bws.zip" | ||
} | ||
|
||
validate_checksum() { | ||
checksum_url="https://github.com/bitwarden/sdk/releases/download/bws-v${BWS_VERSION}/bws-sha256-checksums-${BWS_VERSION}.txt" | ||
echo "Downloading checksum file from: $checksum_url" | ||
checksum_file="$tmp_dir/bws-checksums.txt" | ||
downloader "$checksum_url" "$checksum_file" | ||
|
||
expected_checksum="$(grep "bws-${ARCH}-${PLATFORM}-${BWS_VERSION}.zip" "$checksum_file" | awk '{print $1}')" | ||
actual_checksum="$(checksum "$tmp_dir/bws.zip" | awk '{print $1}')" | ||
|
||
if [ "$actual_checksum" != "$expected_checksum" ]; then | ||
error "Checksum validation failed. Expected: $expected_checksum, Actual: $actual_checksum" | ||
else | ||
echo "Checksum validation successful." | ||
fi | ||
} | ||
|
||
install_bws() { | ||
echo "Installing bws..." | ||
extract "$tmp_dir/bws.zip" "$tmp_dir" | ||
chmod +x "$tmp_dir/bws" | ||
|
||
if can_sudo; then | ||
sudo install -m 755 "$tmp_dir/bws" /usr/local/bin/bws | ||
|
||
if ! command -v bws >/dev/null; then | ||
error "Installation failed. bws was not found in /usr/local/bin" | ||
fi | ||
|
||
echo "bws installed to /usr/local/bin/bws" | ||
else | ||
echo "Installing to your \$HOME directory..." | ||
user_bin_dir="${HOME}/.local/bin" | ||
mkdir -p "${user_bin_dir}" | ||
install -m 755 "$tmp_dir/bws" "${user_bin_dir}/bws" | ||
|
||
if ! command -v "${user_bin_dir}/bws" >/dev/null; then | ||
error "Installation failed. bws was not found in ${user_bin_dir}" | ||
fi | ||
|
||
echo "bws installed at ${user_bin_dir}/bws" | ||
echo "Please add ${user_bin_dir} to your PATH by adding the following line to your ~/.profile or shell rc file:" | ||
echo "export PATH=\"\$PATH:${user_bin_dir}\"" | ||
fi | ||
|
||
rm -rf "$tmp_dir" | ||
} | ||
|
||
uninstall_bws() { | ||
if command -v bws >/dev/null; then | ||
echo "Uninstalling bws..." | ||
if can_sudo; then | ||
sudo rm "$(command -v bws)" | ||
else | ||
rm "$(command -v bws)" | ||
fi | ||
|
||
# Safely remove the configuration directory | ||
if [ -n "$HOME" ]; then | ||
echo "Removing bws configuration directory at ${HOME}/.bws" | ||
echo "If you use another directory for your configuration, you may want to remove it manually." | ||
rm -rf "${HOME}/.bws" | ||
else | ||
echo "HOME environment variable is not set. Cannot safely remove .bws directory." | ||
fi | ||
|
||
echo "bws uninstalled successfully." | ||
else | ||
echo "bws is not installed." | ||
fi | ||
exit 0 | ||
} | ||
|
||
main "$@" |