mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2025-12-11 20:15:30 +01:00
* Attempt to fix Windows CI: - Ensure version 15 of LLVM is installed in Windows CI (due to` ffmpeg-sys-next`) - Use `GITHUB_TOKEN` in setup-system.ps1 to avoid rate-limiting by github api in Windows CI - Add `yaml` settings to `.editorconfig` - Create a symbolic link from `.prettierignore` to `.eslintignore` - Move `eslint` root to package root config - Enable `fileNesting` to reduce dotfile clutter in vscode - Pass `--strict` to apps/releases `lint` command to avoid making interactive queries and hanging `pnpm lint` - Format with `prettier` and `eslint` - Remove empty interface/hooks/useMediaQuery.ts * Replace unmaintained `actions-rs/toolchain` with `dtolnay/rust-toolchain` - Change setup-system.ps1 to avoid installing pnpm in CI - Change `pnpm/action-setup` to lock only o major versions of the action
385 lines
15 KiB
PowerShell
385 lines
15 KiB
PowerShell
# Enables strict mode, which causes PowerShell to treat uninitialized variables, undefined functions, and other common errors as terminating errors.
|
|
$ErrorActionPreference = if ($env:CI) { 'Stop' } else { 'Inquire' }
|
|
Set-StrictMode -Version Latest
|
|
|
|
function Reset-Path {
|
|
$env:Path = [System.Environment]::ExpandEnvironmentVariables(
|
|
[System.Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path', 'User')
|
|
)
|
|
}
|
|
|
|
function Set-EnvVar($variable, $value = $null) {
|
|
if ($null -ne $value) {
|
|
[System.Environment]::SetEnvironmentVariable($variable, $value, 'User')
|
|
if ($env:CI -and ($variable -ne 'Path')) {
|
|
# If running in CI, we need to use GITHUB_ENV instead of the normal env variables
|
|
Add-Content $env:GITHUB_ENV "$variable=$value`n"
|
|
}
|
|
}
|
|
# The following is needed to make the environment variable available to the current PowerShell process
|
|
if ($variable -eq 'Path') {
|
|
Reset-Path
|
|
} else {
|
|
[System.Environment]::SetEnvironmentVariable(
|
|
$variable, [System.Environment]::GetEnvironmentVariable($variable, 'User'), 'Process'
|
|
)
|
|
}
|
|
}
|
|
|
|
# Verify if environment is Windows 64-bit and if the user is an administrator
|
|
if ((-not [string]::IsNullOrEmpty($env:PROCESSOR_ARCHITEW6432)) -or (
|
|
"$env:PROCESSOR_ARCHITECTURE" -eq 'ARM64'
|
|
) -or (
|
|
-not [System.Environment]::Is64BitOperatingSystem
|
|
# Powershell >= 6 is cross-platform, check if running on Windows
|
|
) -or (($PSVersionTable.PSVersion.Major -ge 6) -and (-not $IsWindows))
|
|
) {
|
|
$ErrorActionPreference = 'Continue'
|
|
Write-Host # There is no oficial ffmpeg binaries for Windows 32 or ARM
|
|
if (Test-Path "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -PathType Leaf) {
|
|
throw 'You are using PowerShell (32-bit), please re-run in PowerShell (64-bit)'
|
|
} else {
|
|
throw 'This script is only supported on Windows 64-bit'
|
|
}
|
|
Exit 1
|
|
} elseif (
|
|
-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
) {
|
|
# Start a new PowerShell process with administrator privileges and set the working directory to the directory where the script is located
|
|
Start-Process -Wait -FilePath 'PowerShell.exe' -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$($MyInvocation.MyCommand.Definition)`"" -WorkingDirectory "$PSScriptRoot"
|
|
# NOTICE: Any modified environment variables should be reloaded here, so the user doesn't have to restart the shell after running the script
|
|
Reset-Path
|
|
Set-EnvVar('PROTOC')
|
|
Set-EnvVar('FFMPEG_DIR')
|
|
Exit
|
|
}
|
|
|
|
function Exit-WithError($err, $help = $null) {
|
|
if ($null -ne $help) {
|
|
Write-Host
|
|
Write-Host $help -ForegroundColor DarkRed
|
|
}
|
|
throw $err
|
|
Exit 1
|
|
}
|
|
|
|
function Add-DirectoryToPath($directory) {
|
|
if ($env:Path.Split(';') -notcontains $directory) {
|
|
Set-EnvVar 'Path' "$($env:Path);$directory"
|
|
if ($env:CI) {
|
|
# If running in CI, we need to use GITHUB_PATH instead of the normal PATH env variables
|
|
Add-Content $env:GITHUB_PATH "$directory`n"
|
|
}
|
|
}
|
|
Reset-Path
|
|
}
|
|
|
|
function Invoke-RestMethodGithub {
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$Uri,
|
|
[string]$Method = 'GET',
|
|
[hashtable]$Headers = @{},
|
|
[string]$UserAgent = 'PowerShell'
|
|
)
|
|
|
|
if (![string]::IsNullOrEmpty($env:GITHUB_TOKEN)) {
|
|
$headers.Add("Authorization", "Bearer $($env:GITHUB_TOKEN)")
|
|
}
|
|
|
|
$params = @{
|
|
Uri = $Uri
|
|
Method = $Method
|
|
Headers = $Headers
|
|
UserAgent = $UserAgent
|
|
}
|
|
|
|
Invoke-RestMethod @params
|
|
}
|
|
|
|
# Reset PATH to ensure the script doesn't read any stale entries
|
|
Reset-Path
|
|
|
|
# Get temp folder
|
|
$temp = [System.IO.Path]::GetTempPath()
|
|
|
|
# Get project dir (get grandparent dir from script location: <PROJECT_ROOT>\.github\scripts)
|
|
$projectRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent
|
|
|
|
# Currently pnpm >= 8 is not supported due to incompatibilities with some dependencies
|
|
$pnpm_major = '7'
|
|
|
|
# Currently LLVM >= 16 is not supported due to incompatibilities with ffmpeg-sys-next
|
|
# See https://github.com/spacedriveapp/spacedrive/issues/677
|
|
$llvm_major = '15'
|
|
|
|
# Change CWD to project root
|
|
Set-Location $projectRoot
|
|
|
|
Write-Host 'Spacedrive Development Environment Setup' -ForegroundColor Magenta
|
|
Write-Host @"
|
|
|
|
To set up your machine for Spacedrive development, this script will do the following:
|
|
1) Install Windows C++ build tools
|
|
2) Install Edge Webview 2
|
|
3) Install Rust and Cargo
|
|
4) Install Rust tools
|
|
5) Install Node.js, npm and pnpm $pnpm_major
|
|
6) Install LLVM $llvm_major (compiler for ffmpeg-rust)
|
|
7) Download protbuf compiler and set the PROTOC environment variable
|
|
8) Download ffmpeg and set the FFMPEG_DIR environment variable
|
|
"@
|
|
|
|
# Check connectivity to GitHub
|
|
$ProgressPreference = 'SilentlyContinue'
|
|
if (-not ((Test-NetConnection -ComputerName 'github.com' -Port 80).TcpTestSucceeded)) {
|
|
throw "Can't connect to github, maybe internet is down?"
|
|
}
|
|
$ProgressPreference = 'Continue'
|
|
|
|
# Install C++ build tools and Rust
|
|
# GitHub Actions already has all of this installed
|
|
if (-not $env:CI) {
|
|
if (-not (Get-Command winget -ea 0)) {
|
|
Exit-WithError 'winget not available' @'
|
|
Follow the instructions here to install winget:
|
|
https://learn.microsoft.com/windows/package-manager/winget/
|
|
'@
|
|
}
|
|
|
|
Write-Host
|
|
Write-Host 'Installing Visual Studio Build Tools...' -ForegroundColor Yellow
|
|
Write-Host 'This will take some time as it involves downloading several gigabytes of data....' -ForegroundColor Cyan
|
|
# Force install because BuildTools is itself an installer for multiple packages, so let itself decide if it need to install anythin or not
|
|
winget install --exact --no-upgrade --accept-source-agreements --force --disable-interactivity --id Microsoft.VisualStudio.2022.BuildTools --override '--wait --quiet --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended'
|
|
|
|
Write-Host
|
|
Write-Host 'Installing Edge Webview 2...' -ForegroundColor Yellow
|
|
try {
|
|
# This is normally already available, but on some early Windows 10 versions it isn't
|
|
winget install --exact --no-upgrade --accept-source-agreements --disable-interactivity --id Microsoft.EdgeWebView2Runtime
|
|
} catch {}
|
|
|
|
Write-Host
|
|
Write-Host 'Installing Rust and Cargo...' -ForegroundColor Yellow
|
|
try {
|
|
winget install --exact --no-upgrade --accept-source-agreements --disable-interactivity --id Rustlang.Rustup
|
|
Reset-Path # Reset Path to ensure that cargo is available to the command bellow
|
|
} catch {}
|
|
|
|
Write-Host
|
|
Write-Host 'Installing Rust tools' -ForegroundColor Yellow
|
|
cargo install cargo-watch
|
|
}
|
|
|
|
Write-Host
|
|
Write-Host 'Checking for pnpm...' -ForegroundColor Yellow
|
|
if ($env:CI) {
|
|
# The CI has pnpm installed already
|
|
Write-Host 'Running with CI, skipping pnpm install.' -ForegroundColor Green
|
|
}if ((Get-Command pnpm -ea 0) -and (pnpm --version | Select-Object -First 1) -match "^$pnpm_major\." ) {
|
|
Write-Host "pnpm $pnpm_major is installed." -ForegroundColor Green
|
|
} else {
|
|
# Check for pnpm installed with standalone installer
|
|
if (($null -ne $env:PNPM_HOME) -and (Test-Path "$env:PNPM_HOME/pnpm.exe" -PathType Leaf)) {
|
|
Exit-WithError 'You have a incompatible version of pnpm installed, please remove it and run this script again' @'
|
|
Follow the instructions here to uninstall pnpm:
|
|
https://pnpm.io/uninstall
|
|
'@
|
|
} else {
|
|
# Remove possible remaining envvars from old pnpm installation
|
|
[System.Environment]::SetEnvironmentVariable('PNPM_HOME', $null, [System.EnvironmentVariableTarget]::Machine)
|
|
[System.Environment]::SetEnvironmentVariable('PNPM_HOME', $null, [System.EnvironmentVariableTarget]::User)
|
|
}
|
|
|
|
if (-not $env:CI) {
|
|
Write-Host 'Installing NodeJS...' -ForegroundColor Yellow
|
|
try {
|
|
winget install --exact --no-upgrade --accept-source-agreements --disable-interactivity --id OpenJS.NodeJS
|
|
# Add NodeJS to the PATH
|
|
Add-DirectoryToPath "$env:SystemDrive\Program Files\nodejs"
|
|
} catch {}
|
|
}
|
|
|
|
Write-Host 'Installing pnpm...'
|
|
# Currently pnpm >= 8 is not supported due to incompatibilities with some dependencies
|
|
npm install -g 'pnpm@latest-7'
|
|
# Add NPM global modules to the PATH
|
|
if (Test-Path "$env:APPDATA\npm" -PathType Container) {
|
|
Add-DirectoryToPath "$env:APPDATA\npm"
|
|
}
|
|
}
|
|
|
|
Write-Host
|
|
Write-Host 'Checking for LLVM...' -ForegroundColor Yellow
|
|
if ($env:CI) {
|
|
# The CI has LLVM installed already
|
|
Write-Host 'Running with CI, skipping LLVM install.' -ForegroundColor Green
|
|
} elseif (
|
|
(Get-Command clang -ea 0) -and (
|
|
(clang --version | Select-String -Pattern 'version\s+(\d+)' | ForEach-Object { $_.Matches.Groups[1].Value }) -eq "$llvm_major"
|
|
)
|
|
) {
|
|
Write-Host "LLVM $llvm_major is installed." -ForegroundColor Green
|
|
} else {
|
|
$downloadUri = $null
|
|
$releasesUri = 'https://api.github.com/repos/llvm/llvm-project/releases'
|
|
$llvmVersion = "LLVM $llvm_major*"
|
|
$filenamePattern = '*-win64.exe'
|
|
|
|
Write-Host "Downloading LLVM $llvm_major installer..." -ForegroundColor Yellow
|
|
$releases = Invoke-RestMethodGithub -Uri $releasesUri
|
|
$downloadUri = $releases | ForEach-Object {
|
|
if ($_.name -like $llvmVersion) {
|
|
$_.assets | Where-Object { $_.name -like $filenamePattern } | Select-Object -ExpandProperty 'browser_download_url'
|
|
}
|
|
} | Select-Object -First 1
|
|
|
|
if ($null -eq $downloadUri) {
|
|
Exit-WithError "Couldn't find a LLVM installer for version: $llvm_major"
|
|
}
|
|
|
|
$oldUninstaller = "$env:SystemDrive\Program Files\LLVM\Uninstall.exe"
|
|
if (Test-Path $oldUninstaller -PathType Leaf) {
|
|
Exit-WithError 'You have a incompatible version of LLVM installed' 'Uninstall the current version of LLVM and run this script again'
|
|
}
|
|
|
|
Start-BitsTransfer -TransferType Download -Source $downloadUri -Destination "$temp\llvm.exe"
|
|
|
|
Write-Host "Installing LLVM $llvm_major" -ForegroundColor Yellow
|
|
Write-Host 'This may take a while and will have no visual feedback, please wait...' -ForegroundColor Cyan
|
|
Start-Process -FilePath "$temp\llvm.exe" -Verb RunAs -ArgumentList '/S' -Wait -ErrorAction Stop
|
|
|
|
Add-DirectoryToPath "$env:SystemDrive\Program Files\LLVM\bin"
|
|
|
|
Remove-Item "$temp\llvm.exe"
|
|
}
|
|
|
|
Write-Host
|
|
Write-Host 'Checking for protobuf compiler...' -ForegroundColor Yellow
|
|
$protocVersion = $null
|
|
if (($null -ne $env:PROTOC) -and (Test-Path $env:PROTOC -PathType Leaf)) {
|
|
$protocVersion = &"$env:PROTOC" --version 2>&1 | Out-String
|
|
}
|
|
|
|
if ($protocVersion) {
|
|
Write-Host 'protobuf compiler is installed.' -ForegroundColor Green
|
|
} else {
|
|
$filename = $null
|
|
$downloadUri = $null
|
|
$releasesUri = 'https://api.github.com/repos/protocolbuffers/protobuf/releases'
|
|
$filenamePattern = '*-win64.zip'
|
|
|
|
Write-Host 'Downloading protobuf compiler...' -ForegroundColor Yellow
|
|
$releases = Invoke-RestMethodGithub -Uri $releasesUri
|
|
for ($i = 0; $i -lt $releases.Count; $i++) {
|
|
$release = $releases[$i]
|
|
foreach ($asset in $release.assets) {
|
|
if ($asset.name -like $filenamePattern) {
|
|
$filename = $asset.name
|
|
$downloadUri = $asset.browser_download_url
|
|
$i = $releases.Count
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if (-not ($filename -and $downloadUri)) {
|
|
Exit-WithError "Couldn't find a protobuf compiler installer"
|
|
}
|
|
|
|
$foldername = "$env:LOCALAPPDATA\$([System.IO.Path]::GetFileNameWithoutExtension($fileName))"
|
|
New-Item -Path $foldername -ItemType Directory -ErrorAction SilentlyContinue
|
|
|
|
Write-Host 'Dowloading protobuf zip...' -ForegroundColor Yellow
|
|
Start-BitsTransfer -TransferType Download -Source $downloadUri -Destination "$temp\protobuf.zip"
|
|
|
|
Write-Host 'Expanding protobuf zip...' -ForegroundColor Yellow
|
|
Expand-Archive "$temp\protobuf.zip" $foldername -ErrorAction SilentlyContinue
|
|
Remove-Item "$temp\protobuf.zip"
|
|
|
|
Write-Host 'Setting PROTOC environment variable...' -ForegroundColor Yellow
|
|
Set-EnvVar 'PROTOC' "$foldername\bin\protoc.exe"
|
|
Add-DirectoryToPath "$foldername\bin"
|
|
}
|
|
|
|
Write-Host
|
|
Write-Host 'Update cargo packages...' -ForegroundColor Yellow
|
|
# Run first time to ensure packages are up to date
|
|
cargo metadata --format-version 1 > $null
|
|
|
|
Write-Host
|
|
Write-Host 'Checking for ffmpeg build...' -ForegroundColor Yellow
|
|
# Get ffmpeg-sys-next version
|
|
$ffmpegVersion = (cargo metadata --format-version 1 | ConvertFrom-Json).packages.dependencies | Where-Object {
|
|
$_.name -like 'ffmpeg-sys-next'
|
|
} | Select-Object -ExpandProperty 'req' | ForEach-Object {
|
|
$_ -replace '[~^<>=!*]+', ''
|
|
} | Sort-Object -Unique | Select-Object -Last 1
|
|
|
|
if (($null -ne $env:FFMPEG_DIR) -and (
|
|
$ffmpegVersion.StartsWith(
|
|
(($env:FFMPEG_DIR.split('\') | Where-Object { $_ -like 'ffmpeg-*' }) -replace 'ffmpeg-(\d+(\.\d+)*).*', '$1'),
|
|
[System.StringComparison]::InvariantCulture
|
|
)
|
|
)
|
|
) {
|
|
Write-Host 'ffmpeg is installed.' -ForegroundColor Green
|
|
} else {
|
|
$filename = $null
|
|
$downloadUri = $null
|
|
$releasesUri = 'https://api.github.com/repos/GyanD/codexffmpeg/releases'
|
|
$filenamePattern = '*-full_build-shared.zip'
|
|
|
|
# Downloads a build of ffmpeg from GitHub compatible with the declared ffmpeg-sys-next version
|
|
$releases = Invoke-RestMethodGithub -Uri $releasesUri
|
|
$version = $ffmpegVersion
|
|
while (-not ($filename -and $downloadUri) -and $version) {
|
|
for ($i = 0; $i -lt $releases.Count; $i++) {
|
|
$release = $releases[$i]
|
|
if ($release.tag_name -eq $version) {
|
|
foreach ($asset in $release.assets) {
|
|
if ($asset.name -like $filenamePattern) {
|
|
$filename = $asset.name
|
|
$downloadUri = $asset.browser_download_url
|
|
$i = $releases.Count
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$version = $version -replace '\.?\d+$'
|
|
}
|
|
|
|
if (-not ($filename -and $downloadUri)) {
|
|
Exit-WithError "Couldn't find a ffmpeg installer for version: $ffmpegVersion"
|
|
}
|
|
|
|
$foldername = "$env:LOCALAPPDATA\$([System.IO.Path]::GetFileNameWithoutExtension($fileName))"
|
|
|
|
Write-Host 'Dowloading ffmpeg zip...' -ForegroundColor Yellow
|
|
Start-BitsTransfer -TransferType Download -Source $downloadUri -Destination "$temp\ffmpeg.zip"
|
|
|
|
Write-Host 'Expanding ffmpeg zip...' -ForegroundColor Yellow
|
|
# FFmpeg zip contains a subdirectory with the same name as the zip file
|
|
Expand-Archive "$temp\ffmpeg.zip" $env:LOCALAPPDATA -ErrorAction SilentlyContinue
|
|
Remove-Item "$temp\ffmpeg.zip"
|
|
|
|
Write-Host 'Setting FFMPEG_DIR environment variable...' -ForegroundColor Yellow
|
|
Set-EnvVar 'FFMPEG_DIR' "$foldername"
|
|
Add-DirectoryToPath "$foldername\bin"
|
|
}
|
|
|
|
Write-Host
|
|
Write-Host 'Copying Required .dll files...' -ForegroundColor Yellow
|
|
# Create target\debug folder, continue if already exists
|
|
New-Item -Path $projectRoot\target\debug -ItemType Directory -ErrorAction SilentlyContinue
|
|
# Copies all .dll required for rust-ffmpeg to target\debug folder
|
|
Get-ChildItem "$env:FFMPEG_DIR\bin" -Recurse -Filter *.dll | Copy-Item -Destination "$projectRoot\target\debug"
|
|
|
|
Write-Host
|
|
Write-Host 'Your machine has been setup for Spacedrive development!' -ForegroundColor Green
|
|
Write-Host 'You will need to re-run this script if there are rust dependencies changes or you use `pnpm clean` or `cargo clean`!' -ForegroundColor Red
|
|
if (-not $env:CI) { Read-Host 'Press Enter to continue' }
|