bundle-windows.ps1

  1[CmdletBinding()]
  2Param(
  3    [Parameter()][Alias('i')][switch]$Install,
  4    [Parameter()][Alias('h')][switch]$Help,
  5    [Parameter()][string]$Name
  6)
  7
  8. "$PSScriptRoot/lib/blob-store.ps1"
  9. "$PSScriptRoot/lib/workspace.ps1"
 10
 11# https://stackoverflow.com/questions/57949031/powershell-script-stops-if-program-fails-like-bash-set-o-errexit
 12$ErrorActionPreference = 'Stop'
 13$PSNativeCommandUseErrorActionPreference = $true
 14
 15$buildSuccess = $false
 16
 17if ($Help) {
 18    Write-Output "Usage: test.ps1 [-Install] [-Help]"
 19    Write-Output "Build the installer for Windows.\n"
 20    Write-Output "Options:"
 21    Write-Output "  -Install, -i  Run the installer after building."
 22    Write-Output "  -Help, -h     Show this help message."
 23    exit 0
 24}
 25
 26Push-Location -Path crates/zed
 27$channel = Get-Content "RELEASE_CHANNEL"
 28$env:ZED_RELEASE_CHANNEL = $channel
 29Pop-Location
 30
 31function CheckEnvironmentVariables {
 32    $requiredVars = @(
 33        'ZED_WORKSPACE', 'RELEASE_VERSION', 'ZED_RELEASE_CHANNEL',
 34        'AZURE_TENANT_ID', 'AZURE_CLIENT_ID', 'AZURE_CLIENT_SECRET',
 35        'ACCOUNT_NAME', 'CERT_PROFILE_NAME', 'ENDPOINT',
 36        'FILE_DIGEST', 'TIMESTAMP_DIGEST', 'TIMESTAMP_SERVER'
 37    )
 38
 39    foreach ($var in $requiredVars) {
 40        if (-not (Test-Path "env:$var")) {
 41            Write-Error "$var is not set"
 42            exit 1
 43        }
 44    }
 45}
 46
 47$innoDir = "$env:ZED_WORKSPACE\inno"
 48
 49function PrepareForBundle {
 50    if (Test-Path "$innoDir") {
 51        Remove-Item -Path "$innoDir" -Recurse -Force
 52    }
 53    New-Item -Path "$innoDir" -ItemType Directory -Force
 54    Copy-Item -Path "$env:ZED_WORKSPACE\crates\zed\resources\windows\*" -Destination "$innoDir" -Recurse -Force
 55    New-Item -Path "$innoDir\make_appx" -ItemType Directory -Force
 56    New-Item -Path "$innoDir\appx" -ItemType Directory -Force
 57    New-Item -Path "$innoDir\bin" -ItemType Directory -Force
 58    New-Item -Path "$innoDir\tools" -ItemType Directory -Force
 59}
 60
 61function BuildZedAndItsFriends {
 62    Write-Output "Building Zed and its friends, for channel: $channel"
 63    # Build zed.exe, cli.exe and auto_update_helper.exe
 64    cargo build --release --package zed --package cli --package auto_update_helper
 65    Copy-Item -Path ".\target\release\zed.exe" -Destination "$innoDir\Zed.exe" -Force
 66    Copy-Item -Path ".\target\release\cli.exe" -Destination "$innoDir\cli.exe" -Force
 67    Copy-Item -Path ".\target\release\auto_update_helper.exe" -Destination "$innoDir\auto_update_helper.exe" -Force
 68    # Build explorer_command_injector.dll
 69    switch ($channel) {
 70        "stable" {
 71            cargo build --release --features stable --no-default-features --package explorer_command_injector
 72        }
 73        "preview" {
 74            cargo build --release --features preview --no-default-features --package explorer_command_injector
 75        }
 76        default {
 77            cargo build --release --package explorer_command_injector
 78        }
 79    }
 80    Copy-Item -Path ".\target\release\explorer_command_injector.dll" -Destination "$innoDir\zed_explorer_command_injector.dll" -Force
 81}
 82
 83function ZipZedAndItsFriendsDebug {
 84    $items = @(
 85        ".\target\release\zed.pdb",
 86        ".\target\release\cli.pdb",
 87        ".\target\release\auto_update_helper.pdb",
 88        ".\target\release\explorer_command_injector.pdb"
 89    )
 90
 91    Compress-Archive -Path $items -DestinationPath ".\target\release\zed-$env:RELEASE_VERSION-$env:ZED_RELEASE_CHANNEL.dbg.zip" -Force
 92}
 93
 94function MakeAppx {
 95    switch ($channel) {
 96        "stable" {
 97            $manifestFile = "$env:ZED_WORKSPACE\crates\explorer_command_injector\AppxManifest.xml"
 98        }
 99        "preview" {
100            $manifestFile = "$env:ZED_WORKSPACE\crates\explorer_command_injector\AppxManifest-Preview.xml"
101        }
102        default {
103            $manifestFile = "$env:ZED_WORKSPACE\crates\explorer_command_injector\AppxManifest-Nightly.xml"
104        }
105    }
106    Copy-Item -Path "$manifestFile" -Destination "$innoDir\make_appx\AppxManifest.xml"
107    # Add makeAppx.exe to Path
108    $sdk = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64"
109    $env:Path += ';' + $sdk
110    makeAppx.exe pack /d "$innoDir\make_appx" /p "$innoDir\zed_explorer_command_injector.appx" /nv
111}
112
113function SignZedAndItsFriends {
114    $files = "$innoDir\Zed.exe,$innoDir\cli.exe,$innoDir\auto_update_helper.exe,$innoDir\zed_explorer_command_injector.dll,$innoDir\zed_explorer_command_injector.appx"
115    & "$innoDir\sign.ps1" $files
116}
117
118function CollectFiles {
119    Move-Item -Path "$innoDir\zed_explorer_command_injector.appx" -Destination "$innoDir\appx\zed_explorer_command_injector.appx" -Force
120    Move-Item -Path "$innoDir\zed_explorer_command_injector.dll" -Destination "$innoDir\appx\zed_explorer_command_injector.dll" -Force
121    Move-Item -Path "$innoDir\cli.exe" -Destination "$innoDir\bin\zed.exe" -Force
122    Move-Item -Path "$innoDir\auto_update_helper.exe" -Destination "$innoDir\tools\auto_update_helper.exe" -Force
123}
124
125function BuildInstaller {
126    $issFilePath = "$innoDir\zed.iss"
127    switch ($channel) {
128        "stable" {
129            $appId = "{{2DB0DA96-CA55-49BB-AF4F-64AF36A86712}"
130            $appIconName = "app-icon"
131            $appName = "Zed Editor"
132            $appDisplayName = "Zed Editor"
133            $appSetupName = "ZedEditorUserSetup-x64-$env:RELEASE_VERSION"
134            # The mutex name here should match the mutex name in crates\zed\src\zed\windows_only_instance.rs
135            $appMutex = "Zed-Editor-Stable-Instance-Mutex"
136            $appExeName = "Zed"
137            $regValueName = "ZedEditor"
138            $appUserId = "ZedIndustries.Zed"
139            $appShellNameShort = "Z&ed Editor"
140            $appAppxFullName = "ZedIndustries.Zed_1.0.0.0_neutral__japxn1gcva8rg"
141        }
142        "preview" {
143            $appId = "{{F70E4811-D0E2-4D88-AC99-D63752799F95}"
144            $appIconName = "app-icon-preview"
145            $appName = "Zed Editor Preview"
146            $appDisplayName = "Zed Editor Preview"
147            $appSetupName = "ZedEditorUserSetup-x64-$env:RELEASE_VERSION-preview"
148            # The mutex name here should match the mutex name in crates\zed\src\zed\windows_only_instance.rs
149            $appMutex = "Zed-Editor-Preview-Instance-Mutex"
150            $appExeName = "Zed"
151            $regValueName = "ZedEditorPreview"
152            $appUserId = "ZedIndustries.Zed.Preview"
153            $appShellNameShort = "Z&ed Editor Preview"
154            $appAppxFullName = "ZedIndustries.Zed.Preview_1.0.0.0_neutral__japxn1gcva8rg"
155        }
156        "nightly" {
157            $appId = "{{1BDB21D3-14E7-433C-843C-9C97382B2FE0}"
158            $appIconName = "app-icon-nightly"
159            $appName = "Zed Editor Nightly"
160            $appDisplayName = "Zed Editor Nightly"
161            $appSetupName = "ZedEditorUserSetup-x64-$env:RELEASE_VERSION-nightly"
162            # The mutex name here should match the mutex name in crates\zed\src\zed\windows_only_instance.rs
163            $appMutex = "Zed-Editor-Nightly-Instance-Mutex"
164            $appExeName = "Zed"
165            $regValueName = "ZedEditorNightly"
166            $appUserId = "ZedIndustries.Zed.Nightly"
167            $appShellNameShort = "Z&ed Editor Nightly"
168            $appAppxFullName = "ZedIndustries.Zed.Nightly_1.0.0.0_neutral__japxn1gcva8rg"
169        }
170        "dev" {
171            $appId = "{{8357632E-24A4-4F32-BA97-E575B4D1FE5D}"
172            $appIconName = "app-icon-nightly"
173            $appName = "Zed Editor Dev"
174            $appDisplayName = "Zed Editor Dev"
175            $appSetupName = "ZedEditorUserSetup-x64-$env:RELEASE_VERSION-dev"
176            # The mutex name here should match the mutex name in crates\zed\src\zed\windows_only_instance.rs
177            $appMutex = "Zed-Editor-Dev-Instance-Mutex"
178            $appExeName = "Zed"
179            $regValueName = "ZedEditorDev"
180            $appUserId = "ZedIndustries.Zed.Dev"
181            $appShellNameShort = "Z&ed Editor Dev"
182            $appAppxFullName = "ZedIndustries.Zed.Dev_1.0.0.0_neutral__japxn1gcva8rg"
183        }
184        default {
185            Write-Error "can't bundle installer for $channel."
186            exit 1
187        }
188    }
189
190    # Windows runner 2022 default has iscc in PATH, https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md
191    # Currently, we are using Windows 2022 runner.
192    # Windows runner 2025 doesn't have iscc in PATH for now, https://github.com/actions/runner-images/issues/11228
193    # $innoSetupPath = "iscc.exe"
194    $innoSetupPath = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
195
196    $definitions = @{
197        "AppId"          = $appId
198        "AppIconName"    = $appIconName
199        "OutputDir"      = "$env:ZED_WORKSPACE\target"
200        "AppSetupName"   = $appSetupName
201        "AppName"        = $appName
202        "AppDisplayName" = $appDisplayName
203        "RegValueName"   = $regValueName
204        "AppMutex"       = $appMutex
205        "AppExeName"     = $appExeName
206        "ResourcesDir"   = "$innoDir"
207        "ShellNameShort" = $appShellNameShort
208        "AppUserId"      = $appUserId
209        "Version"        = "$env:RELEASE_VERSION"
210        "SourceDir"      = "$env:ZED_WORKSPACE"
211        "AppxFullName"   = $appAppxFullName
212    }
213
214    $signTool = "powershell.exe -ExecutionPolicy Bypass -File $innoDir\sign.ps1 `$f"
215
216    $defs = @()
217    foreach ($key in $definitions.Keys) {
218        $defs += "/d$key=`"$($definitions[$key])`""
219    }
220
221    $innoArgs = @($issFilePath) + $defs + "/sDefaultsign=`"$signTool`""
222
223    # Execute Inno Setup
224    Write-Host "🚀 Running Inno Setup: $innoSetupPath $innoArgs"
225    $process = Start-Process -FilePath $innoSetupPath -ArgumentList $innoArgs -NoNewWindow -Wait -PassThru
226
227    if ($process.ExitCode -eq 0) {
228        Write-Host "✅ Inno Setup successfully compiled the installer"
229        Write-Output "SETUP_PATH=target/$appSetupName.exe" >> $env:GITHUB_ENV
230        $script:buildSuccess = $true
231    }
232    else {
233        Write-Host "❌ Inno Setup failed: $($process.ExitCode)"
234        $script:buildSuccess = $false
235    }
236}
237
238ParseZedWorkspace
239CheckEnvironmentVariables
240PrepareForBundle
241BuildZedAndItsFriends
242MakeAppx
243SignZedAndItsFriends
244ZipZedAndItsFriendsDebug
245CollectFiles
246BuildInstaller
247
248$debugArchive = ".\target\release\zed-$env:RELEASE_VERSION-$env:ZED_RELEASE_CHANNEL.dbg.zip"
249$debugStoreKey = "$env:ZED_RELEASE_CHANNEL/zed-$env:RELEASE_VERSION-$env:ZED_RELEASE_CHANNEL.dbg.zip"
250UploadToBlobStorePublic -BucketName "zed-debug-symbols" -FileToUpload $debugArchive -BlobStoreKey $debugStoreKey
251
252if ($buildSuccess) {
253    Write-Output "Build successful"
254    if ($Install) {
255        Write-Output "Installing Zed..."
256        Start-Process -FilePath "$env:ZED_WORKSPACE/target/ZedEditorUserSetup-x64-$env:RELEASE_VERSION.exe"
257    }
258    exit 0
259}
260else {
261    Write-Output "Build failed"
262    exit 1
263}