Initial public release of Warp.

Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
David Stern
2026-04-28 08:43:33 -05:00
commit 0dbd3d567a
4982 changed files with 1431549 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
# Inno Setup installer script
## What is `windows-installer.iss`?
On Windows, programs are conventionally installed using an installer, also known as an installation wizard.
The installer is a single executable that takes care of:
* Creating a directory to store the program's files
* Downloading assets
* Initializing registry entries
* Creating a desktop icon
* ... and more, depending on the application's needs.
`windows-installer.iss` is an **Inno Setup script**:
a configuration file for building a Warp installer.
The Inno Setup Compiler takes a script file and generates an installer executable.
This is roughly equivalent to the bundling process on MacOS.
## How to edit the installer
See the Inno Setup documentation: [Inno Setup Help](https://jrsoftware.org/ishelp/).
This script can be edited manually using any code editor.
However, it requires the Inno Setup compiler to be turned into a `.exe` file.
## How to compile this installer
First, ensure you've set up your environment.
* Download and install the [Inno Setup Compiler](https://jrsoftware.org/isdl.php).
* Run `cargo build` to ensure the installer uses the latest version of Warp.
### Option 1: Use the CLI
1. Add the Inno Setup Command-line Compiler executable to your shell path.
By default, it is located at `C:\Program Files (x86)\Inno Setup 6\ISCC.exe`.
2. Compile the installer:
```shell
iscc .\script\windows\windows-installer.iss`.
```
3. Run the generated executable:
```shell
.\script\windows\Output\Warp-Windows-Setup.exe`.
```
The script begins with a series of preprocessor definitions.
From the command line, use the `/D` flag to emulate preprocessor definitions
and override the hardcoded defaults.
Usage: `iscc <script path> /D<name>[=<value>]`
The following constants can be overwritten:
* `MyAppVersion` (default: `0.1.0`)
* `MyAppExeName` (default: `warp.exe`)
* `ReleaseChannel` (default: `dev`)
* `TargetProfileDir` (default: `debug`)
### Option 2: Use the GUI
1. Open the Inno Setup application and select this script.
2. Click the "compile" button. This will generate an installer executable in a directory called `Output` at the same level as this script.
2. To run the installer, click the "run" button in Inno Setup.
## Using icons
Windows has its own icon file format that bundles together multiple icon sizes.
App icons are located in `app/channels/<channel_name>/icon/no-padding`.
The `.ico` files are generated using imagemagick:
```shell
convert 16x16.png 32x32.png 48x48.png 64x64.png 256x256.png icon.ico
```
Note that sizes above 256x256 are not supported.
See the [Inno Setup docs](https://jrsoftware.org/ishelp/index.php?topic=setup_setupiconfile).
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env powershell
$ErrorActionPreference = 'Stop'
# Git for Windows can be installed system-wide (Program Files) or per-user (LOCALAPPDATA\Programs\Git).
$gitBinCandidates = @(
"$env:PROGRAMFILES\Git\bin",
"$env:LOCALAPPDATA\Programs\Git\bin"
)
$gitBinDir = $gitBinCandidates | Where-Object { Test-Path -PathType Container $_ } | Select-Object -First 1
if (-not $gitBinDir) {
Write-Error 'Git for Windows is required. Please install it at:'
Write-Error 'https://gitforwindows.org/'
exit 1
}
if (-not (Get-Command -Name cargo -Type Application -ErrorAction SilentlyContinue)) {
Write-Output 'Installing rust...'
Invoke-WebRequest -Uri 'https://win.rustup.rs/x86_64' -OutFile "$env:Temp\rustup-init.exe"
& "$env:Temp\rustup-init.exe"
Write-Output 'Please start a new terminal session so that cargo is in your PATH'
exit 1
}
# A bash executable should come with Git for Windows
& "$gitBinDir\bash.exe" "$PWD\script\install_cargo_test_deps"
# Needed in wasm compilation for parsing the version of wasm-bindgen
winget install jqlang.jq
# CMake is needed to build some dependencies, e.g.: sentry-contrib-native.
winget install -e --id Kitware.CMake
# We use InnoSetup to build our release bundle installer.
winget install -e --id JRSoftware.InnoSetup
# If we don't see gcloud command, try adding the install location to the PATH.
if (-not (Get-Command -Name gcloud -Type Application -ErrorAction SilentlyContinue)) {
$env:PATH += ";$env:LOCALAPPDATA\Google\Cloud SDK\google-cloud-sdk\bin"
}
# If we still don't see it, install it.
if (-not (Get-Command -Name gcloud -Type Application -ErrorAction SilentlyContinue)) {
(New-Object Net.WebClient).DownloadFile('https://dl.google.com/dl/cloudsdk/channels/rapid/GoogleCloudSDKInstaller.exe', "$env:Temp\GoogleCloudSDKInstaller.exe")
Start-Process "$env:Temp\GoogleCloudSDKInstaller.exe" -Wait
}
[string]$identityToken = gcloud auth print-identity-token
if ($identityToken.Trim().Length -eq 0) {
Write-Output 'gcloud CLI authentication missing. Press enter to continue...'
Read-Host
gcloud auth login
}
+215
View File
@@ -0,0 +1,215 @@
#!/usr/bin/env powershell
#
# Bundle the application for release.
Param (
# Build dev bundles by default.
[Switch]$DEBUG_BUILD = $False,
[Alias('check-only')]
[Switch]$CHECK_ONLY,
[ValidateSet('local', 'dev', 'preview', 'stable')]
[String]$CHANNEL = 'dev',
[Alias('release-tag')]
[String]$RELEASE_TAG = '',
[String]$FEATURES = 'release_bundle,crash_reporting,gui',
# Builds only the Warp binary, skips the installer.
[Switch]$SKIP_BUILD_INSTALLER = $False,
# Builds only the installer, skips the Warp binary. Use this if the Warp
# binary has already been built.
[Switch]$SKIP_BUILD_BINARY = $False,
[ValidateSet('x64', 'arm64')]
[String]$ARCH = '',
# A signtool command for Inno Setup to sign the setup engine and uninstaller.
# Uses $f as the file placeholder, e.g.:
# 'signtool.exe sign /fd SHA256 ... $f'
# When empty, the installer is built without signing.
[Alias('sign-tool-cmd')]
[String]$SIGN_TOOL_CMD = ''
)
if ($RELEASE_TAG) {
$env:GIT_RELEASE_TAG = $RELEASE_TAG
}
# Use provided ARCH parameter if set, otherwise detect from system
if (-not $ARCH) {
if ($env:PROCESSOR_ARCHITECTURE -eq 'AMD64') {
$ARCH = 'x64'
} elseif ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') {
$ARCH = 'arm64'
} else {
throw "Unsupported processor architecture: $env:PROCESSOR_ARCHITECTURE"
}
}
if ($ARCH -eq 'arm64') {
$FILE_ENDING = 'Setup-arm64'
$PLATFORM_TARGET = 'aarch64-pc-windows-msvc'
} else {
# If x64, then we just use the filename "WarpSetup.exe" for example
$FILE_ENDING = 'Setup'
$PLATFORM_TARGET = 'x86_64-pc-windows-msvc'
}
$ErrorActionPreference = 'Stop'
$WORKSPACE_ROOT_DIR = $(Get-Location).Path
$CARGO_TARGET_DIR = $WORKSPACE_ROOT_DIR + '\target'
$WINDOWS_INSTALLER_DIR = $WORKSPACE_ROOT_DIR + '\script\windows'
if ($DEBUG_BUILD) {
$CARGO_PROFILE = 'dev'
} elseif (("$CHANNEL" -eq 'local') -or ("$CHANNEL" -eq 'dev')) {
# For dev bundles, we want to enable debug assertions to
# catch violations that would otherwise silently pass in
# a normal release build (e.g. in stable).
$CARGO_PROFILE = 'rltoda'
} else {
$CARGO_PROFILE = 'rlto'
}
if ($CARGO_PROFILE -eq 'dev') {
$CARGO_TARGET_OUTPUT_DIR = "$CARGO_TARGET_DIR" + '\' + $PLATFORM_TARGET + '\debug'
} else {
$CARGO_TARGET_OUTPUT_DIR = "$CARGO_TARGET_DIR" + '\' + $PLATFORM_TARGET + '\' + "$CARGO_PROFILE"
}
$BUNDLE_ID = "dev.warp.$app_name"
# Update parameters based on the target release channel.
#
# APP_NAME here must match the value used in Rust as the
# application name; see app/src/channel.rs.
#
# WARP_BIN is the name of the binary produced by cargo;
# BINARY_NAME is the desired name of the binary in the final package.
if ("$CHANNEL" -eq 'local') {
$WARP_BIN = 'warp'
$BINARY_NAME = 'warp.exe'
$APP_NAME = 'WarpLocal'
$FEATURES = "$FEATURES,nld_improvements"
} elseif ("$CHANNEL" -eq 'dev') {
$WARP_BIN = 'dev'
$BINARY_NAME = 'dev.exe'
$APP_NAME = 'WarpDev'
$FEATURES = "$FEATURES,agent_mode_debug,nld_improvements"
} elseif ("$CHANNEL" -eq 'preview') {
$WARP_BIN = 'preview'
$BINARY_NAME = 'preview.exe'
$APP_NAME = 'WarpPreview'
$FEATURES = "$FEATURES,preview_channel,nld_improvements"
} elseif ("$CHANNEL" -eq 'stable') {
$WARP_BIN = 'stable'
$BINARY_NAME = 'warp.exe'
$APP_NAME = 'Warp'
# TODO(vorporeal): Remove this once we get tests passing with this default enabled.
$FEATURES = "$FEATURES,nld_improvements"
}
$BINARY_PATH = "$CARGO_TARGET_OUTPUT_DIR\$BINARY_NAME"
$BUNDLE_ID = "dev.warp.$APP_NAME"
$INSTALLER_OUTPUT_DIR = "$WINDOWS_INSTALLER_DIR\Output"
$INSTALLER_NAME = "$($APP_NAME)$($FILE_ENDING)"
$INSTALLER_PATH = "$($INSTALLER_OUTPUT_DIR)\$($INSTALLER_NAME).exe"
$PDB_PATH = "$CARGO_TARGET_OUTPUT_DIR\$WARP_BIN.pdb"
# The CARGO_FULL_PROFILE environment variable is read by the `cargo` build
# script (`app/build.rs`) to determine where to place `conpty.dll`.
if ($DEBUG_BUILD) {
$env:CARGO_FULL_PROFILE = 'debug'
} else {
$env:CARGO_FULL_PROFILE = $CARGO_PROFILE
}
# If we only want to check that compilation will succeed, perform the checks
# then exit. We use this script to invoke `cargo check` to ensure that we are
# using the same feature flags and profile that we would be using in production.
if ($CHECK_ONLY) {
cargo check -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES" --target $PLATFORM_TARGET
if (-Not $?) {
Write-Error "Failed to verify Warp $WARP_BIN compilation with profile $CARGO_PROFILE"
exit 1
}
exit 0
}
if (-Not $SKIP_BUILD_BINARY) {
Write-Output "Building Warp for channel $CHANNEL and bundle id $BUNDLE_ID"
$env:CARGO_BIN_NAME = $CHANNEL
$env:WARP_APP_NAME = $APP_NAME
cargo build -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES" --target $PLATFORM_TARGET
if (-Not $?) {
Write-Error "Failed to build Warp $WARP_BIN binary with profile $CARGO_PROFILE"
exit 1
}
# If we desire an executable name different from the cargo bin, rename it.
if ("$WARP_BIN.exe" -ne $BINARY_NAME) {
$binarySource = "$CARGO_TARGET_OUTPUT_DIR\$WARP_BIN.exe"
Write-Output "Renaming executable $WARP_BIN.exe to $BINARY_NAME"
Move-Item -Path "$binarySource" -Destination "$BINARY_PATH" -Force
}
}
if ($SKIP_BUILD_INSTALLER) {
# If this is being run within a GitHub action, set an output variable with the
# location of the binary so it can be referenced by subsequent actions.
if ($env:GITHUB_ACTIONS -eq 'true') {
Write-Output '::echo::on'
"target_profile_dir=$CARGO_TARGET_OUTPUT_DIR" >> "$env:GITHUB_OUTPUT"
"binary_path=$BINARY_PATH" >> "$env:GITHUB_OUTPUT"
Write-Output '::echo::off'
}
exit 0
}
Write-Output "Built for $ARCH with executable at $BINARY_PATH"
# Prepare bundled resources
$BUNDLED_RESOURCES_DIR = "$CARGO_TARGET_OUTPUT_DIR\resources"
Write-Output "Preparing bundled resources..."
& "$WINDOWS_INSTALLER_DIR\prepare_bundled_resources.ps1" -DestinationDir "$BUNDLED_RESOURCES_DIR" -Channel "$CHANNEL" -CargoProfile "$CARGO_PROFILE"
if (-Not $?) {
Write-Error "Failed to prepare bundled resources"
exit 1
}
Write-Output 'Building Warp installer'
$ISCC_ARGS = @(
"$WINDOWS_INSTALLER_DIR\windows-installer.iss",
"/DReleaseChannel=$CHANNEL",
"/DMyAppExeName=$BINARY_NAME",
"/DTargetProfileDir=$CARGO_TARGET_OUTPUT_DIR",
"/DMyAppName=$APP_NAME",
"/DMyAppVersion=$env:GIT_RELEASE_TAG",
"/DArch=$ARCH",
"/DOutputName=$INSTALLER_NAME"
)
# Also accept the sign tool command via env var
if (-not $SIGN_TOOL_CMD -and $env:SIGN_TOOL_CMD) {
$SIGN_TOOL_CMD = $env:SIGN_TOOL_CMD
}
if ($SIGN_TOOL_CMD) {
$ISCC_ARGS += '/DSIGN_TOOL=1'
$ISCC_ARGS += "/Scodesign=$SIGN_TOOL_CMD"
}
& ISCC @ISCC_ARGS
if (-Not $?) {
Write-Error "Failed to build $APP_NAME installer"
exit 1
}
# If this is being run within a GitHub action, set an output variable with the
# location of the installer so it can be referenced by subsequent actions.
if ($env:GITHUB_ACTIONS -eq 'true') {
Write-Output '::echo::on'
$INSTALLER_PATH = $INSTALLER_PATH -replace '\\', '/'
"installer_path=$INSTALLER_PATH" >> "$env:GITHUB_OUTPUT"
"pdb_file_path=$PDB_PATH" >> "$env:GITHUB_OUTPUT"
Write-Output '::echo::off'
}
+73
View File
@@ -0,0 +1,73 @@
[Code]
{ Adapted from https://stackoverflow.com/a/46609047 }
const
SystemEnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
UserEnvironmentKey = 'Environment';
{ Get the appropriate registry key and root based on install mode. }
procedure GetEnvironmentKeyInfo(var RootKey: Integer; var SubKey: string);
begin
if IsAdminInstallMode then begin
RootKey := HKEY_LOCAL_MACHINE;
SubKey := SystemEnvironmentKey;
end else begin
RootKey := HKEY_CURRENT_USER;
SubKey := UserEnvironmentKey;
end;
end;
{ Add path to environment PATH variable. }
procedure EnvAddPath(Path: string);
var
Paths: string;
RootKey: Integer;
SubKey: string;
begin
{ Get the appropriate registry location }
GetEnvironmentKeyInfo(RootKey, SubKey);
{ Retrieve current path (use empty string if entry not exists) }
if not RegQueryStringValue(RootKey, SubKey, 'Path', Paths)
then Paths := '';
{ Skip if string already found in path }
if Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';') > 0 then exit;
{ Append string to the end of the path variable }
Paths := Paths + ';'+ Path +';'
{ Overwrite (or create if missing) path environment variable }
if RegWriteStringValue(RootKey, SubKey, 'Path', Paths)
then Log(Format('Added [%s] to PATH: [%s]', [Path, Paths]))
else Log(Format('Error adding [%s] to PATH: [%s]', [Path, Paths]));
end;
{ Remove path from environment PATH variable. }
procedure EnvRemovePath(Path: string);
var
Paths: string;
P: Integer;
RootKey: Integer;
SubKey: string;
begin
{ Get the appropriate registry location }
GetEnvironmentKeyInfo(RootKey, SubKey);
{ Skip if registry entry not exists }
if not RegQueryStringValue(RootKey, SubKey, 'Path', Paths) then
exit;
{ Skip if string not found in path }
P := Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';');
if P = 0 then exit;
{ Update path variable }
Delete(Paths, P - 1, Length(Path) + 1);
{ Overwrite path environment variable }
if RegWriteStringValue(RootKey, SubKey, 'Path', Paths)
then Log(Format('Removed [%s] from PATH: [%s]', [Path, Paths]))
else Log(Format('Error removing [%s] from PATH: [%s]', [Path, Paths]));
end;
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env powershell
#
# Install all dependencies required to build Warp on Windows.
# Install Rust + cargo.
bash (((Get-Location).path) + '\script\install_rust')
# Install various build-time dependencies through cargo.
bash (((Get-Location).path) + '\script\install_cargo_build_deps')
Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@@ -0,0 +1,183 @@
#
# Prepares bundled resources for distribution on Windows.
#
# This script copies resources that should be bundled with Warp into a
# destination directory. It is used by the Windows build script.
#
# Usage:
# prepare_bundled_resources.ps1 <destination_directory>
#
# Arguments:
# destination_directory: The directory where resources should be installed.
# Resources will be copied to subdirectories within
# this path (e.g., $DEST_DIR\skills).
Param(
[Parameter(Mandatory = $true)]
[String]$DestinationDir,
[Parameter(Mandatory = $false)]
[String]$Channel = '',
[Parameter(Mandatory = $false)]
[String]$CargoProfile = ''
)
$ErrorActionPreference = 'Stop'
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$RepoRoot = (Get-Item "$ScriptDir\..\.." | Select-Object -ExpandProperty FullName)
$ResourcesSource = Join-Path $RepoRoot 'resources'
# Validate that the source resources directory exists
if (-Not (Test-Path $ResourcesSource -PathType Container)) {
Write-Error "Resources directory not found at $ResourcesSource"
exit 1
}
# Create the destination directory if it doesn't exist
if (-Not (Test-Path $DestinationDir)) {
New-Item -ItemType Directory -Path $DestinationDir -Force | Out-Null
}
# Copy bundled resources
$BundledSource = Join-Path $ResourcesSource 'bundled'
if (Test-Path $BundledSource -PathType Container) {
$BundledDestination = Join-Path $DestinationDir 'bundled'
Write-Output "Copying bundled resources to $BundledDestination"
if (Test-Path $BundledDestination -PathType Container) {
Remove-Item -Path $BundledDestination -Recurse -Force
}
Copy-Item -Path $BundledSource -Destination $BundledDestination -Recurse -Force
} else {
Write-Warning "No bundled directory found at $BundledSource"
}
if ($env:GIT_RELEASE_TAG) {
$VersionMetadataDir = Join-Path (Join-Path $DestinationDir 'bundled') 'metadata'
$VersionMetadataPath = Join-Path $VersionMetadataDir 'version.json'
Write-Output "Writing bundled Warp version metadata to $VersionMetadataPath"
if (-Not (Test-Path $VersionMetadataDir -PathType Container)) {
New-Item -ItemType Directory -Path $VersionMetadataDir -Force | Out-Null
}
@{ warp_version = $env:GIT_RELEASE_TAG } |
ConvertTo-Json |
Set-Content -Path $VersionMetadataPath -Encoding utf8
}
# Copy channel-gated skills matching the current release channel.
$GatedSource = Join-Path (Join-Path $RepoRoot 'resources') 'channel-gated-skills'
$DestSkills = Join-Path (Join-Path $DestinationDir 'bundled') 'skills'
if ($Channel -and (Test-Path $GatedSource -PathType Container)) {
Write-Output "Copying channel-gated skills for channel '$Channel'..."
# Error out if a stable/ gate directory exists.
$StableDir = Join-Path $GatedSource 'stable'
if (Test-Path $StableDir -PathType Container) {
Write-Error "Found a 'stable/' directory in $GatedSource. The stable channel does not use gated skills. Move stable-ready skills to resources/skills/ instead."
exit 1
}
# Gate labels ordered from most-inclusive to least-inclusive.
$GateOrder = @('dogfood', 'preview')
# Map the release channel to its gate label.
switch ($Channel) {
'local' { $Gate = 'dogfood' }
'dev' { $Gate = 'dogfood' }
'preview' { $Gate = 'preview' }
default {
Write-Output " Channel '$Channel' has no gated skills, skipping"
$Gate = $null
}
}
if ($Gate) {
# Build the set of included gates (progressive: this gate and all after it).
$GateIndex = [array]::IndexOf($GateOrder, $Gate)
$IncludedGates = $GateOrder[$GateIndex..($GateOrder.Length - 1)]
foreach ($GateDir in Get-ChildItem -Path $GatedSource -Directory | Sort-Object Name) {
if ($GateDir.Name -notin $IncludedGates) {
$Skills = (Get-ChildItem -Path $GateDir.FullName -Directory | Sort-Object Name | ForEach-Object { $_.Name }) -join ', '
Write-Output " Skipping gate '$($GateDir.Name)' (channel '$Channel') - would include: $Skills"
continue
}
foreach ($SkillDir in Get-ChildItem -Path $GateDir.FullName -Directory | Sort-Object Name) {
$Dest = Join-Path $DestSkills $SkillDir.Name
Write-Output " Copying gated skill: $($SkillDir.Name) (gate: $($GateDir.Name))"
Copy-Item -Path $SkillDir.FullName -Destination $Dest -Recurse -Force
}
}
}
}
# Generate third-party license attribution.
#
# Additional (non-Cargo) third-party license files to include in the output.
# When adding a new third-party component to the bundle, add its license file
# to the repo alongside the component and add an entry here.
# Cross-platform components:
$AdditionalLicenses = @(
@{ Name = 'Hack Font'; License = 'MIT'; Path = 'app\assets\bundled\fonts\hack\LICENSE.md' },
@{ Name = 'Roboto Font'; License = 'SIL Open Font License'; Path = 'app\assets\bundled\fonts\roboto\LICENSE.txt' },
@{ Name = 'bash-preexec'; License = 'MIT'; Path = 'app\assets\bundled\bootstrap\bash-preexec-LICENSE.md' },
@{ Name = 'Claude API Skill'; License = 'Apache-2.0'; Path = 'resources\bundled\skills\claude-api\LICENSE.txt' },
@{ Name = 'rudder-sdk-rust'; License = 'MIT'; Path = 'app\src\server\telemetry\LICENSE-RUDDER-SDK-RUST.txt' },
@{ Name = 'Windows Terminal'; License = 'MIT'; Path = 'app\assets\windows\LICENSE-WINDOWS-TERMINAL' },
@{ Name = 'GitHub Desktop'; License = 'MIT'; Path = 'app\src\code_review\GITHUB-DESKTOP-LICENSE' }
)
# Windows-only components:
$AdditionalLicenses += @(
@{ Name = 'OpenConsole / ConPTY (Windows Terminal)'; License = 'MIT'; Path = 'app\assets\windows\LICENSE-WINDOWS-TERMINAL' },
@{ Name = 'DirectX Shader Compiler'; License = 'NCSA'; Path = 'app\assets\windows\LICENSE-DXC' }
)
$LicensesOutput = Join-Path $DestinationDir 'THIRD_PARTY_LICENSES.txt'
Write-Output "Generating third-party licenses at $LicensesOutput"
cargo about generate --workspace --manifest-path "$RepoRoot\Cargo.toml" -c "$RepoRoot\about.toml" -o "$LicensesOutput" "$RepoRoot\about.hbs"
if (-Not $?) {
Write-Error 'Failed to generate third-party licenses'
exit 1
}
# Append additional (non-Cargo) third-party licenses.
foreach ($entry in $AdditionalLicenses) {
$LicenseFile = Join-Path $RepoRoot $entry.Path
if (-Not (Test-Path $LicenseFile)) {
Write-Error "License file not found: $LicenseFile"
exit 1
}
Add-Content -Path $LicensesOutput -Value ''
Add-Content -Path $LicensesOutput -Value "$($entry.Name) ($($entry.License))"
Add-Content -Path $LicensesOutput -Value ('-' * 80)
Get-Content -Path $LicenseFile | Add-Content -Path $LicensesOutput
Add-Content -Path $LicensesOutput -Value ''
}
# Generate settings JSON schema unless explicitly skipped.
if ($env:SKIP_SETTINGS_SCHEMA -ne '1') {
$SchemaOutput = Join-Path $DestinationDir 'settings_schema.json'
Write-Output "Generating settings schema at $SchemaOutput"
$SchemaCmd = @('run')
if ($CargoProfile) {
$SchemaCmd += @('--profile', $CargoProfile)
}
$SchemaCmd += @('--manifest-path', (Join-Path $RepoRoot 'Cargo.toml'), '--bin', 'generate_settings_schema', '--')
if ($Channel) {
$SchemaCmd += @('--channel', $Channel)
}
$SchemaCmd += $SchemaOutput
& cargo @SchemaCmd
if (-Not $?) {
Write-Error 'Failed to generate settings schema'
exit 1
}
}
Write-Output "Successfully prepared bundled resources in $DestinationDir"
+250
View File
@@ -0,0 +1,250 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#include "environment.iss"
#define MyAppPublisher "Denver Technologies, Inc."
#define MyAppURL "https://www.warp.dev/"
#ifndef MyAppName
#define MyAppName "WarpDev"
#endif
#ifndef MyAppVersion
#define MyAppVersion "0.1.0"
#endif
#ifndef MyAppExeName
#define MyAppExeName "dev.exe"
#endif
#ifndef ReleaseChannel
#define ReleaseChannel "dev"
#endif
#ifndef TargetProfileDir
#define TargetProfileDir "target\release-lto-debug_assertions"
#endif
#define AssetsDir "..\..\app\assets\windows"
// The mutex name must match what the Rust app creates in single_instance_manager.rs:
#define ChannelPascalCase \
(ReleaseChannel == "stable") ? "Stable" : \
((ReleaseChannel == "dev") ? "Dev" : \
((ReleaseChannel == "preview") ? "Preview" : \
((ReleaseChannel == "local") ? "Local" : \
((ReleaseChannel == "integration") ? "Integration" : \
"Unknown"))))
#define AppMutexName "Local\Warp" + ChannelPascalCase + "_SingleInstance"
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId=warp-terminal-{#ReleaseChannel}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
UninstallDisplayName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
ArchitecturesAllowed={#Arch}
ArchitecturesInstallIn64BitMode={#Arch}
DisableProgramGroupPage=yes
; The following line defaults the installer to use non administrative install mode (install for current user only).
PrivilegesRequired=lowest
; Allow the user to choose administrative install mode (install for all users).
PrivilegesRequiredOverridesAllowed=dialog
OutputBaseFilename={#OutputName}
Compression=lzma
SolidCompression=yes
WizardStyle=modern
WizardSmallImageFile="installer-images\warp-logo.bmp"
WizardImageFile="installer-images\warp-banner.bmp"
SetupIconFile="..\..\app\channels\{#ReleaseChannel}\icon\no-padding\icon.ico"
UninstallDisplayIcon="{app}\icon.ico"
; Force close previous Warp if it hasn't shut down yet.
; In the update flow we already warn the user if they have something running and make them confirm
; before running this installer. Therefore, we are good to force close Warp without fear of losing
; unsaved work.
; VSCode does something similar:
; https://github.com/microsoft/vscode/blob/aac9914f93551f894b8df1e4680bd847e7636be3/build/win32/code.iss#L41
CloseApplications=force
; For manual installs: if Warp is running, show a dialog prompting the user to close it
; before Setup proceeds. Returned empty for background updates so the check is skipped.
; TODO(andy) uncomment this after the 4/22 release
;AppMutex={code:GetAppMutex}
SetupMutex={#AppMutexName}Setup
; Version 1809 / Build 18362 is required for ConPTY. See https://github.com/microsoft/vscode-docs/blob/9d736b662fdde3fed17d8bc2ed70bfea4ae20636/docs/supporting/troubleshoot-terminal-launch.md?plain=1#L66/
MinVersion=10.0.18362
; Tell Windows Explorer to reload the environment so that path changes take effect.
ChangesEnvironment=true
; Sign the setup engine and uninstaller so that the temporary bootstrapper
; extracted to %TEMP% is Authenticode-signed. This prevents Microsoft Defender
; ASR rule D4F940AB from blocking the installer in enterprise environments.
; The sign tool command is supplied via ISCC /S on the command line; when not
; defined (e.g. local dev builds) signing is skipped.
#ifdef SIGN_TOOL
SignTool=codesign
SignedUninstaller=yes
#endif
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
[Files]
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
Source: "{#TargetProfileDir}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#AssetsDir}\{#Arch}\conpty.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#AssetsDir}\{#Arch}\OpenConsole.exe"; DestDir: "{app}\{#Arch}"; Flags: ignoreversion
Source: "..\..\app\channels\{#ReleaseChannel}\icon\no-padding\icon.ico"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#AssetsDir}\{#Arch}\vcruntime140.dll"; DestDir: "{app}"
Source: "{#AssetsDir}\{#Arch}\vcruntime140_1.dll"; DestDir: "{app}"
Source: "{#AssetsDir}\{#Arch}\msvcp140.dll"; DestDir: "{app}"
Source: "..\..\app\assets\bundled\bootstrap\pwsh.ps1"; DestDir: "{app}"
Source: "{#AssetsDir}\{#Arch}\dxcompiler.dll"; DestDir: "{app}"
Source: "{#AssetsDir}\{#Arch}\dxil.dll"; DestDir: "{app}"
Source: "{#TargetProfileDir}\resources\*"; DestDir: "{app}\resources"; Flags: ignoreversion recursesubdirs
[Registry]
Root: HKCU; Subkey: "SOFTWARE\Warp.dev\{#MyAppName}"; Flags: uninsdeletekey
; cleanup "Open Warp Here" registry entries
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}"; Flags: deletekey
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}"; Flags: deletekey
; Add "Open Warp in new tab" to directory context menu
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Tab"; ValueType: string; ValueName: ""; ValueData: "Open {#MyAppName} in new tab"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Tab"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\icon.ico"
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Tab\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""{#MyAppName}://action/new_tab?path=%1"""
; Add "Open Warp in new tab" to directory background context menu
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Tab"; ValueType: string; ValueName: ""; ValueData: "Open {#MyAppName} in new tab"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Tab"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\icon.ico"
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Tab\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""{#MyAppName}://action/new_tab?path=%V"""
; Add "Open Warp in new window" to directory context menu
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Window"; ValueType: string; ValueName: ""; ValueData: "Open {#MyAppName} in new window"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Window"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\icon.ico"
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Window\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""{#MyAppName}://action/new_window?path=%1"""
; Add "Open Warp in new window" to directory background context menu
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Window"; ValueType: string; ValueName: ""; ValueData: "Open {#MyAppName} in new window"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Window"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\icon.ico"
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Window\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""{#MyAppName}://action/new_window?path=%V"""
[Tasks]
Name: addToPath; Description: "Add Warp to PATH"
[UninstallDelete]
Type: filesandordirs; Name: "{userappdata}\warp\{#MyAppName}"
Type: filesandordirs; Name: "{localappdata}\warp\{#MyAppName}"
Type: filesandordirs; Name: "{app}\bin"
[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\icon.ico"; AppUserModelID: "dev.warp.{#MyAppName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\icon.ico"; AppUserModelID: "dev.warp.{#MyAppName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: postinstall runhidden nowait
[Code]
function IsNotStable(): Boolean;
begin
#if ReleaseChannel == "stable"
Result := False;
#else
Result := True;
#endif
end;
{ Returns true when the installer was launched by Warp's auto-update code.
The auto-update path passes /update=1 on the command line and /NOCLOSEAPPLICATIONS
so that the installer does not forcibly kill the running Warp process. Instead we
wait for Warp to exit naturally by polling the app mutex below. }
function IsBackgroundUpdate(): Boolean;
begin
Result := ExpandConstant('{param:update|false}') <> 'false';
end;
{ For background updates, return an empty mutex name so that Inno Setup skips its
built-in "application is running" dialog - we handle the wait ourselves. For manual
installs, return the real mutex name so the user is prompted to close Warp first. }
function GetAppMutex(Value: string): string;
begin
if IsBackgroundUpdate() then
Result := ''
else
Result := '{#AppMutexName}';
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
BinDir: string;
CmdScriptName: string;
CmdScriptPath: string;
CmdScriptContent: string;
WaitCounter: Integer;
ResultCode: Integer;
begin
{ Background update: the installer was launched while Warp was still running.
We passed /NOCLOSEAPPLICATIONS so Inno won't kill it. Wait here - before any
files are touched - for Warp to release its single-instance mutex, which
happens as part of normal process exit. }
if CurStep = ssInstall then
begin
if IsBackgroundUpdate() then
begin
Log('Background update: waiting for Warp to exit (mutex: {#AppMutexName})...');
WaitCounter := 0;
while CheckForMutexes('{#AppMutexName}') and (WaitCounter < 30) do
begin
Sleep(500);
WaitCounter := WaitCounter + 1;
end;
if CheckForMutexes('{#AppMutexName}') then
begin
Log('Warp mutex still held after timeout; force-killing remaining processes.');
{ Kill by image name. {#MyAppExeName} (e.g. warp.exe, dev.exe) is unique
enough that collateral damage is not a concern. OpenConsole.exe is NOT
killed by name because it is shared with Windows Terminal; instead we
rely on Warp's Job Object (JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE) to
cascade-kill any child OpenConsole.exe processes when warp.exe dies. }
Exec('taskkill.exe', '/f /im {#MyAppExeName}', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
if ResultCode <> 0 then
Log('force-kill failed for {#MyAppExeName} (exit code: ' + IntToStr(ResultCode) + ')');
Sleep(1000);
end
else
Log('Warp has exited; proceeding with file installation.');
end;
end;
{ After a successful install, write a helper script for running the Warp CLI. }
{ We use this to add a "warp-" prefix (e.g. "warp-preview.cmd" vs. "preview.exe") }
if CurStep = ssPostInstall then begin
{ Add Warp to PATH if requested }
if IsTaskSelected('addToPath') then
EnvAddPath(ExpandConstant('{app}\bin'));
BinDir := ExpandConstant('{app}\bin');
if not DirExists(BinDir) then
CreateDir(BinDir);
{ Determine the channel-specific script name. }
#if ReleaseChannel == "stable"
CmdScriptName := 'oz.cmd'
#else
CmdScriptName := 'oz-{#ReleaseChannel}.cmd';
#endif
{ Create the helper CMD script }
CmdScriptPath := BinDir + '\' + CmdScriptName;
CmdScriptContent := '@echo off' + #13#10 +
'set "WARP_CLI_MODE=1"' + #13#10 +
'"' + ExpandConstant('{app}\{#MyAppExeName}') + '" %*' + #13#10;
SaveStringToFile(CmdScriptPath, CmdScriptContent, False);
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usPostUninstall then
EnvRemovePath(ExpandConstant('{app}\bin'));
end;