diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..82519c19f --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2020.3.1 \ No newline at end of file diff --git a/ci/azure-pipelines.yaml b/ci/azure-pipelines.yaml index 83a5df563..009d17082 100644 --- a/ci/azure-pipelines.yaml +++ b/ci/azure-pipelines.yaml @@ -261,12 +261,16 @@ stages: - job: Windows_64_bit pool: name: 'Devolutions - Windows containers' - + workspace: clean: all container: devolutions/waykbuilder:vstools2k19 + variables: + TargetPlatform: "windows" + TargetArchitecture: "x86_64" + steps: - checkout: self clean: true @@ -291,25 +295,42 @@ stages: $secureString = convertto-securestring "$(WINDOWS_SIGNING_PASSPHRASE)" -asplaintext -force Import-PfxCertificate -FilePath CodeSigningCertificateUnsecure.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $secureString Import-PfxCertificate -FilePath CodeSigningCertificateUnsecure.pfx -CertStoreLocation Cert:\CurrentUser\My -Password $secureString + Write-Host "##vso[task.setvariable variable=SignToolName]Devolutions" displayName: Import signing certificate - powershell: | - $version = Get-Content $(Agent.BuildDirectory)\version\VERSION - conan install openssl/$(OPENSSL_VERSION)@devolutions/stable -g virtualenv -pr windows-x86_64 + $CargoVersion = Get-Content $(Agent.BuildDirectory)\version\VERSION + $TargetOutputPath = "$(Build.StagingDirectory)/$(TargetPlatform)/$(TargetArchitecture)" + Write-Host "##vso[task.setvariable variable=CargoVersion]$CargoVersion" + Write-Host "##vso[task.setvariable variable=TargetOutputPath]$TargetOutputPath" + conan install openssl/$(OPENSSL_VERSION)@devolutions/stable -g virtualenv -pr $(TargetPlatform)-$(TargetArchitecture) .\activate.ps1 cargo build --release - mkdir $(Build.ArtifactStagingDirectory)/windows/x86_64 - cp $(Build.Repository.LocalPath)/target/release/devolutions-gateway.exe $(Build.ArtifactStagingDirectory)/windows/x86_64/DevolutionsGateway_windows_"$version"_x86_64.exe + mkdir $TargetOutputPath + $DGatewayExecutable = "$TargetOutputPath/DevolutionsGateway_$(TargetPlatform)_${CargoVersion}_$(TargetArchitecture).exe" + cp $(Build.Repository.LocalPath)/target/release/devolutions-gateway.exe $DGatewayExecutable + Write-Host "##vso[task.setvariable variable=DGATEWAY_EXECUTABLE]$DGatewayExecutable" displayName: Building devolutions-gateway env: RUSTFLAGS: '-C target-feature=+crt-static' - powershell: | - $version = Get-Content $(Agent.BuildDirectory)\version\VERSION - signtool sign /fd SHA256 /v /t http://timestamp.verisign.com/scripts/timstamp.dll $(Build.ArtifactStagingDirectory)/windows/x86_64/DevolutionsGateway_windows_"$version"_x86_64.exe + signtool sign /fd SHA256 /v /t http://timestamp.verisign.com/scripts/timstamp.dll $(DGATEWAY_EXECUTABLE) displayName: Signing binary + - task: PowerShell@2 + inputs: + targetType: 'filePath' + filePath: $(System.DefaultWorkingDirectory)\ci\tlk.ps1 + arguments: package -Platform $(TargetPlatform) -Architecture $(TargetArchitecture) + env: + TARGET_OUTPUT_PATH: "$(TargetOutputPath)" + DGATEWAY_EXECUTABLE: "$(DGATEWAY_EXECUTABLE)" + DGATEWAY_PACKAGE_FILENAME: "DevolutionsGateway-$(TargetArchitecture)-$(CargoVersion).msi" + SIGNTOOL_NAME: "$(SignToolName)" + displayName: Creating MSI package + - task: PublishBuildArtifacts@1 inputs: - pathToPublish: $(Build.ArtifactStagingDirectory) + pathToPublish: $(Build.StagingDirectory) artifactName: devolutions-gateway diff --git a/ci/tlk.ps1 b/ci/tlk.ps1 new file mode 100644 index 000000000..089fd2bd0 --- /dev/null +++ b/ci/tlk.ps1 @@ -0,0 +1,280 @@ + +# global initialization + +if (-Not (Test-Path 'variable:global:IsWindows')) { + $global:IsWindows = $true; # Windows PowerShell 5.1 or earlier +} + +if ($IsWindows) { + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; +} + +function Get-DotEnvFile { + param( + [Parameter(Position=0,Mandatory=$true)] + [string] $InputFile + ) + + $DotEnv = @{} + $InputValue = Get-Content -Path $InputFile -Encoding UTF8 -ErrorAction Stop + $($InputValue | Select-String -AllMatches -Pattern "^(.+)=`"(.+)`"$").Matches | ForEach-Object { + $DotEnv.Add($_.Groups[1].Value, $_.Groups[2].Value) + } + return $DotEnv +} + +function Get-TlkPlatform { + param( + [Parameter(Position=0)] + [string] $Platform + ) + + if (-Not $Platform) { + $Platform = if ($IsWindows) { + 'windows' + } elseif ($IsMacOS) { + 'macos' + } elseif ($IsLinux) { + 'linux' + } + } + + $Platform +} + +function Get-TlkArchitecture { + param( + [Parameter(Position=0)] + [string] $Architecture + ) + + if (-Not $Architecture) { + $Architecture = 'x86_64' + } + + $Architecture +} + +class TlkTarget +{ + [string] $Platform + [string] $Architecture + + [string] $ExecutableExtension + + TlkTarget() { + $this.Init() + } + + [void] Init() { + $this.Platform = Get-TlkPlatform + $this.Architecture = Get-TlkArchitecture + + if ($this.IsWindows()) { + $this.ExecutableExtension = 'exe' + } else { + $this.ExecutableExtension = '' + } + } + + [bool] IsWindows() { + return $this.Platform -eq 'Windows' + } + + [bool] IsMacOS() { + return $this.Platform -eq 'macOS' + } + + [bool] IsLinux() { + return $this.Platform -eq 'Linux' + } +} + +class TlkRecipe +{ + [string] $PackageName + [string] $Version + [string] $SourcePath + [bool] $Verbose + + [TlkTarget] $Target + + TlkRecipe() { + $this.Init() + } + + [void] Init() { + $this.SourcePath = $($PSScriptRoot | Get-Item).Parent.FullName + $this.PackageName = "DevolutionsGateway" + $this.Version = $(Get-Content -Path "$($this.SourcePath)/VERSION").Trim() + $this.Verbose = $true + + $this.Target = [TlkTarget]::new() + } + + [void] Build() { + $OPENSSL_VERSION = '1.1.1b-5' + $ConanPackage = "openssl/${OPENSSL_VERSION}@devolutions/stable" + $ConanProfile = "$($this.Target.Platform)-$($this.Target.Architecture)" + + $BuildStagingDirectory = Join-Path $this.SourcePath "artifacts" # Build.StagingDirectory + + & 'conan' 'install' $ConanPackage '-g' 'virtualenv' '-pr' $ConanProfile + $dotenv = Get-DotEnvFile ".\environment.sh.env" + + Get-ChildItem 'conanbuildinfo.*' | Remove-Item + Get-ChildItem 'environment.*.env' | Remove-Item + Get-ChildItem '*activate.*' | Remove-Item + + $OPENSSL_DIR = $dotenv['OPENSSL_DIR'] + $Env:OPENSSL_DIR = $OPENSSL_DIR + + if ($this.Target.IsWindows()) { + $Env:RUSTFLAGS = "-C target-feature=+crt-static" + } + + $OutputPath = "${BuildStagingDirectory}/$($this.Target.Platform)/$($this.Target.Architecture)" + New-Item -Path $OutputPath -ItemType 'Directory' -Force | Out-Null + + Push-Location + Set-Location $this.SourcePath + & 'cargo' 'build' '--release' + $DstExecutableName = $SrcExecutableName = 'devolutions-gateway', $this.Target.ExecutableExtension -ne '' -Join '.' + if ($this.Target.IsWindows()) { + $DstExecutableName = "DevolutionsGateway.exe" + } + Copy-Item "$($this.SourcePath)/target/release/${SrcExecutableName}" ` + -Destination "${OutputPath}/${DstExecutableName}" -Force + Pop-Location + } + + [void] Package() { + $ShortVersion = $this.Version.Substring(2) # msi version + $CargoVersion = "0.14.0" # Cargo.toml version + $TargetArch = if ($this.Target.Architecture -eq 'x86_64') { 'x64' } else { 'x86' } + + $ModuleName = "DevolutionsGateway" + $ModuleVersion = $this.Version # both versions should match + + Push-Location + Set-Location "$($this.SourcePath)/package/$($this.Target.Platform)" + + if (Test-Path Env:DGATEWAY_EXECUTABLE) { + $DGatewayExecutable = $Env:DGATEWAY_EXECUTABLE + } else { + $WebClient = [System.Net.WebClient]::new() + $DownloadUrl = "https://github.com/Devolutions/devolutions-gateway/releases/download/" + ` + "v${CargoVersion}/DevolutionsGateway_windows_${CargoVersion}_x86_64.exe" + + $OutputFile = "$(Get-Location)/bin/DevolutionsGateway.exe" + New-Item -Path "bin" -ItemType 'Directory' -ErrorAction 'SilentlyContinue' | Out-Null + Remove-Item $OutputFile -ErrorAction 'SilentlyContinue' + $WebClient.DownloadFile($DownloadUrl, $OutputFile) + $DGatewayExecutable = $OutputFile + } + + Save-Module -Name $ModuleName -Force -RequiredVersion $ModuleVersion -Repository 'PSGallery' -Path '.' + Remove-Item -Path "${ModuleName}/${ModuleVersion}/PSGetModuleInfo.xml" -ErrorAction 'SilentlyContinue' + + $WixExtensions = @('WixUtilExtension', 'WixUIExtension', 'WixFirewallExtension') + $WixExtensions += $(Join-Path $(Get-Location) 'WixUserPrivilegesExtension.dll') + + $WixArgs = @($WixExtensions | ForEach-Object { @('-ext', $_) }) + @( + "-dDGatewayPSSourceDir=${ModuleName}/${ModuleVersion}", + "-dDGatewayExecutable=$DGatewayExecutable", + "-dVersion=$ShortVersion", "-v") + + $WixFiles = @('DevolutionsGateway', "DevolutionsGateway-$TargetArch") + + $HeatArgs = @('dir', "${ModuleName}/${ModuleVersion}", + "-dr", "DGATEWAYPSROOTDIRECTORY", + "-cg", "DGatewayPSComponentGroup", + '-var', 'var.DGatewayPSSourceDir', + '-nologo', '-srd', '-suid', '-scom', '-sreg', '-sfrag', '-gg') + + & 'heat.exe' $HeatArgs + @('-t', 'HeatTransform64.xslt', '-o', "$($this.PackageName)-$TargetArch.wxs") + + $InputFiles = $WixFiles | ForEach-Object { "$_.wxs" } + $ObjectFiles = $WixFiles | ForEach-Object { "$_.wixobj" } + + $Cultures = @('en-US', 'fr-FR') + + foreach ($Culture in $Cultures) { + & 'candle.exe' "-nologo" $InputFiles $WixArgs "-dPlatform=$TargetArch" ` + "-dWixUILicenseRtf=$($this.PackageName)_EULA_${Culture}.rtf" + + $OutputFile = "$($this.PackageName)_${Culture}.msi" + + if ($Culture -eq 'en-US') { + $OutputFile = "$($this.PackageName).msi" + } + + & 'light.exe' "-v" "-nologo" $ObjectFiles "-cultures:${Culture}" "-loc" "$($this.PackageName)_${Culture}.wxl" ` + "-out" $OutputFile $WixArgs "-dPlatform=$TargetArch" "-sice:ICE61" + } + + foreach ($Culture in $($Cultures | Select-Object -Skip 1)) { + & 'torch.exe' "-v" "$($this.PackageName).msi" "$($this.PackageName)_${Culture}.msi" "-o" "${Culture}_$TargetArch.mst" + & 'cscript.exe' "/nologo" "WiSubStg.vbs" "$($this.PackageName).msi" "${Culture}_$TargetArch.mst" "1036" + & 'cscript.exe' "/nologo" "WiLangId.vbs" "$($this.PackageName).msi" "Package" "1033,1036" + } + + if (Test-Path Env:TARGET_OUTPUT_PATH) { + $TargetOutputPath = $Env:TARGET_OUTPUT_PATH + $PackageFileName = "$($this.PackageName).msi" + if (Test-Path Env:DGATEWAY_PACKAGE_FILENAME) { + $PackageFileName = $Env:DGATEWAY_PACKAGE_FILENAME + } + $TargetPackageFile = $(Join-Path $TargetOutputPath $PackageFileName) + Copy-Item -Path "$($this.PackageName).msi" -Destination $TargetPackageFile + + if (Test-Path Env:SIGNTOOL_NAME) { + $SignToolName = $Env:SIGNTOOL_NAME + $TimestampServer = 'http://timestamp.verisign.com/scripts/timstamp.dll' + $SignToolArgs = @( + 'sign', '/fd', 'SHA256', '/v', + '/n', $SignToolName, + '/t', $TimestampServer, + $TargetPackageFile + ) + & 'signtool' $SignToolArgs + } + } + + Pop-Location + } +} + +function Invoke-TlkStep { + param( + [Parameter(Position=0,Mandatory=$true)] + [ValidateSet('build','package')] + [string] $TlkVerb, + [ValidateSet('windows','macos','linux')] + [string] $Platform, + [ValidateSet('x86','x86_64','arm64')] + [string] $Architecture + ) + + if (-Not $Platform) { + $Platform = Get-TlkPlatform + } + + if (-Not $Architecture) { + $Architecture = Get-TlkArchitecture + } + + $RootPath = Split-Path -Parent $PSScriptRoot + + $tlk = [TlkRecipe]::new() + $tlk.SourcePath = $RootPath + $tlk.Target.Platform = $Platform + $tlk.Target.Architecture = $Architecture + + switch ($TlkVerb) { + "build" { $tlk.Build() } + "package" {$tlk.Package() } + } +} + +Invoke-TlkStep @args diff --git a/package/Windows/DevolutionsGateway.wxs b/package/Windows/DevolutionsGateway.wxs index 92625f0d4..4689765c3 100644 --- a/package/Windows/DevolutionsGateway.wxs +++ b/package/Windows/DevolutionsGateway.wxs @@ -199,7 +199,7 @@ - + diff --git a/package/Windows/package.ps1 b/package/Windows/package.ps1 deleted file mode 100644 index 465562921..000000000 --- a/package/Windows/package.ps1 +++ /dev/null @@ -1,63 +0,0 @@ - -$PackageName = "DevolutionsGateway" -$Version = '2020.3.0' # TODO: detect version -$ShortVersion = $Version.Substring(2) -$InternalVersion = "0.14.0" -$TargetArch = "x64" - -$ModuleName = "DevolutionsGateway" -$ModuleVersion = '2020.3.1' - -$WebClient = [System.Net.WebClient]::new() -$DownloadUrl = "https://github.com/Devolutions/devolutions-gateway/releases/download/" + ` - "v${InternalVersion}/DevolutionsGateway_windows_${InternalVersion}_x86_64.exe" - -$OutputFile = "$(Get-Location)/bin/${TargetArch}/DevolutionsGateway.exe" -New-Item -Path "bin/${TargetArch}" -ItemType 'Directory' -ErrorAction 'SilentlyContinue' | Out-Null -Remove-Item $OutputFile -ErrorAction 'SilentlyContinue' -$WebClient.DownloadFile($DownloadUrl, $OutputFile) - -Save-Module -Name $ModuleName -Force -RequiredVersion $ModuleVersion -Repository 'PSGallery' -Path '.' -Remove-Item -Path "${ModuleName}/${ModuleVersion}/PSGetModuleInfo.xml" -ErrorAction 'SilentlyContinue' - -$WixExtensions = @('WixUtilExtension', 'WixUIExtension', 'WixFirewallExtension') -$WixExtensions += $(Join-Path $(Get-Location) 'WixUserPrivilegesExtension.dll') - -$WixArgs = @($WixExtensions | ForEach-Object { @('-ext', $_) }) + @( - "-dDGatewayPSSourceDir=${ModuleName}/${ModuleVersion}", - "-dVersion=$ShortVersion") - -$WixFiles = @('DevolutionsGateway', "DevolutionsGateway-${TargetArch}") - -$HeatArgs = @('dir', "${ModuleName}/${ModuleVersion}", - "-dr", "DGATEWAYPSROOTDIRECTORY", - "-cg", "DGatewayPSComponentGroup", - '-var', 'var.DGatewayPSSourceDir', - '-nologo', '-srd', '-suid', '-scom', '-sreg', '-sfrag', '-gg') - -& 'heat.exe' $HeatArgs + @('-t', 'HeatTransform64.xslt', '-o', "${PackageName}-${TargetArch}.wxs") - -$InputFiles = $WixFiles | ForEach-Object { "$_.wxs" } -$ObjectFiles = $WixFiles | ForEach-Object { "$_.wixobj" } - -$Cultures = @('en-US', 'fr-FR') - -foreach ($Culture in $Cultures) { - & 'candle.exe' "-nologo" $InputFiles $WixArgs "-dPlatform=${TargetArch}" ` - "-dWixUILicenseRtf=${PackageName}_EULA_${Culture}.rtf" - - $OutputFile = "${PackageName}_${Culture}.msi" - - if ($Culture -eq 'en-US') { - $OutputFile = "${PackageName}.msi" - } - - & 'light.exe' "-v" "-nologo" $ObjectFiles "-cultures:${Culture}" "-loc" "${PackageName}_${Culture}.wxl" ` - "-out" $OutputFile $WixArgs "-dPlatform=${TargetArch}" "-sice:ICE61" -} - -foreach ($Culture in $($Cultures | Select-Object -Skip 1)) { - & 'torch.exe' "-v" "${PackageName}.msi" "${PackageName}_${Culture}.msi" "-o" "${Culture}_${TargetArch}.mst" - & 'cscript.exe' "/nologo" "WiSubStg.vbs" "${PackageName}.msi" "${Culture}_${TargetArch}.mst" "1036" - & 'cscript.exe' "/nologo" "WiLangId.vbs" "${PackageName}.msi" "Package" "1033,1036" -}