@@ -7,7 +7,8 @@ Write-Host "Config: $config"
7
7
function Build-Version {
8
8
if ([string ]::IsNullOrEmpty($env: flowVersion )) {
9
9
$targetPath = Join-Path $solution " Output/Release/Flow.Launcher.dll" - Resolve
10
- $v = (Get-Command ${targetPath} ).FileVersionInfo.FileVersion
10
+ # Use Get-Item for reliability and ProductVersion to align with AssemblyInformationalVersion.
11
+ $v = (Get-Item $targetPath ).VersionInfo.ProductVersion
11
12
} else {
12
13
$v = $env: flowVersion
13
14
}
@@ -32,56 +33,73 @@ function Build-Path {
32
33
}
33
34
34
35
function Copy-Resources ($path ) {
35
- # making version static as multiple versions can exist in the nuget folder and in the case a breaking change is introduced.
36
- Copy-Item - Force $env: USERPROFILE \.nuget\packages\squirrel.windows\1.5 .2 \tools\Squirrel.exe $path \Output\Update.exe
36
+ $squirrelExe = (Get-ChildItem - Path " $env: USERPROFILE \.nuget\packages\squirrel.windows\*" - Directory | Sort-Object Name - Descending | Select-Object - First 1 ).FullName + " \tools\Squirrel.exe"
37
+ if (Test-Path $squirrelExe ) {
38
+ Copy-Item - Force $squirrelExe $path \Output\Update.exe
39
+ } else {
40
+ Write-Host " Warning: Squirrel.exe could not be found in the NuGet cache." - ForegroundColor Yellow
41
+ }
37
42
}
38
43
39
- function Delete-Unused ($path , $config ) {
44
+ function Remove-UnusedFiles ($path , $config ) {
40
45
$target = " $path \Output\$config "
41
46
$included = Get-ChildItem $target - Filter " *.dll"
42
47
foreach ($i in $included ){
43
- $deleteList = Get-ChildItem $target \Plugins - Include $i - Recurse | Where { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion -And $_.Name -eq " $i " }
44
- $deleteList | ForEach-Object { Write-Host Deleting duplicated $_.Name with version $_.VersionInfo.FileVersion at location $_.Directory.FullName }
45
- $deleteList | Remove-Item
48
+ $deleteList = Get-ChildItem $target \Plugins - Include $i.Name - Recurse | Where-Object { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion }
49
+ foreach ($fileToDelete in $deleteList ) {
50
+ # A plugin's main DLL has the same name as its parent directory. We must not delete it.
51
+ if ($fileToDelete.Directory.Name -ne $fileToDelete.BaseName ) {
52
+ Remove-Item $fileToDelete.FullName
53
+ }
54
+ }
46
55
}
47
56
Remove-Item - Path $target - Include " *.xml" - Recurse
48
57
}
49
58
50
59
function Remove-CreateDumpExe ($path , $config ) {
51
60
$target = " $path \Output\$config "
52
61
53
- $depjson = Get-Content $target \Flow.Launcher.deps.json - raw
54
- $depjson -replace ' (?s)(.createdump.exe": {.*?}.*?\n)\s*' , " " | Out-File $target \Flow.Launcher.deps.json - Encoding UTF8
62
+ $depjsonPath = (Get-Item " $target \Flow.Launcher.deps.json" ).FullName
63
+ if (Test-Path $depjsonPath ) {
64
+ $depjson = Get-Content $depjsonPath - raw
65
+ $depjson -replace ' (?s)(.createdump.exe": {.*?}.*?\n)\s*' , " " | Out-File $depjsonPath - Encoding UTF8
66
+ }
55
67
Remove-Item - Path $target - Include " *createdump.exe" - Recurse
56
68
}
57
69
58
70
59
- function Validate-Directory ($output ) {
60
- New-Item $output - ItemType Directory - Force
71
+ function Initialize-Directory ($output ) {
72
+ if (Test-Path $output ) {
73
+ Remove-Item - Recurse - Force $output
74
+ }
75
+ New-Item $output - ItemType Directory - Force | Out-Null
61
76
}
62
77
63
78
64
- function Pack-Squirrel-Installer ($path , $version , $output ) {
79
+ function New-SquirrelInstallerPackage ($path , $version , $output ) {
65
80
# msbuild based installer generation is not working in appveyor, not sure why
66
81
Write-Host " Begin pack squirrel installer"
67
82
68
83
$spec = " $path \Scripts\flowlauncher.nuspec"
69
- $input = " $path \Output\Release"
84
+ $inputPath = " $path \Output\Release"
70
85
71
86
Write-Host " Packing: $spec "
72
- Write-Host " Input path: $input "
87
+ Write-Host " Input path: $inputPath "
73
88
74
- # dotnet pack is not used because ran into issues, need to test installation and starting up if to use it.
75
- nuget pack $spec - Version $version - BasePath $input - OutputDirectory $output - Properties Configuration= Release
89
+ nuget pack $spec - Version $version - BasePath $inputPath - OutputDirectory $output - Properties Configuration= Release
76
90
77
91
$nupkg = " $output \FlowLauncher.$version .nupkg"
78
92
Write-Host " nupkg path: $nupkg "
79
93
$icon = " $path \Flow.Launcher\Resources\app.ico"
80
94
Write-Host " icon: $icon "
81
- # Squirrel.com: https://github.com/Squirrel/Squirrel.Windows/issues/369
82
- New-Alias Squirrel $env: USERPROFILE \.nuget\packages\squirrel.windows\1.5 .2 \tools\Squirrel.exe - Force
83
- # why we need Write-Output: https://github.com/Squirrel/Squirrel.Windows/issues/489#issuecomment-156039327
84
- # directory of releaseDir in squirrel can't be same as directory ($nupkg) in releasify
95
+
96
+ $squirrelExe = (Get-ChildItem - Path " $env: USERPROFILE \.nuget\packages\squirrel.windows\*" - Directory | Sort-Object Name - Descending | Select-Object - First 1 ).FullName + " \tools\Squirrel.exe"
97
+ if (-not (Test-Path $squirrelExe )) {
98
+ Write-Host " FATAL: Squirrel.exe could not be found, aborting installer creation." - ForegroundColor Red
99
+ exit 1
100
+ }
101
+ New-Alias Squirrel $squirrelExe - Force
102
+
85
103
$temp = " $output \Temp"
86
104
87
105
Squirrel -- releasify $nupkg -- releaseDir $temp -- setupIcon $icon -- no- msi | Write-Output
@@ -96,41 +114,127 @@ function Pack-Squirrel-Installer ($path, $version, $output) {
96
114
Write-Host " End pack squirrel installer"
97
115
}
98
116
99
- function Publish-Self-Contained ($p ) {
117
+ function Build-Solution ($p ) {
118
+ Write-Host " Building solution..."
119
+ $solutionFile = Join-Path $p " Flow.Launcher.sln"
120
+ dotnet build $solutionFile - c Release
121
+ if ($LASTEXITCODE -ne 0 ) { return $false }
122
+ return $true
123
+ }
100
124
125
+ function Publish-SelfContainedToTemp ($p , $outputPath ) {
126
+ Write-Host " Publishing self-contained application to temporary directory..."
101
127
$csproj = Join-Path " $p " " Flow.Launcher/Flow.Launcher.csproj" - Resolve
102
- $profile = Join-Path " $p " " Flow.Launcher/Properties/PublishProfiles/Net9.0-SelfContained.pubxml" - Resolve
128
+
129
+ # We publish to a temporary directory first to ensure a clean, self-contained build
130
+ # without interfering with the main /Output/Release folder, which contains plugins.
131
+ # Let publish do its own build to ensure all self-contained dependencies are correctly resolved.
132
+ dotnet publish - c Release $csproj - r win- x64 -- self- contained true - o $outputPath
133
+ if ($LASTEXITCODE -ne 0 ) { return $false }
134
+ return $true
135
+ }
103
136
104
- # we call dotnet publish on the main project.
105
- # The other projects should have been built in Release at this point.
106
- dotnet publish - c Release $csproj / p:PublishProfile= $profile
137
+ function Merge-PublishToRelease ($publishPath , $releasePath ) {
138
+ Write-Host " Merging published files into release directory..."
139
+ Copy-Item - Path " $publishPath \*" - Destination $releasePath - Recurse - Force
140
+ Remove-Item - Recurse - Force $publishPath
107
141
}
108
142
109
- function Publish-Portable ($outputLocation , $version ) {
143
+ function Publish-Portable ($outputLocation , $version , $path ) {
144
+ # The portable version is created by silently running the installer to a temporary location,
145
+ # then packaging the result. This ensures the structure is identical to a real installation
146
+ # and can be updated by Squirrel.
147
+ & " $outputLocation \Flow-Launcher-Setup.exe" -- silent | Out-Null
148
+
149
+ $installRoot = Join-Path $env: LocalAppData " FlowLauncher"
150
+ $appPath = Join-Path $installRoot " app-$version "
151
+ $appExePath = Join-Path $appPath " Flow.Launcher.exe"
152
+
153
+ # Wait for silent installation to complete
154
+ $waitTime = 0
155
+ $maxWaitTime = 60 # 60 seconds timeout
156
+ while (-not (Test-Path $appExePath ) -and $waitTime -lt $maxWaitTime ) {
157
+ Start-Sleep - Seconds 1
158
+ $waitTime ++
159
+ }
160
+
161
+ if (-not (Test-Path $appExePath )) {
162
+ Write-Host " Error: Timed out waiting for silent installation to complete." - ForegroundColor Red
163
+ return
164
+ }
110
165
111
- & $outputLocation \Flow-Launcher-Setup.exe -- silent | Out-Null
112
- mkdir " $env: LocalAppData \FlowLauncher\app-$version \UserData"
113
- Compress-Archive - Path $env: LocalAppData \FlowLauncher - DestinationPath $outputLocation \Flow- Launcher- Portable.zip
166
+ # Create a temporary staging directory for the portable package
167
+ $stagingDir = Join-Path $outputLocation " PortableStaging"
168
+ Initialize-Directory $stagingDir
169
+
170
+ try {
171
+ # Copy installed files to staging directory
172
+ Copy-Item - Path " $installRoot \*" - Destination $stagingDir - Recurse - Force
173
+
174
+ # Create the UserData folder inside app-<version> to enable portable mode.
175
+ New-Item - Path (Join-Path $stagingDir " app-$version " " UserData" ) - ItemType Directory - Force | Out-Null
176
+
177
+ # Remove the unnecessary 'packages' directory before creating the archive
178
+ $packagesPath = Join-Path $stagingDir " packages"
179
+ if (Test-Path $packagesPath ) {
180
+ Remove-Item - Path $packagesPath - Recurse - Force
181
+ }
182
+
183
+ # Create the zip from the staging directory's contents
184
+ Compress-Archive - Path " $stagingDir \*" - DestinationPath " $outputLocation \Flow-Launcher-Portable.zip" - Force
185
+ }
186
+ finally {
187
+ if (Test-Path $stagingDir ) {
188
+ Remove-Item - Recurse - Force $stagingDir
189
+ }
190
+ }
191
+
192
+ # Uninstall after packaging
193
+ $uninstallExe = Join-Path $installRoot " Update.exe"
194
+ if (Test-Path $uninstallExe ) {
195
+ Write-Host " Uninstalling temporary application..."
196
+ Start-Process - FilePath $uninstallExe - ArgumentList " --uninstall -s" - Wait
197
+ }
114
198
}
115
199
116
200
function Main {
117
201
$p = Build-Path
118
- $v = Build-Version
119
- Copy-Resources $p
120
202
121
203
if ($config -eq " Release" ){
122
204
123
- Delete- Unused $p $config
124
-
125
- Publish-Self - Contained $p
126
-
205
+ if (-not (Build-Solution $p )) {
206
+ Write-Host " dotnet build failed. Aborting post-build script." - ForegroundColor Red
207
+ exit 1
208
+ }
209
+
210
+ $tempPublishPath = Join-Path $p " Output\PublishTemp"
211
+ Initialize-Directory $tempPublishPath
212
+ if (-not (Publish-SelfContainedToTemp $p $tempPublishPath )) {
213
+ Write-Host " dotnet publish failed. Aborting." - ForegroundColor Red
214
+ exit 1
215
+ }
216
+
217
+ Merge-PublishToRelease $tempPublishPath (Join-Path $p " Output\Release" )
218
+
219
+ $v = Build-Version
220
+ if ([string ]::IsNullOrEmpty($v )) {
221
+ Write-Host " Could not determine build version. Aborting." - ForegroundColor Red
222
+ exit 1
223
+ }
224
+
225
+ Copy-Resources $p
226
+ Remove-UnusedFiles $p $config
127
227
Remove-CreateDumpExe $p $config
128
228
129
229
$o = " $p \Output\Packages"
130
- Validate- Directory $o
131
- Pack- Squirrel- Installer $p $v $o
132
-
133
- Publish-Portable $o $v
230
+ Initialize-Directory $o
231
+ New-SquirrelInstallerPackage $p $v $o
232
+ if ($LASTEXITCODE -ne 0 ) {
233
+ Write-Host " Squirrel packaging failed. Aborting." - ForegroundColor Red
234
+ exit 1
235
+ }
236
+
237
+ Publish-Portable $o $v $p
134
238
}
135
239
}
136
240
0 commit comments