-
-
Notifications
You must be signed in to change notification settings - Fork 442
Build script fixed + enhanced #4000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
dbda6a4
4e33956
92286f3
c25b927
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -7,7 +7,8 @@ Write-Host "Config: $config" | |||||||||||||||||||||||||
function Build-Version { | ||||||||||||||||||||||||||
if ([string]::IsNullOrEmpty($env:flowVersion)) { | ||||||||||||||||||||||||||
$targetPath = Join-Path $solution "Output/Release/Flow.Launcher.dll" -Resolve | ||||||||||||||||||||||||||
$v = (Get-Command ${targetPath}).FileVersionInfo.FileVersion | ||||||||||||||||||||||||||
# Use Get-Item for reliability and ProductVersion to align with AssemblyInformationalVersion. | ||||||||||||||||||||||||||
$v = (Get-Item $targetPath).VersionInfo.ProductVersion | ||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||
$v = $env:flowVersion | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
@@ -32,56 +33,73 @@ function Build-Path { | |||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Copy-Resources ($path) { | ||||||||||||||||||||||||||
# making version static as multiple versions can exist in the nuget folder and in the case a breaking change is introduced. | ||||||||||||||||||||||||||
Copy-Item -Force $env:USERPROFILE\.nuget\packages\squirrel.windows\1.5.2\tools\Squirrel.exe $path\Output\Update.exe | ||||||||||||||||||||||||||
$squirrelExe = (Get-ChildItem -Path "$env:USERPROFILE\.nuget\packages\squirrel.windows\*" -Directory | Sort-Object Name -Descending | Select-Object -First 1).FullName + "\tools\Squirrel.exe" | ||||||||||||||||||||||||||
if (Test-Path $squirrelExe) { | ||||||||||||||||||||||||||
Copy-Item -Force $squirrelExe $path\Output\Update.exe | ||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||
Write-Host "Warning: Squirrel.exe could not be found in the NuGet cache." -ForegroundColor Yellow | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Delete-Unused ($path, $config) { | ||||||||||||||||||||||||||
function Remove-UnusedFiles ($path, $config) { | ||||||||||||||||||||||||||
$target = "$path\Output\$config" | ||||||||||||||||||||||||||
$included = Get-ChildItem $target -Filter "*.dll" | ||||||||||||||||||||||||||
foreach ($i in $included){ | ||||||||||||||||||||||||||
$deleteList = Get-ChildItem $target\Plugins -Include $i -Recurse | Where { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion -And $_.Name -eq "$i" } | ||||||||||||||||||||||||||
$deleteList | ForEach-Object{ Write-Host Deleting duplicated $_.Name with version $_.VersionInfo.FileVersion at location $_.Directory.FullName } | ||||||||||||||||||||||||||
$deleteList | Remove-Item | ||||||||||||||||||||||||||
$deleteList = Get-ChildItem $target\Plugins -Include $i.Name -Recurse | Where-Object { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion } | ||||||||||||||||||||||||||
foreach ($fileToDelete in $deleteList) { | ||||||||||||||||||||||||||
# A plugin's main DLL has the same name as its parent directory. We must not delete it. | ||||||||||||||||||||||||||
if ($fileToDelete.Directory.Name -ne $fileToDelete.BaseName) { | ||||||||||||||||||||||||||
Remove-Item $fileToDelete.FullName | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
Remove-Item -Path $target -Include "*.xml" -Recurse | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Remove-CreateDumpExe ($path, $config) { | ||||||||||||||||||||||||||
$target = "$path\Output\$config" | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$depjson = Get-Content $target\Flow.Launcher.deps.json -raw | ||||||||||||||||||||||||||
$depjson -replace '(?s)(.createdump.exe": {.*?}.*?\n)\s*', "" | Out-File $target\Flow.Launcher.deps.json -Encoding UTF8 | ||||||||||||||||||||||||||
$depjsonPath = (Get-Item "$target\Flow.Launcher.deps.json").FullName | ||||||||||||||||||||||||||
if (Test-Path $depjsonPath) { | ||||||||||||||||||||||||||
$depjson = Get-Content $depjsonPath -raw | ||||||||||||||||||||||||||
$depjson -replace '(?s)(.createdump.exe": {.*?}.*?\n)\s*', "" | Out-File $depjsonPath -Encoding UTF8 | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
Remove-Item -Path $target -Include "*createdump.exe" -Recurse | ||||||||||||||||||||||||||
Comment on lines
+62
to
67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix: Get-Item runs before the existence check and will throw if the file is missing. Swap to Test-Path before Get-Item. Apply this diff: - $depjsonPath = (Get-Item "$target\Flow.Launcher.deps.json").FullName
- if (Test-Path $depjsonPath) {
- $depjson = Get-Content $depjsonPath -raw
+ $depjsonPath = Join-Path $target "Flow.Launcher.deps.json"
+ if (Test-Path $depjsonPath) {
+ $depjson = Get-Content $depjsonPath -Raw
$depjson -replace '(?s)(.createdump.exe": {.*?}.*?\n)\s*', "" | Out-File $depjsonPath -Encoding UTF8
} 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Validate-Directory ($output) { | ||||||||||||||||||||||||||
New-Item $output -ItemType Directory -Force | ||||||||||||||||||||||||||
function Initialize-Directory ($output) { | ||||||||||||||||||||||||||
if (Test-Path $output) { | ||||||||||||||||||||||||||
Remove-Item -Recurse -Force $output | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
New-Item $output -ItemType Directory -Force | Out-Null | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Pack-Squirrel-Installer ($path, $version, $output) { | ||||||||||||||||||||||||||
function New-SquirrelInstallerPackage ($path, $version, $output) { | ||||||||||||||||||||||||||
# msbuild based installer generation is not working in appveyor, not sure why | ||||||||||||||||||||||||||
Write-Host "Begin pack squirrel installer" | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$spec = "$path\Scripts\flowlauncher.nuspec" | ||||||||||||||||||||||||||
$input = "$path\Output\Release" | ||||||||||||||||||||||||||
$inputPath = "$path\Output\Release" | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Write-Host "Packing: $spec" | ||||||||||||||||||||||||||
Write-Host "Input path: $input" | ||||||||||||||||||||||||||
Write-Host "Input path: $inputPath" | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# dotnet pack is not used because ran into issues, need to test installation and starting up if to use it. | ||||||||||||||||||||||||||
nuget pack $spec -Version $version -BasePath $input -OutputDirectory $output -Properties Configuration=Release | ||||||||||||||||||||||||||
nuget pack $spec -Version $version -BasePath $inputPath -OutputDirectory $output -Properties Configuration=Release | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$nupkg = "$output\FlowLauncher.$version.nupkg" | ||||||||||||||||||||||||||
Write-Host "nupkg path: $nupkg" | ||||||||||||||||||||||||||
$icon = "$path\Flow.Launcher\Resources\app.ico" | ||||||||||||||||||||||||||
Write-Host "icon: $icon" | ||||||||||||||||||||||||||
# Squirrel.com: https://github.com/Squirrel/Squirrel.Windows/issues/369 | ||||||||||||||||||||||||||
New-Alias Squirrel $env:USERPROFILE\.nuget\packages\squirrel.windows\1.5.2\tools\Squirrel.exe -Force | ||||||||||||||||||||||||||
# why we need Write-Output: https://github.com/Squirrel/Squirrel.Windows/issues/489#issuecomment-156039327 | ||||||||||||||||||||||||||
# directory of releaseDir in squirrel can't be same as directory ($nupkg) in releasify | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$squirrelExe = (Get-ChildItem -Path "$env:USERPROFILE\.nuget\packages\squirrel.windows\*" -Directory | Sort-Object Name -Descending | Select-Object -First 1).FullName + "\tools\Squirrel.exe" | ||||||||||||||||||||||||||
if (-not (Test-Path $squirrelExe)) { | ||||||||||||||||||||||||||
Write-Host "FATAL: Squirrel.exe could not be found, aborting installer creation." -ForegroundColor Red | ||||||||||||||||||||||||||
exit 1 | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
New-Alias Squirrel $squirrelExe -Force | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$temp = "$output\Temp" | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Squirrel --releasify $nupkg --releaseDir $temp --setupIcon $icon --no-msi | Write-Output | ||||||||||||||||||||||||||
|
@@ -96,41 +114,127 @@ function Pack-Squirrel-Installer ($path, $version, $output) { | |||||||||||||||||||||||||
Write-Host "End pack squirrel installer" | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Publish-Self-Contained ($p) { | ||||||||||||||||||||||||||
function Build-Solution ($p) { | ||||||||||||||||||||||||||
Write-Host "Building solution..." | ||||||||||||||||||||||||||
$solutionFile = Join-Path $p "Flow.Launcher.sln" | ||||||||||||||||||||||||||
dotnet build $solutionFile -c Release | ||||||||||||||||||||||||||
if ($LASTEXITCODE -ne 0) { return $false } | ||||||||||||||||||||||||||
return $true | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Publish-SelfContainedToTemp($p, $outputPath) { | ||||||||||||||||||||||||||
Write-Host "Publishing self-contained application to temporary directory..." | ||||||||||||||||||||||||||
$csproj = Join-Path "$p" "Flow.Launcher/Flow.Launcher.csproj" -Resolve | ||||||||||||||||||||||||||
$profile = Join-Path "$p" "Flow.Launcher/Properties/PublishProfiles/Net9.0-SelfContained.pubxml" -Resolve | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# We publish to a temporary directory first to ensure a clean, self-contained build | ||||||||||||||||||||||||||
# without interfering with the main /Output/Release folder, which contains plugins. | ||||||||||||||||||||||||||
# Let publish do its own build to ensure all self-contained dependencies are correctly resolved. | ||||||||||||||||||||||||||
dotnet publish -c Release $csproj -r win-x64 --self-contained true -o $outputPath | ||||||||||||||||||||||||||
if ($LASTEXITCODE -ne 0) { return $false } | ||||||||||||||||||||||||||
return $true | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# we call dotnet publish on the main project. | ||||||||||||||||||||||||||
# The other projects should have been built in Release at this point. | ||||||||||||||||||||||||||
dotnet publish -c Release $csproj /p:PublishProfile=$profile | ||||||||||||||||||||||||||
function Merge-PublishToRelease($publishPath, $releasePath) { | ||||||||||||||||||||||||||
Write-Host "Merging published files into release directory..." | ||||||||||||||||||||||||||
Copy-Item -Path "$publishPath\*" -Destination $releasePath -Recurse -Force | ||||||||||||||||||||||||||
Remove-Item -Recurse -Force $publishPath | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Publish-Portable ($outputLocation, $version) { | ||||||||||||||||||||||||||
function Publish-Portable ($outputLocation, $version, $path) { | ||||||||||||||||||||||||||
# The portable version is created by silently running the installer to a temporary location, | ||||||||||||||||||||||||||
# then packaging the result. This ensures the structure is identical to a real installation | ||||||||||||||||||||||||||
# and can be updated by Squirrel. | ||||||||||||||||||||||||||
& "$outputLocation\Flow-Launcher-Setup.exe" --silent | Out-Null | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$installRoot = Join-Path $env:LocalAppData "FlowLauncher" | ||||||||||||||||||||||||||
$appPath = Join-Path $installRoot "app-$version" | ||||||||||||||||||||||||||
$appExePath = Join-Path $appPath "Flow.Launcher.exe" | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Wait for silent installation to complete | ||||||||||||||||||||||||||
$waitTime = 0 | ||||||||||||||||||||||||||
$maxWaitTime = 60 # 60 seconds timeout | ||||||||||||||||||||||||||
while (-not (Test-Path $appExePath) -and $waitTime -lt $maxWaitTime) { | ||||||||||||||||||||||||||
Start-Sleep -Seconds 1 | ||||||||||||||||||||||||||
$waitTime++ | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if (-not (Test-Path $appExePath)) { | ||||||||||||||||||||||||||
Write-Host "Error: Timed out waiting for silent installation to complete." -ForegroundColor Red | ||||||||||||||||||||||||||
return | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Comment on lines
+144
to
165
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Portable packaging flow: two risks and one hardening suggestion.
Apply this diff: - & "$outputLocation\Flow-Launcher-Setup.exe" --silent | Out-Null
+ # Avoid clobbering a developer's local install; allow override via env var
+ if (-not $env:CI -and -not $env:APPVEYOR) {
+ Write-Host "Warning: Skipping silent install outside CI to avoid overwriting a local install." -ForegroundColor Yellow
+ return
+ }
+ & "$outputLocation\Flow-Launcher-Setup.exe" --silent | Out-Null
@@
- $appPath = Join-Path $installRoot "app-$version"
- $appExePath = Join-Path $appPath "Flow.Launcher.exe"
+ # Prefer discovering the latest app-* folder to avoid version string mismatches
+ $latestAppDir = Get-ChildItem -Path $installRoot -Directory -Filter "app-*" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
+ $appPath = $latestAppDir?.FullName
+ $appExePath = if ($appPath) { Join-Path $appPath "Flow.Launcher.exe" } else { $null }
@@
- $maxWaitTime = 60 # 60 seconds timeout
+ $maxWaitTime = 180 # allow slower agents
@@
- Write-Host "Error: Timed out waiting for silent installation to complete." -ForegroundColor Red
+ Write-Host "Error: Timed out waiting for silent installation to complete." -ForegroundColor Red
return On removing “packages” from the portable zip: this is safe for update functionality; Update.exe downloads RELEASES and nupkg files from the configured feed on demand, and the local packages cache is recreated as needed. (gist.github.com) Also applies to: 167-185, 186-198 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||
& $outputLocation\Flow-Launcher-Setup.exe --silent | Out-Null | ||||||||||||||||||||||||||
mkdir "$env:LocalAppData\FlowLauncher\app-$version\UserData" | ||||||||||||||||||||||||||
Compress-Archive -Path $env:LocalAppData\FlowLauncher -DestinationPath $outputLocation\Flow-Launcher-Portable.zip | ||||||||||||||||||||||||||
# Create a temporary staging directory for the portable package | ||||||||||||||||||||||||||
$stagingDir = Join-Path $outputLocation "PortableStaging" | ||||||||||||||||||||||||||
Initialize-Directory $stagingDir | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||
# Copy installed files to staging directory | ||||||||||||||||||||||||||
Copy-Item -Path "$installRoot\*" -Destination $stagingDir -Recurse -Force | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Create the UserData folder inside app-<version> to enable portable mode. | ||||||||||||||||||||||||||
New-Item -Path (Join-Path $stagingDir "app-$version" "UserData") -ItemType Directory -Force | Out-Null | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Remove the unnecessary 'packages' directory before creating the archive | ||||||||||||||||||||||||||
$packagesPath = Join-Path $stagingDir "packages" | ||||||||||||||||||||||||||
if (Test-Path $packagesPath) { | ||||||||||||||||||||||||||
Remove-Item -Path $packagesPath -Recurse -Force | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Create the zip from the staging directory's contents | ||||||||||||||||||||||||||
Compress-Archive -Path "$stagingDir\*" -DestinationPath "$outputLocation\Flow-Launcher-Portable.zip" -Force | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
finally { | ||||||||||||||||||||||||||
if (Test-Path $stagingDir) { | ||||||||||||||||||||||||||
Remove-Item -Recurse -Force $stagingDir | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# Uninstall after packaging | ||||||||||||||||||||||||||
$uninstallExe = Join-Path $installRoot "Update.exe" | ||||||||||||||||||||||||||
if (Test-Path $uninstallExe) { | ||||||||||||||||||||||||||
Write-Host "Uninstalling temporary application..." | ||||||||||||||||||||||||||
Start-Process -FilePath $uninstallExe -ArgumentList "--uninstall -s" -Wait | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
function Main { | ||||||||||||||||||||||||||
$p = Build-Path | ||||||||||||||||||||||||||
$v = Build-Version | ||||||||||||||||||||||||||
Copy-Resources $p | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if ($config -eq "Release"){ | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Delete-Unused $p $config | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Publish-Self-Contained $p | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if (-not (Build-Solution $p)) { | ||||||||||||||||||||||||||
Write-Host "dotnet build failed. Aborting post-build script." -ForegroundColor Red | ||||||||||||||||||||||||||
exit 1 | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$tempPublishPath = Join-Path $p "Output\PublishTemp" | ||||||||||||||||||||||||||
Initialize-Directory $tempPublishPath | ||||||||||||||||||||||||||
if (-not (Publish-SelfContainedToTemp $p $tempPublishPath)) { | ||||||||||||||||||||||||||
Write-Host "dotnet publish failed. Aborting." -ForegroundColor Red | ||||||||||||||||||||||||||
exit 1 | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Merge-PublishToRelease $tempPublishPath (Join-Path $p "Output\Release") | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$v = Build-Version | ||||||||||||||||||||||||||
if ([string]::IsNullOrEmpty($v)) { | ||||||||||||||||||||||||||
Write-Host "Could not determine build version. Aborting." -ForegroundColor Red | ||||||||||||||||||||||||||
exit 1 | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Copy-Resources $p | ||||||||||||||||||||||||||
Remove-UnusedFiles $p $config | ||||||||||||||||||||||||||
Remove-CreateDumpExe $p $config | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
$o = "$p\Output\Packages" | ||||||||||||||||||||||||||
Validate-Directory $o | ||||||||||||||||||||||||||
Pack-Squirrel-Installer $p $v $o | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Publish-Portable $o $v | ||||||||||||||||||||||||||
Initialize-Directory $o | ||||||||||||||||||||||||||
New-SquirrelInstallerPackage $p $v $o | ||||||||||||||||||||||||||
if ($LASTEXITCODE -ne 0) { | ||||||||||||||||||||||||||
Write-Host "Squirrel packaging failed. Aborting." -ForegroundColor Red | ||||||||||||||||||||||||||
exit 1 | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Publish-Portable $o $v $p | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normalize ProductVersion to a Squirrel/NuGet‑safe version (strip +build metadata).
Build metadata (e.g., 1.2.3-beta+abc) can break folder matching (app-$version) and sometimes NuGet/Squirrel expectations. Strip anything after “+”.
Apply this diff:
Evidence that Squirrel uses app- conventions and Release feed versions. (github.com)
📝 Committable suggestion
🤖 Prompt for AI Agents