Compare commits

...

29 commits

Author SHA1 Message Date
jkarasti
fb2805e59f
Merge 223fb0f1b9 into f540a67d06 2024-10-30 20:10:22 +00:00
jkarasti
223fb0f1b9 Fix: Dangerzone installed using an msi built with WiX Toolset 3 is not uninstalled by an msi built with WiX Toolset 5
Work around the issue by adding some extra functionality to the "Next" button on the welcome screen of the installer. When the user clicks it to proceed with the installation this:
1. Flips the install scope to "perUser" which is the default in WiX 3
2. Finds the older installation
3. And finally flips the scope back to "perMachine" which is the default in WiX 4 and newer

TODO: Revert this once we are reasonably certain there are no affected Dangerzone Installations?
2024-10-30 22:08:36 +02:00
jkarasti
8603cd3b86 Change: Wrap installer ui related things in a UI element
fix
2024-10-30 22:08:23 +02:00
Alexis Métaireau
f540a67d06
Update RELEASE.md to upload container.tar.gz for both i686 and arm64 architectures.
Some checks are pending
Tests / macOS (x86_64) (push) Blocked by required conditions
Tests / build-deb (debian bookworm) (push) Blocked by required conditions
Tests / build-deb (debian bullseye) (push) Blocked by required conditions
Tests / build-deb (debian trixie) (push) Blocked by required conditions
Tests / build-deb (ubuntu 20.04) (push) Blocked by required conditions
Tests / build-deb (ubuntu 22.04) (push) Blocked by required conditions
Tests / build-deb (ubuntu 24.04) (push) Blocked by required conditions
Tests / build-deb (ubuntu 24.10) (push) Blocked by required conditions
Tests / install-deb (debian bookworm) (push) Blocked by required conditions
Tests / install-deb (debian bullseye) (push) Blocked by required conditions
Tests / install-deb (debian trixie) (push) Blocked by required conditions
Tests / install-deb (ubuntu 20.04) (push) Blocked by required conditions
Tests / install-deb (ubuntu 22.04) (push) Blocked by required conditions
Tests / install-deb (ubuntu 24.04) (push) Blocked by required conditions
Tests / install-deb (ubuntu 24.10) (push) Blocked by required conditions
Tests / build-install-rpm (fedora 39) (push) Blocked by required conditions
Tests / build-install-rpm (fedora 40) (push) Blocked by required conditions
Tests / build-install-rpm (fedora 41) (push) Blocked by required conditions
Tests / run tests (debian bookworm) (push) Blocked by required conditions
Tests / run tests (debian bullseye) (push) Blocked by required conditions
Tests / run tests (debian trixie) (push) Blocked by required conditions
Tests / run tests (fedora 39) (push) Blocked by required conditions
Tests / run tests (fedora 40) (push) Blocked by required conditions
Tests / run tests (fedora 41) (push) Blocked by required conditions
Tests / run tests (ubuntu 20.04) (push) Blocked by required conditions
Tests / run tests (ubuntu 22.04) (push) Blocked by required conditions
Tests / run tests (ubuntu 24.04) (push) Blocked by required conditions
Tests / run tests (ubuntu 24.10) (push) Blocked by required conditions
Scan latest app and container / security-scan-container (push) Waiting to run
Scan latest app and container / security-scan-app (push) Waiting to run
2024-10-30 19:11:24 +01:00
Alex Pyrgiotis
68f8338d20
Revert "Disable gVisor's DirectFS feature."
This reverts commit 73b0f8b7d4.
Unfortunately, disabling DirectFS causes a problem in Linux systems that
enable Yama mode 2. Turns out that Tails is such a system, so we have to
revert this change, if we want to support it.

Refs #982
2024-10-30 19:10:26 +01:00
Alex Pyrgiotis
d561878e03
tests: Restore previously mocked function
Restore the `isolation_provider.base.kill_process_group()` function,
which was previously mocked, at the end of the
`test_linger_unkillable()` test. This function is initially mocked, in
order to simulate a hang process. After the mocking completes, the test
needs the original function once more, in order to actually kill the
spawned process.
2024-10-30 16:45:45 +01:00
Alexis Métaireau
59e1666c28
Drop support for Ubuntu Mantic (23.10), which is EOL since 11 Jul 2024. 2024-10-30 16:43:50 +01:00
jkarasti
95d7d8a4d9
Fix: Error with cx_freeze when building the windows executables 2024-10-30 17:41:15 +02:00
jkarasti
ed2791bbbc
Revert: "fix win build failure due to package autodiscovery"
This reverts commit 4d9f729654.

The error described in #178 doesen't happen anymore so this workaround is not needed.
2024-10-30 17:41:15 +02:00
JKarasti
7e4346a306 Change: Build 64bit installer 2024-10-27 17:43:59 +02:00
JKarasti
dba5b7a3ac Docs: Documentation for WiX Toolset 5 2024-10-27 17:43:59 +02:00
JKarasti
a0f99f89f7 Change: Make build-app.bat script work with WiX Toolset v5
- WiX Toolset v3 used to validate the msi package by default. In v5 that has moved to a new command, so add a new validation step to the script.
2024-10-27 17:43:59 +02:00
JKarasti
c1dc2490b5 Change: Use WiX Toolset v5 to build the msi in CI 2024-10-27 17:43:59 +02:00
JKarasti
6e2a95326d Change: Write Dangerzone.wxs inside the script directly
Also reduce duplication slightly by definig `build_dir`, `cx_freeze_dir` and `dist_dir`
2024-10-27 17:43:58 +02:00
JKarasti
5d47984e45 Fix: Make GUIDs uppercase
See [1]

[1] https://learn.microsoft.com/en-us/windows/win32/msi/guid
2024-10-27 17:43:58 +02:00
JKarasti
d61f8667ae Change: Write dangerzone version and upgradecode into Package and SummaryInformation elements directly 2024-10-27 17:43:57 +02:00
JKarasti
4f97ed4177 Refactor: build_dir_xml() function
- rename for clarity
- remove unnecessary checks
2024-10-27 17:43:57 +02:00
JKarasti
9035497da3 Change: Wrap all files to be included in the .msi in a ComponentGroupRef
With this, all the files are organised into Components,
each of which points to a Directory defined in the StandardDirectory element.
This simplifies the Feature element considerable as only thing it needs to
include everything in the built msi is a reference to `ApplicationComponents`
2024-10-27 17:43:57 +02:00
JKarasti
ea3f4c88a5 Refactor: Simplify build_data() function
- Rename variables to be more clear about what they do:
- reorganise code
- simplify a few checks
2024-10-27 17:43:57 +02:00
JKarasti
a1dba4a098 Change: Swap Media element with MediaTemplate
This is a new default and makes authoring slightly simpler without any functional changes.
2024-10-27 17:43:56 +02:00
JKarasti
aab5bd08d7 Change: Convert Wix UI extension authoring to WiX Toolset v5
Due to limitations of the xml.etree.ElementTree library, add the items in the root element as a dictionary
2024-10-27 17:43:56 +02:00
JKarasti
965210dee5 Change: Wrap ProgramFilesFolder component with a StandardDirectory component 2024-10-27 17:43:56 +02:00
JKarasti
f7f81c5960 Change: Wrap ProgramMenuFolder component with a StandardDirectory component 2024-10-27 17:43:55 +02:00
JKarasti
8c26f3512b Change: Merge Product into Package element
- The Keywords and Description items move under a new SummaryInformation element.
- Shuffle things around so that elements previously under the product element are now under the Package element.
- Rename SummaryCodepage in SummaryInformation to Codepage and remove a duplicate Manufacturer item.
- Remove InstallerVersion and let WiX set it to default value. (500 a.k.a Windows 7)
2024-10-27 17:43:55 +02:00
JKarasti
3357b30edb Change: Rename INSTALLDIR to INSTALLFOLDER
It's the new default name for it
2024-10-27 17:43:55 +02:00
JKarasti
b2c085c812 Change: Update WiX schema namespace
Also rename `root_el` to `wix_el`.

WiX version 5 uses the same namespace.
2024-10-27 17:43:55 +02:00
JKarasti
6e2659bc0e Change: Stop generating an XML declaration at the top of the WiX authoring
It's not needed anymore.
2024-10-27 17:43:54 +02:00
JKarasti
99f231b46a Fix: Make generated WiX authoring pass WixCop checks
WixCop.exe is a built in formatting tool that comes with WiX toolset v3. This fixes `wix convert` command not beins able to run
2024-10-27 17:43:54 +02:00
JKarasti
a22d8443e8 Fix: SyntaxWarning while generating Dangerzone.wxs 2024-10-27 17:43:54 +02:00
15 changed files with 242 additions and 197 deletions

View file

@ -33,8 +33,6 @@ jobs:
version: "20.04"
- distro: ubuntu
version: "22.04"
- distro: ubuntu
version: "23.10"
- distro: ubuntu
version: "24.04"
- distro: ubuntu

View file

@ -23,8 +23,6 @@ jobs:
version: "24.10" # oracular
- distro: ubuntu
version: "24.04" # noble
- distro: ubuntu
version: "23.10" # mantic
- distro: ubuntu
version: "22.04" # jammy
- distro: ubuntu

View file

@ -110,10 +110,14 @@ jobs:
key: v1-tessdata-${{ hashFiles('./install/common/download-tessdata.py') }}
- name: Run CLI tests
run: poetry run make test
# Taken from: https://github.com/orgs/community/discussions/27149#discussioncomment-3254829
- name: Set path for candle and light
run: echo "C:\Program Files (x86)\WiX Toolset v3.14\bin" >> $GITHUB_PATH
shell: bash
- name: Set up .NET CLI environment
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.x"
- name: Install WiX Toolset
run: dotnet tool install --global wix --version 5.0.1
- name: Add WiX UI extension
run: wix extension add --global WixToolset.UI.wixext/5.0.1
- name: Build the MSI installer
# NOTE: This also builds the .exe internally.
run: poetry run .\install\windows\build-app.bat
@ -159,8 +163,6 @@ jobs:
version: "20.04"
- distro: ubuntu
version: "22.04"
- distro: ubuntu
version: "23.10"
- distro: ubuntu
version: "24.04"
- distro: ubuntu
@ -229,8 +231,6 @@ jobs:
version: "20.04"
- distro: ubuntu
version: "22.04"
- distro: ubuntu
version: "23.10"
- distro: ubuntu
version: "24.04"
- distro: ubuntu
@ -350,8 +350,6 @@ jobs:
version: "20.04"
- distro: ubuntu
version: "22.04"
- distro: ubuntu
version: "23.10"
- distro: ubuntu
version: "24.04"
- distro: ubuntu

View file

@ -13,7 +13,7 @@ jobs:
- name: Download container image for the latest release
run: |
VERSION=$(curl https://api.github.com/repos/freedomofpress/dangerzone/releases/latest | jq -r '.tag_name')
wget https://github.com/freedomofpress/dangerzone/releases/download/${VERSION}/container.tar.gz
wget https://github.com/freedomofpress/dangerzone/releases/download/${VERSION}/container-${VERSION}-i686.tar.gz -O container.tar.gz
- name: Load container image
run: docker load -i container.tar.gz
# NOTE: Scan first without failing, else we won't be able to read the scan

View file

@ -474,11 +474,22 @@ poetry shell
.\dev_scripts\dangerzone.bat
```
### If you want to build the installer
### If you want to build the Windows installer
* Go to https://dotnet.microsoft.com/download/dotnet-framework and download and install .NET Framework 3.5 SP1 Runtime. I downloaded `dotnetfx35.exe`.
* Go to https://wixtoolset.org/releases/ and download and install WiX toolset. I downloaded `wix314.exe`.
* Add `C:\Program Files (x86)\WiX Toolset v3.14\bin` to the path ([instructions](https://web.archive.org/web/20230221104142/https://windowsloop.com/how-to-add-to-windows-path/)).
Install [.NET SDK](https://dotnet.microsoft.com/en-us/download) version 6 or later. Then, open a terminal and install the [WiX Toolset .NET tool](https://wixtoolset.org/) v5.0.1.
```sh
dotnet tool install --global wix --version 5.0.1
```
Install the WiX UI extension **in a new terminal**, in order to use the newly installed `wix` .NET tool:
```sh
wix extension add --global WixToolset.UI.wixext/5.0.1
```
> [!IMPORTANT]
> To prevent compatibility issues, ensure that all WiX plugins you install match the version of WiX Toolset.
### If you want to sign binaries with Authenticode

View file

@ -11,7 +11,6 @@ an isolated environment. It will be installed automatically when installing Dang
Dangerzone is available for:
- Ubuntu 24.10 (oracular)
- Ubuntu 24.04 (noble)
- Ubuntu 23.10 (mantic)
- Ubuntu 22.04 (jammy)
- Ubuntu 20.04 (focal)
- Debian 13 (trixie)
@ -290,7 +289,7 @@ Our [GitHub Releases page](https://github.com/freedomofpress/dangerzone/releases
hosts the following files:
* Windows installer (`Dangerzone-<version>.msi`)
* macOS archives (`Dangerzone-<version>-<arch>.dmg`)
* Container image (`container.tar.gz`)
* Container images (`container-<version>-<arch>.tar.gz`)
* Source package (`dangerzone-<version>.tar.gz`)
All these files are accompanied by signatures (as `.asc` files). We'll explain
@ -315,10 +314,10 @@ gpg --verify Dangerzone-0.6.1-arm64.dmg.asc Dangerzone-0.6.1-arm64.dmg
gpg --verify Dangerzone-0.6.1-i686.dmg.asc Dangerzone-0.6.1-i686.dmg
```
For the container image:
For the container images:
```
gpg --verify container.tar.gz.asc container.tar.gz
gpg --verify container-0.6.1-i686.tar.gz.asc container-0.6.1-i686.tar.gz
```
For the source package:

View file

@ -285,6 +285,11 @@ Once we are confident that the release will be out shortly, and doesn't need any
* You can verify the correct Python version is used with `poetry debug info`
- [ ] Verify and checkout the git tag for this release
- [ ] Run `poetry install --sync`
- [ ] On the silicon mac, build the container image:
```
python3 ./install/common/build-image.py
```
Then copy the `share/container.tar.gz` to the assets folder on `dangerzone-$VERSION-arm64.tar.gz`, along with the `share/image-id.txt` file.
- [ ] Run `poetry run ./install/macos/build-app.py`; this will make `dist/Dangerzone.app`
- [ ] Make sure that the build application works with the containerd graph
driver (see [#933](https://github.com/freedomofpress/dangerzone/issues/933))
@ -403,6 +408,8 @@ Build the latest container:
python3 ./install/common/build-image.py
```
Copy the container image to the assets folder on `dangerzone-$VERSION-i686.tar.gz`.
Create a .rpm:
```sh
@ -449,9 +456,9 @@ To publish the release:
* Copy the release notes text from the template at [`docs/templates/release-notes`](https://github.com/freedomofpress/dangerzone/tree/main/docs/templates/)
* You can use `./dev_scripts/upload-asset.py`, if you want to upload an asset
using an access token.
- [ ] Upload the `container.tar.gz` i686 image that was created in the previous step
- [ ] Upload the `container-$VERSION-i686.tar.gz` and `container-$VERSION-arm64.tar.gz` images that were created in the previous step
**Important:** Make sure that it's the same container image as the ones that
**Important:** Make sure that it's the same container images as the ones that
are shipped in other platforms (see our [Pre-release](#Pre-release) section)
- [ ] Upload the detached signatures (.asc) and checksum file.

View file

@ -142,9 +142,6 @@ runsc_argv = [
"--rootless=true",
"--network=none",
"--root=/home/dangerzone/.containers",
# Disable DirectFS for to make the seccomp filter even stricter,
# at some performance cost.
"--directfs=false",
]
if os.environ.get("RUNSC_DEBUG"):
runsc_argv += ["--debug=true", "--alsologtostderr=true"]

View file

@ -696,8 +696,6 @@ class Env:
DOCKERFILE_CONMON_UPDATE + DOCKERFILE_BUILD_DEV_DEBIAN_DEPS
)
elif self.distro == "ubuntu" and self.version in (
"23.10",
"mantic",
"24.04",
"noble",
"24.10",
@ -784,8 +782,6 @@ class Env:
# package (see https://github.com/freedomofpress/dangerzone/issues/685)
install_deps = DOCKERFILE_CONMON_UPDATE + DOCKERFILE_BUILD_DEBIAN_DEPS
elif self.distro == "ubuntu" and self.version in (
"23.10",
"mantic",
"24.04",
"noble",
"24.10",

View file

@ -978,11 +978,6 @@ class QAUbuntu2204(QADebianBased):
VERSION = "22.04"
class QAUbuntu2310(QADebianBased):
DISTRO = "ubuntu"
VERSION = "23.10"
class QAUbuntu2404(QADebianBased):
DISTRO = "ubuntu"
VERSION = "24.04"

View file

@ -11,7 +11,8 @@ log = logging.getLogger(__name__)
DZ_ASSETS = [
"container.tar.gz",
"container-{version}-i686.tar.gz",
"container-{version}-arm64.tar.gz",
"Dangerzone-{version}.msi",
"Dangerzone-{version}-arm64.dmg",
"Dangerzone-{version}-i686.dmg",

View file

@ -17,22 +17,24 @@ signtool.exe sign /v /d "Dangerzone" /a /n "Freedom of the Press Foundation" /fd
REM verify the signature of dangerzone-cli.exe
signtool.exe verify /pa build\exe.win-amd64-3.12\dangerzone-cli.exe
REM build the wix file
python install\windows\build-wxs.py > build\Dangerzone.wxs
REM build the wxs file
python install\windows\build-wxs.py
REM build the msi package
cd build
candle.exe Dangerzone.wxs
light.exe -ext WixUIExtension Dangerzone.wixobj
wix build -arch x64 -ext WixToolset.UI.wixext .\Dangerzone.wxs -out Dangerzone.msi
REM validate Dangerzone.msi
wix msi validate Dangerzone.msi
REM code sign Dangerzone.msi
insignia.exe -im Dangerzone.msi
wix msi inscribe Dangerzone.msi
signtool.exe sign /v /d "Dangerzone" /a /n "Freedom of the Press Foundation" /fd sha256 /t http://time.certum.pl/ Dangerzone.msi
REM verify the signature of Dangerzone.msi
signtool.exe verify /pa Dangerzone.msi
REM moving Dangerzone.msi to dist
REM move Dangerzone.msi to dist
cd ..
mkdir dist
move build\Dangerzone.msi dist

View file

@ -4,114 +4,75 @@ import uuid
import xml.etree.ElementTree as ET
def build_data(dirname, dir_prefix, id_, name):
def build_data(base_path, path_prefix, dir_id, dir_name):
data = {
"id": id_,
"name": name,
"directory_name": dir_name,
"directory_id": dir_id,
"files": [],
"dirs": [],
}
for basename in os.listdir(dirname):
filename = os.path.join(dirname, basename)
if os.path.isfile(filename):
data["files"].append(os.path.join(dir_prefix, basename))
elif os.path.isdir(filename):
if id_ == "INSTALLDIR":
id_prefix = "Folder"
if dir_id == "INSTALLFOLDER":
data["component_id"] = "ApplicationFiles"
else:
data["component_id"] = "Component" + dir_id
data["component_guid"] = str(uuid.uuid4()).upper()
for entry in os.listdir(base_path):
entry_path = os.path.join(base_path, entry)
if os.path.isfile(entry_path):
data["files"].append(os.path.join(path_prefix, entry))
elif os.path.isdir(entry_path):
if dir_id == "INSTALLFOLDER":
next_dir_prefix = "Folder"
else:
id_prefix = id_
next_dir_prefix = dir_id
# Skip lib/PySide6/examples folder due to ilegal file names
if "\\build\\exe.win-amd64-3.12\\lib\\PySide6\\examples" in dirname:
if "\\build\\exe.win-amd64-3.12\\lib\\PySide6\\examples" in base_path:
continue
# Skip lib/PySide6/qml/QtQuick folder due to ilegal file names
# XXX Since we're not using Qml it should be no problem
if "\\build\\exe.win-amd64-3.12\\lib\\PySide6\\qml\\QtQuick" in dirname:
if "\\build\\exe.win-amd64-3.12\\lib\\PySide6\\qml\\QtQuick" in base_path:
continue
id_value = f"{id_prefix}{basename.capitalize().replace('-', '_')}"
data["dirs"].append(
build_data(
os.path.join(dirname, basename),
os.path.join(dir_prefix, basename),
id_value,
basename,
)
next_dir_id = next_dir_prefix + entry.capitalize().replace("-", "_")
subdata = build_data(
os.path.join(base_path, entry),
os.path.join(path_prefix, entry),
next_dir_id,
entry,
)
if len(data["files"]) > 0:
if id_ == "INSTALLDIR":
data["component_id"] = "ApplicationFiles"
else:
data["component_id"] = "FolderComponent" + id_[len("Folder") :]
data["component_guid"] = str(uuid.uuid4())
# Add the subdirectory only if it contains files or subdirectories
if subdata["files"] or subdata["dirs"]:
data["dirs"].append(subdata)
return data
def build_dir_xml(root, data):
def build_directory_xml(root, data):
attrs = {}
if "id" in data:
attrs["Id"] = data["id"]
if "name" in data:
attrs["Name"] = data["name"]
el = ET.SubElement(root, "Directory", attrs)
attrs["Id"] = data["directory_id"]
attrs["Name"] = data["directory_name"]
directory_el = ET.SubElement(root, "Directory", attrs)
for subdata in data["dirs"]:
build_dir_xml(el, subdata)
# If this is the ProgramMenuFolder, add the menu component
if "id" in data and data["id"] == "ProgramMenuFolder":
component_el = ET.SubElement(
el,
"Component",
Id="ApplicationShortcuts",
Guid="539e7de8-a124-4c09-aa55-0dd516aad7bc",
)
ET.SubElement(
component_el,
"Shortcut",
Id="ApplicationShortcut1",
Name="Dangerzone",
Description="Dangerzone",
Target="[INSTALLDIR]dangerzone.exe",
WorkingDirectory="INSTALLDIR",
)
ET.SubElement(
component_el,
"RegistryValue",
Root="HKCU",
Key="Software\Freedom of the Press Foundation\Dangerzone",
Name="installed",
Type="integer",
Value="1",
KeyPath="yes",
)
build_directory_xml(directory_el, subdata)
def build_components_xml(root, data):
component_ids = []
if "component_id" in data:
component_ids.append(data["component_id"])
component_el = ET.SubElement(
root,
"Component",
Id=data["component_id"],
Guid=data["component_guid"],
Directory=data["directory_id"],
)
for filename in data["files"]:
ET.SubElement(component_el, "File", Source=filename)
for subdata in data["dirs"]:
if "component_guid" in subdata:
dir_ref_el = ET.SubElement(root, "DirectoryRef", Id=subdata["id"])
component_el = ET.SubElement(
dir_ref_el,
"Component",
Id=subdata["component_id"],
Guid=subdata["component_guid"],
)
for filename in subdata["files"]:
file_el = ET.SubElement(
component_el, "File", Source=filename, Id="file_" + uuid.uuid4().hex
)
component_ids += build_components_xml(root, subdata)
return component_ids
build_components_xml(root, subdata)
def main():
@ -123,122 +84,200 @@ def main():
with open(version_filename) as f:
# Read the Dangerzone version from share/version.txt, and remove any potential
# -rc markers.
version = f.read().strip().split("-")[0]
dangerzone_version = f.read().strip().split("-")[0]
dist_dir = os.path.join(
dangerzone_product_upgrade_code = "12B9695C-965B-4BE0-BC33-21274E809576"
build_dir = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
"build",
"exe.win-amd64-3.12",
)
cx_freeze_dir = "exe.win-amd64-3.12"
dist_dir = os.path.join(build_dir, cx_freeze_dir)
if not os.path.exists(dist_dir):
print("You must build the dangerzone binary before running this")
return
data = {
"id": "TARGETDIR",
"name": "SourceDir",
"dirs": [
{
"id": "ProgramFilesFolder",
"dirs": [],
},
{
"id": "ProgramMenuFolder",
"dirs": [],
},
],
}
data["dirs"][0]["dirs"].append(
build_data(
dist_dir,
"exe.win-amd64-3.12",
"INSTALLDIR",
"Dangerzone",
)
# Prepare data for WiX file harvesting from the output of cx_Freeze
data = build_data(
dist_dir,
cx_freeze_dir,
"INSTALLFOLDER",
"Dangerzone",
)
root_el = ET.Element("Wix", xmlns="http://schemas.microsoft.com/wix/2006/wi")
product_el = ET.SubElement(
root_el,
"Product",
# Add the Wix root element
wix_el = ET.Element(
"Wix",
{
"xmlns": "http://wixtoolset.org/schemas/v4/wxs",
"xmlns:ui": "http://wixtoolset.org/schemas/v4/wxs/ui",
},
)
# Add the Package element
package_el = ET.SubElement(
wix_el,
"Package",
Name="Dangerzone",
Manufacturer="Freedom of the Press Foundation",
Id="*",
UpgradeCode="$(var.ProductUpgradeCode)",
UpgradeCode=dangerzone_product_upgrade_code,
Language="1033",
Codepage="1252",
Version="$(var.ProductVersion)",
)
ET.SubElement(
product_el,
"Package",
Id="*",
Keywords="Installer",
Description="Dangerzone $(var.ProductVersion) Installer",
Manufacturer="Freedom of the Press Foundation",
InstallerVersion="100",
Languages="1033",
Compressed="yes",
SummaryCodepage="1252",
Codepage="1252",
Version=dangerzone_version,
)
ET.SubElement(product_el, "Media", Id="1", Cabinet="product.cab", EmbedCab="yes")
ET.SubElement(
product_el, "Icon", Id="ProductIcon", SourceFile="..\\share\\dangerzone.ico"
package_el,
"SummaryInformation",
Keywords="Installer",
Description="Dangerzone " + dangerzone_version + " Installer",
Codepage="1252",
)
ET.SubElement(product_el, "Property", Id="ARPPRODUCTICON", Value="ProductIcon")
ET.SubElement(package_el, "MediaTemplate", EmbedCab="yes")
ET.SubElement(
product_el,
package_el, "Icon", Id="ProductIcon", SourceFile="..\\share\\dangerzone.ico"
)
ET.SubElement(package_el, "Property", Id="ARPPRODUCTICON", Value="ProductIcon")
ET.SubElement(
package_el,
"Property",
Id="ARPHELPLINK",
Value="https://dangerzone.rocks",
)
ET.SubElement(
product_el,
package_el,
"Property",
Id="ARPURLINFOABOUT",
Value="https://freedom.press",
)
ui_el = ET.SubElement(package_el, "UI")
ET.SubElement(
product_el,
"Property",
Id="WIXUI_INSTALLDIR",
Value="INSTALLDIR",
ui_el, "ui:WixUI", Id="WixUI_InstallDir", InstallDirectory="INSTALLFOLDER"
)
ET.SubElement(product_el, "UIRef", Id="WixUI_InstallDir")
ET.SubElement(product_el, "UIRef", Id="WixUI_ErrorProgressText")
ET.SubElement(ui_el, "UIRef", Id="WixUI_ErrorProgressText")
# Workaround for an issue after upgrading from WiX Toolset 3 to 5 where the older
# version of Dangerzone is not uninstalled during the upgrade
#
# Work around the issue by adding some extra functionality to the "Next" button on the welcome screen
# of the installer. When the user clicks it to proceed with the installation this:
# 1. Flips the install scope to "perUser" which is the default in WiX 3
# 2. Finds the older installation
# 3. And finally flips the scope back to "perMachine" which is the default in WiX 4 and newer
#
# Adapted from this stack overflow answer: https://stackoverflow.com/a/35064434
#
# TODO: Revert this once we are reasonably certain there are no affected Dangerzone Installations?
ET.SubElement(
product_el,
ui_el,
"Publish",
Dialog="WelcomeDlg",
Control="Next",
Property="ALLUSERS",
Value="{}",
)
ET.SubElement(
ui_el,
"Publish",
Dialog="WelcomeDlg",
Control="Next",
Event="DoAction",
Value="FindRelatedProducts",
)
ET.SubElement(
ui_el,
"Publish",
Dialog="WelcomeDlg",
Control="Next",
Property="ALLUSERS",
Value="1",
)
ET.SubElement(
package_el,
"WixVariable",
Id="WixUILicenseRtf",
Value="..\\install\\windows\\license.rtf",
)
ET.SubElement(
product_el,
package_el,
"WixVariable",
Id="WixUIDialogBmp",
Value="..\\install\\windows\\dialog.bmp",
)
ET.SubElement(
product_el,
package_el,
"MajorUpgrade",
AllowSameVersionUpgrades="yes",
DowngradeErrorMessage="A newer version of [ProductName] is already installed. If you are sure you want to downgrade, remove the existing installation via Programs and Features.",
)
build_dir_xml(product_el, data)
component_ids = build_components_xml(product_el, data)
# Add the ProgramMenuFolder StandardDirectory
programmenufolder_el = ET.SubElement(
package_el,
"StandardDirectory",
Id="ProgramMenuFolder",
)
feature_el = ET.SubElement(product_el, "Feature", Id="DefaultFeature", Level="1")
for component_id in component_ids:
ET.SubElement(feature_el, "ComponentRef", Id=component_id)
shortcut_el = ET.SubElement(
programmenufolder_el,
"Component",
Id="ApplicationShortcuts",
Guid="539E7DE8-A124-4C09-AA55-0DD516AAD7BC",
)
ET.SubElement(
shortcut_el,
"Shortcut",
Id="DangerzoneStartMenuShortcut",
Name="Dangerzone",
Description="Dangerzone",
Target="[INSTALLFOLDER]dangerzone.exe",
WorkingDirectory="INSTALLFOLDER",
)
ET.SubElement(
shortcut_el,
"RegistryValue",
Root="HKCU",
Key="Software\\Freedom of the Press Foundation\\Dangerzone",
Name="installed",
Type="integer",
Value="1",
KeyPath="yes",
)
# Add the ProgramFilesFolder StandardDirectory
programfilesfolder_el = ET.SubElement(
package_el,
"StandardDirectory",
Id="ProgramFiles64Folder",
)
# Generate the directory layout for the installed product
build_directory_xml(programfilesfolder_el, data)
applicationcomponents_el = ET.SubElement(
package_el, "ComponentGroup", Id="ApplicationComponents"
)
# Generate the components for the installed product
build_components_xml(applicationcomponents_el, data)
# Add the Feature element
feature_el = ET.SubElement(package_el, "Feature", Id="DefaultFeature", Level="1")
ET.SubElement(feature_el, "ComponentGroupRef", Id="ApplicationComponents")
ET.SubElement(feature_el, "ComponentRef", Id="ApplicationShortcuts")
print('<?xml version="1.0" encoding="windows-1252"?>')
print(f'<?define ProductVersion = "{version}"?>')
print('<?define ProductUpgradeCode = "12b9695c-965b-4be0-bc33-21274e809576"?>')
ET.indent(root_el)
print(ET.tostring(root_el).decode())
ET.indent(wix_el, space=" ")
with open(os.path.join(build_dir, "Dangerzone.wxs"), "w") as wxs_file:
wxs_file.write(ET.tostring(wix_el).decode())
if __name__ == "__main__":

View file

@ -4,7 +4,6 @@ from cx_Freeze import Executable, setup
with open("share/version.txt") as f:
version = f.read().strip()
packages = ["dangerzone", "dangerzone.gui"]
setup(
name="dangerzone",
@ -12,10 +11,13 @@ setup(
# On Windows description will show as the app's name in the "Open With" menu. See:
# https://github.com/freedomofpress/dangerzone/issues/283#issuecomment-1365148805
description="Dangerzone",
packages=packages,
options={
"build_exe": {
"packages": packages,
# Explicitly specify pymupdf.util module to fix building the executables
# with cx_freeze. See https://github.com/marcelotduarte/cx_Freeze/issues/2653
# for more details.
# TODO: Upgrade to cx_freeze 7.3.0 which should include a fix.
"packages": ["dangerzone", "dangerzone.gui", "pymupdf.utils"],
"excludes": ["test", "tkinter"],
"include_files": [("share", "share"), ("LICENSE", "LICENSE")],
"include_msvcr": True,

View file

@ -164,6 +164,7 @@ class IsolationProviderTermination:
terminate_proc_mock = mocker.patch.object(
provider, "terminate_doc_to_pixels_proc", return_value=None
)
kill_pg_orig = base.kill_process_group
kill_pg_mock = mocker.patch(
"dangerzone.isolation_provider.base.kill_process_group", return_value=None
)
@ -178,6 +179,7 @@ class IsolationProviderTermination:
# Reset the function to the original state.
provider.terminate_doc_to_pixels_proc = terminate_proc_orig # type: ignore [method-assign]
base.kill_process_group = kill_pg_orig
# Really kill the spawned process, so that it doesn't linger after the tests
# complete.