Publish-Website.psm1
<#
.SYNOPSIS Parse project and all child projects and return dependent libraries .DESCRIPTION Parse project and all child projects and return dependent libraries .PARAMETER Project Path to project file .PARAMETER Configuration Build configuration. Valid values are Release and Debug. Default is Release. .EXAMPLE Get-Project-Libraries -Project .\Components\DMS\DMS\DMS.csproj -Configuration 'Release' .EXAMPLE Get-Item -LiteralPath .\Components\DMS\DMS\DMS.csproj | Get-Project-Libraries #> 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' .EXAMPLE Get-Item -LiteralPath .\cisss.sln | Publish-Website #> function Publish-Website { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, HelpMessage="Solution file")] [string] $Solution, [Parameter(HelpMessage="Build configuration")] [ValidateSet('Release','Debug')] [string] $Configuration = "Release", [switch] [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, HelpMessage="Disable restore nugets")] $DisableRestoreNugets, [switch] [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, HelpMessage="Force rebuild")] $ForceRebuild, [ValidateSet('quiet','minimal','normal',' detailed', 'diagnostic')] $Verbosity = "quiet", [switch] [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$false, HelpMessage="Disable cleanup")] $DisableCleanup ) Begin{ } Process{ # if(!(Test-Path -LiteralPath $Solution -PathType 'Leaf')){ throw "File is missing [$Solution]." } # $solutionFile = ( Resolve-Path $Solution ).Path $solutionPath = Split-Path $solutionFile -Parent # $projectSections = Get-Content -LiteralPath $solutionFile -Delimiter "EndProject" #restore nugets if(!$DisableRestoreNugets.IsPresent){ Write-Output "#### AWT RESTORE nugets ####" nuget restore $solutionFile -verbosity quiet if($LastExitCode) { throw "NUGET RESTORE failed" } } #prepare publish $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 } $publishPath = $null if($_ -match "$Configuration.AspNetCompiler.TargetPath = `"([^`"]*)`""){ $publishPath = ([IO.Path]::Combine($solutionPath, $Matches[1])) } # cleanup if( -not ($DisableCleanup.IsPresent)) { Write-Verbose "Remove publish [$publishPath] & bin [$binPath] folder " # if($null -ne $publishPath) { Remove-Item -Path $publishPath -Force -Recurse -ErrorAction SilentlyContinue } # Get-ChildItem -Path $binPath -Recurse | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } # if($_ -match "ProjectReferences = `"([^`"]*)`""){ $childProjects = @() $Matches[1] -split ';' | ForEach-Object { $projectReference, $library = $_.Split('|') if($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) # if(!(Test-Path -LiteralPath $libraryPath -PathType 'Leaf') -or $ForceRebuild.IsPresent){ Write-Output "#### AWT BUILD .netstandard library [$fileName] ####" dotnet build -nologo --configuration $Configuration $projectFile if($LastExitCode) { throw "DOTNET $(Split-Path -Leaf $project) failed" } } # if(!(Test-Path -LiteralPath $libraryPath -PathType 'Leaf')){ throw("Missing library $libraryPath"); } } else{ $libraryPath = [IO.Path]::Combine($projectPath, 'bin', $Configuration, $library) # if(!(Test-Path -LiteralPath $libraryPath -PathType 'Leaf') -or $ForceRebuild.IsPresent){ Write-Output "#### AWT BUILD .net48 library [$fileName] ####" $buildResult = Invoke-MsBuild $projectFile -ShowBuildOutputInCurrentWindow -MsBuildParameters "/restore /target:Restore;Build /p:Configuration=$Configuration /verbosity:$Verbosity /nologo /noWarn:CS0618;CS0169;CS0168" 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"); } } } } 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 $_!" } } } } } #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 /verbosity:$Verbosity /nologo /noWarn:CS0618;CS0169;CS0168" if($buildResult.BuildSucceeded -eq $false){ 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 # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAMdYjG45/q2hnS # T7sGnM0KutBJayE5BfoUzuPARiwIiKCCBQ8wggULMIIC86ADAgECAgIApTANBgkq # 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 # AgELMQ4wDAYKKwYBBAGCNwIBFjAvBgkqhkiG9w0BCQQxIgQgAl0d1NLJL6Lc2l2L # O91ISyXp7rGMuMdYH9kkLKXQ+zEwDQYJKoZIhvcNAQEBBQAEggEAYfi+DcrJDiJl # qlZ4jVIcdb6QAsgBo5jromoT1tnsTkrc4M0MCbyBpju4SUIb9IcZ5CpkMFIoILED # iqxRbG3qf1UDH5uSClPNU6JsjW7zv9IagYJGLXKzYvTQ10oVyNbn6Po8fNipBdT0 # jrdacMlohJQkH94DE6xiiaYsL0rN7ZBBkCFiFBfOrYGWBc9ViL5bvkPar5lGc+Dq # SeRK7aza226YH24CQIpmlOSuwuYmtMO5yV+xiCv9pw7HGChm8k5jZ+931nq3Z/jC # U5ZHv6J79TEcm4/sIETQiGZb+UjDwGX4fR18yq2NSQ0crqbHALcgnjKUfAOu+NRm # SA/nZVRdQg== # SIG # End signature block |