Publish-Application.psm1
|
# function Get-Absolute-Path([string]$path){ if($path.StartsWith(".")){ $path = [IO.Path]::Combine((Get-Location).Path,$path) } return [IO.Path]::GetFullPath($path) } # function Get-Custom-Property([pscustomobject] $property, $msbuid){ if ($null -eq $property ){ return '' } if($true -eq $msbuid) { $parameters = $property.PSObject.Properties | Select-Object @{ Name="Property"; Expression= { "/property:"+ $_.Name + "=" + $_.Value } } | Select-Object -ExpandProperty Property } else{ $parameters = $property.PSObject.Properties | Select-Object @{ Name="Property"; Expression= { "/p:"+ $_.Name + "=" + $_.Value } } | Select-Object -ExpandProperty Property } return $parameters -join ' ' } # function Get-Default-Settings($debug,$configuration,[string] $publishPath,[string] $project){ # $setting = @{} # $setting.Enabled = $true if($null -ne $configuration.Enabled){ $setting.Enabled = $configuration.Enabled } # $setting.Configuration = "Release" if($debug){ if($null -ne $configuration.Configuration){ $setting.Configuration = $configuration.Configuration } } # $setting.Runtime = "linux-x64" if($null -ne $configuration.Runtime){ $setting.Runtime =$configuration.Runtime } # $setting.SelfContained = $false if($null -ne $configuration.SelfContained){ $setting.SelfContained = $configuration.SelfContained } # $setting.SingleFile = $false if($null -ne $configuration.SingleFile ){ $setting.SingleFile = $configuration.SingleFile } # $path = $configuration.Path if([string]::IsNullOrEmpty($path)){ $path = "" } # if([string]::IsNullOrEmpty($path) -and $null -ne $project){ $path = [IO.Path]::GetFileNameWithoutExtension($project) } # $setting.Path = [IO.Path]::Combine($publishPath, $path); # $setting.Properties = $configuration.Properties return $setting } # function Get-Pack-Property([string] $project){ #legacy (non sdk) csproj has no Pack target - import the one the .NET SDK ships. The nuspec stays #authoritative for id and version, PackageVersion is only a placeholder the Pack target requires if((Get-Content -Path $project -Raw) -match '<Project[^>]*\sSdk\s*=|<Sdk\s+Name\s*=|<Import[^>]*\sSdk\s*='){ return @() } #same sdk the dotnet pack below resolves (global.json) $version = dotnet --version $sdk = dotnet --list-sdks | Where-Object { $_ -like "$version *" } | Select-Object -First 1 if($sdk -notmatch '\[(?<path>.+)\]$'){ throw "dotnet SDK $version not found" } $targets = [IO.Path]::Combine($Matches.path, $version, 'Sdks', 'NuGet.Build.Tasks.Pack', 'build', 'NuGet.Build.Tasks.Pack.targets') if(-not (Test-Path -Path $targets -PathType Leaf)){ throw "Missing pack targets $targets" } return @("-p:CustomAfterMicrosoftCommonTargets=$targets", '-p:PackageVersion=1.0.0') } <# .Synopsis Automatic Publish Tool (APT) .DESCRIPTION Publish visual studio solution .EXAMPLE Publish-Application D:\Projects\project.sln D:\Project\publish\admin .NOTES Author: Imrich Szolik #> function Publish-Application { [CmdletBinding()] [Alias()] Param( # Solution file (sln) [string] [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$false, HelpMessage="Project file.")] $Solution, #Publish path. [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$false, HelpMessage="Publish path.")] [string] $PublishPath, #config [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, HelpMessage="Publish json config")] [string] $JsonConfig = "(lomtec|nuaktiv)\.json", #verbosity [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, HelpMessage="Build verbosity")] [ValidateSet('quiet','minimal','normal','detailed', 'diagnostic')] [string] $Verbosity = "quiet", #verbosity [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, HelpMessage="Build platform")] [ValidateSet('all','linux','windows')] [string] $Platform = "all", #enable debug mode [switch] [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, HelpMessage="Enable Debug compilation")] $EnableDebug ) Begin{ #required if ($null -eq (Get-Command dotnet -ErrorAction SilentlyContinue)) { throw "Please install dotnet SDK. [ Download https://dotnet.microsoft.com/en-us/download ]" } #validation if ($platform -eq 'linux') { $msbuild = $null } else{ $msbuild = (Get-MsBuildCommand -ErrorAction SilentlyContinue) if( $null -eq $msbuild) { throw "Please install Visual Studio. [ Download https://visualstudio.microsoft.com/downloads/ ]" } } #solution if( (-not (Test-Path -Path $Solution -PathType Leaf)) -or (-not ( $Solution -like '*.sln')) ){ throw "$Solution is not valid" } $solution = ( Resolve-Path $Solution ).Path $solutionPath = Split-Path -Parent $Solution # $PublishPath = Get-Absolute-Path $PublishPath # } Process{ try{ #restore packages Write-Host "#### APT NUGET restoring packages ####" if($null -ne $msbuild){ #msbuild restores PackageReference and packages.config projects (older projects) & "$msbuild" -nologo -t:restore -p:RestorePackagesConfig=true -verbosity:quiet $solution } else{ dotnet restore $solution --verbosity quiet } if($LastExitCode) { throw "NUGET RESTORE failed" } #config $lomtecConfigs = Get-ChildItem -Recurse $solutionPath | Where-Object { $_.Name -Match $JsonConfig } | Select-Object -ExpandProperty FullName if($lomtecConfigs.Length -eq 0){ throw "Not found any build configuration [$JsonConfig]!"} # foreach($lomtec in $lomtecConfigs){ #has project section $project = Get-ChildItem (Split-Path -Parent $lomtec) -Filter "*.csproj" | Select-Object -ExpandProperty FullName -First 1 if($null -eq $project){ Write-Verbose "Missing csproj file for [$lomtec]" Continue } #project path $projectPath = Split-Path $project -Parent #json $json = Get-Content $lomtec | ConvertFrom-Json #has build section if($null -eq $json.Build){ Write-Warning "Missing Build section for [$lomtecConfigs]" Continue } #process Publish or Nuget if($null -ne $json.Build.Publish -and $json.Build.Publish.Count -gt 0){ # foreach($config in $json.Build.Publish){ #setting $setting = Get-Default-Settings $EnableDebug.IsPresent $config $PublishPath $project #detailed log Write-Verbose " Configuration $($setting | ConvertTo-Json -Compress)" #platform validation if($platform -ne 'all'){ # if($platform -eq 'linux'){ if($setting.Runtime -notlike "linux*") { Continue } } # else{ if($setting.Runtime -notlike "win*") { Continue } } } # if( (($json.Build.Publish.Length -eq 0) -and ($json.Build.Publish.Enabled -eq $false)) -or ($setting.Enabled -eq $false) ) { Write-Warning "#### APT PUBLISH $(Split-Path -Leaf $project) [$(Split-Path -Leaf $setting.Path)] is not enabled ####" } else{ #initial cleanup for nuget Get-ChildItem $projectPath -Recurse -Directory -Filter obj | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Get-ChildItem $projectPath -Recurse -Directory -Filter bin | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue # if(($json.Build.Command -eq 'msbuild') -and ($null -ne $msbuild)){ $customProperties = Get-Custom-Property $setting.Properties $true Write-Host "#### APT PUBLISH $(Split-Path -Leaf $project) to $($setting.Path) [msbuild] ####" & "$msbuild" -nologo -nodeReuse:false -m:4 -property:UseSharedCompilation=false -verbosity:$Verbosity -property:Configuration=$($setting.Configuration) /property:OutDir=$($setting.Path) $customProperties -restore $project if($LastExitCode) { throw "MSBUILD BUILD $(Split-Path -Leaf $project) failed" } } else{ $customProperties = Get-Custom-Property $setting.Properties $false Write-Host "#### APT PUBLISH $(Split-Path -Leaf $project) to $($setting.Path) [dotnet] ####" dotnet publish -nologo /nodeReuse:false -m:4 -p:UseSharedCompilation=false --verbosity $Verbosity --runtime $setting.Runtime --configuration $setting.Configuration --self-contained $setting.SelfContained -p:PublishSingleFile=$($setting.SingleFile) $customProperties $project --output $setting.Path if($LastExitCode) { throw "DOTNET PUBLISH $(Split-Path -Leaf $project) failed" } } #final cleanup for nuget Get-ChildItem $projectPath -Recurse -Directory -Filter obj | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Get-ChildItem $projectPath -Recurse -Directory -Filter bin | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } } } elseif($null -ne $json.Build.Nuget){ #setting $setting = Get-Default-Settings $EnableDebug.IsPresent $json.Build.Nuget $PublishPath #detailed log Write-Verbose "Configuration $($setting | ConvertTo-Json -Compress)" # if( ($json.Build.Nuget.Enabled -eq $false) -or ($setting.Enabled -eq $false) ){ Write-Warning "Build/Nuget is disabled for $(Split-Path -Leaf $project)" } else{ #initial cleanup for nuget Get-ChildItem $projectPath -Recurse -Directory -Filter obj | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Get-ChildItem $projectPath -Recurse -Directory -Filter bin | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue if(($json.Build.Command -eq 'msbuild') -and ($null -ne $msbuild)){ $customProperties = Get-Custom-Property $setting.Properties $true Write-Host "#### APT BUILD $(Split-Path -Leaf $project) [msbuild] ####" & "$msbuild" -nologo -nodeReuse:false -m:4 -property:UseSharedCompilation=false -verbosity:$Verbosity -property:Configuration=$($setting.Configuration) $customProperties -restore $project if($LastExitCode) { throw "MSBUILD BUILD $(Split-Path -Leaf $project) failed" } } else{ $customProperties = Get-Custom-Property $setting.Properties $false Write-Host "#### APT BUILD $(Split-Path -Leaf $project) [dotnet] ####" dotnet build -nologo /nodeReuse:false -m:4 -p:UseSharedCompilation=false --verbosity $Verbosity --configuration $setting.Configuration --no-incremental $customProperties $project if($LastExitCode) { throw "DOTNET BUILD $(Split-Path -Leaf $project) failed" } } Write-Host "#### APT NUGET $(Split-Path -Leaf $project) to $($setting.Path) ####" $nuspec = $project.Replace("csproj","nuspec") if(Test-Path -Path $nuspec -PathType Leaf){ #pack the built output with the project nuspec (id, version, dependencies and files from nuspec) $packProperties = @(Get-Pack-Property $project) dotnet pack $project --no-build --no-restore --verbosity quiet --configuration $setting.Configuration --output $setting.Path -p:NuspecFile=$nuspec -p:NuspecBasePath=$projectPath "-p:NuspecProperties=configuration=$($setting.Configuration)" @packProperties if($LastExitCode) { throw "NUGET PACK $(Split-Path -Leaf $project) failed" } } else{ Write-Warning "Missing nuspec $nuspec!" } #final cleanup for nuget Get-ChildItem $projectPath -Recurse -Directory -Filter obj | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Get-ChildItem $projectPath -Recurse -Directory -Filter bin | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } } else{ Write-Warning "Missing Build/Publish or Build/Nuget section for [$lomtecConfigs]!" } } #cleanup Write-Verbose "Publish cleanup [$PublishPath]" Get-ChildItem -Path $PublishPath -Recurse -Filter *.pdb -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue Get-ChildItem -Path $PublishPath -Recurse -Filter $JsonConfig -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue Get-ChildItem -Path $PublishPath -Recurse -Filter appsettings.*.json -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue Get-ChildItem -Path $PublishPath -Recurse -Filter web.*.config -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue } finally{ #release build servers (msbuild nodes, roslyn compiler, razor) from memory Write-Verbose "Build server shutdown" dotnet build-server shutdown | Out-Null $global:LASTEXITCODE = 0 } } End{ } } Export-ModuleMember -Function Publish-Application # SIG # Begin signature block # MIIIEwYJKoZIhvcNAQcCoIIIBDCCCAACAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCy00tkh4/Xv7aK # WYUhkU058DewJqBJ5w4n5HbmypvlFqCCBQ8wggULMIIC86ADAgECAgIApTANBgkq # hkiG9w0BAQsFADCBoDELMAkGA1UEBhMCU0sxETAPBgNVBAgTCFNsb3Zha2lhMRMw # EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpMb210ZWMuY29tMSswKQYDVQQD # EyJMb210ZWMuY29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MScwJQYJKoZIhvcN # AQkBFhhJbXJpY2guU3pvbGlrQGxvbXRlYy5jb20wHhcNMTkwMzI2MTUwNDQzWhcN # MzAwMTAxMDAwMDAwWjCBkzELMAkGA1UEBhMCU0sxETAPBgNVBAgTCFNsb3Zha2lh # MRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpMb210ZWMuY29tMR4wHAYD # VQQDExVMb210ZWMuY29tIFBvd2Vyc2hlbGwxJzAlBgkqhkiG9w0BCQEWGEltcmlj # aC5Tem9saWtAbG9tdGVjLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC # ggEBAL4n4nCHbkdrf09IHNFQ2P/z6I43GKScsFJOQHUMkRD3ALoUFL/URC9sW2fY # rqG5VkFAKhnM0VxeiICR53cAshNShjFf58PhaS973jtCoJcaugIVBVoFIuQ+gnNY # Jp2VdBbIPKMW4JjjZOxBEkHpMWmfitXKWGKeU68Qcn3oI6PO+YSztfXLe1NU+1GI # O3fA7E0vHVPUf/qWZXMYU5ElLQVm9AXbfX79mTgl76A57+OC6j+Aehkd2OPfUl4w # snox3fOyUAUA8iojeWh97PpXd/s+RkuxWdgsC4YSWDUjhZSzBkml9uerYqo9a+XA # b39dvkpK9TPl3q5HNBQMkCfp8bkCAwEAAaNaMFgwCQYDVR0TBAIwADALBgNVHQ8E # BAMCB4AwKwYDVR0lBCQwIgYIKwYBBQUHAwMGCisGAQQBgjcCARUGCisGAQQBgjcC # ARYwEQYJYIZIAYb4QgEBBAQDAgSwMA0GCSqGSIb3DQEBCwUAA4ICAQAJJapv9skY # jh5HTsJnqDdtqh7YOOXuA8g+DKBj+5gDEZE5V9VhAFVp8UJ9RoITGGIRTVId0lqc # LJiVSTHx305VW9aID8vo77kfrTyXvPXNIsTtHnPkkwH47+CoiY3IpPQLjUA/Q6Qd # qwINvvwom7/Wc+OoIqlPdJH5DbBrIy85dr6M/Lm3Rw2BolcTRwXTB3xAhweth78B # P6pbcAd32FdymkRopLIihuNs7g7ZR/Q/5803G+OiQIMRGyTvaQ+aQjJgFpkzp7NI # whzougfCOV47Sc89jEpUqw16i2UFfz2ywOlWUyYtue1S1PjM1ljgJfRo+e0wUnFp # gFQzXGF1bTYVaQ4e3nJleADfvqeXoH2AYeBTbz9BcogkkfURAC3iiob1bNs5jE1C # brEDCw6m/03k0oOmm3xQksXyAhBYuUkRwu9jd4y3FwZ/syDGLz3b6cY8o1YyINOO # A3B2r92shNt0rWhJu3v+qcIVmFQ0aKlhNNRoiVlQgJ7NgO0UV+vU2lgiscpUSxEt # xKN+450r49su06NA6zsyn3CELUmVkPyjx5fyizwt9KxVuYOUSEb32Y7QCffHJ1qt # F6SuQrKbgb/24y7cCDW6PDVRvPOySUlKu9sPykICDjvzXBvjYEILM7AmtYCIBGQg # imBsQvTEoXJXiwAOi1XNz3LxcjQHQ/ZM4zGCAlowggJWAgEBMIGnMIGgMQswCQYD # VQQGEwJTSzERMA8GA1UECBMIU2xvdmFraWExEzARBgNVBAcTCkJyYXRpc2xhdmEx # EzARBgNVBAoTCkxvbXRlYy5jb20xKzApBgNVBAMTIkxvbXRlYy5jb20gQ2VydGlm # aWNhdGlvbiBBdXRob3JpdHkxJzAlBgkqhkiG9w0BCQEWGEltcmljaC5Tem9saWtA # bG9tdGVjLmNvbQICAKUwDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEK # MAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3 # AgELMQ4wDAYKKwYBBAGCNwIBFjAvBgkqhkiG9w0BCQQxIgQgsJyyBrpTmYqJ/1zV # ryCvm5b76IpYcTrYn9uD4S5F0iAwDQYJKoZIhvcNAQEBBQAEggEAL8XacAwLRA2r # 1wfVHKDFSVEQFGbt1f32S3qS7M97RKSRwceH8HpWGRGFy8PWeBAKLVk+qhUKGnGr # 5WtBLzKN/ZAqeqt4ojs4YYR45jIVxy9Fitb2HPtU8IYXcJZaHpHULAxL+8QV2j4s # A7DM2YMfxNUrzjJsS8Z+6WAyM1oR3ap0uTikQokySuJzaX7Tgfl+Mo9Ku5E9G7W5 # zWMzL4kM6v3hl7TIB0J/2L5WcvEVHnVUOQ3OFAhgO2udjSHjYaBwa3unFXy/U4la # jqrOv1uDXjYVX744V4Ih1CtnzpX1YFH7dfhrq1JKLhR6yRJrMG3brgdkEhFJiLbB # LOLBZNEiMQ== # SIG # End signature block |