Files
spacedrive/.github/scripts/setup-system.ps1
Vítor Vasconcellos cf482f5621 [ENG-270, ENG-213] Stabilize release pipeline (#768)
* Attempt at building our own ffmpeg dylibs for macOS
 - Create dockerfile to setup osxcross and required host dependencies for cross-compiling ffmpeg for macOS
 - Create script to setup required macOS dependencies and build ffmpeg for both x86_64 and aarch64

* Improve dockerfile to better use docker's cache
 - Attempt at fixing arm64 build (still not there yet)

* ARM64 sucessfully compiles \o/
 - Use clang for everything (e.g. linker, assembler, ...)
 - Remove -lc++ because it is now handled internally thanks to a patch
 - Apply 3 open PRs to osxcross as external patches to solve some of our problems
 - PR 180 reduces the macports dependencies size by prefering non universal libs for x88
 - PR 314 adds the -lc++ flag for macOS SDKs >= 11.1
 - PR 379 fix macports pulling incorrects deps for SDK11 and adds support for SDK13 (future proofing, as it does nothing for us rigth now)

* Fix relink and copy logic in ffmpeg build script
 - Ensure ffmpeg and dependencies dylibs are correctly relinked and copied over to the output directory
 - Copy includes from ffmpeg and dependencies to allow for dev building against these dylibs
 - Set up symlinks for all dylibs to the common `lib` directory
 - Remove superfluous linker and compiler options
 - Add `-headerpad_max_install_names` linker option to accommodate the required relink changes
 - Remove `--disable-fft` for the arm64 build, as it doesn't seem to be required nowadays
 - Allow `swresample` and `avdevices` to be compiled as they seem to be expected to exist by `ffmpeg-sys-next`
 - Disable ffmpeg program compilation
 - Fix dylibs id to match their new expected location
 - Fix ffmpeg dylibs inter-linkage not being updated
 - Add custom patch for osxcross macports to load already downloaded files from cache
 - Remove the requirement for specifying the darwin version in the Dockerfile
 - Enable docker cache for macports
 - Move arm min macOS version ARG to the top

* Attempt at building ffmpeg with github actions
 - Split osxcross setup into it's own Dockerfile to allow exporting it as a image to Dockerhub
 - Create a github action to build ffmpeg
 - Add osxcross patch for PR 372 for future proofing (Add support for macOS SDK 13.1)

* Remove incompatible step name

* Change FFMPEG_VERSION to string to avoid yaml weird type casting

* Start to use our ffmpeg build in the macOS
 - Adjust the macOS setup script to download our ffmpeg build, also replace installing protobuf compiler from brew with grabbing it from it's own repository
 - Some misc improvement to the *nix setup script
 - Fix ffmpeg build script not copying static libs (for when we may want to statically link ffmpeg)
 - Fix ffmpeg build script not taking into acount possible libraries that are multiple paths deep in /lib
 - Update CI to actions/checkout@v3, v2 is deprecated
 - Update ffmpeg build CI to not xz the artifacts, as github already zips it anyway

* Fix macOS setup not finding the ffmpeg artifact due to a jq script mistake
 - Comment out embeeding static libs in ffmpeg artifact for now, as they take too much space
 - Remove incorrect dockerfile settings from editorconfig

* Fix protobuf download in macOS
 - Fix Framework directory creation not following script's dir but cwd
 - Improve download logic to avoid being rate limited on failures
 - Return to using xz for ffmpeg build, as it saves quite a bit of space

* Replace `OSTYPE` with `$(uname)` for a more standardized way to check which os is running
 - Fix mobile check using `==` instead of `=` in test command

* Fix syntax error in bash 3.x (which is the default in macOS)
 - Fix jq not downloading all deps and being placed in the incorrect directory

* Fix incorrect install_name_tool arguments
 - Remove leading './' when referencing ffmpeg libs during build

* Fix protoc not being executable
 - Fix some error messages

* jq throw input when it is invalid
 - Enable debug log in setup script when running in CI

* Add a dev.js build script for desktop app
 - Remove dll copy from setup-system.ps1, now done by dev.js
 - Minor rework to build.js to improve signals and stdio handling

* Configure cargo to use FFMPEG_DIR and PROTOC envvars on macOS

* Pass GITHUB_TOKEN to macOS setup script in CI

* Replace simple curl with gh_curl in github request

* Fix some ctrl+c/ctrl+v typos

* Add missing ffmpeg deps
 - Fix missing symlinks for ffmpeg libs in the output_dir/libs
 - Change arm64 minimum macOS target to 11.2 due to libbrotli only being available precompiled to this version
 - Add more options to ffmpeg configure in an attempt to reduce its size + improve performance

* Rework ffmpeg build script to create a FFMpeg.framework instead of loose dylibs
 - Disable unused postproc and enabled missing required protocols in ffmpeg configuration
 - Adjust Dockerfile and setup-script to handle the new FFMpeg.framework

* Fix setup script incorrect linking logic for FFMpeg.framework

* Forgot to remote the leading path in the lib/header linking logic for FFMpeg.framework

* Enable size optimization for ffmpeg
 - Remove Frameworks directory before setting it up in setup-system.sh

* Revert lib id to use `@executable_path/../Frameworks/` instead of `@rpath`
 - `@rpath` breaks dev builds
 - Add logic to create less versioned versions of dylibs in setup-system script, due to it being required for compiling ffmpeg-sys-next (not required during runtime, just for compilation)
 - Add scripts/deps to gitignore

* Fix ffmpeg build script not copying unversioned symlinks to FFMpeg.framework
 - Remove unecessary unversioned symlink logic from setup-system
 - Add new build scripts for dev and prod that setup the environment and tauri to correctly point to FFMpeg.framework
 - Rework windows setup-system script to follow the same logic as in macOS setup-system

* Attempt at fixing windows setup script
 - Add powershell editorconfig

* Attempt to fix Windows CI

* Fix some mistakes in the build scripts
 - Replace toml lib with something more used and maybe better?
 - Attempt to fix Windows CI

* Fix some more problems with the build script

* Another attempt at fixing windows CI

* Some more fixes for the windows setup script

* Add build.js step to release CI
 - Implement patch only mode for build.js when running under CI
 - Implement appeding extra env in cargo config in env.js
 - Only run windows dlls copy in dev in env.js
 - Another attempt at fixing windows CI

* Maybe this will make the windows CI happy?

* Windows CI why dont you work, whyyy?

* Try to apease the Windows CI Gods
 - Disable updater build in macOS, due to tauri-apps/tauri#3933

* Fix build.js extra env vars
 - Uncomment parts of setup-system.ps1 to check if it keeps working

* Uncomment another section and see if windows CI will complain

* uncomment some more of setup-system.ps1

* Use Start-Process for robocopy instead of executing it directly
 - Only raise an error if robocopy exists with a status code >=8
 - Revert build.js macOS specific bundles change
 - Disable updater for now

* Remove updater from cargo.toml

* Add -PassThru to Start-Process to ensure we get and Process obj back

* Comment out more of updater

* Improve documentation for both of the docker containers
 - Fix a harcoded install_name_tool call in the ffmpeg-build-macos.sh script

* Configure tauri to copy ffmpeg dlls to windows prod version
 - Fix windows dlls copy on dev
 - Stop replacing tauri.conf.json, except on CI, for prod builds and use a tauri.conf.patch.json for any required changes
 - Don't unset macOSPrivateApi on prod build, we need it for the transparent background
 - Fix dev.js not exiting when the spawned command was over

* Fix windows not find protoc
 - Fix missing import in env.js

* Fix Windows Dlls copy logic for prod build
 - Fix dev script failing due to missing env
 - Implement error handler to spawned process

* Format + Fix pnpm-lock

* Fix video thumb generation failing on Windows due to bad path to CString conversion logic

* Fix mobile build
 - Greatly improve windows setup-script error handling
 - Install LLVM with winget instead of downloading exe from github

* Improve CI a bit
 - Fix mobile CI not using github token to avoid being rate limited

* Fix pnpm not accesible to actions/setup-node

* Skip pnpm check on CI

* Fix pnpm skip not working
 - Fix pnpm cache check missing a step

* Only lock action to major versions

* CI really doesn't like running robocopy directly

* Attempt to build our own patched tauri bundler

* Trigger new workflow

* Fix attempt for patched tauri action tests
 - Disable cache for patched tauri action
 - Enable package publishing for patched tauri action

* Attempt fix patched tauri publish

* Remove commented code from patched tauri workflow
 - Replace deprecated `actions-rs/toolchain` with `dtolnay/rust-toolchain`

* Fix url patching logic for publishing step of patched tauri package

* Fix prepublishOnly command for patched tauri package

* Adjust patched tauri package package.json

* Also patch the specific os/arch sub packages

* Instruct napi to stop doing github releases

* Patch package.json befor build

* Re-enable updater
 - Patch tauri cli to workaround a tauri bug that prevented use from bundling frameworks in the updater
 - Update tauri/api to 1.3 and tauri/cli 1.3.1
 - Add target triple in the release artifacts name
 - Use ubuntu-20.04 instead of ubuntu-latest
 - Configure release workflow to build to all supported platforms
 - Replace `tauri-apps/tauri-action` with simply calling `pnpm desktop build`
 - Simplify tauri-patched-cli-js to only build the required macOS binaries
 - Unify build.js and dev.js in a tauri.js build script, which now acts as an all around wrapper for the tauri/cli

* Restore incorrectly removed step from `tauri-patched-cli-js`

* Disable auto-run of tauri-patched-cli-js
 - Update setup-system.sh with the latest tauri-patched-cli-js artifacts

* Forgot to mkdir bin

* Fix pnpm-lock.yaml not being up to date
 - Remove pnpm deps caching

* Fix variable name conflict

* Enable the updater build conditionally
 - Enable release workflow to test it

* Fix artifacts not being published
 - Change macOS on arm64 minimumSystemVersion to 11.2
 - Commented out rust cache to check if this is the culprit to the low memory problem on windows runner
 - Add some debug log to tauri.js

* Fix release workflow artifact uploading

* Specify which bundles to build on each platform
 - Attempt fix apple arm build
 - Don't include internal deb archives in linux updater artifact

* Attempt to fix apple arm build
 - Fix dmg background not applying

* Fix incorrect semver usage

* Patch swift-rs to see if that fix apple arm64 release build

* Update swift-rs submodule
 - Remove unused deps lodash.merge

* Configure so only release workflow runs without cache
 - Improve tauri.js logs

* Ignore `crates/swift-rs`

* Revert "Ignore `crates/swift-rs`"
- Remove `crates/swift-rs` before running `cargo fmt`

This reverts commit 851bd84373.

* Github CI input/output are always string
 - Attempt to fix Windows Clippy

* Fix CI syntax error

* Fix mobile CI
 - Disable pnpm deps caching
 - Disable rust targets caching on Windows
 - Configure cache factory to run for all targets

* Remove `crates/swift-rs`

* Attempt fix Mobile CI
 - Enable cache factory run in pull_request to test it
 - Specific more path for the CI run to ignore
 - Specify path that will trigger the cache factory run
 - Some cleanup in the setup-pnpm action

* Remove restore-cache options
 - Add prefix key to cache-factory
 - Fix LLVM cache-hit check
 - Add libheif to FFMpeg.framework

* Remove submodule clone from actions

* Add fake deps to ffmpeg build dockerfile
 - Fake install deps that aren't really necessary to build ffmpeg
 - Fail ffmpeg build script if it can't find a macports deps
 - Copy libheif headers to Framework

* Remove automatic trigger for relase and pull request trigger for cache-factory actions

* Remove pnpm setup from Cache factory
 - Cache factory is exclusivly for rust deps caching, no need to setup Node and pnpm with it

* Re-enabled fail-fast in Github CI
2023-05-15 18:02:56 +00:00

381 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') +
[IO.Path]::PathSeparator +
[System.Environment]::GetEnvironmentVariable('Path', 'User')
)
}
# 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
$proc = Start-Process -PassThru -Wait -FilePath 'PowerShell.exe' -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$($MyInvocation.MyCommand.Definition)`"" -WorkingDirectory "$PSScriptRoot"
# Reset path so the user doesn't have to restart the shell to use the tools installed by this script
Reset-Path
Exit $proc.ExitCode
}
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) {
Reset-Path
if ($env:Path.Split([IO.Path]::PathSeparator) -notcontains $directory) {
[System.Environment]::SetEnvironmentVariable(
'Path',
[System.Environment]::GetEnvironmentVariable('Path', 'User') + [IO.Path]::PathSeparator + $directory,
'User'
)
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'
)
$headers.Add('Accept', 'application/vnd.github+json')
$headers.Add('X-GitHub-Api-Version', '2022-11-28')
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 have stale Path 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
$packageJson = Get-Content -Raw -Path "$projectRoot\package.json" | ConvertFrom-Json
# Valid winget exit status
$wingetValidExit = 0, -1978335189, -1978335153, -1978335135
# Currently LLVM >= 16 is not supported due to incompatibilities with ffmpeg-sys-next
# See https://github.com/spacedriveapp/spacedrive/issues/677
$llvmVersion = [Version]'15.0.7'
# Change CWD to project root
Set-Location $projectRoot
Remove-Item -Force -ErrorAction SilentlyContinue -Path "$projectRoot\.cargo\config"
Remove-Item -Force -ErrorAction SilentlyContinue -Path "$projectRoot\target\Frameworks" -Recurse
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
6) Install LLVM $llvmVersion (compiler for ffmpeg-rust)
7) Download the protbuf compiler
8) Download a compatible ffmpeg build
"@
# Install System dependencies (GitHub Actions already has all of those 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/
'@
}
# Check connectivity to GitHub
$ProgressPreference = 'SilentlyContinue'
if (-not ((Test-NetConnection -ComputerName 'github.com' -Port 80).TcpTestSucceeded)) {
Exit-WithError "Can't connect to github, check your internet connection and run this script again"
}
$ProgressPreference = 'Continue'
Write-Host
Read-Host 'Press Enter to continue'
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 a package manager, so let it decide if something needs to be installed or not
winget install -e --accept-source-agreements --force --disable-interactivity --id Microsoft.VisualStudio.2022.BuildTools `
--override '--wait --quiet --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended'
if (-not ($wingetValidExit -contains $LASTEXITCODE)) {
Exit-WithError 'Failed to install Visual Studio Build Tools'
} else {
$LASTEXITCODE = 0
}
Write-Host
Write-Host 'Installing Edge Webview 2...' -ForegroundColor Yellow
# This is normally already available, but on some early Windows 10 versions it isn't
winget install -e --accept-source-agreements --disable-interactivity --id Microsoft.EdgeWebView2Runtime
if (-not ($wingetValidExit -contains $LASTEXITCODE)) {
Exit-WithError 'Failed to install Edge Webview 2'
} else {
$LASTEXITCODE = 0
}
Write-Host
Write-Host 'Installing Rust and Cargo...' -ForegroundColor Yellow
winget install -e --accept-source-agreements --disable-interactivity --id Rustlang.Rustup
if (-not ($wingetValidExit -contains $LASTEXITCODE)) {
Exit-WithError 'Failed to install Rust and Cargo'
} else {
$LASTEXITCODE = 0
}
Write-Host
Write-Host 'Installing NodeJS...' -ForegroundColor Yellow
# Check if Node.JS is already installed and if it's compatible with the project
$currentNode = Get-Command node -ea 0
$currentNodeVersion = if (-not $currentNode) { $null } elseif ($currentNode.Version) { $currentNode.Version } elseif ((node --version) -match '(?sm)(\d+(\.\d+)*)') { [Version]$matches[1] } else { $null }
$enginesNodeVersion = if ($packageJson.engines.node -match '(?sm)(\d+(\.\d+)*)') { [Version]$matches[1] } else { $null }
if ($currentNodeVersion -and $enginesNodeVersion -and $currentNodeVersion.CompareTo($enginesNodeVersion) -lt 0) {
Exit-WithError "Current Node.JS version: $currentNodeVersion (required: $enginesNodeVersion)" `
'Uninstall the current version of Node.JS and run this script again'
}
# Install Node.JS
winget install -e --accept-source-agreements --disable-interactivity --id OpenJS.NodeJS
if (-not ($wingetValidExit -contains $LASTEXITCODE)) {
Exit-WithError 'Failed to install NodeJS'
} else {
$LASTEXITCODE = 0
}
# Add NodeJS to the PATH
Add-DirectoryToPath "$env:SystemDrive\Program Files\nodejs"
Write-Host
Write-Host 'Checking for LLVM...' -ForegroundColor Yellow
# Check if LLVM is already installed and if it's compatible with the project
$currentLLVMVersion = if ("$(winget list -e --disable-interactivity --id LLVM.LLVM)" -match '(?sm)LLVM.LLVM\s+(\d+(\.\d+)*)') { [Version]$matches[1] } else { $null }
if ($currentLLVMVersion -and $currentLLVMVersion.Major -gt $llvmVersion.Major) {
Exit-WithError "Current LLVM version: $currentLLVMVersion (required: $llvmVersion)" `
'Uninstall the current version of LLVM and run this script again'
}
# Install LLVM
winget install -e --accept-source-agreements --disable-interactivity --id LLVM.LLVM --version "$llvmVersion"
if (-not ($wingetValidExit -contains $LASTEXITCODE)) {
Exit-WithError 'Failed to install NodeJS'
} else {
$LASTEXITCODE = 0
}
# Add LLVM to the PATH
Add-DirectoryToPath "$env:SystemDrive\Program Files\LLVM\bin"
# Reset Path to ensure that executable installed above are available to rest of the script
Reset-Path
Write-Host
Write-Host 'Installing Rust MSVC Toolchain...' -ForegroundColor Yellow
rustup toolchain install stable-msvc
if ($LASTEXITCODE -ne 0) {
Exit-WithError 'Failed to install Rust MSVC Toolchain'
}
Write-Host
Write-Host 'Installing Rust tools...' -ForegroundColor Yellow
cargo install cargo-watch
if ($LASTEXITCODE -ne 0) {
Exit-WithError 'Failed to install Rust tools'
}
Write-Host
Write-Host 'Installing for pnpm...' -ForegroundColor Yellow
# Check if pnpm is already installed and if it's compatible with the project
$currentPnpmVersion = if (-not (Get-Command pnpm -ea 0)) { $null } elseif ((pnpm --version) -match '(?sm)(\d+(\.\d+)*)') { [Version]$matches[1] } else { $null }
$enginesPnpmVersion = if ($packageJson.engines.pnpm -match '(?sm)(\d+(\.\d+)*)') { [Version]$matches[1] } else { $null }
if (-not $currentPnpmVersion) {
# 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)
# Install pnpm
npm install -g "pnpm@latest-$($enginesPnpmVersion.Major)"
if ($LASTEXITCODE -ne 0) {
Exit-WithError 'Failed to install pnpm'
}
# Add NPM global modules to the PATH
if (Test-Path "$env:APPDATA\npm" -PathType Container) {
Add-DirectoryToPath "$env:APPDATA\npm"
}
} elseif ($currentPnpmVersion -and $enginesPnpmVersion -and $currentPnpmVersion.CompareTo($enginesPnpmVersion) -lt 0) {
Exit-WithError "Current pnpm version: $currentPnpmVersion (required: $enginesPnpmVersion)" `
'Uninstall the current version of pnpm and run this script again'
}
}
# Create target folder, continue if already exists
New-Item -Force -ErrorAction SilentlyContinue -ItemType Directory -Path "$projectRoot\target\Frameworks" | Out-Null
# --
Write-Host
Write-Host 'Retrieving protobuf version...' -ForegroundColor Yellow
$filename = $null
$downloadUri = $null
$releasesUri = 'https://api.github.com/repos/protocolbuffers/protobuf/releases'
$filenamePattern = '*-win64.zip'
$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"
}
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" "$projectRoot\target\Frameworks" -Force
Remove-Item -Force -ErrorAction SilentlyContinue -Path "$temp\protobuf.zip"
# --
Write-Host
Write-Host 'Retrieving ffmpeg version...' -ForegroundColor Yellow
# Run first to update packages
cargo metadata --format-version 1 | Out-Null
# 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 ($LASTEXITCODE -ne 0) {
Exit-WithError 'Failed to get ffmpeg-sys-next version'
}
$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"
}
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 -Force -Path "$temp\ffmpeg.zip" -DestinationPath "$temp"
Remove-Item -Force -ErrorAction SilentlyContinue -Path "$temp\ffmpeg.zip"
$ffmpegDir = "$temp\$([System.IO.Path]::GetFileNameWithoutExtension($fileName))"
$proc = Start-Process -PassThru -Wait -FilePath 'Robocopy.exe' -Verb RunAs -ArgumentList `
"`"$ffmpegDir`" `"$projectRoot\target\Frameworks`" /E /NS /NC /NFL /NDL /NP /NJH /NJS"
# https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy#exit-return-codes
if ($proc.ExitCode -ge 8) {
Exit-WithError 'Failed to copy ffmpeg files'
}
Remove-Item -Force -ErrorAction SilentlyContinue -Recurse -Path "$ffmpegDir"
@(
'[env]',
"PROTOC = `"$("$projectRoot\target\Frameworks\bin\protoc" -replace '\\', '\\')`"",
"FFMPEG_DIR = `"$("$projectRoot\target\Frameworks" -replace '\\', '\\')`"",
'',
(Get-Content "$projectRoot\.cargo\config.toml" -Encoding utf8)
) | Out-File -Force -Encoding utf8 -FilePath "$projectRoot\.cargo\config"
if (-not $env:CI) {
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
Write-Host
Read-Host 'Press Enter to continue'
}
if ($LASTEXITCODE -ne 0) {
Exit-WithError "Something went wrong, exit code: $LASTEXITCODE"
}