2020-10-31 11:32:12 -07:00
# We would have preferred to put this main section to the end of the file,
# but script arguments must be defined as the first statement in a PowerShell
# script.
2019-10-01 05:10:25 -07:00
P a r a m (
[ parameter( Position = 0) ] $makeRule
)
2020-10-31 11:32:12 -07:00
# While the different sections of this file may be better with import statements
# or even better with PowerShell modules, choosing this option would require
# them to be installed on CircleCI servers, which also breaks selfcontainement
# of this makefile.
2019-10-01 05:10:25 -07:00
2020-10-31 11:32:12 -07:00
################################################################################
# Logging functions
################################################################################
#Region
f u n c t i o n P r i n t {
Param (
[ String] $message ,
[ Switch] $NoNewLine
)
if ( $NoNewLine ) {
Write-Host " $message " -NoNewLine
} else {
Write-Host " $message "
}
}
2019-10-01 05:10:25 -07:00
2020-10-31 11:32:12 -07:00
f u n c t i o n P r i n t - I n f o {
Param (
[ String] $message ,
[ Switch] $NoNewLine
)
if ( [ String] ::IsNullOrEmpty( $message ) ) {
return
}
Write-Host "[" -NoNewLine
Write-Host "+" -NoNewLine -ForegroundColor Green
Write-Host "]" -NoNewLine
if ( $NoNewLine ) {
Write-Host " $message " -NoNewLine
} else {
Write-Host " $message "
}
}
f u n c t i o n P r i n t - W a r n i n g {
Param (
[ String] $message ,
[ Switch] $NoNewLine
)
if ( [ String] ::IsNullOrEmpty( $message ) ) {
return
}
Write-Host "[" -NoNewLine
Write-Host "!" -NoNewLine -ForegroundColor Magenta
Write-Host "]" -NoNewLine
if ( $NoNewLine ) {
Write-Host " $message " -NoNewLine
} else {
Write-Host " $message "
}
}
# Avoid stacktrace to be displayed along side the error message.
# We want things simplistic.
# src.: https://stackoverflow.com/q/38064704/3514658
# src.: https://stackoverflow.com/a/38064769
# We won't use [Console]::*Write* not $host.ui.Write* statements
# as they are UI items
# src.: https://web.archive.org/web/20190720224207/https://docs.microsoft.com/en-us/powershell/developer/cmdlet/types-of-cmdlet-output
# Rewriting the error printing function in C# and calling it from Posh is not
# working either because the redirection to stderr doesn't work under Posh but
# is working when the Posh script is run from cmd.exe. We are giving up here
# and simply using Write-Host without stderr redirection.
f u n c t i o n P r i n t - E r r o r {
Param (
[ String] $message ,
[ Switch] $NoNewLine
)
if ( [ String] ::IsNullOrEmpty( $message ) ) {
return
}
Write-Host "[" -NoNewLine
Write-Host "-" -NoNewLine -ForegroundColor Red
Write-Host "]" -NoNewLine
if ( $NoNewLine ) {
Write-Host " $message " -NoNewLine
} else {
Write-Host " $message "
}
}
#EndRegion
2019-10-01 05:10:25 -07:00
################################################################################
2020-10-31 11:32:12 -07:00
# OS related functions
2019-10-01 05:10:25 -07:00
################################################################################
2020-10-31 11:32:12 -07:00
#Region
f u n c t i o n C h e c k - C o m m a n d ( $ c m d n a m e ) {
return [ bool] ( Get-Command -Name $cmdname -ErrorAction SilentlyContinue)
}
f u n c t i o n R e f r e s h - P a t h {
$env :Path =
[ System.Environment] ::GetEnvironmentVariable( "Path" , "Machine" ) +
";" +
[ System.Environment] ::GetEnvironmentVariable( "Path" , "User" )
}
f u n c t i o n G e t - R o o t D i r {
return " $( Split-Path $PSCommandPath ) \..\"
}
# src: https://superuser.com/a/756696/456258
f u n c t i o n I s - A d m i n {
return ( [ Security.Principal.WindowsPrincipal] `
[ Security.Principal.WindowsIdentity] ::GetCurrent( ) `
) .IsInRole( [ Security.Principal.WindowsBuiltInRole] ::Administrator)
}
#EndRegion
################################################################################
# Check and install of dependencies related functions
################################################################################
#Region
f u n c t i o n C h e c k - D e p s {
Param (
[ Switch]
$verbose ,
[ Switch]
$throwable
)
if ( $PSVersionTable .PSVersion.Major -lt 5) {
Print-Error "You need at least PowerShell 5.0 to execute this Makefile. Operation aborted."
exit
}
[ array] $missing = @( )
if ( $verbose ) { Print-Info "Checking choco dependency..." }
if ( !( Check-Command "choco" ) ) {
if ( $verbose ) { Print-Error "choco dependency missing." }
$missing += "choco"
}
if ( $verbose ) { Print-Info "Checking git dependency..." }
if ( !( Check-Command "git" ) ) {
if ( $verbose ) { Print-Error "git dependency missing." }
$missing += "git"
}
if ( $verbose ) { Print-Info "Checking nodejs/npm dependency..." }
# Testing if the folder is not empty first is needed otherwise if there is
# a file called like that in the path where the makefile is invocated, the
# check will succeed while it is plain wrong.
if ( [ string] ::IsNullOrEmpty( $( Get-NpmDir) ) -or
# We could have used the builtin Test-Path cmdlet instead but it is
# tested for folders as well. We need to test for a file existence
# here.
![ System.IO.File] ::Exists( " $( Get-NpmDir) \npm.cmd " ) -or
![ System.IO.File] ::Exists( " $( Get-NpmDir) \node.exe " ) ) {
if ( $verbose ) { Print-Error "nodejs/npm dependency missing." }
$missing += "npm"
}
if ( $verbose ) { Print-Info "Checking wix dependency..." }
if ( [ string] ::IsNullOrEmpty( $( Get-WixDir) ) -or
![ System.IO.File] ::Exists( " $( Get-WixDir) \heat.exe " ) -or
![ System.IO.File] ::Exists( " $( Get-WixDir) \candle.exe " ) -or
![ System.IO.File] ::Exists( " $( Get-WixDir) \light.exe " ) ) {
if ( $verbose ) { Print-Error "wix dependency missing." }
$missing += "wix"
}
2019-10-01 05:10:25 -07:00
2020-10-31 11:32:12 -07:00
if ( $verbose ) { Print-Info "Checking signtool dependency..." }
if ( [ string] ::IsNullOrEmpty( $( Get-SignToolDir) ) -or
![ System.IO.File] ::Exists( " $( Get-SignToolDir) \signtool.exe " ) ) {
if ( $verbose ) { Print-Error "signtool dependency missing." }
$missing += "signtool"
}
if ( $verbose ) { Print-Info "Checking jq dependency..." }
if ( !( Check-Command "jq" ) ) {
if ( $verbose ) { Print-Error "jq dependency missing." }
$missing += "jq"
2019-10-01 05:10:25 -07:00
}
2020-10-31 11:32:12 -07:00
if ( $throwable -and $missing .Count -gt 0) {
throw "com.mattermost.makefile.deps.missing"
}
return $missing
2019-10-01 05:10:25 -07:00
}
2020-10-31 11:32:12 -07:00
f u n c t i o n I n s t a l l - D e p s {
[ array] $missing = Check-Deps -Verbose
if ( $missing -eq $null ) {
Print-Info "All dependencies met; exiting dependencies installation..."
2019-10-01 05:10:25 -07:00
return
}
2020-10-31 11:32:12 -07:00
if ( -not ( Is-Admin) ) {
throw "com.mattermost.makefile.deps.notadmin"
}
foreach ( $missingItem in $missing ) {
switch ( $missingItem ) {
"choco" {
Print-Info "Installing chocolatey..."
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ( ( New-Object System.Net.WebClient) .DownloadString( 'https://chocolatey.org/install.ps1' ) )
break;
}
"git" {
Print-Info "Installing git..."
choco install git --yes
break;
}
"wix" {
Install-Wix
break;
}
"signtool" {
Print-Info "Installing Windows 10 SDK (for signtool)..."
choco install windows-sdk-10.1 --yes
break;
}
"npm" {
Print-Info "Installing nodejs-lts (with npm)..."
choco install nodejs-lts --yes
break;
}
"jq" {
Print-Info "Installing jq"
choco install jq --yes
break;
}
}
Print-Info "Refreshing PATH..."
Refresh-Path
}
}
f u n c t i o n I n s t a l l - W i x {
Print-Info "Downloading wixtoolset..."
# choco is using 3.11 which causes problems building on remote ssh due to dotnet3.5
# choco install wixtoolset --yes
$WebClient = New-Object System.Net.WebClient
# if they ever fix the installer we can move to 3.11
2022-10-12 08:07:32 -07:00
$WebClient .DownloadFile( "https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311.exe" ,".\scripts\wix.exe" )
#$WebClient.DownloadFile("https://github.com/wixtoolset/wix3/releases/download/wix3104rtm/wix310.exe",".\scripts\wix.exe")
2020-10-31 11:32:12 -07:00
Print-Info "Installing wixtoolset..."
# todo: check hash
.\s cripts\w ix.exe -q
if ( $LastExitCode -ne $null ) {
throw "com.mattermost.makefile.deps.wix"
}
Print-Info "wixtoolset installed!"
}
#EndRegion
################################################################################
# Research of dependencies related functions
################################################################################
#Region
f u n c t i o n G e t - W i x D i r {
$progFile = ( ${ env : ProgramFiles (x86) } , ${ env : ProgramFiles } -ne $null ) [ 0]
$wixDirs = @( Get-ChildItem -Path $progFile -Recurse -Filter "*wix toolset*" -Attributes Directory -Depth 2 -ErrorAction SilentlyContinue)
if ( $wixDirs [ 0] -eq $null ) {
return $null
}
$wixDir = Join-Path -Path " $progFile " -ChildPath " $( $wixDirs [ 0] ) "
$wixDir = Join-Path -Path " $wixDir " -ChildPath "bin"
return $wixDir
2019-10-01 05:10:25 -07:00
}
2020-10-31 11:32:12 -07:00
f u n c t i o n G e t - S i g n T o o l D i r {
$progFile = ( ${ env : ProgramFiles (x86) } , ${ env : ProgramFiles } -ne $null ) [ 0]
$signToolDir = Join-Path -Path " $progFile " -ChildPath " Windows Kits\10\bin\"
# Check if we are on 64 bits or not.
if ( $env :PROCESSOR_ARCHITECTURE -ilike '*64*' ) {
$arch = "x64"
} else {
$arch = "x86"
}
[ array] $signToolExes = (
Get-ChildItem -Path " $signToolDir " -Filter "signtool.exe" -Recurse -ErrorAction SilentlyContinue -Force | % {
if ( $_ .FullName -ilike '*x64*' ) {
return $_ .FullName;
}
}
)
if ( $signToolExes -eq $null -or
[ string] ::IsNullOrEmpty( $signToolExes [ 0] ) ) {
return $null
}
if ( Test-Path $signToolExes [ 0] ) {
return Split-Path $signToolExes [ 0]
}
return $null
}
f u n c t i o n G e t - N p m D i r {
# npm is always installed as a nodejs dependency. 64 bits version available.
# C:\Program Files\nodejs\npm with a shortcut leading to
# C:\Program Files\nodejs\node_modules\npm\bin
$progFile = ${ env : ProgramFiles }
$npmDir = Join-Path -Path " $progFile " -ChildPath "nodejs"
if ( [ System.IO.File] ::Exists( " $npmDir \npm.cmd " ) ) {
return $npmDir
}
$progFile = ${ env : ProgramW6432 }
$npmDir = Join-Path -Path " $progFile " -ChildPath "nodejs"
if ( [ System.IO.File] ::Exists( " $npmDir \npm.cmd " ) ) {
return $npmDir
}
return $null
}
#EndRegion
2019-10-01 05:10:25 -07:00
################################################################################
# Mattermost related functions
################################################################################
#region
f u n c t i o n P r e p a r e - P a t h {
# As we may need to install new dependencies, make sure the PATH env
# variable is not too large. Some CI envs like AppVeyor have already the
# PATH env variable defined at the maximum which prevents new strings to
# be added to it. We will remove all the stuff added for programs in
# Program Files (64 bits and 32 bits variants) except the path of our
# dependencies.
# src.: https://gist.github.com/wget/a102f89c301014836aaa49a98dd06ee2
$oldPath = $env :Path
[ array] $newPath
# Cleanup the PATH from everything contained in Program Files...
$newPath = ( $env :Path -split ';' ) | Where-Object { $_ -notlike "C:\Program Files*" }
# ...except from Git
$newPath += ( $env :Path -split ';' ) | Where-Object { $_ -like "C:\Program Files*\*Git*" }
$env :Path = $newPath -join ';'
Print-Info "Reducing and reordering PATH from `n " " $oldPath " "`n to`n " " $env :Path " ""
# Prepending ensures we are using our own path here to avoid the paths the
# user might have defined to interfere.
# Prepend the PATH with npm/nodejs dir
Print-Info "Checking if npm dir is already in the PATH..."
$env :Path = " $( Get-NpmDir) " + ";" + $env :Path
# Prepend the PATH with wix dir
Print-Info "Checking if wix dir is already in the PATH..."
$env :Path = " $( Get-WixDir) " + ";" + $env :Path
# Prepend the PATH with signtool dir
Print-Info "Checking if signtool dir is already in the PATH..."
$env :Path = " $( Get-SignToolDir) " + ";" + $env :Path
}
f u n c t i o n C a t c h - I n t e r r u p t i o n {
[ console] ::TreatControlCAsInput = $true
while ( $true ) {
if ( [ console] ::KeyAvailable) {
$key = Read-Host
#$key = [system.console]::readkey($true)
if ( ( $key .modifiers -band [ consolemodifiers] "control" ) -and
( $key .key -eq "C" ) ) {
Print-Warning "Ctrl-C pressed. Cancelling the build process and restoring computer state..."
Restore-ComputerState
exit
}
}
}
}
f u n c t i o n B a c k u p - C o m p u t e r S t a t e {
$env :COM_MATTERMOST_MAKEFILE_PATH_BACKUP = $env :Path
Push-Location " $( Get-RootDir) "
# Needed because for native apps, PowerShell doesn't change the
# process current path location
#src.: https://stackoverflow.com/a/4725090/3514658
[ Environment] ::CurrentDirectory = $PWD
# Refresh path because it might have been made durty in the current shell
Refresh-Path
}
f u n c t i o n R e s t o r e - C o m p u t e r S t a t e {
Print-Info "Restoring PATH..."
$env :Path = $env :COM_MATTERMOST_MAKEFILE_PATH_BACKUP
Print-Info "Restoring current working directory..."
Pop-location
[ Environment] ::CurrentDirectory = $PWD
# Remove all COM_MATTERMOST_MAKEFILE_ prefixed env variable
foreach ( $item in ( Get-Item -Path Env:*) ) {
if ( $item .Name -imatch 'COM_MATTERMOST_MAKEFILE_' ) {
Print-Info " Removing Mattermost env variable: $( $item .Name) ... "
Remove-Item env:\$ ( $item .Name)
}
}
}
f u n c t i o n O p t i m i z e - B u i l d {
Print-Info "Checking if Windows Search is running..."
if ( ( Get-Service -Name "Windows Search" ) .Status -eq "Running" ) {
Print-Info "Windows Search is running. Disabling it..."
Stop-Service "Windows Search"
Print-Warning "WARNING: This makefile disabled Windows Search, to reenable it, type in an administror Powershell: Start-Service " "Windows Search" ""
} else {
Print-Info "Windows Search has already been disabled."
}
Print-Info "Checking if Windows Defender realtime protection is active..."
if ( !( Get-MpPreference) .DisableRealtimeMonitoring) {
Print-Info "Windows Defender realtime protection is active. Disabling it..."
Set-MpPreference -DisableRealtimeMonitoring $true
Print-Warning " WARNING: This makefile disabled Windows Defender realtime protection, to reenable it, type in an administror Powershell: Set-MpPreference -DisableRealtimeMonitoring ` $false "
} else {
Print-Info "Windows Defender realtime protection has already been disabled."
}
}
f u n c t i o n R u n - B u i l d I d {
Print-Info -NoNewLine "Getting build date..."
$env :COM_MATTERMOST_MAKEFILE_BUILD_DATE = ( Get-Date) .ToUniversalTime( ) .ToString( "yyyy-MM-dd" )
Print " [ $env :COM_MATTERMOST_MAKEFILE_BUILD_DATE] "
# Generate build version ids
#
# nodejs/npm does require to have semver parsable versions:
# major.minor.patch
# Non number values are allowed only if they are not starting the dot verion.
# 4.3.0-rc2 is allowed but 4.3.rc2 is not
#
# wix toolset supports semver up to the revision dot syntax:
# major.minor.patch.revision.
# ProductVersion Property is defined as
# [0-255].[0-255].[0-65535]
# 8 , 8 , 16 signed bit
# File Version is defined as
# [0-65535].[0-65535].[0-65535].[0-65535]
# 16 , 16 , 16 , 16 signed bit
#
# Other chars other than numbers should be removed.
# Versions like v4.3.0-rc0 shoud be. We are thus forcing to
# have a format like 4.3.0.rc0.
# When the last tag is not present or not a parsable semver version, we are
# taking the number of revisions reachable from the HEAD of the current branch
# (other branches are not taken into account).
# Example:
# $ git rev-list --count --first-parent HEAD
# 645
# Using the date is unreliable, because this requires to have a precision at
# seconds, leading to an overflow of the integer range supported by wix.
# 4.3.0.20190512074020 is not accepted and fails with the following error:
# candle.exe : error CNDL0001 : Value was either too large or too small for an Int32.
# Exception Type: System.OverflowException
# Add the revision only if we are not building a tag
2020-02-11 02:06:43 -08:00
$version = " $( jq -r '.version' package.json) "
$winVersion = " $( $version -Replace '-' ,'.' -Replace '[^0-9.]' ) "
2019-10-01 05:10:25 -07:00
Print-Info " Checking build id tag validity... [ $version ] "
[ version] $appVersion = New-Object -TypeName System.Version
2020-02-11 02:06:43 -08:00
[ void] [ version] ::TryParse( $winVersion , [ ref] $appVersion )
2019-10-01 05:10:25 -07:00
if ( !( $appVersion ) ) {
2020-02-11 02:06:43 -08:00
# if we couldn't parse, it might be a -develop or something similar, so we just add a
# number there that will change overtime. Most likely this is a PR to be tested
$revision = " $( git rev-list --all --count) "
$winVersion = " $( $version -Replace '-.*' ) . ${ revision } "
[ void] [ version] ::TryParse( $winVersion , [ ref] $appVersion )
if ( !( $appVersion ) ) {
Print-Error "Non parsable tag detected. Fallbacking to version 0.0.0."
$version = "0.0.0"
}
2019-10-01 05:10:25 -07:00
}
Print-Info -NoNewLine "Getting build id version..."
2020-02-11 02:06:43 -08:00
$env :COM_MATTERMOST_MAKEFILE_BUILD_ID = " $version "
2019-10-01 05:10:25 -07:00
Print " [ $env :COM_MATTERMOST_MAKEFILE_BUILD_ID] "
Print-Info -NoNewLine "Getting build id version for msi..."
2020-02-11 02:06:43 -08:00
$env :COM_MATTERMOST_MAKEFILE_BUILD_ID_MSI = $winVersion .Split( '.' ) [ 0..3] -Join '.'
2019-10-01 05:10:25 -07:00
Print " [ $env :COM_MATTERMOST_MAKEFILE_BUILD_ID_MSI] "
Print-Info -NoNewLine "Getting build id version for node/npm..."
2020-02-11 02:06:43 -08:00
$env :COM_MATTERMOST_MAKEFILE_BUILD_ID_NODE = $version
2019-10-01 05:10:25 -07:00
Print " [ $env :COM_MATTERMOST_MAKEFILE_BUILD_ID_NODE] "
Print-Info "Patching version from msi xml descriptor..."
$msiDescriptorFileName = "scripts\msi_installer.wxs"
$msiDescriptor = [ xml] ( Get-Content $msiDescriptorFileName )
$msiDescriptor .Wix.Product.Version = [ string] $env :COM_MATTERMOST_MAKEFILE_BUILD_ID_MSI
2020-02-11 02:06:43 -08:00
$ComponentDownload = $msiDescriptor .CreateElement( "Property" , "http://schemas.microsoft.com/wix/2006/wi" )
$ComponentDownload .InnerText = " https://releases.mattermost.com/desktop/ $version /mattermost-desktop- $version -` $( var.Platform) .msi "
$ComponentDownload .SetAttribute( "Id" , "ComponentDownload" )
$msiDescriptor .Wix.Product.AppendChild( $ComponentDownload )
2019-10-01 05:10:25 -07:00
$msiDescriptor .Save( $msiDescriptorFileName )
2020-02-11 02:06:43 -08:00
Print-Info "Modified Wix XML"
2019-10-01 05:10:25 -07:00
}
f u n c t i o n R u n - B u i l d E l e c t r o n {
2020-07-10 07:39:23 -07:00
Print-Info "Installing nodejs/electron dependencies (running npm ci)..."
2022-08-22 12:50:26 -07:00
npm i -g node-gyp
node-gyp install
npm ci
2019-10-01 05:10:25 -07:00
#npm install --prefix="$(Get-RootDir)" "$(Get-RootDir)"
Print-Info "Building nodejs/electron code (running npm run build)..."
npm run build
#npm run build --prefix="$(Get-RootDir)" "$(Get-RootDir)"
Print-Info "Packaging nodejs/electron for Windows (running npm run package:windows)..."
2022-06-30 09:25:28 -07:00
# NSIS has the upgrade flag enabled, so it must be done first
npm run package:windows-nsis
2019-10-01 05:10:25 -07:00
npm run package:windows
#npm run package:windows --prefix="$(Get-RootDir)" "$(Get-RootDir)"
}
f u n c t i o n R u n - B u i l d F o r c e S i g n a t u r e {
# Only sign the executable and .dll if this is a release and not a pull request
# check.
2020-10-31 11:32:12 -07:00
if ( Test-Path 'env:PFX' ) {
2019-10-01 05:10:25 -07:00
Print-Info "Signing"
foreach ( $archPath in "release\win-unpacked" , "release\win-ia32-unpacked" ) {
# Note: The C++ redistribuable files will be resigned again even if they have a
# correct signature from Microsoft. Windows doesn't seem to complain, but we
# don't know whether this is authorized by the Microsoft EULA.
Get-ChildItem -Path $archPath -recurse "*.dll" | ForEach-Object {
Print-Info " Signing $( $_ .Name) (waiting for 2 * 15 seconds)... "
# Waiting for at least 15 seconds is needed because these time
# servers usually have rate limits and signtool can fail with the
# following error message:
# "SignTool Error: The specified timestamp server either could not be reached or returned an invalid response.
# src.: https://web.archive.org/web/20190306223053/https://github.com/electron-userland/electron-builder/issues/2795#issuecomment-466831315
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p " $env :PFX_KEY " /tr "http://timestamp.digicert.com" /fd sha1 /td sha1 " $( $_ .FullName) "
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p " $env :PFX_KEY " /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 /as " $( $_ .FullName) "
}
Print-Info "Signing Mattermost.exe (waiting for 2 * 15 seconds)..."
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p " $env :PFX_KEY " /tr "http://timestamp.digicert.com" /fd sha1 /td sha1 " $archPath \Mattermost.exe "
Start-Sleep -s 15
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p " $env :PFX_KEY " /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 /as " $archPath \Mattermost.exe "
}
} else {
2020-10-31 11:32:12 -07:00
Print-Info "Certificate file not found, DLLs and executable won't be signed."
2019-10-01 05:10:25 -07:00
}
}
f u n c t i o n R u n - B u i l d L i c e n s e {
# Convert license to RTF
$licenseTxtFile = "LICENSE.txt" ;
$licenseRtfFile = "resources/windows/license.rtf" ;
$licenseNewParagraph = "\par" + [ Environment] ::NewLine;
$sw = [ System.IO.File] ::CreateText( $licenseRtfFile ) ;
$sw .WriteLine( "{\rtf1\ansi\deff0\nouicompat{\fonttbl{\f0\fnil\fcharset0 Courier New;}}\pard\qj\f0\fs18" ) ;
$lineToAdd = "" ;
$gapDetected = 0;
# We are relying on introspected C#/.NET rather than the buggy Get-Content
# cmdlet because Get-Content considers by default a `-Delimiter` to '\n'
# and thus breaks the purpose of the parser.
foreach ( $line in [ System.IO.File] ::ReadLines( $licenseTxtFile ) ) {
# trim() is equivalent to .replace("\ \s+", "")
# We replace one backslash by two. Since the first arg is a regex,
# we need to escape it.
# src.: https://stackoverflow.com/a/31324570/3514658
$sanitizedLine = $line .trim( ) .replace( "\\" , "\\" ) .replace( "{" , "\{" ) .replace( "}" , "\}" ) ;
# Print previous string gathered if gap detected.
if ( [ string] ::IsNullOrEmpty( $sanitizedLine ) ) {
$gapDetected ++;
# For first line keep paragraph definition from document head.
if ( $gapDetected -eq 1) {
$sw .Write( $lineToAdd ) ;
} elseif ( $gapDetected -eq 2) {
$sw .Write( $licenseNewParagraph + $lineToAdd ) ;
} else {
$sw .Write( $licenseNewParagraph + $lineToAdd + $licenseNewParagraph ) ;
}
$lineToAdd = "" ;
continue ;
}
# Keep carriage return for first two blocks comprising Copyright and
# license name statements.
if ( $gapDetected -lt 3) {
$lineToAdd += $sanitizedLine + $licenseNewParagraph ;
continue ;
}
# Do not add heading space if the line begins a new paragraph.
if ( $lineToAdd -eq "" ) {
$lineToAdd += $sanitizedLine ;
continue ;
}
$lineToAdd += " " + $sanitizedLine ;
}
if ( $lineToAdd -ne "" ) {
$sw .Write( [ Environment] ::NewLine + $licenseNewParagraph + $lineToAdd + "\par" ) ;
}
$sw .Close( ) ;
}
f u n c t i o n R u n - B u i l d M s i {
Print-Info "Building 32 bits msi installer..."
heat.exe dir "release\win-ia32-unpacked\" -o " scripts\m si_installer_files.wxs" -scom -frag -srd -sreg -gg -cg MattermostDesktopFiles -t " scripts\m si_installer_files_replace_id.xslt" -dr INSTALLDIR
candle.exe -dPlatform= x86 "scripts\msi_installer.wxs" "scripts\msi_installer_files.wxs" -o " scripts\"
2022-03-10 12:47:45 -08:00
light.exe "scripts\msi_installer.wixobj" "scripts\msi_installer_files.wixobj" -loc "resources\windows\msi_i18n\en_US.wxl" -o " release\$( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID)\mattermost-desktop- $( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID) -x86.msi " -b " release\win-ia32-unpacked\"
2019-10-01 05:10:25 -07:00
Print-Info "Building 64 bits msi installer..."
heat.exe dir "release\win-unpacked\" -o " scripts\m si_installer_files.wxs" -scom -frag -srd -sreg -gg -cg MattermostDesktopFiles -t " scripts\m si_installer_files_replace_id.xslt" -t " scripts\m si_installer_files_set_win64.xslt" -dr INSTALLDIR
candle.exe -dPlatform= x64 "scripts\msi_installer.wxs" "scripts\msi_installer_files.wxs" -o " scripts\"
2022-03-10 12:47:45 -08:00
light.exe "scripts\msi_installer.wixobj" "scripts\msi_installer_files.wixobj" -loc "resources\windows\msi_i18n\en_US.wxl" -o " release\$( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID)\mattermost-desktop- $( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID) -x64.msi " -b " release\win-unpacked\"
2019-10-01 05:10:25 -07:00
# Only sign the executable and .dll if this is a release and not a pull request
# check.
2020-10-31 11:32:12 -07:00
if ( Test-Path 'env:PFX' ) {
2019-10-01 05:10:25 -07:00
Print-Info " Signing mattermost-desktop- $( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID) -x86.msi (waiting for 15 seconds)... "
Start-Sleep -s 15
# Dual signing is not supported on msi files. Is it recommended to sign with 256 hash.
# src.: https://security.stackexchange.com/a/124685/84134
# src.: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-us/d4b70ecd-a883-4289-8047-cc9cde28b492#0b3e3b80-6b3b-463f-ac1e-1bf0dc831952
2022-03-10 12:47:45 -08:00
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p " $env :PFX_KEY " /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 /d " release\$( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID)\mattermost-desktop- $( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID) -x86.msi " " release\$( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID)\mattermost-desktop- $( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID) -x86.msi "
2019-10-01 05:10:25 -07:00
Print-Info " Signing mattermost-desktop- $( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID) -x64.msi (waiting for 15 seconds)... "
Start-Sleep -s 15
2022-03-10 12:47:45 -08:00
signtool.exe sign /f "./mattermost-desktop-windows.pfx" /p " $env :PFX_KEY " /tr "http://timestamp.digicert.com" /fd sha256 /td sha256 /d " release\$( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID)\mattermost-desktop- $( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID) -x64.msi " " release\$( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID)\mattermost-desktop- $( $env :COM_MATTERMOST_MAKEFILE_BUILD_ID) -x64.msi "
2019-10-01 05:10:25 -07:00
} else {
2020-10-31 11:32:12 -07:00
Print-Info "Certificate file not found, the msi installers won't be signed."
2019-10-01 05:10:25 -07:00
}
}
f u n c t i o n G e t - C e r t {
if ( Test-Path 'env:PFX' ) {
Print-Info "Getting windows certificate"
[ IO.File] ::WriteAllBytes( "./mattermost-desktop-windows.pfx" , [ Convert] ::FromBase64String( $env :PFX) )
$password = " $env :PFX_KEY " | convertto-securestring -asplaintext -force
Print-Info "Importing certificate into the machine"
Import-PfxCertificate -filepath "./mattermost-desktop-windows.pfx" cert:\l ocalMachine\m y -password $password
} else {
2020-10-31 11:32:12 -07:00
Print-Warning "No env:PFX environment variable found, build will not be signed."
2019-10-01 05:10:25 -07:00
}
}
f u n c t i o n R e m o v e - C e r t {
2019-11-19 02:31:32 -08:00
if ( Test-Path 'env:PFX' ) {
2019-10-01 05:10:25 -07:00
Print-Info "Removing windows certificate"
Remove-Item -path "./mattermost-desktop-windows.pfx"
}
}
f u n c t i o n R u n - B u i l d {
Check-Deps -Verbose -Throwable
Prepare-Path
2019-10-17 08:11:41 -07:00
Get-Cert
2019-10-01 05:10:25 -07:00
Run-BuildId
Run-BuildElectron
Run-BuildForceSignature
Run-BuildLicense
Run-BuildMsi
Remove-Cert
}
f u n c t i o n R u n - T e s t {
Check-Deps -Verbose -Throwable
Prepare-Path
npm test
}
2020-10-31 11:32:12 -07:00
#EndRegion
2019-10-01 05:10:25 -07:00
################################################################################
# Main function
################################################################################
2020-10-31 11:32:12 -07:00
#Region
2019-10-01 05:10:25 -07:00
f u n c t i o n M a i n {
try {
if ( $makeRule -eq $null ) {
Print-Info "No argument passed to the make file. Executing " "all" " rule."
$makeRule = "all"
}
Backup-ComputerState
switch ( $makeRule .toLower( ) ) {
"all" {
Install-Deps
Run-Build
}
"build" {
2020-10-31 12:44:53 -07:00
Install-Deps
2019-10-01 05:10:25 -07:00
Run-Build
}
"test" {
2020-10-31 12:44:53 -07:00
Install-Deps
2019-10-01 05:10:25 -07:00
Run-Test
}
"install-deps" {
Install-Deps
}
"optimize" {
Optimize-Build
}
2019-10-17 08:11:41 -07:00
"install-cert" {
Get-Cert
}
"remove-cert" {
Remove-Cert
}
2019-10-01 05:10:25 -07:00
default {
Print-Error "Makefile argument " " $_ " " is invalid. Build process aborted."
}
}
$env :COM_MATTERMOST_MAKEFILE_EXECUTION_SUCCESS = $true
2020-10-31 11:32:12 -07:00
$exitCode = 0
2019-10-01 05:10:25 -07:00
} catch {
switch ( $_ .Exception.Message) {
"com.mattermost.makefile.deps.missing" {
Print-Error " The following dependencies are missing: $( $missing -Join ', ' ) .`n Please install dependencies as an administrator:`n # makefile.ps1 install-deps "
2020-10-31 11:32:12 -07:00
$exitCode = -1
2019-10-01 05:10:25 -07:00
}
"com.mattermost.makefile.deps.notadmin" {
Print-Error "Installing dependencies requires admin privileges. Operation aborted.`n Please reexecute this makefile as an administrator:`n # makefile.ps1 install-deps"
2020-10-31 11:32:12 -07:00
$exitCode = -2
2019-10-01 05:10:25 -07:00
}
"com.mattermost.makefile.deps.wix" {
Print-Error "There was nothing wrong with your source code,but we found a problem installing wix toolset and couldn't continue. please try re-running the job."
2020-10-31 11:32:12 -07:00
$exitCode = -3
2019-10-01 05:10:25 -07:00
}
default {
Print-Error " Another error occurred: $_ "
2020-10-31 11:32:12 -07:00
$exitCode = -100
2019-10-01 05:10:25 -07:00
}
}
} finally {
if ( !( $env :COM_MATTERMOST_MAKEFILE_EXECUTION_SUCCESS) ) {
Print-Warning "Makefile interrupted by Ctrl + C or by another interruption handler."
}
Restore-ComputerState
2020-10-31 11:32:12 -07:00
exit $exitCode
2019-10-01 05:10:25 -07:00
}
}
M a i n
2020-10-31 11:32:12 -07:00
#EndRegion