diff --git a/.github/workflows/gen_windows.yml b/.github/workflows/gen_windows.yml index c29423a3a..c12d5851b 100644 --- a/.github/workflows/gen_windows.yml +++ b/.github/workflows/gen_windows.yml @@ -70,7 +70,7 @@ jobs: shell: bash run: | mkdir pkg_ - mv *.zip pkg_ + mv *.zip *.exe pkg_ - name: "Upload artifact" diff --git a/.github/workflows/gen_windows_continuous.yml b/.github/workflows/gen_windows_continuous.yml index 892ec97ad..4bc50fb34 100644 --- a/.github/workflows/gen_windows_continuous.yml +++ b/.github/workflows/gen_windows_continuous.yml @@ -78,6 +78,6 @@ jobs: - name: "Upload to Nightly Release" uses: wez/upload-release-assets@releases/v1 with: - files: "WezTerm-*.zip" + files: "WezTerm-*.zip;WezTerm-*.exe" release-tag: "nightly" repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/gen_windows_tag.yml b/.github/workflows/gen_windows_tag.yml index eb1e04207..7ac0b6c34 100644 --- a/.github/workflows/gen_windows_tag.yml +++ b/.github/workflows/gen_windows_tag.yml @@ -63,6 +63,9 @@ jobs: - name: "Upload to Tagged Release" uses: softprops/action-gh-release@v1 with: - files: "WezTerm-*.zip" + files: | + WezTerm-*.zip + WezTerm-*.exe + env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.gitignore b/.gitignore index b0fcfb433..fa6a46c41 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store /docs/_site /WezTerm*.zip +/WezTerm*.exe /wezterm*.deb /wezterm*.tar.xz /pkg diff --git a/ci/deploy.sh b/ci/deploy.sh index 4d5c4010c..6eae0af09 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -35,8 +35,10 @@ case $OSTYPE in zipdir=WezTerm-windows-$TAG_NAME if [[ "$BUILD_REASON" == "Schedule" ]] ; then zipname=WezTerm-windows-nightly.zip + instname=WezTerm-nightly-setup else zipname=$zipdir.zip + instname=WezTerm-${TAG_NAME}-setup fi rm -rf $zipdir $zipname mkdir $zipdir @@ -48,6 +50,7 @@ case $OSTYPE in $zipdir cp -r assets/colors $zipdir/ 7z a -tzip $zipname $zipdir + iscc.exe -DMyAppVersion=${TAG_NAME#nightly} -F${instname} ci/windows-installer.iss ;; linux-gnu) distro=$(lsb_release -is) diff --git a/ci/generate-workflows.py b/ci/generate-workflows.py index 20fee6baf..13ab67df8 100755 --- a/ci/generate-workflows.py +++ b/ci/generate-workflows.py @@ -259,7 +259,9 @@ cargo build --all --release""", run = "mkdir pkg_\n" if self.uses_yum(): run += "mv ~/rpmbuild/RPMS/*/*.rpm pkg_\n" - if ("win" in self.name) or ("mac" in self.name): + if "win" in self.name: + run += "mv *.zip *.exe pkg_\n" + if "mac" in self.name: run += "mv *.zip pkg_\n" if ("ubuntu" in self.name) or ("debian" in self.name): run += "mv *.deb *.xz pkg_\n" @@ -279,7 +281,9 @@ cargo build --all --release""", patterns = [] if self.uses_yum(): patterns += ["wezterm-*.rpm"] - elif ("win" in self.name) or ("mac" in self.name): + elif "win" in self.name: + patterns += ["WezTerm-*.zip", "WezTerm-*.exe"] + elif "mac" in self.name: patterns += ["WezTerm-*.zip"] elif ("ubuntu" in self.name) or ("debian" in self.name): patterns += ["wezterm-*.deb", "wezterm-*.xz", "wezterm-*.tar.gz"] diff --git a/ci/windows-installer.iss b/ci/windows-installer.iss new file mode 100644 index 000000000..5316060c6 --- /dev/null +++ b/ci/windows-installer.iss @@ -0,0 +1,136 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! +; vim:ts=2:sw=2:et: + +#define MyAppName "WezTerm" +;#define MyAppVersion "1.5" +#define MyAppPublisher "Wez Furlong" +#define MyAppURL "http://wezfurlong.org/wezterm" +#define MyAppExeName "wezterm.exe" + +[Setup] +AppId={{BCF6F0DA-5B9A-408D-8562-F680AE6E1EAF} +ArchitecturesAllowed=x64 +ArchitecturesInstallIn64BitMode=x64 +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={autopf}\{#MyAppName} +DisableProgramGroupPage=yes +;LicenseFile=..\LICENSE.md +; Remove the following line to run in administrative install mode (install for all users.) +;PrivilegesRequired=lowest +;PrivilegesRequiredOverridesAllowed=dialog +OutputDir=.. +OutputBaseFilename=WezTerm-Setup +SetupIconFile=..\assets\windows\terminal.ico +Compression=lzma +SolidCompression=yes +WizardStyle=modern +; Build 1809 is required for pty support +MinVersion=10.0.17763 +ChangesEnvironment=true + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "..\target\release\wezterm.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\target\release\conpty.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\target\release\OpenConsole.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\target\release\strip-ansi-escapes.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\assets\colors\*"; DestDir: "{app}\colors"; Flags: ignoreversion +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + +[Code] +{ https://stackoverflow.com/a/46609047/149111 } +const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; + +procedure EnvAddPath(instlPath: string); +var + Paths: string; +begin + { Retrieve current path (use empty string if entry not exists) } + if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then + Paths := ''; + + if Paths = '' then + Paths := instlPath + ';' + else + begin + { Skip if string already found in path } + if Pos(';' + Uppercase(instlPath) + ';', ';' + Uppercase(Paths) + ';') > 0 then exit; + if Pos(';' + Uppercase(instlPath) + '\;', ';' + Uppercase(Paths) + ';') > 0 then exit; + + { Append App Install Path to the end of the path variable } + if Paths[length(Paths)] <> ';' then + Paths := Paths + ';'; + + Paths := Paths + instlPath + ';'; + end; + + { Overwrite (or create if missing) path environment variable } + if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) + then Log(Format('The [%s] added to PATH: [%s]', [instlPath, Paths])) + else Log(Format('Error while adding the [%s] to PATH: [%s]', [instlPath, Paths])); +end; + +procedure EnvRemovePath(instlPath: string); +var + Paths: string; + P, Offset, DelimLen: Integer; +begin + { Skip if registry entry not exists } + if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then + exit; + + { Skip if string not found in path } + DelimLen := 1; { Length(';') } + P := Pos(';' + Uppercase(instlPath) + ';', ';' + Uppercase(Paths) + ';'); + if P = 0 then + begin + { perhaps instlPath lives in Paths, but terminated by '\;' } + DelimLen := 2; { Length('\;') } + P := Pos(';' + Uppercase(instlPath) + '\;', ';' + Uppercase(Paths) + ';'); + if P = 0 then exit; + end; + + { Decide where to start string subset in Delete() operation. } + if P = 1 then + Offset := 0 + else + Offset := 1; + { Update path variable } + Delete(Paths, P - Offset, Length(instlPath) + DelimLen); + + { Overwrite path environment variable } + if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) + then Log(Format('The [%s] removed from PATH: [%s]', [instlPath, Paths])) + else Log(Format('Error while removing the [%s] from PATH: [%s]', [instlPath, Paths])); +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if CurStep = ssPostInstall then + EnvAddPath(ExpandConstant('{app}')); +end; + +procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); +begin + if CurUninstallStep = usPostUninstall then + EnvRemovePath(ExpandConstant('{app}')); +end;