diff --git a/cmake/MakePortableZip.cmake b/cmake/MakePortableZip.cmake new file mode 100644 index 000000000..6f873c5d5 --- /dev/null +++ b/cmake/MakePortableZip.cmake @@ -0,0 +1,3 @@ +if (CMAKE_INSTALL_PREFIX MATCHES "/ZIP/") + file(TOUCH "${CMAKE_INSTALL_PREFIX}/.portable") +endif() diff --git a/release-tool b/release-tool index b838f8753..afc3229b3 100755 --- a/release-tool +++ b/release-tool @@ -1014,17 +1014,6 @@ build() { # release. cpack -G "${CPACK_GENERATORS};${build_generators}" - # Inject the portable config into the zip build and rename - touch .portable - for filename in ${APP_NAME}-*.zip; do - logInfo "Creating portable zip file" - local folder=$(echo ${filename} | sed -r 's/(.*)\.zip/\1/') - python -c 'import zipfile,sys ; zipfile.ZipFile(sys.argv[1],"a").write(sys.argv[2],sys.argv[3])' \ - ${filename} .portable ${folder}/.portable - mv ${filename} ${folder}-portable.zip - done - rm .portable - mv "${APP_NAME}-"*.* ../ else mkdir -p "${OUTPUT_DIR}/KeePassXC.AppDir" diff --git a/release-tool.ps1 b/release-tool.ps1 new file mode 100644 index 000000000..fda7ff891 --- /dev/null +++ b/release-tool.ps1 @@ -0,0 +1,540 @@ +<# +.SYNOPSIS +KeePassXC Release Tool + +.DESCRIPTION +Commands: + merge Merge release branch into main branch and create release tags + build Build and package binary release from sources + sign Sign previously compiled release packages + +.NOTES +The following are descriptions of certain parameters: + -Vcpkg Specify VCPKG toolchain file (example: C:\vcpkg\scripts\buildsystems\vcpkg.cmake) + -Tag Release tag to check out (defaults to version number) + -Snapshot Build current HEAD without checkout out Tag + -CMakeGenerator Override the default CMake generator + -CMakeOptions Additional CMake options for compiling the sources + -CPackGenerators Set CPack generators (default: WIX;ZIP) + -Compiler Compiler to use (example: g++, clang, msbuild) + -MakeOptions Options to pass to the make program + -SignBuild Perform platform specific App Signing before packaging + -SignKey Specify the App Signing Key/Identity + -TimeStamp Explicitly set the timestamp server to use for appsign + -SourceBranch Source branch to merge from (default: 'release/$Version') + -TargetBranch Target branch to merge to (default: master) + -VSToolChain Specify Visual Studio Toolchain by name if more than one is available +#> + +param( + [Parameter(ParameterSetName = "merge", Mandatory, Position = 0)] + [switch] $Merge, + [Parameter(ParameterSetName = "build", Mandatory, Position = 0)] + [switch] $Build, + [Parameter(ParameterSetName = "sign", Mandatory, Position = 0)] + [switch] $Sign, + + [Parameter(ParameterSetName = "merge", Mandatory, Position = 1)] + [Parameter(ParameterSetName = "build", Mandatory, Position = 1)] + [Parameter(ParameterSetName = "sign", Mandatory, Position = 1)] + [ValidatePattern("^[0-9]\.[0-9]\.[0-9]$")] + [string] $Version, + + [Parameter(ParameterSetName = "build", Mandatory)] + [string] $Vcpkg, + + [Parameter(ParameterSetName = "sign", Mandatory)] + [SupportsWildcards()] + [string[]] $SignFiles, + + # [Parameter(ParameterSetName = "build")] + # [switch] $DryRun, + [Parameter(ParameterSetName = "build")] + [switch] $Snapshot, + [Parameter(ParameterSetName = "build")] + [switch] $SignBuild, + + [Parameter(ParameterSetName = "build")] + [string] $CMakeGenerator = "Ninja", + [Parameter(ParameterSetName = "build")] + [string] $CMakeOptions, + [Parameter(ParameterSetName = "build")] + [string] $CPackGenerators = "WIX;ZIP", + [Parameter(ParameterSetName = "build")] + [string] $Compiler, + [Parameter(ParameterSetName = "build")] + [string] $MakeOptions, + [Parameter(ParameterSetName = "build")] + [Parameter(ParameterSetName = "sign")] + [string] $SignKey, + [Parameter(ParameterSetName = "build")] + [Parameter(ParameterSetName = "sign")] + [string] $Timestamp = "http://timestamp.sectigo.com", + [Parameter(ParameterSetName = "merge")] + [Parameter(ParameterSetName = "build")] + [Parameter(ParameterSetName = "sign")] + [string] $GpgKey = "CFB4C2166397D0D2", + [Parameter(ParameterSetName = "merge")] + [Parameter(ParameterSetName = "build")] + [string] $SourceDir = ".", + [Parameter(ParameterSetName = "build")] + [string] $OutDir = ".\release", + [Parameter(ParameterSetName = "merge")] + [Parameter(ParameterSetName = "build")] + [string] $Tag, + [Parameter(ParameterSetName = "merge")] + [string] $SourceBranch, + [Parameter(ParameterSetName = "merge")] + [string] $TargetBranch = "master", + [Parameter(ParameterSetName = "build")] + [string] $VSToolChain, + [Parameter(ParameterSetName = "merge")] + [Parameter(ParameterSetName = "build")] + [Parameter(ParameterSetName = "sign")] + [string] $ExtraPath +) + +# Helper function definitions +function Test-RequiredPrograms { + # If any of these fail they will throw an exception terminating the script + if ($Build) { + Get-Command git | Out-Null + Get-Command cmake | Out-Null + } + if ($Merge) { + Get-Command git | Out-Null + Get-Command tx | Out-Null + Get-Command lupdate | Out-Null + } + if ($Sign -or $SignBuild) { + if ($SignKey.Length) { + Get-Command signtool | Out-Null + } + Get-Command gpg | Out-Null + } +} + +function Test-VersionInFiles { + # Check CMakeLists.txt + $Major, $Minor, $Patch = $Version.split(".", 3) + if (!(Select-String "$SourceDir\CMakeLists.txt" -pattern "KEEPASSXC_VERSION_MAJOR `"$Major`"" -Quiet) ` + -or !(Select-String "$SourceDir\CMakeLists.txt" -pattern "KEEPASSXC_VERSION_MINOR `"$Minor`"" -Quiet) ` + -or !(Select-String "$SourceDir\CMakeLists.txt" -pattern "KEEPASSXC_VERSION_PATCH `"$Patch`"" -Quiet)) { + throw "CMakeLists.txt has not been updated to $Version." + } + + # Check Changelog + if (!(Select-String "$SourceDir\CHANGELOG.md" -pattern "^## $Version \(\d{4}-\d{2}-\d{2}\)$" -Quiet)) { + throw "CHANGELOG.md does not contain a section for $Version." + } + + # Check AppStreamInfo + if (!(Select-String "$SourceDir\share\linux\org.keepassxc.KeePassXC.appdata.xml" ` + -pattern "" -Quiet)) { + throw "share/linux/org.keepassxc.KeePassXC.appdata.xml does not contain a section for $Version." + } + + # Check Snapcraft + if (!(Select-String "$SourceDir\snap\snapcraft.yaml" -pattern "version: $Version" -Quiet)) { + throw "snap/snapcraft.yaml has not been updated to $Version." + } +} + +function Test-WorkingTreeClean { + & git diff-index --quiet HEAD -- + if ($LASTEXITCODE) { + throw "Current working tree is not clean! Please commit or unstage any changes." + } +} + +function Invoke-VSToolchain([String] $Toolchain, [String] $Path, [String] $Arch) { + # Find Visual Studio installations + $vs = Get-CimInstance MSFT_VSInstance + if ($vs.count -eq 0) { + $err = "No Visual Studio installations found, download one from https://visualstudio.com/downloads." + $err = "$err`nIf Visual Studio is installed, you may need to repair the install then restart." + throw $err + } + + $VSBaseDir = $vs[0].InstallLocation + if ($Toolchain) { + # Try to find the specified toolchain by name + foreach ($_ in $vs) { + if ($_.Name -eq $Toolchain) { + $VSBaseDir = $_.InstallLocation + break + } + } + } elseif ($vs.count -gt 1) { + # Ask the user which install to use + $i = 0 + foreach ($_ in $vs) { + $i = $i + 1 + $i.ToString() + ") " + $_.Name | Write-Host + } + $i = Read-Host -Prompt "Which Visual Studio installation do you want to use?" + $i = [Convert]::ToInt32($i, 10) - 1 + if ($i -lt 0 -or $i -ge $vs.count) { + throw "Invalid selection made" + } + $VSBaseDir = $vs[$i].InstallLocation + } + + # Bootstrap the specified VS Toolchain + Import-Module "$VSBaseDir\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" + Enter-VsDevShell -VsInstallPath $VSBaseDir -Arch $Arch -StartInPath $Path | Write-Host + Write-Host # Newline after command output +} + +function Invoke-Cmd([string] $command, [string[]] $options = @(), [switch] $maskargs, [switch] $quiet) { + $call = ('{0} {1}' -f $command, ($options -Join ' ')) + if ($maskargs) { + Write-Host "$command " -ForegroundColor DarkGray + } + else { + Write-Host $call -ForegroundColor DarkGray + } + if ($quiet) { + Invoke-Expression $call > $null + } else { + Invoke-Expression $call + } + if ($LASTEXITCODE -ne 0) { + throw "Failed to run command: {0}" -f $command + } + Write-Host #insert newline after command output +} + +function Invoke-SignFiles([string[]] $files, [string] $key, [string] $time) { + if (!(Test-Path -Path "$key" -PathType leaf)) { + throw "Appsign key file was not found! ($key)" + } + if ($files.Length -eq 0) { + return + } + + Write-Host "Signing files using $key" -ForegroundColor Cyan + $KeyPassword = Read-Host "Key password: " -MaskInput + + foreach ($_ in $files) { + Write-Host "Signing file '$_' using Microsoft signtool..." + Invoke-Cmd "signtool" "sign -f `"$key`" -p `"$KeyPassword`" -d `"KeePassXC`" -td sha256 -fd sha256 -tr `"$time`" `"$_`"" -maskargs + } +} + +function Invoke-GpgSignFiles([string[]] $files, [string] $key) { + if ($files.Length -eq 0) { + return + } + + Write-Host "Signing files using GPG key $key" -ForegroundColor Cyan + + foreach ($_ in $files) { + Write-Host "Signing file '$_' and creating DIGEST..." + Remove-Item "$_.sig" + Invoke-Cmd "gpg" "--output `"$_.sig`" --armor --local-user `"$key`" --detach-sig `"$_`"" + $FileName = (Get-Item $_).Name + (Get-FileHash "$_" SHA256).Hash + " *$FileName" | Out-File "$_.DIGEST" -NoNewline + } +} + + +# Handle errors and restore state +$OrigDir = (Get-Location).Path +$OrigBranch = & git rev-parse --abbrev-ref HEAD +$ErrorActionPreference = 'Stop' +trap { + Write-Host "Restoring state..." -ForegroundColor Yellow + & git checkout $OrigBranch + Set-Location "$OrigDir" +} + +Write-Host "KeePassXC Release Preparation Helper" -ForegroundColor Green +Write-Host "Copyright (C) 2022 KeePassXC Team `n" -ForegroundColor Green + +# Prepend extra PATH locations as specified +if ($ExtraPath) { + $env:Path = "$ExtraPath;$env:Path" +} + +# Resolve absolute directory for paths +$SourceDir = (Resolve-Path $SourceDir).Path + +# Check format of -Version +if ($Version -notmatch "^\d+\.\d+\.\d+$") { + throw "Invalid format for -Version input" +} + +# Check platform +if (!$IsWindows) { + throw "The PowerShell release tool is not available for Linux or macOS at this time." +} + +if ($Merge) { + Test-RequiredPrograms + + # Change to SourceDir + Set-Location "$SourceDir" + + Test-VersionInFiles + Test-WorkingTreeClean + + if (!$SourceBranch.Length) { + $SourceBranch = & git branch --show-current + } + + if ($SourceBranch -notmatch "^release/.*|develop$") { + throw "Must be on develop or a release/* branch to continue merging." + } + + # Update translation files + Write-Host "Updating source translation file..." + Invoke-Cmd "lupdate" "-no-ui-lines -disable-heuristic similartext -locations none", ` + "-no-obsolete ./src -ts share/translations/keepassxc_en.ts" + + Write-Host "Pulling updated translations from Transifex..." + Invoke-Cmd "tx" "pull -af --minimum-perc=60 --parallel -r keepassxc.share-translations-keepassxc-en-ts--develop" + + # Only commit if there are changes + & git diff-index --quiet HEAD -- + if ($LASTEXITCODE) { + Write-Host "Committing translation updates..." + Invoke-Cmd "git" "add -A ./share/translations/" -quiet + Invoke-Cmd "git" "commit -m `"Update translations`"" -quiet + } + + # Read the version release notes from CHANGELOG + $Changelog = "" + $ReadLine = $false + Get-Content "CHANGELOG.md" | ForEach-Object { + if ($ReadLine) { + if ($_ -match "^## ") { + $ReadLine = $false + } else { + $Changelog += $_ + "`n" + } + } elseif ($_ -match "$Version \(\d{4}-\d{2}-\d{2}\)") { + $ReadLine = $true + } + } + + Write-Host "Checking out target branch '$TargetBranch'..." + Invoke-Cmd "git" "checkout `"$TargetBranch`"" -quiet + + Write-Host "Merging '$SourceBranch' into '$TargetBranch'..." + Invoke-Cmd "git" "merge `"$SourceBranch`" --no-ff -m `"Release $Version`" -m `"$Changelog`" `"$SourceBranch`" -S" -quiet + + Write-Host "Creating tag for '$Version'..." + Invoke-Cmd "git" "tag -a `"$Version`" -m `"Release $Version`" -m `"$Changelog`" -s" -quiet + + Write-Host "All done!" + Write-Host "Please merge the release branch back into the develop branch now and then push your changes." + Write-Host "Don't forget to also push the tags using 'git push --tags'." +} elseif ($Build) { + $OutDir = (Resolve-Path $OutDir).Path + $BuildDir = "$OutDir\build-release" + $Vcpkg = (Resolve-Path $Vcpkg).Path + + # Find Visual Studio and establish build environment + Invoke-VSToolchain $VSToolChain $SourceDir -Arch "amd64" + + Test-RequiredPrograms + + if ($Snapshot) { + $Tag = "HEAD" + $SourceBranch = & git rev-parse --abbrev-ref HEAD + $ReleaseName = "$Version-snapshot" + $CMakeOptions = "$CMakeOptions -DKEEPASSXC_BUILD_TYPE=Snapshot -DOVERRIDE_VERSION=`"$ReleaseName`"" + Write-Host "Using current branch '$SourceBranch' to build." -ForegroundColor Cyan + } else { + Test-WorkingTreeClean + + # Clear output directory + if (Test-Path $OutDir) { + Remove-Item $OutDir -Recurse + } + + if ($Version -match "-beta\\d+$") { + $CMakeOptions = "$CMakeOptions -DKEEPASSXC_BUILD_TYPE=PreRelease" + } else { + $CMakeOptions = "$CMakeOptions -DKEEPASSXC_BUILD_TYPE=Release" + } + + # Setup Tag if not defined then checkout tag + if ($Tag -eq "" -or $Tag -eq $null) { + $Tag = $Version + } + Write-Host "Checking out tag 'tags/$Tag' to build." -ForegroundColor Cyan + Invoke-Cmd "git" "checkout `"tags/$Tag`"" + } + + # Create directories + New-Item "$OutDir" -ItemType Directory -Force | Out-Null + New-Item "$BuildDir" -ItemType Directory -Force | Out-Null + + # Enter build directory + Set-Location "$BuildDir" + + # Setup CMake options + $CMakeOptions = "$CMakeOptions -DWITH_XC_ALL=ON -DWITH_TESTS=OFF -DCMAKE_BUILD_TYPE=Release" + $CMakeOptions = "$CMakeOptions -DCMAKE_TOOLCHAIN_FILE:FILEPATH=`"$Vcpkg`" -DX_VCPKG_APPLOCAL_DEPS_INSTALL=ON" + + Write-Host "Configuring build..." -ForegroundColor Cyan + Invoke-Cmd "cmake" "$CMakeOptions -G `"$CMakeGenerator`" `"$SourceDir`"" + + Write-Host "Compiling sources..." -ForegroundColor Cyan + Invoke-Cmd "cmake" "--build . --config Release -- $MakeOptions" + + if ($SignBuild) { + $files = Get-ChildItem "$BuildDir\src" -Include "*keepassxc*.exe", "*keepassxc*.dll" -Recurse -File | ForEach-Object { $_.FullName } + Invoke-SignFiles $files $SignKey $Timestamp + } + + Write-Host "Create deployment packages..." -ForegroundColor Cyan + Invoke-Cmd "cpack" "-G `"$CPackGenerators`"" + Move-Item "$BuildDir\keepassxc-*" -Destination "$OutDir" -Force + + if ($SignBuild) { + # Enter output directory + Set-Location -Path "$OutDir" + + # Sign MSI files using AppSign key + $files = Get-ChildItem $OutDir -Include "*.msi" -Name + Invoke-SignFiles $files $SignKey $Timestamp + + # Sign all output files using the GPG key then hash them + $files = Get-ChildItem $OutDir -Include "*.msi", "*.zip" -Name + Invoke-GpgSignFiles $files $GpgKey + } + + # Restore state + Invoke-Command {git checkout $OrigBranch} + Set-Location "$OrigDir" +} elseif ($Sign) { + if (Test-Path $SignKey) { + # Need to include path to signtool program + Invoke-VSToolchain $VSToolChain $SourceDir -Arch "amd64" + } + + Test-RequiredPrograms + + # Resolve wildcard paths + $ResolvedFiles = @() + foreach ($_ in $SignFiles) { + $ResolvedFiles += (Get-ChildItem $_ -File | ForEach-Object { $_.FullName }) + } + + $AppSignFiles = $ResolvedFiles.Where({ $_ -match "\.(msi|exe|dll)$" }) + Invoke-SignFiles $AppSignFiles $SignKey $Timestamp + + $GpgSignFiles = $ResolvedFiles.Where({ $_ -match "\.(msi|zip|gz|xz|dmg|appimage)$" }) + Invoke-GpgSignFiles $GpgSignFiles $GpgKey +} + +# SIG # Begin signature block +# MIIThAYJKoZIhvcNAQcCoIITdTCCE3ECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB +# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR +# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUyaXWK5K1LP2TD/IgGb5Tfs8v +# C2GgghC8MIIFOjCCBCKgAwIBAgIQWKLXLYzA/YnM/yHg1O3HSjANBgkqhkiG9w0B +# AQsFADB8MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVy +# MRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxJDAi +# BgNVBAMTG1NlY3RpZ28gUlNBIENvZGUgU2lnbmluZyBDQTAeFw0yMTAzMTUwMDAw +# MDBaFw0yNDAzMTQyMzU5NTlaMIGhMQswCQYDVQQGEwJVUzEOMAwGA1UEEQwFMjIz +# MTUxETAPBgNVBAgMCFZpcmdpbmlhMRIwEAYDVQQHDAlGcmFuY29uaWExGzAZBgNV +# BAkMEjY2NTMgQXVkcmV5IEtheSBDdDEeMBwGA1UECgwVRHJvaWRNb25rZXkgQXBw +# cywgTExDMR4wHAYDVQQDDBVEcm9pZE1vbmtleSBBcHBzLCBMTEMwggEiMA0GCSqG +# SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwB9L/+1zlcXOQLoYvdrYAWS9B5ui+7E9c +# XCn6wcB4NdmaRbNM3kdWc8nbjOOHeOct2jVzVu/pJR1SagI+V1R1BfzgfzuW55Yy +# iHrqXQGfL9xhqJAWSvdQRinvlkZ+WY3QxnOhzcQk+BTLYdUwq04O3jMv7vnH6fuL +# q/HXEsgDObZC7EyKEtVbWVo4nqY0tUTviJXvRI/sFDN8DvULefwZWIvF7G11NFeK +# It24+hDCzvVBKtEn7DNmFGO1CJAB7Sz4jFewV4MP1gviMAfGbSBqavyRDBOG7eda +# SVb1Zq482yoHNAs+mpIQK2SGvUKKAJK2wCDbzgpvu5sfzwStpc0hAgMBAAGjggGQ +# MIIBjDAfBgNVHSMEGDAWgBQO4TqoUzox1Yq+wbutZxoDha00DjAdBgNVHQ4EFgQU +# 7u2WZ7fqJiaM3u9SlzAwGBhoWH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQC +# MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEQYJYIZIAYb4QgEBBAQDAgQQMEoGA1Ud +# IARDMEEwNQYMKwYBBAGyMQECAQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2Vj +# dGlnby5jb20vQ1BTMAgGBmeBDAEEATBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8v +# Y3JsLnNlY3RpZ28uY29tL1NlY3RpZ29SU0FDb2RlU2lnbmluZ0NBLmNybDBzBggr +# BgEFBQcBAQRnMGUwPgYIKwYBBQUHMAKGMmh0dHA6Ly9jcnQuc2VjdGlnby5jb20v +# U2VjdGlnb1JTQUNvZGVTaWduaW5nQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8v +# b2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAD2w/Tt5KyPbX2M+h +# WVwgqpKm42nk6aN2HvSp+KWlrB2t+ziL+1IRXwq7S0V7p2e1ZK8uXLzBjUDVGjBc +# ugh5hGG95MGVltxCJrr/bk1He62L7MwVxfH5b5MrE/vC/cHcSxEB1AZwZxYKjDPf +# R81biDVch++XeKmvUxfT4XGo7McJqT4K/TcLwijSb/AWsXR+r2BXEAqgsoG37kk/ +# fbPKimpJ07hxd/RNYVpE33E93zCQ1Tjc1tP3DaLq8cpS6jGUY5NNOzRgp2mGcGHy +# lv6Q/xf45qNvHiqFVctdvY9of0QFjg5eYDr4rLDa+mks9f1Jd8aDWKcsfCBnlohT +# KIffbTCCBYEwggRpoAMCAQICEDlyRDr5IrdR19NsEN0xNZUwDQYJKoZIhvcNAQEM +# BQAwezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQ +# MA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAf +# BgNVBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0xOTAzMTIwMDAwMDBa +# Fw0yODEyMzEyMzU5NTlaMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEpl +# cnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJV +# U1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9u +# IEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIASZRc2 +# DsPbCLPQrFcNdu3NJ9NMrVCDYeKqIE0JLWQJ3M6Jn8w9qez2z8Hc8dOx1ns3KBEr +# R9o5xrw6GbRfpr19naNjQrZ28qk7K5H44m/Q7BYgkAk+4uh0yRi0kdRiZNt/owbx +# iBhqkCI8vP4T8IcUe/bkH47U5FHGEWdGCFHLhhRUP7wz/n5snP8WnRi9UY41pqdm +# yHJn2yFmsdSbeAPAUDrozPDcvJ5M/q8FljUfV1q3/875PbcstvZU3cjnEjpNrkyK +# t1yatLcgPcp/IjSufjtoZgFE5wFORlObM2D3lL5TN5BzQ/Myw1Pv26r+dE5px2uM +# YJPexMcM3+EyrsyTO1F4lWeL7j1W/gzQaQ8bD/MlJmszbfduR/pzQ+V+DqVmsSl8 +# MoRjVYnEDcGTVDAZE6zTfTen6106bDVc20HXEtqpSQvf2ICKCZNijrVmzyWIzYS4 +# sT+kOQ/ZAp7rEkyVfPNrBaleFoPMuGfi6BOdzFuC00yz7Vv/3uVzrCM7LQC/NVV0 +# CUnYSVgaf5I25lGSDvMmfRxNF7zJ7EMm0L9BX0CpRET0medXh55QH1dUqD79dGMv +# sVBlCeZYQi5DGky08CVHWfoEHpPUJkZKUIGy3r54t/xnFeHJV4QeD2PW6WK61l9V +# LupcxigIBCU5uA4rqfJMlxwHPw1S9e3vL4IPAgMBAAGjgfIwge8wHwYDVR0jBBgw +# FoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYDVR0OBBYEFFN5v1qqK0rPVIDh2JvA +# nfKyA2bLMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MBEGA1UdIAQK +# MAgwBgYEVR0gADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLmNvbW9kb2Nh +# LmNvbS9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDA0BggrBgEFBQcBAQQoMCYw +# JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTANBgkqhkiG9w0B +# AQwFAAOCAQEAGIdR3HQhPZyK4Ce3M9AuzOzw5steEd4ib5t1jp5y/uTW/qofnJYt +# 7wNKfq70jW9yPEM7wD/ruN9cqqnGrvL82O6je0P2hjZ8FODN9Pc//t64tIrwkZb+ +# /UNkfv3M0gGhfX34GRnJQisTv1iLuqSiZgR2iJFODIkUzqJNyTKzuugUGrxx8Vvw +# QQuYAAoiAxDlDLH5zZI3Ge078eQ6tvlFEyZ1r7uq7z97dzvSxAKRPRkA0xdcOds/ +# exgNRc2ThZYvXd9ZFk8/Ub3VRRg/7UqO6AZhdCMWtQ1QcydER38QXYkqa4UxFMTo +# qWpMgLxqeM+4f452cpkMnf7XkQgWoaNflTCCBfUwggPdoAMCAQICEB2iSDBvmyYY +# 0ILgln0z02owDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQI +# EwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhl +# IFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRp +# ZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEwMjAwMDAwMFoXDTMwMTIzMTIzNTk1 +# OVowfDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQ +# MA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYD +# VQQDExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEB +# AQUAA4IBDwAwggEKAoIBAQCGIo0yhXoYn0nwli9jCB4t3HyfFM/jJrYlZilAhlRG +# dDFixRDtsocnppnLlTDAVvWkdcapDlBipVGREGrgS2Ku/fD4GKyn/+4uMyD6DBmJ +# qGx7rQDDYaHcaWVtH24nlteXUYam9CflfGqLlR5bYNV+1xaSnAAvaPeX7Wpyvjg7 +# Y96Pv25MQV0SIAhZ6DnNj9LWzwa0VwW2TqE+V2sfmLzEYtYbC43HZhtKn52BxHJA +# teJf7wtF/6POF6YtVbC3sLxUap28jVZTxvC6eVBJLPcDuf4vZTXyIuosB69G2flG +# HNyMfHEo8/6nxhTdVZFuihEN3wYklX0Pp6F8OtqGNWHTAgMBAAGjggFkMIIBYDAf +# BgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUDuE6qFM6 +# MdWKvsG7rWcaA4WtNA4wDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8C +# AQAwHQYDVR0lBBYwFAYIKwYBBQUHAwMGCCsGAQUFBwMIMBEGA1UdIAQKMAgwBgYE +# VR0gADBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20v +# VVNFUlRydXN0UlNBQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYIKwYBBQUH +# AQEEajBoMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vVVNF +# UlRydXN0UlNBQWRkVHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3Nw +# LnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggIBAE1jUO1HNEphpNveaiqM +# m/EAAB4dYns61zLC9rPgY7P7YQCImhttEAcET7646ol4IusPRuzzRl5ARokS9At3 +# WpwqQTr81vTr5/cVlTPDoYMot94v5JT3hTODLUpASL+awk9KsY8k9LOBN9O3ZLCm +# I2pZaFJCX/8E6+F0ZXkI9amT3mtxQJmWunjxucjiwwgWsatjWsgVgG10Xkp1fqW4 +# w2y1z99KeYdcx0BNYzX2MNPPtQoOCwR/oEuuu6Ol0IQAkz5TXTSlADVpbL6fICUQ +# DRn7UJBhvjmPeo5N9p8OHv4HURJmgyYZSJXOSsnBf/M6BZv5b9+If8AjntIeQ3pF +# McGcTanwWbJZGehqjSkEAnd8S0vNcL46slVaeD68u28DECV3FTSK+TbMQ5Lkuk/x +# YpMoJVcp+1EZx6ElQGqEV8aynbG8HArafGd+fS7pKEwYfsR7MUFxmksp7As9V1DS +# yt39ngVR5UR43QHesXWYDVQk/fBO4+L4g71yuss9Ou7wXheSaG3IYfmm8SoKC6W5 +# 9J7umDIFhZ7r+YMp08Ysfb06dy6LN0KgaoLtO0qqlBCk4Q34F8W2WnkzGJLjtXX4 +# oemOCiUe5B7xn1qHI/+fpFGe+zmAEc3btcSnqIBv5VPU4OOiwtJbGvoyJi1qV3Ac +# PKRYLqPzW0sH3DJZ84enGm1YMYICMjCCAi4CAQEwgZAwfDELMAkGA1UEBhMCR0Ix +# GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEY +# MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdvIFJTQSBD +# b2RlIFNpZ25pbmcgQ0ECEFii1y2MwP2JzP8h4NTtx0owCQYFKw4DAhoFAKB4MBgG +# CisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcC +# AQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYE +# FPvoURlVLtMyc41aoH1W7jNXhNkUMA0GCSqGSIb3DQEBAQUABIIBACa4ISoVYuy4 +# LQD5f2XzRDboWCOwR2ClFczB/vOn7uX+RKpbW+vZwllcL0wk0kA4Iotk12yKLAni +# K0DkhX8P/Gt5B4hMFaWYKkwTZljITgCEHoAy8vQzpfDUdfJF40R7IIEQLzr2/n5q +# Iztv/ApXsPX8SkgEGdikFbBA0i/xtzI8+3sI1QINiRig8xEH/1eOZlR54YHwClvS +# 8QhXueb9NbqNN9oKBwx5gRWcOE4I2E5mYAppDDQyhqitbeeY2Pw4Eo5koLM3zTDy +# 4/zc+A9lNkAa5eDTavxMHQVqKgO5KomzIYHAdIFnKs85SdntIOr5nSAHnAl6svTh +# iJXqSEggdX8= +# SIG # End signature block diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ead58ea7f..9e0f2b356 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -435,6 +435,9 @@ if(WIN32) "${CMAKE_SOURCE_DIR}/LICENSE.GPL-2" "${CMAKE_CURRENT_BINARY_DIR}/INSTALLER_LICENSE.txt") + # Prepare portal zip file + set(CPACK_INSTALL_SCRIPTS "${CMAKE_SOURCE_DIR}/cmake/MakePortableZip.cmake") + string(REGEX REPLACE "-.*$" "" KEEPASSXC_VERSION_CLEAN ${KEEPASSXC_VERSION}) set(CPACK_GENERATOR "ZIP;WIX")