Publish-Website.psm1
|
function Get-Project-Libraries { Param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, HelpMessage="Project file")] [string] $Project, [Parameter(HelpMessage="Build configuration")] [string] $Configuration = 'Release', #Level [int] $Level = 0 ) Begin{ } Process{ # Log with Level Write-Verbose "$(''.PadLeft($Level,' ')) Reading project $([IO.Path]::GetFullPath($Project))" # Get content $xmlContent = [xml] (Get-Content -LiteralPath $Project) $directory = Split-Path $Project -Parent # Referenced libraries with HintPath $xmlContent.Project.ItemGroup.Reference.HintPath | ForEach-Object { if($_){ Write-Output ([IO.Path]::GetFullPath([IO.Path]::Combine($directory, $_))) } } # Project assembly name $assemblyName = $null $xmlContent.Project.PropertyGroup.AssemblyName | ForEach-Object { if($_){ $assemblyName = $_ + ".dll" if($xmlContent.Project.Sdk.Length){ Write-Output ([IO.Path]::GetFullPath([IO.Path]::Combine($directory, 'bin', $Configuration, 'netstandard2.0', $assemblyName))) } else{ Write-Output ([IO.Path]::GetFullPath([IO.Path]::Combine($directory, 'bin', $Configuration, $assemblyName))) } } } # if($null -eq $assemblyName){ $assemblyName = [IO.Path]::GetFileNameWithoutExtension($Project) + ".dll" Write-Output ([IO.Path]::GetFullPath([IO.Path]::Combine($directory, 'bin', $Configuration, $assemblyName))) } $Level += 4 # Subproject Get-Content -LiteralPath $Project | Where-Object { $_ -match '<ProjectReference Include="(.+)"' } | ForEach-Object { $anotherProjectPath = Join-Path -Path $directory -ChildPath $matches[1] Get-Project-Libraries -Project $anotherProjectPath -Configuration $Configuration $Level } } End{ } } <# .SYNOPSIS Automati Webform Publish Tool (AWT) .DESCRIPTION Compile and publish website projects .PARAMETER Solution Path to solution file .PARAMETER Configuration Build configuration. Valid values are Release and Debug. Default is Release. .EXAMPLE Publish-Website -Solution .\cisss.sln -Configuration 'Release' #> function Publish-Website { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, HelpMessage="Solution file")] [string] $Solution, [switch] [Parameter(HelpMessage="Use task file for publish")] $EnableTasks, [Parameter(HelpMessage="Build configuration")] [string] $Configuration = "Release", [ValidateSet('quiet','minimal','normal','detailed', 'diagnostic')] $Verbosity = "quiet", [Parameter(HelpMessage="Task file")] [string] $TaskFile = "websites.task" ) Begin{ if ($null -eq (Get-Command dotnet -ErrorAction SilentlyContinue)) { throw "Please install dotnet SDK. [ Download https://dotnet.microsoft.com/en-us/download ]" } if( $null -eq (Get-MsBuildCommand -ErrorAction SilentlyContinue)) { throw "Please install Visual Studio. [ Download https://visualstudio.microsoft.com/downloads/ ]" } } Process{ if(!(Test-Path -LiteralPath $Solution -PathType Leaf)){ throw "$Solution is not valid" } # $solutionFile = ( Resolve-Path $Solution ).Path $solutionPath = Split-Path $solutionFile -Parent #restore nugets Write-Output "#### AWT RESTORE nugets ####" #msbuild restores PackageReference and packages.config projects. Web Site projects are skipped #(as nuget restore did), their packages come from the packages.config of the other projects & "$(Get-MsBuildCommand)" -nologo -t:restore -p:RestorePackagesConfig=true -verbosity:quiet $solutionFile if($LastExitCode) { throw "NUGET RESTORE failed" } #prepare publish $exist = New-Object Collections.Generic.List[String] # $projectSections = Get-Content -LiteralPath $solutionFile -Delimiter "EndProject" $projectSections | ForEach-Object { # Spracuj iba WebSite projekty if($_ -match "Project\(`"{E24C65DC-7377-472B-9ABA-BC803B73C61A}`"\) = `"([^`"]*)`", `"([^`"]*)`""){ $site = $Matches[1] $sitePath = $Matches[2] Write-Verbose "Found website project $site with $sitePath" # $binPath = [IO.Path]::Combine($solutionPath, $sitePath, 'bin') if(!(Test-Path -LiteralPath $binPath -PathType 'Container')){ New-Item -Path $binPath -Type 'Directory' | Out-Null } # if($_ -match "ProjectReferences = `"([^`"]*)`""){ $childProjects = @() $Matches[1] -split ';' | ForEach-Object { $projectReference, $library = $_.Split('|') if( $library) { if(-not $exist.Contains($library)) { # $exist.Add($library) # $projectSections | Where-Object { $_ -match "Project\(`"{.*}`"\) = `"[^`"]*`", `"([^`"]*)`", `"$projectReference`"" } | Select-Object -First 1 | Out-Null Write-Verbose "Found required library $library from project $($Matches[1])" $projectFile = [IO.Path]::Combine($solutionPath, $Matches[1]) $projectPath = Split-Path $projectFile -Parent $fileName = [IO.Path]::GetFileName($projectFile) if($childProjects -notcontains $projectFile){ $childProjects+= $projectFile } if((Get-Content -LiteralPath $projectFile) -match "<Project Sdk=`"Microsoft.NET.Sdk`">"){ $libraryPath = [IO.Path]::Combine($projectPath, 'bin', $Configuration, 'netstandard2.0', $library) } else{ $libraryPath = [IO.Path]::Combine($projectPath, 'bin', $Configuration, $library) } # Write-Output "#### AWT BUILD .netstandard/.net48 library ($fileName) [msbuild] ####" $buildResult = Invoke-MsBuild $projectFile -ShowBuildOutputInCurrentWindow -MsBuildParameters "/restore /target:Restore;Build /p:RestoreLockedMode=true /p:Configuration=$Configuration /p:BuildInParallel=true /verbosity:$Verbosity /maxCpuCount /nologo /noWarn:CS0618;CS0169;CS0168;CS1685" if($buildResult.BuildSucceeded -eq $false){ throw ("Build failed after {0:N1} seconds." -f $buildResult.BuildDuration.TotalSeconds) } if(!(Test-Path -LiteralPath $libraryPath -PathType 'Leaf')){ throw("Missing library $libraryPath for $site") } } else{ Write-Verbose "Found compiled library $library from project $($Matches[1])" } } } # Write-Output "#### AWT PREPARE website: $site ####" # Copy child dependencies $childProjects | Get-Project-Libraries -Configuration $Configuration | Select-Object -Unique | ForEach-Object { if(Test-Path -LiteralPath $_ -PathType 'Leaf'){ Write-Verbose "Copying $_ to $binPath" Copy-Item -LiteralPath $_ -Destination $binPath -Force -ErrorAction SilentlyContinue } else{ Write-Warning "Missing $_!" } } } } } if ($EnableTasks.IsPresent){ $path = Get-SolutionPath $Solution # $task = [System.IO.Path]::Combine($path.Devops,$TaskFile) if (-not (Test-Path -PathType Leaf -Path $task)){ $task = [System.IO.Path]::Combine($path.Src,$TaskFile) if (-not (Test-Path -PathType Leaf -Path $task)){ $message = "$TaskFile is not found!" Write-Error "#### AWT TASK PUBLISH failed: $message ####" throw $message } } # Write-Output "#### AWT TASK PUBLISH $solutionFile using configuration: $Configuration ####" $buildResult = Invoke-MsBuild $task -ShowBuildOutputInCurrentWindow -MsBuildParameters "/maxCpuCount /p:RestoreLockedMode=true /p:Configuration=$Configuration /p:BuildInParallel=true /p:AspNetConfiguration=$Configuration /verbosity:$Verbosity /nologo /noWarn:CS0618;CS0169;CS0168;CS1685" if ($buildResult.BuildSucceeded) { Write-Output "#### AWT TASK PUBLISH succeeded ###" } else { Write-Error "#### AWT TASK PUBLISH failed: $($buildResult.Message) ####" throw ("Publish failed after {0:N1} seconds." -f $buildResult.BuildDuration.TotalSeconds) } # Cleanup if($null -ne $path.Output) { Write-Verbose "Publish cleanup [$($path.Output)]" Get-ChildItem -Path $path.Output -Recurse -Filter *.pdb -File -ErrorAction SilentlyContinue | Remove-Item -Force } } else{ #publish $projectSections | ForEach-Object { # Spracuj iba WebSite projekty if($_ -match "Project\(`"{E24C65DC-7377-472B-9ABA-BC803B73C61A}`"\) = `"([^`"]*)`", `"([^`"]*)`""){ $site = $Matches[1] $publishPath = $null if($_ -match "$Configuration.AspNetCompiler.TargetPath = `"([^`"]*)`""){ $publishPath = ([IO.Path]::Combine($solutionPath, $Matches[1])) } Write-Output "#### AWT PUBLISH website: $site ####" # Build Website $siteName = $site.Replace(".","_") # $buildResult = Invoke-MsBuild $solutionFile -ShowBuildOutputInCurrentWindow -MsBuildParameters "/restore /target:$siteName;Restore;Build;Publish /p:RestoreLockedMode=true /p:Configuration=$Configuration /p:BuildInParallel=true /verbosity:$Verbosity /maxCpuCount /nologo /noWarn:CS0618;CS0169;CS0168;CS1685" if ($buildResult.BuildSucceeded) { Write-Output "#### AWT PUBLISH succeeded: $site ###" } else { Write-Error "#### AWT PUBLISH failed: $site => $($buildResult.Message) ####" throw ("Publish failed after {0:N1} seconds." -f $buildResult.BuildDuration.TotalSeconds) } # Cleanup if($null -ne $publishPath) { Write-Verbose "Publish cleanup [$publishPath]" Get-ChildItem -Path $publishPath -Recurse -Filter *.pdb -File -ErrorAction SilentlyContinue | Remove-Item -Force } } } } } End{ } } Export-ModuleMember -Function Publish-WebSite # SIG # Begin signature block # MIIIEwYJKoZIhvcNAQcCoIIIBDCCCAACAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDgxvhBfQGqM+tb # xZRf8iTIqgyNg/qjNked+s/ESYbqoKCCBQ8wggULMIIC86ADAgECAgIApTANBgkq # 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 # AgELMQ4wDAYKKwYBBAGCNwIBFjAvBgkqhkiG9w0BCQQxIgQgwDggMCHFMsI6qVQ9 # Jqz5cRsX97prFpACNm8wxtZT8DEwDQYJKoZIhvcNAQEBBQAEggEAvCo1bvUKOGXm # +mGrrurYj2VFMSzAfiUlVDrbvbYU3/nIdosNwC8E/p+oNLmJP9NeKWJoqTyqRAZz # CZURlu5VKDcdHRTj3KlUK86UD2M3R1M0Ln3IQDBsXk1lJHUITWjSyZg5AqusRidK # wgAmwIlaV2HBFvkNevc+/uImCWo1ykNDBz9/5GSNc2Q8N64GKp6IC+kVvFz7lR2m # OClgGSsCvG6e+6SN8s1HkPw6/bd4lQzXNR8d7vAC9MyJ69mt/kVihJ4XOuT1ceBL # UpVs/Af30Sy9c5EsRTsGV31CGYM5bddg5Xyxy68xdci+I8a6KT7cqm9JmKuRr5lp # JBS/5ZX4vg== # SIG # End signature block |