mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 09:52:37 +02:00

Some checks are pending
Build dev environments / Build dev-env (debian-bookworm) (push) Waiting to run
Build dev environments / Build dev-env (debian-bullseye) (push) Waiting to run
Build dev environments / Build dev-env (debian-trixie) (push) Waiting to run
Build dev environments / Build dev-env (fedora-40) (push) Waiting to run
Build dev environments / Build dev-env (fedora-41) (push) Waiting to run
Build dev environments / Build dev-env (fedora-42) (push) Waiting to run
Build dev environments / Build dev-env (ubuntu-22.04) (push) Waiting to run
Build dev environments / Build dev-env (ubuntu-24.04) (push) Waiting to run
Build dev environments / Build dev-env (ubuntu-24.10) (push) Waiting to run
Build dev environments / Build dev-env (ubuntu-25.04) (push) Waiting to run
Build dev environments / build-container-image (push) Waiting to run
Tests / run tests (fedora 42) (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
Tests / run tests (ubuntu 25.04) (push) Blocked by required conditions
Tests / build-deb (ubuntu 22.04) (push) Blocked by required conditions
Tests / run-lint (push) Waiting to run
Tests / build-container-image (push) Waiting to run
Tests / Download and cache Tesseract data (push) Waiting to run
Tests / windows (push) Blocked by required conditions
Tests / macOS (arch64) (push) Blocked by required conditions
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 24.04) (push) Blocked by required conditions
Tests / build-deb (ubuntu 24.10) (push) Blocked by required conditions
Tests / build-deb (ubuntu 25.04) (push) Blocked by required conditions
Tests / install-deb (debian bookworm) (push) Blocked by required conditions
Tests / build-install-rpm (fedora 42) (push) Blocked by required conditions
Tests / run tests (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 22.04) (push) Blocked by required conditions
Tests / install-deb (ubuntu 24.04) (push) Blocked by required conditions
Tests / run tests (debian bullseye) (push) Blocked by required conditions
Tests / install-deb (ubuntu 24.10) (push) Blocked by required conditions
Tests / install-deb (ubuntu 25.04) (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 trixie) (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
Release multi-arch container image / build-push-image (push) Waiting to run
Scan latest app and container / security-scan-container (ubuntu-24.04) (push) Waiting to run
Scan latest app and container / security-scan-container (ubuntu-24.04-arm) (push) Waiting to run
Scan latest app and container / security-scan-app (ubuntu-24.04) (push) Waiting to run
Scan latest app and container / security-scan-app (ubuntu-24.04-arm) (push) Waiting to run
Refs #1026
282 lines
9.2 KiB
Python
282 lines
9.2 KiB
Python
#!/usr/bin/env python3
|
|
import os
|
|
import uuid
|
|
import xml.etree.ElementTree as ET
|
|
|
|
|
|
def build_data(base_path, path_prefix, dir_id, dir_name):
|
|
data = {
|
|
"directory_name": dir_name,
|
|
"directory_id": dir_id,
|
|
"files": [],
|
|
"dirs": [],
|
|
}
|
|
|
|
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:
|
|
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 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 base_path:
|
|
continue
|
|
|
|
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,
|
|
)
|
|
|
|
# Add the subdirectory only if it contains files or subdirectories
|
|
if subdata["files"] or subdata["dirs"]:
|
|
data["dirs"].append(subdata)
|
|
|
|
return data
|
|
|
|
|
|
def build_directory_xml(root, data):
|
|
attrs = {}
|
|
attrs["Id"] = data["directory_id"]
|
|
attrs["Name"] = data["directory_name"]
|
|
directory_el = ET.SubElement(root, "Directory", attrs)
|
|
for subdata in data["dirs"]:
|
|
build_directory_xml(directory_el, subdata)
|
|
|
|
|
|
def build_components_xml(root, data):
|
|
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"]:
|
|
build_components_xml(root, subdata)
|
|
|
|
|
|
def main():
|
|
version_filename = os.path.join(
|
|
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
|
|
"share",
|
|
"version.txt",
|
|
)
|
|
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]
|
|
|
|
build_dir = os.path.join(
|
|
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
|
|
"build",
|
|
)
|
|
|
|
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
|
|
|
|
# Prepare data for WiX file harvesting from the output of cx_Freeze
|
|
data = build_data(
|
|
dist_dir,
|
|
cx_freeze_dir,
|
|
"INSTALLFOLDER",
|
|
"Dangerzone",
|
|
)
|
|
|
|
# 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",
|
|
UpgradeCode="12B9695C-965B-4BE0-BC33-21274E809576",
|
|
Language="1033",
|
|
Compressed="yes",
|
|
Codepage="1252",
|
|
Version=version,
|
|
)
|
|
ET.SubElement(
|
|
package_el,
|
|
"SummaryInformation",
|
|
Keywords="Installer",
|
|
Description="Dangerzone " + version + " Installer",
|
|
Codepage="1252",
|
|
)
|
|
ET.SubElement(package_el, "MediaTemplate", EmbedCab="yes")
|
|
ET.SubElement(
|
|
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(
|
|
package_el,
|
|
"Property",
|
|
Id="ARPURLINFOABOUT",
|
|
Value="https://freedom.press",
|
|
)
|
|
ET.SubElement(
|
|
package_el, "ui:WixUI", Id="WixUI_InstallDir", InstallDirectory="INSTALLFOLDER"
|
|
)
|
|
ET.SubElement(package_el, "UIRef", Id="WixUI_ErrorProgressText")
|
|
ET.SubElement(
|
|
package_el,
|
|
"WixVariable",
|
|
Id="WixUILicenseRtf",
|
|
Value="..\\install\\windows\\license.rtf",
|
|
)
|
|
ET.SubElement(
|
|
package_el,
|
|
"WixVariable",
|
|
Id="WixUIDialogBmp",
|
|
Value="..\\install\\windows\\dialog.bmp",
|
|
)
|
|
ET.SubElement(
|
|
package_el,
|
|
"MajorUpgrade",
|
|
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.",
|
|
)
|
|
|
|
# Workaround for an issue after upgrading from WiX Toolset v3 to v5 where the previous
|
|
# version of Dangerzone is not uninstalled during the upgrade by checking if the older installation
|
|
# exists in "C:\Program Files (x86)\Dangerzone".
|
|
#
|
|
# Also handle a special case for Dangerzone 0.8.0 which allows choosing the install location
|
|
# during install by checking if the registry key for it exists.
|
|
#
|
|
# Note that this seems to allow installing Dangerzone 0.8.0 after installing Dangerzone from this branch.
|
|
# In this case the installer errors until Dangerzone 0.8.0 is uninstalled again
|
|
#
|
|
# TODO: Revert this once we are reasonably certain there aren't too many affected Dangerzone installations.
|
|
find_old_el = ET.SubElement(package_el, "Property", Id="OLDDANGERZONEFOUND")
|
|
directory_search_el = ET.SubElement(
|
|
find_old_el,
|
|
"DirectorySearch",
|
|
Id="dangerzone_install_folder",
|
|
Path="C:\\Program Files (x86)\\Dangerzone",
|
|
)
|
|
ET.SubElement(directory_search_el, "FileSearch", Name="dangerzone.exe")
|
|
registry_search_el = ET.SubElement(package_el, "Property", Id="DANGERZONE08FOUND")
|
|
ET.SubElement(
|
|
registry_search_el,
|
|
"RegistrySearch",
|
|
Root="HKLM",
|
|
Key="SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{03C2D2B2-9955-4AED-831F-DA4E67FC0FDB}",
|
|
Name="DisplayName",
|
|
Type="raw",
|
|
)
|
|
ET.SubElement(
|
|
registry_search_el,
|
|
"RegistrySearch",
|
|
Root="HKLM",
|
|
Key="SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{8AAC0808-3556-4164-9D15-6EC1FB673AB2}",
|
|
Name="DisplayName",
|
|
Type="raw",
|
|
)
|
|
ET.SubElement(
|
|
package_el,
|
|
"Launch",
|
|
Condition="NOT OLDDANGERZONEFOUND AND NOT DANGERZONE08FOUND",
|
|
Message='A previous version of [ProductName] is already installed. Please uninstall it from "Apps & Features" before proceeding with the installation.',
|
|
)
|
|
|
|
# Add the ProgramMenuFolder StandardDirectory
|
|
programmenufolder_el = ET.SubElement(
|
|
package_el,
|
|
"StandardDirectory",
|
|
Id="ProgramMenuFolder",
|
|
)
|
|
# Add a shortcut for Dangerzone in the Start menu
|
|
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",
|
|
)
|
|
|
|
# Create the directory structure for the installed product
|
|
build_directory_xml(programfilesfolder_el, data)
|
|
|
|
# Create a component group for application components
|
|
applicationcomponents_el = ET.SubElement(
|
|
package_el, "ComponentGroup", Id="ApplicationComponents"
|
|
)
|
|
# Populate the application components group with components for the installed package
|
|
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")
|
|
|
|
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__":
|
|
main()
|