Skip to content

Commit 7dd9978

Browse files
committed
feat: Add support for msi packages
1 parent c907f5b commit 7dd9978

File tree

6 files changed

+118
-1
lines changed

6 files changed

+118
-1
lines changed

.github/workflows/build_release_assets.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ jobs:
161161
# Make it available
162162
cp rcodesign /usr/local/bin
163163
164+
- name: Install WiX Toolset
165+
if: matrix.os == 'windows-2022'
166+
shell: bash
167+
run: dotnet tool install --global wix --version 4.0.4
168+
164169
- name: Install dependencies
165170
shell: bash
166171
run: |
@@ -274,6 +279,7 @@ jobs:
274279
packages/ggshield-*.rpm
275280
packages/ggshield_*.deb
276281
packages/ggshield.*.nupkg
282+
packages/ggshield-*.msi
277283
278284
# Run some basic tests, the goal is to verify the ggshield binary has all the
279285
# libraries it needs to run

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ repos:
3535
rev: v3.6.0
3636
hooks:
3737
- id: prettier
38+
exclude: \.wxs$
3839

3940
- repo: https://github.com/pycqa/isort
4041
rev: 5.13.2

doc/dev/os-packages.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ flowchart TD
2323
signing -->|no| create_archive
2424
sign --> create_archive --> pkg[/"pkg 🍏"/]
2525
create_archive --> zip[/"zip 🪟"/]
26+
create_archive --> msi[/"msi 🪟"/]
2627
create_archive --> tar.gz[/"tar.gz 🐧"/]
2728
create_archive --> deb[/"deb 🐧"/]
2829
create_archive --> rpm[/"rpm 🐧"/]
@@ -96,3 +97,13 @@ Note 2: `install-keylocker-tools` expects `$PATH` to already contain the install
9697
#### Building signed binaries
9798

9899
Once all environment variables are set and DigiCert tools are installed, one can build signed Windows binaries using `build-os-packages --sign`.
100+
101+
### MSI Package
102+
103+
The build produces an MSI installer (`ggshield-VERSION-x86_64-pc-windows-msvc.msi`) using [WiX Toolset v4](https://wixtoolset.org/). The WiX source file is `scripts/build-os-packages/ggshield.wxs`.
104+
105+
- **Install location**: `C:\Program Files\GitGuardian\ggshield\`
106+
- **PATH**: The installer adds the install location to the system `PATH`. This is removed on uninstall.
107+
- **Upgrades**: Installing a newer version automatically removes the previous one (via `MajorUpgrade`).
108+
- **Silent install**: `msiexec /i ggshield-X.Y.Z-x86_64-pc-windows-msvc.msi /quiet`
109+
- **Silent uninstall**: `msiexec /x ggshield-X.Y.Z-x86_64-pc-windows-msvc.msi /quiet`

scripts/build-os-packages/build-os-packages

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ init_system_vars() {
114114
EXE_EXT=".exe"
115115
HUMAN_OS=Windows
116116
TARGET="$arch-pc-windows-msvc"
117-
REQUIREMENTS="$REQUIREMENTS choco"
117+
REQUIREMENTS="$REQUIREMENTS choco wix"
118118
;;
119119
*)
120120
die "Unknown OS. uname printed '$out'"
@@ -323,6 +323,7 @@ step_create_archive() {
323323
Windows)
324324
create_windows_packages
325325
test_chocolatey_package
326+
test_msi_package
326327
;;
327328
esac
328329
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2+
<Package
3+
Name="ggshield"
4+
Manufacturer="GitGuardian"
5+
Version="$(var.Version)"
6+
UpgradeCode="b0e3a5b8-6a44-4c2f-8c72-5f3e9a1d7b4e"
7+
Scope="perMachine"
8+
Compressed="yes"
9+
>
10+
<MajorUpgrade DowngradeErrorMessage="A newer version of ggshield is already installed." />
11+
12+
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
13+
14+
<StandardDirectory Id="ProgramFiles64Folder">
15+
<Directory Id="GitGuardianDir" Name="GitGuardian">
16+
<Directory Id="INSTALLFOLDER" Name="ggshield">
17+
<Component
18+
Id="MainExecutable"
19+
Guid="a1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e"
20+
>
21+
<File Source="!(bindpath.SourceDir)\ggshield.exe" />
22+
</Component>
23+
24+
<Component
25+
Id="InternalFiles"
26+
Guid="c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f"
27+
>
28+
<Files Include="!(bindpath.SourceDir)\_internal\**" />
29+
</Component>
30+
31+
<Component Id="PathEntry" Guid="d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f80">
32+
<Environment
33+
Id="PATH"
34+
Name="PATH"
35+
Value="[INSTALLFOLDER]"
36+
Permanent="no"
37+
Part="last"
38+
Action="set"
39+
System="yes"
40+
/>
41+
</Component>
42+
</Directory>
43+
</Directory>
44+
</StandardDirectory>
45+
46+
<Feature Id="Complete" Level="1">
47+
<ComponentRef Id="MainExecutable" />
48+
<ComponentRef Id="InternalFiles" />
49+
<ComponentRef Id="PathEntry" />
50+
</Feature>
51+
</Package>
52+
</Wix>

scripts/build-os-packages/windows-functions.bash

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,53 @@ test_chocolatey_package() {
6262
popd
6363
}
6464

65+
windows_build_msi_package() {
66+
# MSI only supports X.Y.Z version format, strip any suffix (e.g. +sha)
67+
local msi_version="${VERSION%%[+]*}"
68+
69+
local wxs_path
70+
wxs_path=$(cygpath -w "$SCRIPT_DIR/ggshield.wxs")
71+
72+
local source_dir
73+
source_dir=$(cygpath -w "$PACKAGES_DIR/$ARCHIVE_DIR_NAME")
74+
75+
local msi_path="$PACKAGES_DIR/$ARCHIVE_DIR_NAME.msi"
76+
local msi_path_win
77+
msi_path_win=$(cygpath -w "$msi_path")
78+
79+
info "Building MSI package"
80+
wix build "$wxs_path" \
81+
-arch x64 \
82+
-d Version="$msi_version" \
83+
-bindpath "SourceDir=$source_dir" \
84+
-o "$msi_path_win"
85+
86+
if [ "$DO_SIGN" -eq 1 ] ; then
87+
info "Signing MSI package"
88+
smctl sign \
89+
--verbose \
90+
--exit-non-zero-on-fail \
91+
--fingerprint "$WINDOWS_CERT_FINGERPRINT" \
92+
--tool signtool \
93+
--input "$msi_path"
94+
fi
95+
96+
info "MSI package created in $msi_path"
97+
}
98+
99+
test_msi_package() {
100+
local msi_path="$PACKAGES_DIR/$ARCHIVE_DIR_NAME.msi"
101+
if [ ! -f "$msi_path" ] ; then
102+
die "MSI package not found: $msi_path"
103+
fi
104+
if [ ! -s "$msi_path" ] ; then
105+
die "MSI package is empty: $msi_path"
106+
fi
107+
info "MSI package OK: $msi_path"
108+
}
109+
65110
create_windows_packages() {
66111
windows_create_archive
67112
windows_build_chocolatey_package
113+
windows_build_msi_package
68114
}

0 commit comments

Comments
 (0)