AL/Invoke-CompileApp.ps1
<# .Synopsis Compiles the app .Description Compiles the app for the current project and optionally updates the build number of the app and installs it .Parameter ContainerName Token to access Azure DevOps. Can be provided in settings.json .Parameter pfxFile Path to the code sign certificate .Parameter pfxPassword Password for the code sign certificate .Parameter SourcePath Path to the current project. If not defined, the current folder will be used .Parameter OutputPath Path where the compiled app will be saved .Parameter BuildNumber Defines the new build number that should be used to update the app. If not specified, the build numbers revision will be updated (major.minor.revision.build) .Parameter DoNotUpdateVersion Add this switch to not update the build number of the app .Parameter DoNotInstallApp Add this switch to skip the install of the compiled app .Example Invoke-CompileApp -pfxFile "C:\pfx.pfx" -pfxPassword (ConvertTo-SecureString "P@ssword1" -AsPlainText -Force) -OutputPath "C:\Output" -DoNotUpdateVersion #> function Invoke-CompileApp { Param( [Parameter(Mandatory=$false)] [string] $ContainerName, [Parameter(Mandatory=$false)] [string] $pfxCertificate = $null, [Parameter(Mandatory=$false)] [securestring] $pfxFile = $null, [Parameter(Mandatory=$false)] [securestring] $pfxPassword = $null, [Parameter(Mandatory=$false)] [string] $SourcePath = (Get-Location), [Parameter(Mandatory=$true)] [string] $OutputPath, [Parameter(Mandatory=$false)] [string] $BuildNumber = "", [switch] $DoNotUpdateVersion, [switch] $DoNotInstallApp ) $ContainerName = Get-NewContainerName -SourcePath $SourcePath -ContainerName $ContainerName if (!(Test-Path $OutputPath)) { New-EmptyDirectory $OutputPath } if (!(Test-Path (Join-Path $OutputPath "app"))) { New-EmptyDirectory (Join-Path $OutputPath "app") } if (!(Test-Path (Join-Path $OutputPath "runtimeapp"))) { New-EmptyDirectory (Join-Path $OutputPath "runtimeapp") } if (!(Test-Path (Join-Path $OutputPath "testapp"))) { New-EmptyDirectory (Join-Path $OutputPath "testapp") } if (!(Test-Path (Join-Path $OutputPath "tests"))) { New-EmptyDirectory (Join-Path $OutputPath "tests") } Write-Output @' _____ _ _ _ _____ _ _ | __ \ | | | (_) / ____| | | | | | | | | _____ ___ __ | | ___ __ _ __| |_ _ __ __ _ | (___ _ _ _ __ ___ | |__ ___ | |___ | | | |/ _ \ \ /\ / / '_ \| |/ _ \ / _` |/ _` | | '_ \ / _` | \___ \| | | | '_ ` _ \| '_ \ / _ \| / __| | |__| | (_) \ V V /| | | | | (_) | (_| | (_| | | | | | (_| | ____) | |_| | | | | | | |_) | (_) | \__ \ |_____/ \___/ \_/\_/ |_| |_|_|\___/ \__,_|\__,_|_|_| |_|\__, | |_____/ \__, |_| |_| |_|_.__/ \___/|_|___/ __/ | __/ | |___/ |___/ '@ [version]$platform = Get-AppKeyValue -SourcePath $SourcePath -KeyName 'platform' if ($platform.Major -ge 15) { Wait-ForTenantReady -containerName $ContainerName -tenant "default" } if ($null -eq $pfxCertificate -or $pfxCertificate -eq "") { if ($null -eq $pfxFile -or $pfxFile -eq "") { $pfxCertificate = (Get-PfxFile -publisher (Get-AppKeyValue -SourcePath $SourcePath -KeyName 'publisher')) } else { $pfxCertificate = ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pfxFile))) } } if ($null -eq $pfxPassword) { $pfxPassword = (Get-PfxPassword -publisher (Get-AppKeyValue -SourcePath $sourcePath -KeyName 'publisher')) } $CompilerPath = Get-CompilerFromContainer -ContainerName $ContainerName Get-AllSymbol -SourcePath $SourcePath -ContainerName $ContainerName #update the app version with the build number (actually store it in the Revision - the last element of the version no) if (!$DoNotUpdateVersion.IsPresent) { if ($BuildNumber -eq "") { throw "BuildNumber missing" } $AppVersion = [System.Version]::new((Get-AppKeyValue -SourcePath $SourcePath -KeyName 'version')) Set-AppKeyValue -SourcePath $SourcePath -KeyName 'version' -KeyValue ('{0}.{1}.{2}.{3}' -f $AppVersion.Major, $AppVersion.Minor, $AppVersion.Build, $BuildNumber) } try { Remove-Item (Join-Path $SourcePath '.altemplates') -Recurse -Force Remove-Item (Join-Path $SourcePath '.altestrunner') -Recurse -Force } catch { Write-Output "Did not remove folders" } Write-Output @' _____ _ _ _ / ____| (_) (_) /\ | | ___ _ __ ___ _ __ _| |_ _ __ __ _ / \ _ __ _ __ | | / _ \| '_ ` _ \| '_ \| | | | '_ \ / _` | / /\ \ | '_ \| '_ \ | |___| (_) | | | | | | |_) | | | | | | | (_| | / ____ \| |_) | |_) | \_____\___/|_| |_| |_| .__/|_|_|_|_| |_|\__, | /_/ \_\ .__/| .__/ | | __/ | | | | | |_| |___/ |_| |_| '@ # first compile the app only (remove tests) $TestPath = New-TempDirectory Copy-Item "$SourcePath/*" $TestPath -Recurse # update dependencies Remove-ALTestDependencyList -sourcePath $SourcePath #set the target, if applicable if ((Get-EnvironmentKeyValue -SourcePath $SourcePath -KeyName target) -ne "") { Set-AppKeyValue -SourcePath $TestPath -KeyName target -KeyValue (Get-EnvironmentKeyValue -SourcePath $SourcePath -KeyName target) } Remove-Item (Join-Path $SourcePath 'Tests') -Recurse -Force if (!(Invoke-BuildALAppPackage -SourcePath $SourcePath -ContainerName $ContainerName -CompilerPath $CompilerPath -SignApp -DoNotDownloadSymbols -Install:(!$DoNotInstallApp.IsPresent) -pfxCertificate $pfxCertificate -pfxPassword $pfxPassword)){ throw "App could not be built" } if (Test-Path "$SourcePath/Translations/*.g.xlf" -PathType Leaf) { Copy-Item "$SourcePath/Translations/*.g.xlf" -Destination "$TestPath/Translations/" -Force | Out-Null } Copy-Item "$SourcePath/*.app" "$OutputPath/app" Copy-Item "$SourcePath/*.app" "$TestPath/.alpackages" Write-Output @' _____ _ _ _ _______ _ / ____| (_) (_) |__ __| | | /\ | | ___ _ __ ___ _ __ _| |_ _ __ __ _ | | ___ ___| |_ / \ _ __ _ __ | | / _ \| '_ ` _ \| '_ \| | | | '_ \ / _` | | |/ _ \/ __| __| / /\ \ | '_ \| '_ \ | |___| (_) | | | | | | |_) | | | | | | | (_| | | | __/\__ \ |_ / ____ \| |_) | |_) | \_____\___/|_| |_| |_| .__/|_|_|_|_| |_|\__, | |_|\___||___/\__| /_/ \_\ .__/| .__/ | | __/ | | | | | |_| |___/ |_| |_| '@ #build the test app $TestAppId = Get-EnvironmentKeyValue -SourcePath $SourcePath -KeyName 'testappid' if($null -eq $TestAppId) { $TestAppId = ([Guid]::NewGuid().Guid) } Set-AppKeyValue -SourcePath $TestPath -KeyName id -KeyValue $TestAppId Set-AppKeyValue -SourcePath $TestPath -KeyName name -KeyValue ('{0} Tests' -f (Get-AppKeyValue -SourcePath $TestPath -KeyName name)) Set-AppKeyValue -SourcePath $TestPath -KeyName screenshots '' #add dependency on test symbols for test app [version]$BCFallPlatform = '15.0.0.0' [version]$platform = Get-AppKeyValue -SourcePath $TestPath -KeyName 'platform' if ($platform -ge $BCFallPlatform){ Add-TestAppsToAppJson -SourcePath $TestPath Get-AllSymbol -SourcePath $TestPath -ContainerName $ContainerName } else{ # for 2018 (and BC 14), it doesn't properly work to have "test" set, since it updates the symbols when importing the objects (due to possible base object compiles) if (Get-UseStandardTest -MajorVersion $platform.Major -SourcePath $TestPath) { Set-AppKeyValue -SourcePath $TestPath -KeyName 'test' -KeyValue (Get-AppKeyValue -KeyName 'application') Get-AllSymbol -SourcePath $TestPath -ContainerName $ContainerName -includeTestSymbols } else { if (($platform.Major -eq 14) -or ($platform.Major -eq 11)) { Set-AppKeyValue -SourcePath $TestPath -KeyName 'test' -KeyValue (Get-AppKeyValue -KeyName 'application') } else { Set-AppKeyValue -SourcePath $TestPath -KeyName 'test' -KeyValue '' } Get-AllSymbol -SourcePath $TestPath -ContainerName $ContainerName -includeTestSymbols } } New-ALAppDependency -SourcePath $TestPath ` -Id (Get-AppKeyValue -SourcePath $SourcePath -KeyName id) ` -Name (Get-AppKeyValue -SourcePath $SourcePath -KeyName name) ` -Publisher (Get-AppKeyValue -SourcePath $SourcePath -KeyName publisher) ` -Version (Get-AppKeyValue -SourcePath $SourcePath -KeyName version) #remove all directories from the test app apart from those beginning with . and the Logo and Tests folders Get-ChildItem $TestPath -Directory | Where-Object Name -NotLike '.*' | Where-Object Name -NotLike Tests | Where-Object Name -NotLike *Logo* | ForEach-Object {Remove-Item $_.FullName -Force -Recurse} #remove dotnet.al file for test app Get-ChildItem $TestPath | Where-Object Name -Like 'dotnet.al' | ForEach-Object {Remove-Item $_.FullName -Force -Recurse} if ((Get-EnvironmentKeyValue -KeyName 'tests') -eq 'skip') { if (!(Invoke-BuildALAppPackage -SourcePath $TestPath -ContainerName $ContainerName -CompilerPath $CompilerPath -DoNotDownloadSymbols -pfxFile $pfxFile -pfxPassword $pfxPassword)) { throw "test app could not be built" } } else { if (!(Invoke-BuildALAppPackage -SourcePath $TestPath -ContainerName $ContainerName -CompilerPath $CompilerPath -DoNotDownloadSymbols -Install:(!$DoNotInstallApp.IsPresent) -pfxFile $pfxFile -pfxPassword $pfxPassword)) { throw "test app could not be built" } } Write-Output @' _____ _ / ____| | | | | | ___ __ _ _ __ _ _ _ __ | | | |/ _ \/ _` | '_ \| | | | '_ \ | |____| | __/ (_| | | | | |_| | |_) | \_____|_|\___|\__,_|_| |_|\__,_| .__/ | | |_| '@ Copy-Item "$TestPath/*.app" (Join-Path $OutputPath "testapp") Remove-Item $TestPath -Recurse if ($CompilerPath -ne "") { Remove-Item (Split-Path (Split-Path (Split-Path (Split-path $CompilerPath -Parent) -Parent) -Parent) -Parent) -Recurse -Force -ErrorAction SilentlyContinue } } Export-ModuleMember Invoke-CompileApp |