From ca2d2b3dac171b0164cbe236790a049a6e04354e Mon Sep 17 00:00:00 2001 From: Tommy Parnell Date: Fri, 29 Jul 2016 19:18:45 -0400 Subject: [PATCH] init --- src/ScmOutOfOffice/Models/User.cs | 11 + src/ScmOutOfOffice/Program.cs | 6 +- .../PublishProfiles/publish-module.psm1 | 1231 +++++++++++++++++ .../tparnellOutOfOffice-publish.ps1 | 19 + .../tparnellOutOfOffice.pubxml | 28 + .../Properties/launchSettings.json | 46 +- src/ScmOutOfOffice/ScmOutOfOffice.xproj | 3 +- .../ConnectedService.json | 7 + src/ScmOutOfOffice/Startup.cs | 21 +- src/ScmOutOfOffice/appsettings.json | 6 +- src/ScmOutOfOffice/project.json | 119 +- 11 files changed, 1402 insertions(+), 95 deletions(-) create mode 100644 src/ScmOutOfOffice/Models/User.cs create mode 100644 src/ScmOutOfOffice/Properties/PublishProfiles/publish-module.psm1 create mode 100644 src/ScmOutOfOffice/Properties/PublishProfiles/tparnellOutOfOffice-publish.ps1 create mode 100644 src/ScmOutOfOffice/Properties/PublishProfiles/tparnellOutOfOffice.pubxml create mode 100644 src/ScmOutOfOffice/Service References/Application Insights/ConnectedService.json diff --git a/src/ScmOutOfOffice/Models/User.cs b/src/ScmOutOfOffice/Models/User.cs new file mode 100644 index 0000000..8efb7da --- /dev/null +++ b/src/ScmOutOfOffice/Models/User.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ScmOutOfOffice.Models +{ + public class User + { + } +} diff --git a/src/ScmOutOfOffice/Program.cs b/src/ScmOutOfOffice/Program.cs index 7406224..45f018c 100644 --- a/src/ScmOutOfOffice/Program.cs +++ b/src/ScmOutOfOffice/Program.cs @@ -1,9 +1,9 @@ -using System; +using Microsoft.AspNetCore.Hosting; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore.Hosting; namespace ScmOutOfOffice { @@ -21,4 +21,4 @@ namespace ScmOutOfOffice host.Run(); } } -} +} \ No newline at end of file diff --git a/src/ScmOutOfOffice/Properties/PublishProfiles/publish-module.psm1 b/src/ScmOutOfOffice/Properties/PublishProfiles/publish-module.psm1 new file mode 100644 index 0000000..adc6ada --- /dev/null +++ b/src/ScmOutOfOffice/Properties/PublishProfiles/publish-module.psm1 @@ -0,0 +1,1231 @@ +# WARNING: DO NOT MODIFY this file. Visual Studio will override it. +param() + +$script:AspNetPublishHandlers = @{} + +<# +These settings can be overridden with environment variables. +The name of the environment variable should use "Publish" as a +prefix and the names below. For example: + + $env:PublishMSDeployUseChecksum = $true +#> +$global:AspNetPublishSettings = New-Object -TypeName PSCustomObject @{ + MsdeployDefaultProperties = @{ + 'MSDeployUseChecksum'=$false + 'SkipExtraFilesOnServer'=$true + 'retryAttempts' = 20 + 'EnableMSDeployBackup' = $false + 'DeleteExistingFiles' = $false + 'AllowUntrustedCertificate'= $false + 'MSDeployPackageContentFoldername'='website\' + 'EnvironmentName' = 'Production' + 'AuthType'='Basic' + 'MSDeployPublishMethod'='WMSVC' + } +} + +function InternalOverrideSettingsFromEnv{ + [cmdletbinding()] + param( + [Parameter(Position=0)] + [object[]]$settings = ($global:AspNetPublishSettings,$global:AspNetPublishSettings.MsdeployDefaultProperties), + + [Parameter(Position=1)] + [string]$prefix = 'Publish' + ) + process{ + foreach($settingsObj in $settings){ + if($settingsObj -eq $null){ + continue + } + + $settingNames = $null + if($settingsObj -is [hashtable]){ + $settingNames = $settingsObj.Keys + } + else{ + $settingNames = ($settingsObj | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name) + + } + + foreach($name in @($settingNames)){ + $fullname = ('{0}{1}' -f $prefix,$name) + if(Test-Path "env:$fullname"){ + $settingsObj.$name = ((get-childitem "env:$fullname").Value) + } + } + } + } +} + +InternalOverrideSettingsFromEnv -prefix 'Publish' -settings $global:AspNetPublishSettings,$global:AspNetPublishSettings.MsdeployDefaultProperties + +function Register-AspnetPublishHandler{ + [cmdletbinding()] + param( + [Parameter(Mandatory=$true,Position=0)] + $name, + [Parameter(Mandatory=$true,Position=1)] + [ScriptBlock]$handler, + [switch]$force + ) + process{ + if(!($script:AspNetPublishHandlers[$name]) -or $force ){ + 'Adding handler for [{0}]' -f $name | Write-Verbose + $script:AspNetPublishHandlers[$name] = $handler + } + elseif(!($force)){ + 'Ignoring call to Register-AspnetPublishHandler for [name={0}], because a handler with that name exists and -force was not passed.' -f $name | Write-Verbose + } + } +} + +function Get-AspnetPublishHandler{ + [cmdletbinding()] + param( + [Parameter(Mandatory=$true,Position=0)] + $name + ) + process{ + $foundHandler = $script:AspNetPublishHandlers[$name] + + if(!$foundHandler){ + throw ('AspnetPublishHandler with name "{0}" was not found' -f $name) + } + + $foundHandler + } +} + +function GetInternal-ExcludeFilesArg{ + [cmdletbinding()] + param( + $publishProperties + ) + process{ + $excludeFiles = $publishProperties['ExcludeFiles'] + foreach($exclude in $excludeFiles){ + if($exclude){ + [string]$objName = $exclude['objectname'] + + if([string]::IsNullOrEmpty($objName)){ + $objName = 'filePath' + } + + $excludePath = $exclude['absolutepath'] + + # output the result to the return list + ('-skip:objectName={0},absolutePath=''{1}''' -f $objName, $excludePath) + } + } + } +} + +function GetInternal-ReplacementsMSDeployArgs{ + [cmdletbinding()] + param( + $publishProperties + ) + process{ + foreach($replace in ($publishProperties['Replacements'])){ + if($replace){ + $typeValue = $replace['type'] + if(!$typeValue){ $typeValue = 'TextFile' } + + $file = $replace['file'] + $match = $replace['match'] + $newValue = $replace['newValue'] + + if($file -and $match -and $newValue){ + $setParam = ('-setParam:type={0},scope={1},match={2},value={3}' -f $typeValue,$file, $match,$newValue) + 'Adding setparam [{0}]' -f $setParam | Write-Verbose + + # return it + $setParam + } + else{ + 'Skipping replacement because its missing a required value.[file="{0}",match="{1}",newValue="{2}"]' -f $file,$match,$newValue | Write-Verbose + } + } + } + } +} + +<# +.SYNOPSIS +Returns an array of msdeploy arguments that are used across different providers. +For example this will handle useChecksum, AppOffline etc. +This will also add default properties if they are missing. +#> +function GetInternal-SharedMSDeployParametersFrom{ + [cmdletbinding()] + param( + [Parameter(Mandatory=$true,Position=0)] + [HashTable]$publishProperties, + [Parameter(Mandatory=$true,Position=1)] + [System.IO.FileInfo]$packOutput + ) + process{ + $sharedArgs = New-Object psobject -Property @{ + ExtraArgs = @() + DestFragment = '' + EFMigrationData = @{} + } + + # add default properties if they are missing + foreach($propName in $global:AspNetPublishSettings.MsdeployDefaultProperties.Keys){ + if($publishProperties["$propName"] -eq $null){ + $defValue = $global:AspNetPublishSettings.MsdeployDefaultProperties["$propName"] + 'Adding default property to publishProperties ["{0}"="{1}"]' -f $propName,$defValue | Write-Verbose + $publishProperties["$propName"] = $defValue + } + } + + if($publishProperties['MSDeployUseChecksum'] -eq $true){ + $sharedArgs.ExtraArgs += '-usechecksum' + } + + if($publishProperties['EnableMSDeployAppOffline'] -eq $true){ + $sharedArgs.ExtraArgs += '-enablerule:AppOffline' + } + + if($publishProperties['WebPublishMethod'] -eq 'MSDeploy'){ + if($publishProperties['SkipExtraFilesOnServer'] -eq $true){ + $sharedArgs.ExtraArgs += '-enableRule:DoNotDeleteRule' + } + } + + if($publishProperties['WebPublishMethod'] -eq 'FileSystem'){ + if($publishProperties['DeleteExistingFiles'] -eq $false){ + $sharedArgs.ExtraArgs += '-enableRule:DoNotDeleteRule' + } + } + + if($publishProperties['retryAttempts']){ + $sharedArgs.ExtraArgs += ('-retryAttempts:{0}' -f ([int]$publishProperties['retryAttempts'])) + } + + if($publishProperties['EncryptWebConfig'] -eq $true){ + $sharedArgs.ExtraArgs += '-EnableRule:EncryptWebConfig' + } + + if($publishProperties['EnableMSDeployBackup'] -eq $false){ + $sharedArgs.ExtraArgs += '-disablerule:BackupRule' + } + + if($publishProperties['AllowUntrustedCertificate'] -eq $true){ + $sharedArgs.ExtraArgs += '-allowUntrusted' + } + + # add excludes + $sharedArgs.ExtraArgs += (GetInternal-ExcludeFilesArg -publishProperties $publishProperties) + # add replacements + $sharedArgs.ExtraArgs += (GetInternal-ReplacementsMSDeployArgs -publishProperties $publishProperties) + + # add EF Migration + if (($publishProperties['EfMigrations'] -ne $null) -and $publishProperties['EfMigrations'].Count -gt 0){ + if (!(Test-Path -Path $publishProperties['ProjectPath'])) { + throw 'ProjectPath property needs to be defined in the pubxml for EF migration.' + } + try { + # generate T-SQL files + $EFSqlFiles = GenerateInternal-EFMigrationScripts -projectPath $publishProperties['ProjectPath'] -packOutput $packOutput -EFMigrations $publishProperties['EfMigrations'] + $sharedArgs.EFMigrationData.Add('EFSqlFiles',$EFSqlFiles) + } + catch { + throw ('An error occurred while generating EF migrations. {0} {1}' -f $_.Exception,(Get-PSCallStack)) + } + } + # add connection string update + if (($publishProperties['DestinationConnectionStrings'] -ne $null) -and $publishProperties['DestinationConnectionStrings'].Count -gt 0) { + try { + # create/update appsettings.[environment].json + GenerateInternal-AppSettingsFile -packOutput $packOutput -environmentName $publishProperties['EnvironmentName'] -connectionStrings $publishProperties['DestinationConnectionStrings'] + } + catch { + throw ('An error occurred while generating the publish appsettings file. {0} {1}' -f $_.Exception,(Get-PSCallStack)) + } + } + + if(-not [string]::IsNullOrWhiteSpace($publishProperties['ProjectGuid'])) { + AddInternal-ProjectGuidToWebConfig -publishProperties $publishProperties -packOutput $packOutput + } + + # return the args + $sharedArgs + } +} + +<# +.SYNOPSIS +This will publish the folder based on the properties in $publishProperties + +.PARAMETER publishProperties +This is a hashtable containing the publish properties. See the examples here for more info on how to use this parameter. + +.PARAMETER packOutput +The folder path to the output of the dnu publish command. This folder contains the files +that will be published. + +.PARAMETER pubProfilePath +Path to a publish profile (.pubxml file) to import publish properties from. If the same property exists in +publishProperties and the publish profile then publishProperties will win. + +.EXAMPLE + Publish-AspNet -packOutput $packOutput -publishProperties @{ + 'WebPublishMethod'='MSDeploy' + 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` + 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="$env:PublishPwd"} + +.EXAMPLE +Publish-AspNet -packOutput $packOutput -publishProperties @{ + 'WebPublishMethod'='FileSystem' + 'publishUrl'="$publishDest" + } + +.EXAMPLE +Publish-AspNet -packOutput $packOutput -publishProperties @{ + 'WebPublishMethod'='MSDeploy' + 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` +'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="$env:PublishPwd" + 'ExcludeFiles'=@( + @{'absolutepath'='test.txt'}, + @{'absolutepath'='references.js'} +)} + +.EXAMPLE +Publish-AspNet -packOutput $packOutput -publishProperties @{ + 'WebPublishMethod'='FileSystem' + 'publishUrl'="$publishDest" + 'ExcludeFiles'=@( + @{'absolutepath'='test.txt'}, + @{'absolutepath'='_references.js'}) + 'Replacements' = @( + @{'file'='test.txt$';'match'='REPLACEME';'newValue'='updatedValue'}) + } + +Publish-AspNet -packOutput $packOutput -publishProperties @{ + 'WebPublishMethod'='FileSystem' + 'publishUrl'="$publishDest" + 'ExcludeFiles'=@( + @{'absolutepath'='test.txt'}, + @{'absolutepath'='c:\\full\\path\\ok\\as\\well\\_references.js'}) + 'Replacements' = @( + @{'file'='test.txt$';'match'='REPLACEME';'newValue'='updatedValue'}) + } + +.EXAMPLE +Publish-AspNet -packOutput $packOutput -publishProperties @{ + 'WebPublishMethod'='FileSystem' + 'publishUrl'="$publishDest" + 'EnableMSDeployAppOffline'='true' + 'AppOfflineTemplate'='offline-template.html' + 'MSDeployUseChecksum'='true' +} +#> +function Publish-AspNet{ + param( + [Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + [hashtable]$publishProperties = @{}, + + [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] + [System.IO.FileInfo]$packOutput, + + [Parameter(Position=2,ValueFromPipelineByPropertyName=$true)] + [System.IO.FileInfo]$pubProfilePath + ) + process{ + if($publishProperties['WebPublishMethodOverride']){ + 'Overriding publish method from $publishProperties[''WebPublishMethodOverride''] to [{0}]' -f ($publishProperties['WebPublishMethodOverride']) | Write-Verbose + $publishProperties['WebPublishMethod'] = $publishProperties['WebPublishMethodOverride'] + } + + if(-not [string]::IsNullOrWhiteSpace($pubProfilePath)){ + $profileProperties = Get-PropertiesFromPublishProfile -filepath $pubProfilePath + foreach($key in $profileProperties.Keys){ + if(-not ($publishProperties.ContainsKey($key))){ + 'Adding properties from publish profile [''{0}''=''{1}'']' -f $key,$profileProperties[$key] | Write-Verbose + $publishProperties.Add($key,$profileProperties[$key]) + } + } + } + + if(!([System.IO.Path]::IsPathRooted($packOutput))){ + $packOutput = [System.IO.Path]::GetFullPath((Join-Path $pwd $packOutput)) + } + + $pubMethod = $publishProperties['WebPublishMethod'] + 'Publishing with publish method [{0}]' -f $pubMethod | Write-Output + + # get the handler based on WebPublishMethod, and call it. + &(Get-AspnetPublishHandler -name $pubMethod) $publishProperties $packOutput + } +} + +<# +.SYNOPSIS + +Inputs: + +Example of $xmlDocument: '' +Example of $providerDataArray: + + [System.Collections.ArrayList]$providerDataArray = @() + + $iisAppSourceKeyValue=@{"iisApp" = @{"path"='c:\temp\pathtofiles';"appOfflineTemplate" ='offline-template.html'}} + $providerDataArray.Add($iisAppSourceKeyValue) + + $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile"}} + $providerDataArray.Add($dbfullsqlKeyValue) + + $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile2"}} + $providerDataArray.Add($dbfullsqlKeyValue) + + Manifest File content: + + + + + + +#> +function AddInternal-ProviderDataToManifest { + [cmdletbinding()] + param( + [Parameter(Mandatory=$true, Position=0)] + [XML]$xmlDocument, + [Parameter(Position=1)] + [System.Collections.ArrayList]$providerDataArray + ) + process { + $siteNode = $xmlDocument.SelectSingleNode("/sitemanifest") + if ($siteNode -eq $null) { + throw 'sitemanifest element is missing in the xml object' + } + foreach ($providerData in $providerDataArray) { + foreach ($providerName in $providerData.Keys) { + $providerValue = $providerData[$providerName] + $xmlNode = $xmlDocument.CreateElement($providerName) + foreach ($providerValueKey in $providerValue.Keys) { + $xmlNode.SetAttribute($providerValueKey, $providerValue[$providerValueKey]) | Out-Null + } + $siteNode.AppendChild($xmlNode) | Out-Null + } + } + } +} + +function AddInternal-ProjectGuidToWebConfig { + [cmdletbinding()] + param( + [Parameter(Position=0)] + [HashTable]$publishProperties, + [Parameter(Position=1)] + [System.IO.FileInfo]$packOutput + ) + process { + try { + [Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq") | Out-Null + $webConfigPath = Join-Path $packOutput 'web.config' + $projectGuidCommentValue = 'ProjectGuid: {0}' -f $publishProperties['ProjectGuid'] + $xDoc = [System.Xml.Linq.XDocument]::Load($webConfigPath) + $allNodes = $xDoc.DescendantNodes() + $projectGuidComment = $allNodes | Where-Object { $_.NodeType -eq [System.Xml.XmlNodeType]::Comment -and $_.Value -eq $projectGuidCommentValue } | Select -First 1 + if($projectGuidComment -ne $null) { + if($publishProperties['IgnoreProjectGuid'] -eq $true) { + $projectGuidComment.Remove() | Out-Null + $xDoc.Save($webConfigPath) | Out-Null + } + } + else { + if(-not ($publishProperties['IgnoreProjectGuid'] -eq $true)) { + $projectGuidComment = New-Object -TypeName System.Xml.Linq.XComment -ArgumentList $projectGuidCommentValue + $xDoc.LastNode.AddAfterSelf($projectGuidComment) | Out-Null + $xDoc.Save($webConfigPath) | Out-Null + } + } + } + catch { + } + } +} + +<# +.SYNOPSIS + +Example of $EFMigrations: + $EFMigrations = @{'CarContext'='Car Context ConnectionString';'MovieContext'='Movie Context Connection String'} + +#> + +function GenerateInternal-EFMigrationScripts { + [cmdletbinding()] + param( + [Parameter(Mandatory=$true,Position=0)] + [System.IO.FileInfo]$projectPath, + [Parameter(Mandatory=$true,Position=1)] + [System.IO.FileInfo]$packOutput, + [Parameter(Position=2)] + [HashTable]$EFMigrations + ) + process { + $files = @{} + $dotnetExePath = GetInternal-DotNetExePath + foreach ($dbContextName in $EFMigrations.Keys) { + try + { + $tempDir = GetInternal-PublishTempPath -packOutput $packOutput + $efScriptFile = Join-Path $tempDir ('{0}.sql' -f $dbContextName) + $arg = ('ef migrations script --idempotent --output {0} --context {1}' -f + $efScriptFile, + $dbContextName) + + Execute-Command $dotnetExePath $arg $projectPath | Out-Null + if (Test-Path -Path $efScriptFile) { + if (!($files.ContainsKey($dbContextName))) { + $files.Add($dbContextName, $efScriptFile) | Out-Null + } + } + } + catch + { + throw 'error occured when executing dotnet.exe to generate EF T-SQL file' + } + } + # return files object + $files + } +} + +<# +.SYNOPSIS + +Example of $connectionStrings: + $connectionStrings = @{'DefaultConnection'='Default ConnectionString';'CarConnection'='Car Connection String'} + +#> +function GenerateInternal-AppSettingsFile { + [cmdletbinding()] + param( + [Parameter(Mandatory = $true,Position=0)] + [System.IO.FileInfo]$packOutput, + [Parameter(Mandatory = $true,Position=1)] + [string]$environmentName, + [Parameter(Position=2)] + [HashTable]$connectionStrings + ) + process { + $configProdJsonFile = 'appsettings.{0}.json' -f $environmentName + $configProdJsonFilePath = Join-Path -Path $packOutput -ChildPath $configProdJsonFile + + if ([string]::IsNullOrEmpty($configProdJsonFilePath)) { + throw ('The path of {0} is empty' -f $configProdJsonFilePath) + } + + if(!(Test-Path -Path $configProdJsonFilePath)) { + # create new file + '{}' | out-file -encoding utf8 -filePath $configProdJsonFilePath -Force + } + + $jsonObj = ConvertFrom-Json -InputObject (Get-Content -Path $configProdJsonFilePath -Raw) + # update when there exists one or more connection strings + if ($connectionStrings -ne $null) { + foreach ($name in $connectionStrings.Keys) { + #check for hierarchy style + if ($jsonObj.ConnectionStrings.$name) { + $jsonObj.ConnectionStrings.$name = $connectionStrings[$name] + continue + } + #check for horizontal style + $horizontalName = 'ConnectionStrings.{0}:' -f $name + if ($jsonObj.$horizontalName) { + $jsonObj.$horizontalName = $connectionStrings[$name] + continue + } + # create new one + if (!($jsonObj.ConnectionStrings)) { + $contentForDefaultConnection = '{}' + $jsonObj | Add-Member -name 'ConnectionStrings' -value (ConvertFrom-Json -InputObject $contentForDefaultConnection) -MemberType NoteProperty | Out-Null + } + if (!($jsonObj.ConnectionStrings.$name)) { + $jsonObj.ConnectionStrings | Add-Member -name $name -value $connectionStrings[$name] -MemberType NoteProperty | Out-Null + } + } + } + + $jsonObj | ConvertTo-Json | out-file -encoding utf8 -filePath $configProdJsonFilePath -Force + + #return the path of config.[environment].json + $configProdJsonFilePath + } +} + +<# +.SYNOPSIS + +Inputs: +Example of $providerDataArray: + + [System.Collections.ArrayList]$providerDataArray = @() + + $iisAppSourceKeyValue=@{"iisApp" = @{"path"='c:\temp\pathtofiles';"appOfflineTemplate" ='offline-template.html'}} + $providerDataArray.Add($iisAppSourceKeyValue) + + $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile"}} + $providerDataArray.Add($dbfullsqlKeyValue) + + $dbfullsqlKeyValue=@{"dbfullsql" = @{"path"="c:\Temp\PathToSqlFile2"}} + $providerDataArray.Add($dbfullsqlKeyValue) + + Manifest File content: + + + + + + + +#> + +function GenerateInternal-ManifestFile { + [cmdletbinding()] + param( + [Parameter(Mandatory=$true,Position=0)] + [System.IO.FileInfo]$packOutput, + [Parameter(Mandatory=$true,Position=1)] + $publishProperties, + [Parameter(Mandatory=$true,Position=2)] + [System.Collections.ArrayList]$providerDataArray, + [Parameter(Mandatory=$true,Position=3)] + [ValidateNotNull()] + $manifestFileName + ) + process{ + $xmlDocument = [xml]'' + AddInternal-ProviderDataToManifest -xmlDocument $xmlDocument -providerDataArray $providerDataArray | Out-Null + $publishTempDir = GetInternal-PublishTempPath -packOutput $packOutput + $XMLFile = Join-Path $publishTempDir $manifestFileName + $xmlDocument.OuterXml | out-file -encoding utf8 -filePath $XMLFile -Force + + # return + [System.IO.FileInfo]$XMLFile + } +} + +function GetInternal-PublishTempPath { + [cmdletbinding()] + param( + [Parameter(Mandatory=$true, Position=0)] + [System.IO.FileInfo]$packOutput + ) + process { + $tempDir = [io.path]::GetTempPath() + $packOutputFolderName = Split-Path $packOutput -Leaf + $publishTempDir = [io.path]::combine($tempDir,'PublishTemp','obj',$packOutputFolderName) + if (!(Test-Path -Path $publishTempDir)) { + New-Item -Path $publishTempDir -type directory | Out-Null + } + # return + [System.IO.FileInfo]$publishTempDir + } +} + +function Publish-AspNetMSDeploy{ + param( + [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + $publishProperties, + [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] + $packOutput + ) + process{ + if($publishProperties){ + $publishPwd = $publishProperties['Password'] + + $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput + $iisAppPath = $publishProperties['DeployIisAppPath'] + + # create source manifest + + # e.g + # + # + # + # + # + # + + [System.Collections.ArrayList]$providerDataArray = @() + $iisAppValues = @{"path"=$packOutput}; + $iisAppSourceKeyValue=@{"iisApp" = $iisAppValues} + $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null + + if ($sharedArgs.EFMigrationData -ne $null -and $sharedArgs.EFMigrationData.Contains('EFSqlFiles')) { + foreach ($sqlFile in $sharedArgs.EFMigrationData['EFSqlFiles'].Values) { + $dbFullSqlSourceKeyValue=@{"dbFullSql" = @{"path"=$sqlFile}} + $providerDataArray.Add($dbFullSqlSourceKeyValue) | Out-Null + } + } + + [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' + + $providerDataArray.Clear() | Out-Null + # create destination manifest + + # e.g + # + # + # + # + # + + $iisAppValues = @{"path"=$iisAppPath}; + if(-not [string]::IsNullOrWhiteSpace($publishProperties['AppOfflineTemplate'])){ + $iisAppValues.Add("appOfflineTemplate", $publishProperties['AppOfflineTemplate']) | Out-Null + } + + $iisAppDestinationKeyValue=@{"iisApp" = $iisAppValues} + $providerDataArray.Add($iisAppDestinationKeyValue) | Out-Null + + if ($publishProperties['EfMigrations'] -ne $null -and $publishProperties['EfMigrations'].Count -gt 0) { + foreach ($connectionString in $publishProperties['EfMigrations'].Values) { + $dbFullSqlDestinationKeyValue=@{"dbFullSql" = @{"path"=$connectionString}} + $providerDataArray.Add($dbFullSqlDestinationKeyValue) | Out-Null + } + } + + + [System.IO.FileInfo]$destXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml' + + <# + "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" + -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml' + -dest:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\DestManifest.xml',ComputerName='https://contoso.scm.azurewebsites.net/msdeploy.axd',UserName='$contoso',Password='',IncludeAcls='False',AuthType='Basic' + -verb:sync + -enableRule:DoNotDeleteRule + -retryAttempts=2" + #> + + if(-not [string]::IsNullOrWhiteSpace($publishProperties['MSDeployPublishMethod'])){ + $serviceMethod = $publishProperties['MSDeployPublishMethod'] + } + + $msdeployComputerName= InternalNormalize-MSDeployUrl -serviceUrl $publishProperties['MSDeployServiceURL'] -siteName $iisAppPath -serviceMethod $publishProperties['MSDeployPublishMethod'] + if($publishProperties['UseMSDeployServiceURLAsIs'] -eq $true){ + $msdeployComputerName = $publishProperties['MSDeployServiceURL'] + } + + $publishArgs = @() + #use manifest to publish + $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName) + $publishArgs += ('-dest:manifest=''{0}'',ComputerName=''{1}'',UserName=''{2}'',Password=''{3}'',IncludeAcls=''False'',AuthType=''{4}''{5}' -f + $destXMLFile.FullName, + $msdeployComputerName, + $publishProperties['UserName'], + $publishPwd, + $publishProperties['AuthType'], + $sharedArgs.DestFragment) + $publishArgs += '-verb:sync' + $publishArgs += $sharedArgs.ExtraArgs + + $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ') + + if (! [String]::IsNullOrEmpty($publishPwd)) { + $command.Replace($publishPwd,'{PASSWORD-REMOVED-FROM-LOG}') | Print-CommandString + } + Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ') + } + else{ + throw 'publishProperties is empty, cannot publish' + } + } +} + +function Escape-TextForRegularExpressions{ + [cmdletbinding()] + param( + [Parameter(Position=0,Mandatory=$true)] + [string]$text + ) + process{ + [regex]::Escape($text) + } +} + +function Publish-AspNetMSDeployPackage{ + param( + [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + $publishProperties, + [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] + $packOutput + ) + process{ + if($publishProperties){ + $packageDestinationFilepath = $publishProperties['DesktopBuildPackageLocation'] + + if(!$packageDestinationFilepath){ + throw ('The package destination property (DesktopBuildPackageLocation) was not found in the publish properties') + } + + if(!([System.IO.Path]::IsPathRooted($packageDestinationFilepath))){ + $packageDestinationFilepath = [System.IO.Path]::GetFullPath((Join-Path $pwd $packageDestinationFilepath)) + } + + # if the dir doesn't exist create it + $pkgDir = ((new-object -typename System.IO.FileInfo($packageDestinationFilepath)).Directory) + if(!(Test-Path -Path $pkgDir)) { + New-Item $pkgDir -type Directory | Out-Null + } + + <# + "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" + -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml' + -dest:package=c:\temp\path\contosoweb.zip + -verb:sync + -enableRule:DoNotDeleteRule + -retryAttempts=2 + #> + + $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput + + # create source manifest + + # e.g + # + # + # + # + + [System.Collections.ArrayList]$providerDataArray = @() + $iisAppSourceKeyValue=@{"iisApp" = @{"path"=$packOutput}} + $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null + + [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' + + $publishArgs = @() + $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName) + $publishArgs += ('-dest:package=''{0}''' -f $packageDestinationFilepath) + $publishArgs += '-verb:sync' + $packageContentFolder = $publishProperties['MSDeployPackageContentFoldername'] + if(!$packageContentFolder){ $packageContentFolder = 'website' } + $publishArgs += ('-replace:match=''{0}'',replace=''{1}''' -f (Escape-TextForRegularExpressions $packOutput), $packageContentFolder ) + $publishArgs += $sharedArgs.ExtraArgs + + $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ') + $command | Print-CommandString + Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ') + } + else{ + throw 'publishProperties is empty, cannot publish' + } + } +} + +function Publish-AspNetFileSystem{ + param( + [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + $publishProperties, + [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] + $packOutput + ) + process{ + $pubOut = $publishProperties['publishUrl'] + + if([string]::IsNullOrWhiteSpace($pubOut)){ + throw ('publishUrl is a required property for FileSystem publish but it was empty.') + } + + # if it's a relative path then update it to a full path + if(!([System.IO.Path]::IsPathRooted($pubOut))){ + $pubOut = [System.IO.Path]::GetFullPath((Join-Path $pwd $pubOut)) + $publishProperties['publishUrl'] = "$pubOut" + } + + 'Publishing files to {0}' -f $pubOut | Write-Output + + # we use msdeploy.exe because it supports incremental publish/skips/replacements/etc + # msdeploy.exe -verb:sync -source:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\SourceManifest.xml' -dest:manifest='C:\Users\testuser\AppData\Local\Temp\PublishTemp\obj\DestManifest.xml' + + $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput + + # create source manifest + + # e.g + # + # + # + # + + [System.Collections.ArrayList]$providerDataArray = @() + $contentPathValues = @{"path"=$packOutput}; + $contentPathSourceKeyValue=@{"contentPath" = $contentPathValues} + $providerDataArray.Add($contentPathSourceKeyValue) | Out-Null + + [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' + + $providerDataArray.Clear() | Out-Null + # create destination manifest + + # e.g + # + # + # + $contentPathValues = @{"path"=$publishProperties['publishUrl']}; + if(-not [string]::IsNullOrWhiteSpace($publishProperties['AppOfflineTemplate'])){ + $contentPathValues.Add("appOfflineTemplate", $publishProperties['AppOfflineTemplate']) | Out-Null + } + $contentPathDestinationKeyValue=@{"contentPath" = $contentPathValues} + $providerDataArray.Add($contentPathDestinationKeyValue) | Out-Null + + [System.IO.FileInfo]$destXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml' + + $publishArgs = @() + $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName) + $publishArgs += ('-dest:manifest=''{0}''{1}' -f $destXMLFile.FullName, $sharedArgs.DestFragment) + $publishArgs += '-verb:sync' + $publishArgs += $sharedArgs.ExtraArgs + + $command = '"{0}" {1}' -f (Get-MSDeploy),($publishArgs -join ' ') + $command | Print-CommandString + Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ') + + # copy sql script to script folder + if (($sharedArgs.EFMigrationData['EFSqlFiles'] -ne $null) -and ($sharedArgs.EFMigrationData['EFSqlFiles'].Count -gt 0)) { + $scriptsDir = Join-Path $pubOut 'efscripts' + + if (!(Test-Path -Path $scriptsDir)) { + New-Item -Path $scriptsDir -type directory | Out-Null + } + + foreach ($sqlFile in $sharedArgs.EFMigrationData['EFSqlFiles'].Values) { + Copy-Item $sqlFile -Destination $scriptsDir -Force -Recurse | Out-Null + } + } + } +} + +<# +.SYNOPSIS + This can be used to read a publish profile to extract the property values into a hashtable. + +.PARAMETER filepath + Path to the publish profile to get the properties from. Currenlty this only supports reading + .pubxml files. + +.EXAMPLE + Get-PropertiesFromPublishProfile -filepath c:\projects\publish\devpublish.pubxml +#> +function Get-PropertiesFromPublishProfile{ + [cmdletbinding()] + param( + [Parameter(Position=0,Mandatory=$true)] + [ValidateNotNull()] + [ValidateScript({Test-Path $_})] + [System.IO.FileInfo]$filepath + ) + begin{ + Add-Type -AssemblyName System.Core + Add-Type -AssemblyName Microsoft.Build + } + process{ + 'Reading publish properties from profile [{0}]' -f $filepath | Write-Verbose + # use MSBuild to get the project and read properties + $projectCollection = (New-Object Microsoft.Build.Evaluation.ProjectCollection) + if(!([System.IO.Path]::IsPathRooted($filepath))){ + $filepath = [System.IO.Path]::GetFullPath((Join-Path $pwd $filepath)) + } + $project = ([Microsoft.Build.Construction.ProjectRootElement]::Open([string]$filepath.Fullname, $projectCollection)) + + $properties = @{} + foreach($property in $project.Properties){ + $properties[$property.Name]=$property.Value + } + + $properties + } +} + +function Print-CommandString{ + [cmdletbinding()] + param( + [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)] + $command + ) + process{ + 'Executing command [{0}]' -f $command | Write-Output + } +} + +function Execute-CommandString{ + [cmdletbinding()] + param( + [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)] + [string[]]$command, + + [switch] + $useInvokeExpression, + + [switch] + $ignoreErrors + ) + process{ + foreach($cmdToExec in $command){ + 'Executing command [{0}]' -f $cmdToExec | Write-Verbose + if($useInvokeExpression){ + try { + Invoke-Expression -Command $cmdToExec + } + catch { + if(-not $ignoreErrors){ + $msg = ('The command [{0}] exited with exception [{1}]' -f $cmdToExec, $_.ToString()) + throw $msg + } + } + } + else { + cmd.exe /D /C $cmdToExec + + if(-not $ignoreErrors -and ($LASTEXITCODE -ne 0)){ + $msg = ('The command [{0}] exited with code [{1}]' -f $cmdToExec, $LASTEXITCODE) + throw $msg + } + } + } + } +} + +function Execute-Command { + [cmdletbinding()] + param( + [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + [String]$exePath, + [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] + [String]$arguments, + [Parameter(Position=2)] + [System.IO.FileInfo]$workingDirectory + ) + process{ + $psi = New-Object -TypeName System.Diagnostics.ProcessStartInfo + $psi.CreateNoWindow = $true + $psi.UseShellExecute = $false + $psi.RedirectStandardOutput = $true + $psi.RedirectStandardError=$true + $psi.FileName = $exePath + $psi.Arguments = $arguments + if($workingDirectory -and (Test-Path -Path $workingDirectory)) { + $psi.WorkingDirectory = $workingDirectory + } + + $process = New-Object -TypeName System.Diagnostics.Process + $process.StartInfo = $psi + $process.EnableRaisingEvents=$true + + # Register the event handler for error + $stdErrEvent = Register-ObjectEvent -InputObject $process -EventName 'ErrorDataReceived' -Action { + if (! [String]::IsNullOrEmpty($EventArgs.Data)) { + $EventArgs.Data | Write-Error + } + } + + # Starting process. + $process.Start() | Out-Null + $process.BeginErrorReadLine() | Out-Null + $output = $process.StandardOutput.ReadToEnd() + $process.WaitForExit() | Out-Null + $output | Write-Output + + # UnRegister the event handler for error + Unregister-Event -SourceIdentifier $stdErrEvent.Name | Out-Null + } +} + + +function GetInternal-DotNetExePath { + process { + $dotnetinstallpath = $env:dotnetinstallpath + if (!$dotnetinstallpath) { + $DotNetRegItem = Get-ItemProperty -Path 'hklm:\software\dotnet\setup\' + if ($env:DOTNET_HOME) { + $dotnetinstallpath = Join-Path $env:DOTNET_HOME -ChildPath 'dotnet.exe' + } + elseif ($DotNetRegItem -and $DotNetRegItem.InstallDir){ + $dotnetinstallpath = Join-Path $DotNetRegItem.InstallDir -ChildPath 'dotnet.exe' + } + } + if (!(Test-Path $dotnetinstallpath)) { + throw 'Unable to find dotnet.exe, please install it and try again' + } + # return + [System.IO.FileInfo]$dotnetinstallpath + } +} + +function Get-MSDeploy{ + [cmdletbinding()] + param() + process{ + $installPath = $env:msdeployinstallpath + + if(!$installPath){ + $keysToCheck = @('hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\3','hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\2','hklm:\SOFTWARE\Microsoft\IIS Extensions\MSDeploy\1') + + foreach($keyToCheck in $keysToCheck){ + if(Test-Path $keyToCheck){ + $installPath = (Get-itemproperty $keyToCheck -Name InstallPath -ErrorAction SilentlyContinue | select -ExpandProperty InstallPath -ErrorAction SilentlyContinue) + } + + if($installPath){ + break; + } + } + } + + if(!$installPath){ + throw "Unable to find msdeploy.exe, please install it and try again" + } + + [string]$msdInstallLoc = (join-path $installPath 'msdeploy.exe') + + "Found msdeploy.exe at [{0}]" -f $msdInstallLoc | Write-Verbose + + $msdInstallLoc + } +} + +function InternalNormalize-MSDeployUrl{ + [cmdletbinding()] + param( + [Parameter(Position=0,Mandatory=$true)] + [string]$serviceUrl, + + [string] $siteName, + + [ValidateSet('WMSVC','RemoteAgent','InProc')] + [string]$serviceMethod = 'WMSVC' + ) + process{ + $tempUrl = $serviceUrl + $resultUrl = $serviceUrl + + $httpsStr = 'https://' + $httpStr = 'http://' + $msdeployAxd = 'msdeploy.axd' + + if(-not [string]::IsNullOrWhiteSpace($serviceUrl)){ + if([string]::Compare($serviceMethod,'WMSVC',[StringComparison]::OrdinalIgnoreCase) -eq 0){ + # if no http or https then add one + if(-not ($serviceUrl.StartsWith($httpStr,[StringComparison]::OrdinalIgnoreCase) -or + $serviceUrl.StartsWith($httpsStr,[StringComparison]::OrdinalIgnoreCase)) ){ + + $serviceUrl = [string]::Concat($httpsStr,$serviceUrl.TrimStart()) + } + [System.Uri]$serviceUri = New-Object -TypeName 'System.Uri' $serviceUrl + [System.UriBuilder]$serviceUriBuilder = New-Object -TypeName 'System.UriBuilder' $serviceUrl + + # if it's https and the port was not passed in override it to 8172 + if( ([string]::Compare('https',$serviceUriBuilder.Scheme,[StringComparison]::OrdinalIgnoreCase) -eq 0) -and + -not $serviceUrl.Contains((':{0}' -f $serviceUriBuilder.Port)) ) { + $serviceUriBuilder.Port = 8172 + } + + # if no path then add one + if([string]::Compare('/',$serviceUriBuilder.Path,[StringComparison]::OrdinalIgnoreCase) -eq 0){ + $serviceUriBuilder.Path = $msdeployAxd + } + + if ([string]::IsNullOrEmpty($serviceUriBuilder.Query) -and -not([string]::IsNullOrEmpty($siteName))) + { + $serviceUriBuilder.Query = "site=" + $siteName; + } + + $resultUrl = $serviceUriBuilder.Uri.AbsoluteUri + } + elseif([string]::Compare($serviceMethod,'RemoteAgent',[StringComparison]::OrdinalIgnoreCase) -eq 0){ + [System.UriBuilder]$serviceUriBuilder = New-Object -TypeName 'System.UriBuilder' $serviceUrl + # http://{computername}/MSDEPLOYAGENTSERVICE + # remote agent must use http + $serviceUriBuilder.Scheme = 'http' + $serviceUriBuilder.Path = '/MSDEPLOYAGENTSERVICE' + + $resultUrl = $serviceUriBuilder.Uri.AbsoluteUri + } + else{ + # see if it's for localhost + [System.Uri]$serviceUri = New-Object -TypeName 'System.Uri' $serviceUrl + $resultUrl = $serviceUri.AbsoluteUri + } + } + + # return the result to the caller + $resultUrl + } +} + +function InternalRegister-AspNetKnownPublishHandlers{ + [cmdletbinding()] + param() + process{ + 'Registering MSDeploy handler' | Write-Verbose + Register-AspnetPublishHandler -name 'MSDeploy' -force -handler { + [cmdletbinding()] + param( + [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + $publishProperties, + [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] + $packOutput + ) + + Publish-AspNetMSDeploy -publishProperties $publishProperties -packOutput $packOutput + } + + 'Registering MSDeploy package handler' | Write-Verbose + Register-AspnetPublishHandler -name 'Package' -force -handler { + [cmdletbinding()] + param( + [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + $publishProperties, + [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] + $packOutput + ) + + Publish-AspNetMSDeployPackage -publishProperties $publishProperties -packOutput $packOutput + } + + 'Registering FileSystem handler' | Write-Verbose + Register-AspnetPublishHandler -name 'FileSystem' -force -handler { + [cmdletbinding()] + param( + [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] + $publishProperties, + [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] + $packOutput + ) + + Publish-AspNetFileSystem -publishProperties $publishProperties -packOutput $packOutput + } + } +} + +<# +.SYNOPSIS + Used for testing purposes only. +#> +function InternalReset-AspNetPublishHandlers{ + [cmdletbinding()] + param() + process{ + $script:AspNetPublishHandlers = @{} + InternalRegister-AspNetKnownPublishHandlers + } +} + +Export-ModuleMember -function Get-*,Publish-*,Register-*,Enable-* +if($env:IsDeveloperMachine){ + # you can set the env var to expose all functions to importer. easy for development. + # this is required for executing pester test cases, it's set by build.ps1 + Export-ModuleMember -function * +} + +# register the handlers so that Publish-AspNet can be called +InternalRegister-AspNetKnownPublishHandlers + diff --git a/src/ScmOutOfOffice/Properties/PublishProfiles/tparnellOutOfOffice-publish.ps1 b/src/ScmOutOfOffice/Properties/PublishProfiles/tparnellOutOfOffice-publish.ps1 new file mode 100644 index 0000000..332eca6 --- /dev/null +++ b/src/ScmOutOfOffice/Properties/PublishProfiles/tparnellOutOfOffice-publish.ps1 @@ -0,0 +1,19 @@ +[cmdletbinding(SupportsShouldProcess=$true)] +param($publishProperties=@{}, $packOutput, $pubProfilePath) + +# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327 + +try{ + if ($publishProperties['ProjectGuid'] -eq $null){ + $publishProperties['ProjectGuid'] = '802e67be-09d3-4b32-821b-20e4e7ae8846' + } + + $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1' + Import-Module $publishModulePath -DisableNameChecking -Force + + # call Publish-AspNet to perform the publish operation + Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath +} +catch{ + "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error +} \ No newline at end of file diff --git a/src/ScmOutOfOffice/Properties/PublishProfiles/tparnellOutOfOffice.pubxml b/src/ScmOutOfOffice/Properties/PublishProfiles/tparnellOutOfOffice.pubxml new file mode 100644 index 0000000..5e83eab --- /dev/null +++ b/src/ScmOutOfOffice/Properties/PublishProfiles/tparnellOutOfOffice.pubxml @@ -0,0 +1,28 @@ + + + + + MSDeploy + AzureWebSite + Release + Any CPU + http://tparnelloutofoffice.azurewebsites.net + True + False + + True + True + tparnelloutofoffice.scm.azurewebsites.net:443 + tparnellOutOfOffice + + True + WMSVC + True + $tparnellOutOfOffice + <_SavePWD>True + <_DestinationType>AzureWebSite + + \ No newline at end of file diff --git a/src/ScmOutOfOffice/Properties/launchSettings.json b/src/ScmOutOfOffice/Properties/launchSettings.json index c4adbc3..32f00e0 100644 --- a/src/ScmOutOfOffice/Properties/launchSettings.json +++ b/src/ScmOutOfOffice/Properties/launchSettings.json @@ -1,27 +1,27 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:60086/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:60086/", + "sslPort": 0 + } }, - "ScmOutOfOffice": { - "commandName": "Project", - "launchBrowser": true, - "launchUrl": "http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "ScmOutOfOffice": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } } - } } \ No newline at end of file diff --git a/src/ScmOutOfOffice/ScmOutOfOffice.xproj b/src/ScmOutOfOffice/ScmOutOfOffice.xproj index c86efae..de003d3 100644 --- a/src/ScmOutOfOffice/ScmOutOfOffice.xproj +++ b/src/ScmOutOfOffice/ScmOutOfOffice.xproj @@ -14,10 +14,11 @@ 2.0 + /subscriptions/6332a4fe-3d5b-4857-9206-6dedd406f451/resourcegroups/WebResourceGroup/providers/microsoft.insights/components/ScmOutOfOffice - + \ No newline at end of file diff --git a/src/ScmOutOfOffice/Service References/Application Insights/ConnectedService.json b/src/ScmOutOfOffice/Service References/Application Insights/ConnectedService.json new file mode 100644 index 0000000..2661bb3 --- /dev/null +++ b/src/ScmOutOfOffice/Service References/Application Insights/ConnectedService.json @@ -0,0 +1,7 @@ +{ + "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", + "Version": "7.1.719.1", + "GettingStartedDocument": { + "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" + } +} \ No newline at end of file diff --git a/src/ScmOutOfOffice/Startup.cs b/src/ScmOutOfOffice/Startup.cs index e50ef65..da0cef4 100644 --- a/src/ScmOutOfOffice/Startup.cs +++ b/src/ScmOutOfOffice/Startup.cs @@ -1,12 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace ScmOutOfOffice { @@ -60,7 +61,13 @@ namespace ScmOutOfOffice app.UseApplicationInsightsExceptionTelemetry(); app.UseStaticFiles(); - + app.UseCookieAuthentication(new CookieAuthenticationOptions() + { + AutomaticAuthenticate = true, + AutomaticChallenge = true, + LoginPath = new PathString("/signin"), + LogoutPath = new PathString("/signout"), + }); app.UseMvc(routes => { routes.MapRoute( @@ -69,4 +76,4 @@ namespace ScmOutOfOffice }); } } -} +} \ No newline at end of file diff --git a/src/ScmOutOfOffice/appsettings.json b/src/ScmOutOfOffice/appsettings.json index d6672fd..ce60b6f 100644 --- a/src/ScmOutOfOffice/appsettings.json +++ b/src/ScmOutOfOffice/appsettings.json @@ -1,6 +1,6 @@ -{ +{ "ApplicationInsights": { - "InstrumentationKey": "" + "InstrumentationKey": "91759b23-ab62-41eb-8a63-29acb1d04e0c" }, "Logging": { "IncludeScopes": false, @@ -10,4 +10,4 @@ "Microsoft": "Information" } } -} +} \ No newline at end of file diff --git a/src/ScmOutOfOffice/project.json b/src/ScmOutOfOffice/project.json index 6660414..9c82d51 100644 --- a/src/ScmOutOfOffice/project.json +++ b/src/ScmOutOfOffice/project.json @@ -1,66 +1,69 @@ { - "dependencies": { - "Microsoft.NETCore.App": { - "version": "1.0.0", - "type": "platform" + "dependencies": { + "Microsoft.NETCore.App": { + "version": "1.0.0", + "type": "platform" + }, + "Microsoft.ApplicationInsights.AspNetCore": "1.0.0", + "Microsoft.AspNetCore.Diagnostics": "1.0.0", + "Microsoft.AspNetCore.Mvc": "1.0.0", + "Microsoft.AspNetCore.Razor.Tools": { + "version": "1.0.0-preview2-final", + "type": "build" + }, + "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", + "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", + "Microsoft.AspNetCore.StaticFiles": "1.0.0", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", + "Microsoft.Extensions.Configuration.Json": "1.0.0", + "Microsoft.Extensions.Logging": "1.0.0", + "Microsoft.Extensions.Logging.Console": "1.0.0", + "Microsoft.Extensions.Logging.Debug": "1.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", + "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0", + "AspNet.Security.OAuth.GitHub": "1.0.0-beta1-final", + "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0" }, - "Microsoft.ApplicationInsights.AspNetCore": "1.0.0", - "Microsoft.AspNetCore.Diagnostics": "1.0.0", - "Microsoft.AspNetCore.Mvc": "1.0.0", - "Microsoft.AspNetCore.Razor.Tools": { - "version": "1.0.0-preview2-final", - "type": "build" + + "tools": { + "BundlerMinifier.Core": "2.0.238", + "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" }, - "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", - "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", - "Microsoft.AspNetCore.StaticFiles": "1.0.0", - "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", - "Microsoft.Extensions.Configuration.Json": "1.0.0", - "Microsoft.Extensions.Logging": "1.0.0", - "Microsoft.Extensions.Logging.Console": "1.0.0", - "Microsoft.Extensions.Logging.Debug": "1.0.0", - "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", - "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0" - }, - "tools": { - "BundlerMinifier.Core": "2.0.238", - "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", - "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" - }, + "frameworks": { + "netcoreapp1.0": { + "imports": [ + "dotnet5.6", + "portable-net45+win8" + ] + } + }, - "frameworks": { - "netcoreapp1.0": { - "imports": [ - "dotnet5.6", - "portable-net45+win8" - ] - } - }, + "buildOptions": { + "emitEntryPoint": true, + "preserveCompilationContext": true + }, - "buildOptions": { - "emitEntryPoint": true, - "preserveCompilationContext": true - }, + "runtimeOptions": { + "configProperties": { + "System.GC.Server": true + } + }, - "runtimeOptions": { - "configProperties": { - "System.GC.Server": true - } - }, + "publishOptions": { + "include": [ + "wwwroot", + "Views", + "Areas/**/Views", + "appsettings.json", + "web.config" + ] + }, - "publishOptions": { - "include": [ - "wwwroot", - "Views", - "Areas/**/Views", - "appsettings.json", - "web.config" - ] - }, - - "scripts": { - "prepublish": [ "bower install", "dotnet bundle" ], - "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] - } -} + "scripts": { + "prepublish": [ "bower install", "dotnet bundle" ], + "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] + }, + "userSecretsId": "aspnet-ScmOutOfOffice-20160729070651" +} \ No newline at end of file