├── .gitattributes ├── .gitignore ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md ├── Ensure-PublishModuleLoaded.snippet.ps1 ├── GetPackageDownloader.ps1 ├── GetPublishModule.ps1 ├── LICENSE.txt ├── README.md ├── appveyor.ps1 ├── appveyor.yml ├── build.ps1 ├── e2etests └── default-publish.tests.ps1 ├── package-downloader.nuspec ├── package-downloader.psm1 ├── publish-module-blob.nuspec ├── publish-module-blob.psm1 ├── publish-module.nuspec ├── publish-module.psm1 ├── samples ├── default-publish.ps1 ├── old │ ├── end-to-end-01.ps1 │ └── publish-to-multiple-sites.ps1 ├── publish-and-backup.ps1 ├── publish-optimize-images.ps1 ├── publish-to-blob-storage.ps1 ├── publish-to-blob-storage.pubxml └── samples.md ├── tests ├── EFMigration.tests.ps1 ├── MSDeploy.tests.ps1 ├── ManifestProvider.tests.ps1 ├── SampleFiles │ ├── DotNetWebApp │ │ ├── NuGet.config │ │ └── src │ │ │ ├── Controllers │ │ │ ├── BlogsController.cs │ │ │ └── HomeController.cs │ │ │ ├── Migrations │ │ │ ├── 20160406182601_first.Designer.cs │ │ │ ├── 20160406182601_first.cs │ │ │ ├── 20160406212008_second.Designer.cs │ │ │ ├── 20160406212008_second.cs │ │ │ └── BlogsContextModelSnapshot.cs │ │ │ ├── Models │ │ │ └── BlogsContext.cs │ │ │ ├── Properties │ │ │ ├── PublishProfiles │ │ │ │ ├── WebApp-publish.ps1 │ │ │ │ └── WebApp.pubxml │ │ │ └── launchSettings.json │ │ │ ├── Startup.cs │ │ │ ├── Views │ │ │ ├── Blogs │ │ │ │ ├── Create.cshtml │ │ │ │ └── index.cshtml │ │ │ ├── Home │ │ │ │ ├── About.cshtml │ │ │ │ ├── Contact.cshtml │ │ │ │ └── Index.cshtml │ │ │ ├── Shared │ │ │ │ ├── Error.cshtml │ │ │ │ └── _Layout.cshtml │ │ │ ├── _ViewImports.cshtml │ │ │ └── _ViewStart.cshtml │ │ │ ├── appsettings.json │ │ │ ├── project.json │ │ │ ├── web.config │ │ │ └── wwwroot │ │ │ └── web.config │ ├── MvcApplication-packOutput │ │ ├── approot │ │ │ ├── global.json │ │ │ └── src │ │ │ │ └── MvcApplication │ │ │ │ ├── Controllers │ │ │ │ └── HomeController.cs │ │ │ │ ├── Models │ │ │ │ └── User.cs │ │ │ │ ├── Properties │ │ │ │ ├── PublishProfiles │ │ │ │ │ └── ToFileSys.pubxml │ │ │ │ └── debugSettings.json │ │ │ │ ├── Startup.cs │ │ │ │ ├── Views │ │ │ │ ├── Home │ │ │ │ │ └── Index.cshtml │ │ │ │ └── Shared │ │ │ │ │ └── _Layout.cshtml │ │ │ │ └── project.json │ │ ├── kestrel.cmd │ │ ├── web.cmd │ │ └── wwwroot │ │ │ ├── .gitignore │ │ │ ├── tobereplaced.txt │ │ │ └── web.config │ └── MvcApplication │ │ ├── Controllers │ │ └── HomeController.cs │ │ ├── Models │ │ └── User.cs │ │ ├── Properties │ │ ├── PublishProfiles │ │ │ └── ToFileSys.pubxml │ │ └── debugSettings.json │ │ ├── Startup.cs │ │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ └── Shared │ │ │ └── _Layout.cshtml │ │ ├── project.json │ │ └── wwwroot │ │ └── .gitignore ├── e2e-FileSystem.tests.ps1 ├── e2e-Package.tests.ps1 ├── e2e.Package.tests.ps1 └── publish-module.tests.ps1 └── todo.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | *.ps1 text eol=crlf 65 | *.psm1 text eol=crlf 66 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Folders to ignore # 2 | OutputRoot/ 3 | TestResults/ 4 | bin/ 5 | obj/ 6 | _UpgradeReport_Files/ 7 | .svn/ 8 | Backups/ 9 | TestBackup/ 10 | csx/ 11 | packages/ 12 | BuildOutput/ 13 | Backup/ 14 | # CloudServices creates an rcf folder during build 15 | rcf/ 16 | 17 | 18 | # Known files to ignore always # 19 | *.suo 20 | *.user 21 | *.DotSettings 22 | ~*.docx 23 | msbuild.log 24 | msbuild.*.log 25 | *build.log 26 | *build.*.log 27 | .dbshell 28 | *.private 29 | UpgradeLog*.xml 30 | UpgradeLog*.htm 31 | *.metaproj 32 | *.metaproj.tmp 33 | *.sublime-workspace* 34 | 35 | ############## 36 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the code of conduct defined by the Contributor Covenant 4 | to clarify expected behavior in our community. 5 | 6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ====== 3 | 4 | Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo. 5 | -------------------------------------------------------------------------------- /Ensure-PublishModuleLoaded.snippet.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | <# 5 | Add the following snippet to your .ps1 file to ensure that the publish-module is loaded and ready for use 6 | #> 7 | 8 | function Ensure-PublishModuleLoaded{ 9 | [cmdletbinding()] 10 | param($versionToInstall = '1.1.1', 11 | $installScriptUrl = 'http://go.microsoft.com/fwlink/?LinkId=524326', # GetPublishModule.ps1 12 | $toolsDir = ("$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\tools\"), 13 | $installScriptPath = (Join-Path $toolsDir 'GetPublishModule.ps1')) 14 | process{ 15 | if(!(Test-Path $installScriptPath)){ 16 | if(!(Test-Path $toolsDir)){ 17 | New-Item -Path $toolsDir -ItemType Directory | Out-Null 18 | } 19 | 20 | 'Downloading from [{0}] to [{1}]' -f $installScriptUrl, $installScriptPath| Write-Verbose 21 | (new-object Net.WebClient).DownloadFile($installScriptUrl,$installScriptPath) | Out-Null 22 | } 23 | $installScriptArgs = @($versionToInstall,$toolsDir) 24 | # seems to be the best way to invoke a .ps1 file with parameters 25 | Invoke-Expression "& `"$installScriptPath`" $installScriptArgs" 26 | } 27 | } 28 | 29 | Ensure-PublishModuleLoaded 30 | -------------------------------------------------------------------------------- /GetPackageDownloader.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | <# 5 | You should add the snippet below to your PS files to ensure that PackageDownloader is available. 6 | #> 7 | 8 | function Enable-PackageDownloader{ 9 | [cmdletbinding()] 10 | param($toolsDir = ("$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\tools\"),$nugetDownloadUrl = 'http://nuget.org/nuget.exe') 11 | process{ 12 | if(!(get-module package-downloader)){ 13 | if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory | Out-Null } 14 | 15 | $modPath = (join-path $toolsDir 'package-downloader.1.1.1\tools\package-downloader.psm1') 16 | if(!(Test-Path $modPath)){ 17 | $nugetArgs = @('install','package-downloader','-prerelease','-version','1.1.1','-OutputDirectory',(Resolve-Path $toolsDir).ToString()) 18 | $nugetDestPath = Join-Path -Path $toolsDir -ChildPath nuget.exe 19 | if(!(Test-Path $nugetDestPath)){ (New-Object System.Net.WebClient).DownloadFile($nugetDownloadUrl, $nugetDestPath) | Out-Null } 20 | if(!(Test-Path $nugetDestPath)){ throw 'unable to download nuget' } 21 | &$nugetDestPath $nugetArgs 22 | } 23 | import-module $modPath -DisableNameChecking -force 24 | } 25 | } 26 | } 27 | 28 | Enable-PackageDownloader 29 | -------------------------------------------------------------------------------- /GetPublishModule.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding()] 5 | param( 6 | [Parameter(Position=0)] 7 | $versionToInstall = '1.1.1', 8 | [Parameter(Position=1)] 9 | $toolsDir = ("$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\tools\"), 10 | [Parameter(Position=2)] 11 | $nugetDownloadUrl = 'http://nuget.org/nuget.exe' 12 | ) 13 | $script:moduleName = 'publish-module' 14 | 15 | # see if the particular version is installed under localappdata 16 | function GetPublishModuleFile{ 17 | [cmdletbinding()] 18 | param( 19 | $versionToInstall = '1.1.1', 20 | $toolsDir = ("$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\tools\"), 21 | $nugetDownloadUrl = 'http://nuget.org/nuget.exe' 22 | ) 23 | process{ 24 | if(!(Test-Path $toolsDir)){ 25 | New-Item -Path $toolsDir -ItemType Directory | out-null 26 | } 27 | $folderPath = Enable-PackageDownloader -name 'publish-module' -version $versionToInstall 28 | 29 | $psm1File = (Join-Path $folderPath 'tools\publish-module.psm1') 30 | 31 | if(!$psm1file){ 32 | throw "$script:moduleName not found, and was not downloaded successfully. sorry." 33 | } 34 | 35 | $psm1file 36 | } 37 | } 38 | 39 | function Enable-PackageDownloader{ 40 | [cmdletbinding()] 41 | param($toolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader\", 42 | $pkgDownloaderDownloadUrl = 'http://go.microsoft.com/fwlink/?LinkId=524325') # package-downloader.psm1 43 | process{ 44 | if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory } 45 | 46 | $expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1') 47 | if(!(Test-Path $expectedPath)){ 48 | 'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose 49 | (New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath) 50 | } 51 | 52 | if(!$expectedPath){throw ('Unable to download package-downloader.psm1')} 53 | 54 | if(!(get-module package-downloader)){ 55 | 'importing module into global [{0}]' -f $expectedPath | Write-Output 56 | Import-Module $expectedPath -DisableNameChecking -Force -Scope Global 57 | } 58 | } 59 | } 60 | 61 | ########################################### 62 | # Begin script 63 | ########################################### 64 | 65 | Enable-PackageDownloader 66 | 67 | $publishModuleFile = GetPublishModuleFile -versionToInstall $versionToInstall -toolsDir $toolsDir -nugetDownloadUrl $nugetDownloadUrl 68 | if(Get-Module publish-module){ 69 | Remove-Module publish-module -Force | Out-Null 70 | } 71 | 'Importing publish-module from [{0}]' -f $publishModuleFile | Write-Verbose 72 | Import-Module $publishModuleFile -DisableNameChecking -Force -Global -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | publish-module 2 | ============== 3 | 4 | [![Build status](https://ci.appveyor.com/api/projects/status/6svdkhdj34u58kj5?svg=true)](https://ci.appveyor.com/project/aspnetci/vsweb-publish) 5 | 6 | In Visual Studio 2015 we have a new PowerShell based web publish process for ASP.NET Core. In this repository you'll find the [default Visual Studio web publish script](https://github.com/aspnet/vsweb-publish/blob/master/samples/default-publish.ps1), as well as the PowerShell modules that it depends on. 7 | 8 | 9 | 10 | 11 | 12 | This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://www.github.com/aspnet/home) repo. 13 | -------------------------------------------------------------------------------- /appveyor.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | $env:ExitOnPesterFail = $true 5 | $env:IsDeveloperMachine=$true 6 | $env:PesterEnableCodeCoverage = $true 7 | # $env:e2ePkgTestUseCustomMSDeploy=$true 8 | 9 | if($env:APPVEYOR_REPO_BRANCH -eq 'release'){ 10 | .\build.ps1 -build -publishToNuget 11 | } 12 | elseif($env:APPVEYOR_REPO_BRANCH -eq 'publish-staging'){ 13 | .\build.ps1 -build -publishToNuget -nugetUrl https://staging.nuget.org -nugetApiKey $env:NuGetApiKeyStaging 14 | } 15 | else{ 16 | .\build.ps1 -build 17 | } -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | # Full reference at http://www.appveyor.com/docs/appveyor-yml 5 | 6 | version: 1.0.{build} 7 | os: Visual Studio 2015 CTP 8 | 9 | build_script: 10 | - ps: .\appveyor.ps1 11 | 12 | environment: 13 | NuGetApiKey: 14 | secure: HFUEQanhaxHV/sRQYznQqg7LToxSGeIoSvrmyY29PJ1eDbXxUuYrEQ6MPAsZIQFT 15 | NuGetApiKeyStaging: 16 | secure: HFUEQanhaxHV/sRQYznQqg7LToxSGeIoSvrmyY29PJ1eDbXxUuYrEQ6MPAsZIQFT 17 | NuGetPrivateFeedUrl: 18 | secure: oVpjg1GHzihvdCcsXYFwhuB3qD6lWsCXLS7xWJJna21Fk8ouML8iGULZ87a+jLO8a2SkLB8zFyCNOiPzdQsMBA== 19 | 20 | artifacts: 21 | - path: 'OutputRoot\*' 22 | 23 | nuget: 24 | account_feed: true 25 | project_feed: true 26 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding(DefaultParameterSetName ='build')] 5 | param( 6 | # actions 7 | [Parameter(ParameterSetName='build',Position=0)] 8 | [switch]$build, 9 | [Parameter(ParameterSetName='clean',Position=0)] 10 | [switch]$clean, 11 | [Parameter(ParameterSetName='getversion',Position=0)] 12 | [switch]$getversion, 13 | [Parameter(ParameterSetName='setversion',Position=0)] 14 | [switch]$setversion, 15 | [Parameter(ParameterSetName='createnugetlocalrepo',Position=0)] 16 | [switch]$createnugetlocalrepo, 17 | 18 | # build parameters 19 | [Parameter(ParameterSetName='build',Position=1)] 20 | [switch]$cleanBeforeBuild, 21 | 22 | [Parameter(ParameterSetName='build',Position=2)] 23 | [switch]$publishToNuget, 24 | 25 | [Parameter(ParameterSetName='build',Position=3)] 26 | [string]$nugetApiKey = ($env:NuGetApiKey), 27 | 28 | [Parameter(ParameterSetName='build',Position=4)] 29 | [string]$nugetUrl = $null, 30 | 31 | [Parameter(ParameterSetName='build',Position=5)] 32 | [switch]$skipTests, 33 | 34 | # setversion parameters 35 | [Parameter(ParameterSetName='setversion',Position=1,Mandatory=$true)] 36 | [string]$newversion, 37 | 38 | # createnugetlocalrepo parameters 39 | [Parameter(ParameterSetName='createnugetlocalrepo',Position=1)] 40 | [bool]$updateNugetExe = $false 41 | ) 42 | 43 | $env:IsDeveloperMachine=$true 44 | 45 | function Get-ScriptDirectory 46 | { 47 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 48 | Split-Path $Invocation.MyCommand.Path 49 | } 50 | $scriptDir = ((Get-ScriptDirectory) + "\") 51 | 52 | $global:publishmodbuildsettings = New-Object PSObject -Property @{ 53 | LocalNuGetFeedPath = ('{0}\LigerShark\publish-module\nugetfeed' -f $env:localappdata) 54 | } 55 | 56 | <# 57 | .SYNOPSIS 58 | If nuget is in the tools 59 | folder then it will be downloaded there. 60 | #> 61 | function Get-Nuget{ 62 | [cmdletbinding()] 63 | param( 64 | $toolsDir = ("$env:LOCALAPPDATA\LigerShark\tools\"), 65 | $nugetDownloadUrl = 'http://nuget.org/nuget.exe' 66 | ) 67 | process{ 68 | try{ 69 | $nugetDestPath = Join-Path -Path $toolsDir -ChildPath nuget.exe 70 | 71 | if(!(Test-Path $nugetDestPath)){ 72 | $nugetDir = ([System.IO.Path]::GetDirectoryName($nugetDestPath)) 73 | if(!(Test-Path $nugetDir)){ 74 | New-Item -Path $nugetDir -ItemType Directory | Out-Null 75 | } 76 | 77 | 'Downloading nuget.exe' | Write-Verbose 78 | (New-Object System.Net.WebClient).DownloadFile($nugetDownloadUrl, $nugetDestPath) 79 | 80 | # double check that is was written to disk 81 | if(!(Test-Path $nugetDestPath)){ 82 | throw 'unable to download nuget' 83 | } 84 | } 85 | 86 | # return the path of the file 87 | $nugetDestPath 88 | } 89 | catch{ 90 | throw ("Unable to download/find nuget.exe. Error:`n{0}" -f $_.Exception.Message) 91 | } 92 | } 93 | } 94 | 95 | function PublishNuGetPackage{ 96 | [cmdletbinding()] 97 | param( 98 | [Parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)] 99 | [string]$nugetPackages, 100 | 101 | [Parameter(Position=1)] 102 | $nugetApiKey, 103 | 104 | [Parameter(Position=2)] 105 | [string]$nugetUrl 106 | ) 107 | process{ 108 | foreach($nugetPackage in $nugetPackages){ 109 | $pkgPath = (get-item $nugetPackage).FullName 110 | $cmdArgs = @('push',$pkgPath,$nugetApiKey,'-NonInteractive') 111 | 112 | if($nugetUrl -and !([string]::IsNullOrWhiteSpace($nugetUrl))){ 113 | $cmdArgs += "-source" 114 | $cmdArgs += $nugetUrl 115 | } 116 | 117 | 'Publishing nuget package with the following args: [nuget.exe {0}]' -f ($cmdArgs -join ' ') | Write-Verbose 118 | &(Get-Nuget) $cmdArgs 119 | } 120 | } 121 | } 122 | 123 | function Clean{ 124 | [cmdletbinding()] 125 | param() 126 | process{ 127 | $outputRoot = Join-Path $scriptDir "OutputRoot" 128 | if((Test-Path $outputRoot)){ 129 | 'Removing directory: [{0}]' -f $outputRoot | Write-Output 130 | Remove-Item $outputRoot -Recurse -Force 131 | } 132 | else{ 133 | 'Output folder [{0}] doesn''t exist skipping deletion' -f $outputRoot | Write-Output 134 | } 135 | } 136 | } 137 | 138 | function Build{ 139 | [cmdletbinding()] 140 | param() 141 | process{ 142 | 'Starting build' | Write-Output 143 | if($publishToNuget){ $cleanBeforeBuild = $true } 144 | 145 | if($cleanBeforeBuild){ 146 | Clean 147 | } 148 | 149 | $outputRoot = Join-Path $scriptDir "OutputRoot" 150 | $nugetDevRepo = 'C:\temp\nuget\localrepo\' 151 | 152 | if(!(Test-Path $outputRoot)){ 153 | 'Creating output folder [{0}]' -f $outputRoot | Write-Output 154 | New-Item $outputRoot -ItemType Directory 155 | } 156 | 157 | $outputRoot = (Get-Item $outputRoot).FullName 158 | # call nuget to create the package 159 | 160 | $nuspecFiles = @((get-item(Join-Path $scriptDir "publish-module.nuspec")).FullName) 161 | $nuspecFiles += (get-item(Join-Path $scriptDir "publish-module-blob.nuspec")).FullName 162 | $nuspecFiles += (get-item(Join-Path $scriptDir "package-downloader.nuspec")).FullName 163 | 164 | $nuspecFiles | ForEach-Object { 165 | $nugetArgs = @('pack',$_,'-o',$outputRoot) 166 | 'Calling nuget.exe with the command:[nuget.exe {0}]' -f ($nugetArgs -join ' ') | Write-Output 167 | &(Get-Nuget) $nugetArgs 168 | } 169 | 170 | if(Test-Path $nugetDevRepo){ 171 | Get-ChildItem -Path $outputRoot '*.nupkg' | Copy-Item -Destination $nugetDevRepo 172 | } 173 | 174 | # push appveyor artifacts, the e2e tests use them 175 | if((get-command Push-AppveyorArtifact -ErrorAction SilentlyContinue)){ 176 | (Get-ChildItem -Path $outputRoot '*.nupkg').FullName | % { Push-AppveyorArtifact $_ } 177 | } 178 | 179 | if(!$skipTests){ 180 | Run-Tests 181 | } 182 | 183 | if($publishToNuget){ 184 | (Get-ChildItem -Path $outputRoot '*.nupkg').FullName | PublishNuGetPackage -nugetApiKey $nugetApiKey -nugetUrl $nugetUrl 185 | } 186 | } 187 | } 188 | 189 | function Enable-PackageDownloader{ 190 | [cmdletbinding()] 191 | param($toolsDir = "$env:LOCALAPPDATA\LigerShark\tools\package-downloader\", 192 | $pkgDownloaderDownloadUrl = 'https://raw.githubusercontent.com/aspnet/vsweb-publish/master/package-downloader.psm1') 193 | process{ 194 | if(!(get-module package-downloader)){ 195 | if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory -WhatIf:$false } 196 | 197 | $expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1') 198 | if(!(Test-Path $expectedPath)){ 199 | 'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose 200 | (New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath) 201 | if(!$expectedPath){throw ('Unable to download package-downloader.psm1')} 202 | } 203 | 204 | 'importing module [{0}]' -f $expectedPath | Write-Verbose 205 | Import-Module $expectedPath -DisableNameChecking -Force -Scope Global 206 | } 207 | } 208 | } 209 | 210 | <# 211 | .SYNOPSIS 212 | This will inspect the publsish nuspec file and return the value for the Version element. 213 | #> 214 | function GetExistingVersion{ 215 | [cmdletbinding()] 216 | param( 217 | [ValidateScript({test-path $_ -PathType Leaf})] 218 | $nuspecFile = (Join-Path $scriptDir 'publish-module.nuspec') 219 | ) 220 | process{ 221 | ([xml](Get-Content $nuspecFile)).package.metadata.version 222 | } 223 | } 224 | 225 | function Set-Version{ 226 | [cmdletbinding()] 227 | param( 228 | [Parameter(Position=0,Mandatory=$true)] 229 | [ValidateNotNullOrEmpty()] 230 | [string]$newversion, 231 | 232 | [Parameter(Position=1)] 233 | [ValidateNotNullOrEmpty()] 234 | [string]$oldversion = (GetExistingVersion), 235 | 236 | [Parameter(Position=2)] 237 | [string]$filereplacerVersion = '0.2.0-beta' 238 | ) 239 | process{ 240 | 'Updating version from [{0}] to [{1}]' -f $oldversion,$newversion | Write-Verbose 241 | Enable-PackageDownloader 242 | 'trying to load file replacer' | Write-Verbose 243 | Enable-NuGetModule -name 'file-replacer' -version $filereplacerVersion 244 | 245 | $folder = $scriptDir 246 | $include = '*.nuspec;*.ps*1' 247 | # In case the script is in the same folder as the files you are replacing add it to the exclude list 248 | $exclude = "$($MyInvocation.MyCommand.Name);" 249 | $replacements = @{ 250 | "$oldversion"="$newversion" 251 | } 252 | Replace-TextInFolder -folder $folder -include $include -exclude $exclude -replacements $replacements | Write-Verbose 253 | 'Replacement complete' | Write-Verbose 254 | } 255 | } 256 | 257 | function LoadPester{ 258 | [cmdletbinding()] 259 | param( 260 | $pesterDir = (Join-Path $scriptDir 'OutputRoot\contrib\pester\'), 261 | $pesterVersion = '3.3.11' 262 | ) 263 | process{ 264 | $pesterModulepath = (Join-Path $pesterDir ('Pester.{0}\tools\Pester.psd1' -f $pesterVersion)) 265 | if(!(Test-Path $pesterModulepath)){ 266 | if(!(Test-Path $pesterDir)){ 267 | New-Item -Path $pesterDir -ItemType Directory 268 | } 269 | 270 | $pesterDir = (resolve-path $pesterDir) 271 | 272 | Push-Location 273 | try{ 274 | cd $pesterDir 275 | &(Get-Nuget) install pester -version $pesterVersion -source https://www.nuget.org/api/v2/ 276 | } 277 | finally{ 278 | Pop-Location 279 | } 280 | } 281 | else{ 282 | 'Skipping pester download because it was found at [{0}]' -f $pesterModulepath | Write-Verbose 283 | } 284 | 285 | if(!(Test-Path $pesterModulepath)){ 286 | throw ('Pester not found at [{0}]' -f $pesterModulepath) 287 | } 288 | 289 | Import-Module $pesterModulepath -Force 290 | } 291 | } 292 | 293 | function Run-Tests{ 294 | [cmdletbinding()] 295 | param( 296 | $testDirectory = (join-path $scriptDir tests) 297 | ) 298 | begin{ 299 | LoadPester 300 | } 301 | process{ 302 | # go to the tests directory and run pester 303 | push-location 304 | set-location $testDirectory 305 | 306 | $pesterArgs = @{} 307 | if($env:ExitOnPesterFail -eq $true){ 308 | $pesterArgs.Add('-EnableExit',$true) 309 | } 310 | if($env:PesterEnableCodeCoverage -eq $true){ 311 | $pesterArgs.Add('-CodeCoverage',@('..\publish-module.psm1','..\samples\default-publish.ps1')) 312 | } 313 | 314 | Invoke-Pester @pesterArgs 315 | pop-location 316 | } 317 | } 318 | 319 | function GetFolderCreateIfNotExists{ 320 | [cmdletbinding()] 321 | param( 322 | [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true)] 323 | [string[]]$folderPath 324 | ) 325 | process{ 326 | foreach($folder in $folderPath){ 327 | if(!(Test-Path $folderPath)){ 328 | New-Item -Path $folderPath -ItemType Directory | out-null 329 | } 330 | 331 | (Get-Item $folderPath).FullName 332 | } 333 | } 334 | } 335 | 336 | function CreateLocalNuGetRepo{ 337 | [cmdletbinding()] 338 | param($updateNugetExe = $false) 339 | process{ 340 | $nugetFolder = (GetFolderCreateIfNotExists $global:publishmodbuildsettings.LocalNuGetFeedPath) 341 | 342 | $pkgsConfigContent = @' 343 | 344 | 345 | 346 | 347 | 348 | '@ 349 | $pkgsConfigPath = ("$nugetFolder\packages.config") 350 | if(Test-Path $pkgsConfigPath){ 351 | rm -r $pkgsConfigPath 352 | } 353 | 354 | $pkgsConfigContent | Set-Content -Path $pkgsConfigPath 355 | 356 | if($updateNugetExe){ 357 | # update nuget.exe first 358 | &(Get-NuGet) @('update','-self') 359 | Copy-Item -Path (Get-Nuget) -Destination $nugetFolder 360 | } 361 | # copy nuget.exe over there and update it 362 | $pkgsToInstall = @('publish-module','publish-module-blob') 363 | 364 | # call nuget to restore the packages that we want 365 | $nugetArgs = @('install',$pkgsConfigPath,'-o',$nugetFolder) 366 | 'Calling nuget.exe with the following [nuget.exe {0}]' -f ($nugetArgs -join ',') | Write-Verbose 367 | &(Get-Nuget) $nugetArgs 368 | } 369 | } 370 | 371 | # Begin script here 372 | 373 | if(!$getversion -and !$newversion -and !$createnugetlocalrepo -and !$clean){ 374 | # build is the default option 375 | $build = $true 376 | } 377 | 378 | if($build){ Build } 379 | elseif($getversion){ GetExistingVersion } 380 | elseif($newversion){ Set-Version -newversion $newversion } 381 | elseif($createnugetlocalrepo){ CreateLocalNuGetRepo } 382 | elseif($clean){ Clean } 383 | else{ 384 | $cmds = @('-build','-setversion','-createnugetlocalrepo','-clean') 385 | 'No command specified, please pass in one of the following [{0}]' -f ($cmds -join ' ') | Write-Error 386 | } 387 | 388 | -------------------------------------------------------------------------------- /e2etests/default-publish.tests.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding()] 5 | param() 6 | 7 | function Get-ScriptDirectory 8 | { 9 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 10 | Split-Path $Invocation.MyCommand.Path 11 | } 12 | 13 | $scriptDir = ((Get-ScriptDirectory) + "\") 14 | $moduleName = 'publish-module' 15 | $samplesdir = (Join-Path $scriptDir 'SampleFiles') 16 | $nugetPrivateFeedUrl = ($env:NuGetPrivateFeedUrl) 17 | 18 | Describe 'Default publish tests' { 19 | [string]$mvcSourceFolder = (resolve-path (Join-Path $samplesdir 'MvcApplication')) 20 | [string]$mvcPackDir = (resolve-path (Join-Path $samplesdir 'MvcApplication-packOutput')) 21 | [int]$numPublishFiles = ((Get-ChildItem $mvcPackDir -Recurse) | Where-Object { !$_.PSIsContainer }).Length 22 | 23 | BeforeEach { 24 | if(Get-Module publish-module){ 25 | Remove-Module publish-module -Force 26 | } 27 | } 28 | 29 | It 'Publish to file system with default publish' { 30 | if(!([string]::IsNullOrWhiteSpace($nugetPrivateFeedUrl))){ 31 | # publish the pack output to a new temp folder 32 | $publishDest = (Join-Path $TestDrive 'e2eDefaultPub\Basic01') 33 | # verify the folder is empty 34 | $filesbefore = (Get-ChildItem $publishDest -Recurse -ErrorAction SilentlyContinue) | Where-Object { !$_.PSIsContainer } 35 | $filesbefore | Should BeNullOrEmpty 36 | 37 | $defPubFile = (resolve-path (Join-Path $scriptDir '..\samples\default-publish.ps1') ) 38 | $defPubFile | Should Exist 39 | 40 | & ($defPubFile) -nugetUrl $nugetPrivateFeedUrl -packOutput $mvcPackDir -publishProperties @{ 41 | 'WebPublishMethod'='FileSystem' 42 | 'publishUrl'="$publishDest" 43 | } 44 | 45 | # check to see that the files exist 46 | $filesafter = (Get-ChildItem $publishDest -Recurse) | Where-Object { !$_.PSIsContainer } 47 | $filesafter.length | Should Be $numPublishFiles 48 | } 49 | else{ 50 | 'Skipping becuase $env:NuGetPrivateFeedUrl is empty' | Write-Host 51 | 1 | Should be 1 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /package-downloader.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | package-downloader 8 | 1.1.1 9 | Microsoft Open Technologies, Inc. 10 | Microsoft Open Technologies, Inc. 11 | 12 | This nuget package contains a powershell module, package-downloader.psm1, which can be used do 13 | download nuget packages in powershell. 14 | 15 | en-US 16 | https://github.com/aspnet/vsweb-publish/ 17 | https://github.com/aspnet/vsweb-publish/blob/master/LICENSE.txt 18 | false 19 | Copyright © Microsoft Corporation 20 | powershell 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /package-downloader.psm1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding()] 5 | param() 6 | 7 | $global:PkgDownloaderSettings = New-Object PSObject -Property @{ 8 | DefaultToolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader\" 9 | NuGetDownloadUrl = 'http://nuget.org/nuget.exe' 10 | } 11 | <# 12 | .SYNOPSIS 13 | This will return nuget from the $toolsDir. If it is not there then it 14 | will automatically be downloaded before the call completes. 15 | #> 16 | function Get-Nuget{ 17 | [cmdletbinding()] 18 | param( 19 | $toolsDir = ("$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\tools\"), 20 | $nugetDownloadUrl = $global:PkgDownloaderSettings.NuGetDownloadUrl 21 | ) 22 | process{ 23 | if(!(Test-Path $toolsDir)){ 24 | New-Item -Path $toolsDir -ItemType Directory | out-null 25 | } 26 | 27 | $nugetDestPath = Join-Path -Path $toolsDir -ChildPath nuget.exe 28 | 29 | if(!(Test-Path $nugetDestPath)){ 30 | $nugetDir = ([System.IO.Path]::GetDirectoryName($nugetDestPath)) 31 | if(!(Test-Path $nugetDir)){ 32 | New-Item -Path $nugetDir -ItemType Directory | Out-Null 33 | } 34 | 35 | 'Downloading nuget.exe' | Write-Verbose 36 | (New-Object System.Net.WebClient).DownloadFile($nugetDownloadUrl, $nugetDestPath) | Out-Null 37 | 38 | # double check that is was written to disk 39 | if(!(Test-Path $nugetDestPath)){ 40 | throw 'unable to download nuget' 41 | } 42 | } 43 | 44 | # return the path of the file 45 | $nugetDestPath 46 | } 47 | } 48 | 49 | function Execute-CommandString{ 50 | [cmdletbinding()] 51 | param( 52 | [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)] 53 | [string[]]$command, 54 | 55 | [switch] 56 | $ignoreExitCode 57 | ) 58 | process{ 59 | foreach($cmdToExec in $command){ 60 | 'Executing command [{0}]' -f $cmdToExec | Write-Verbose 61 | cmd.exe /D /C $cmdToExec 62 | 63 | if(-not $ignoreExitCode -and ($LASTEXITCODE -ne 0)){ 64 | $msg = ('The command [{0}] exited with code [{1}]' -f $cmdToExec, $LASTEXITCODE) 65 | throw $msg 66 | } 67 | } 68 | } 69 | } 70 | 71 | <# 72 | .SYNOPSIS 73 | This will return the path to where the given NuGet package is installed 74 | under %localappdata%. If the package is not found then empty/null is returned. 75 | #> 76 | function Get-PackageDownloaderInstallPath{ 77 | [cmdletbinding()] 78 | param( 79 | [Parameter(Mandatory=$true,Position=0)] 80 | $name, 81 | [Parameter(Mandatory=$true,Position=1)] # later we can make this optional 82 | $version, 83 | [Parameter(Position=2)] 84 | $toolsDir = $global:PkgDownloaderSettings.DefaultToolsDir 85 | ) 86 | process{ 87 | $pathToFoundPkgFolder = $null 88 | $toolsDir=(get-item $toolsDir).FullName 89 | $expectedNuGetPkgFolder = ((Get-Item -Path (join-path $toolsDir (('{0}.{1}' -f $name, $version))) -ErrorAction SilentlyContinue)) 90 | 91 | if($expectedNuGetPkgFolder){ 92 | $pathToFoundPkgFolder = $expectedNuGetPkgFolder.FullName 93 | } 94 | 95 | $pathToFoundPkgFolder 96 | } 97 | } 98 | 99 | <# 100 | .SYNOPSIS 101 | This will return the path to where the given NuGet package is installed. 102 | #> 103 | function Enable-PackageDownloader{ 104 | [cmdletbinding()] 105 | param( 106 | [Parameter(Mandatory=$true,Position=0)] 107 | $name, 108 | [Parameter(Mandatory=$true,Position=1)] # later we can make this optional 109 | $version, 110 | [Parameter(Position=2)] 111 | $toolsDir = $global:PkgDownloaderSettings.DefaultToolsDir, 112 | 113 | [Parameter(Position=3)] 114 | [string]$nugetUrl = $null 115 | ) 116 | process{ 117 | if(!(Test-Path $toolsDir)){ 118 | New-Item -Path $toolsDir -ItemType Directory | out-null 119 | } 120 | $toolsDir = (Get-Item $toolsDir).FullName.TrimEnd('\') 121 | # if it's already installed just return the path 122 | $installPath = (Get-PackageDownloaderInstallPath -name $name -version $version -toolsDir $toolsDir) 123 | if(!$installPath){ 124 | # install the nuget package and then return the path 125 | $outdir = (get-item (Resolve-Path $toolsDir)).FullName.TrimEnd("\") # nuget.exe doesn't work well with trailing slash 126 | 127 | # set working directory to avoid needing to specify OutputDiretory, having issues with spaces 128 | Push-Location | Out-Null 129 | Set-Location $outdir | Out-Null 130 | $cmdArgs = @('install',$name,'-Version',$version,'-prerelease') 131 | 132 | if($nugetUrl -and !([string]::IsNullOrWhiteSpace($nugetUrl))){ 133 | $cmdArgs += "-source" 134 | $cmdArgs += $nugetUrl 135 | } 136 | 137 | $nugetCommand = ('"{0}" {1}' -f (Get-Nuget -toolsDir $outdir), ($cmdArgs -join ' ' )) 138 | 'Calling nuget to install a package with the following args. [{0}]' -f $nugetCommand | Write-Verbose 139 | Execute-CommandString -command $nugetCommand | Out-Null 140 | Pop-Location | Out-Null 141 | 142 | $installPath = (Get-PackageDownloaderInstallPath -name $name -version $version -toolsDir $toolsDir) 143 | } 144 | 145 | # it should be set by now so throw if not 146 | if(!$installPath){ 147 | throw ('Unable to restore nuget package. [name={0},version={1},toolsDir={2}]' -f $name, $version, $toolsDir) 148 | } 149 | 150 | $installPath 151 | } 152 | } 153 | 154 | <# 155 | This will ensure that the given module is imported into the PS session. If not then 156 | it will be imported from %localappdata%. The package will be restored using 157 | Enable-PackageDownloader. 158 | 159 | This function assumes that the name of the PS module is the name of the .psm1 file 160 | and that file is in the tools\ folder in the NuGet package. 161 | 162 | .EXAMPLE 163 | Enable-NuGetModule -name 'publish-module' -version '1.1.1' 164 | 165 | .EXAMPLE 166 | Enable-NuGetModule -name 'publish-module-blob' -version '1.1.1' 167 | #> 168 | 169 | # For now this function has to be declared directly in the publish 170 | # .ps1 file, not sure why. 171 | function Enable-NuGetModule{ 172 | [cmdletbinding()] 173 | param( 174 | [Parameter(Mandatory=$true,Position=0)] 175 | $name, 176 | $moduleFileName, 177 | [Parameter(Mandatory=$true,Position=1)] # later we can make this optional 178 | $version, 179 | [Parameter(Position=2)] 180 | $toolsDir = $global:PkgDownloaderSettings.DefaultToolsDir, 181 | 182 | [Parameter(Position=3)] 183 | $nugetUrl = $null 184 | ) 185 | process{ 186 | if(!(get-module $name)){ 187 | $installDir = Enable-PackageDownloader -name $name -version $version -nugetUrl $nugetUrl 188 | if(!$moduleFileName){$moduleFileName = $name} 189 | $moduleFile = (join-path $installDir ("tools\{0}.psm1" -f $moduleFileName)) 190 | 'Loading module from [{0}]' -f $moduleFile | Write-Verbose 191 | Import-Module $moduleFile -DisableNameChecking -Global -Force 192 | } 193 | else{ 194 | 'module [{0}] is already loaded skipping' -f $name | Write-Verbose 195 | } 196 | } 197 | } 198 | 199 | function Get-LatestVersionForPackageDownloader{ 200 | [cmdletbinding()] 201 | param( 202 | [Parameter(Mandatory=$true,Position=0)] 203 | $name, 204 | [switch]$prerelease, 205 | [Parameter(Position=1)] 206 | $toolsDir = $global:PkgDownloaderSettings.DefaultToolsDir 207 | ) 208 | process{ 209 | $nugetArgs = @('list',$name) 210 | 211 | if($prerelease){ 212 | $nugetArgs += '-prerelease' 213 | } 214 | 215 | 'Getting pack versions for [{0}]' -f $name | Write-Verbose 216 | 'Calling nuget with the following args [{0}]' -f ($nugetArgs -join ' ') | Write-Verbose 217 | 218 | &(Get-Nuget) $nugetArgs | where{$_.StartsWith('{0} ' -f $name)} |sort 219 | } 220 | } 221 | 222 | Export-ModuleMember -function * 223 | -------------------------------------------------------------------------------- /publish-module-blob.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | publish-module-blob 8 | 1.1.1 9 | Microsoft Open Technologies, Inc. 10 | Microsoft Open Technologies, Inc. 11 | 12 | NuGet package which contians a PS module which can be used to for web publishing. 13 | Note: this is just a sample. 14 | 15 | en-US 16 | https://github.com/aspnet/vsweb-publish/ 17 | https://github.com/aspnet/vsweb-publish/blob/master/LICENSE.txt 18 | false 19 | Copyright © Microsoft Corporation 20 | msbuild 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /publish-module-blob.psm1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding(SupportsShouldProcess=$true)] 5 | param() 6 | 7 | function Publish-FolderToBlobStorage{ 8 | [cmdletbinding()] 9 | param( 10 | [Parameter(Mandatory=$true,Position=0)] 11 | [ValidateScript({Test-Path $_ -PathType Container})] 12 | $folder, 13 | [Parameter(Mandatory=$true,Position=1)] 14 | $storageAcctName, 15 | [Parameter(Mandatory=$true,Position=2)] 16 | $storageAcctKey, 17 | [Parameter(Mandatory=$true,Position=3)] 18 | $containerName 19 | ) 20 | begin{ 21 | 'Publishing folder to blob storage. [folder={0},storageAcctName={1},storageContainer={2}]' -f $folder,$storageAcctName,$containerName | Write-Output 22 | Push-Location 23 | Set-Location $folder 24 | $destContext = New-AzureStorageContext -StorageAccountName $storageAcctName -StorageAccountKey $storageAcctKey 25 | } 26 | end{ Pop-Location } 27 | process{ 28 | $allFiles = (Get-ChildItem $folder -Recurse -File).FullName 29 | 30 | foreach($file in $allFiles){ 31 | $relPath = (Resolve-Path $file -Relative).TrimStart('.\') 32 | "relPath: [$relPath]" | Write-Output 33 | 34 | Set-AzureStorageBlobContent -Blob $relPath -File $file -Container $containerName -Context $destContext 35 | } 36 | } 37 | } 38 | 39 | 'Registering blob storage handler' | Write-Verbose 40 | Register-AspnetPublishHandler -name 'BlobStorage' -handler { 41 | [cmdletbinding()] 42 | param( 43 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 44 | $publishProperties, 45 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 46 | $packOutput 47 | ) 48 | 49 | '[op={0},san={1},con={2}' -f $packOutput,$publishProperties['StorageAcctName'],$publishProperties['StorageContainer'] | Write-Output 50 | 51 | Publish-FolderToBlobStorage -folder $packOutput -storageAcctName $publishProperties['StorageAcctName'] -storageAcctKey $publishProperties['StorageAcctKey'] -containerName $publishProperties['StorageContainer'] 52 | } -------------------------------------------------------------------------------- /publish-module.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | publish-module 8 | 1.1.1 9 | Microsoft Open Technologies, Inc. 10 | Microsoft Open Technologies, Inc. 11 | 12 | NuGet package which contians a PS module which can be used to for web publishing. 13 | Note: this is just a sample. 14 | 15 | en-US 16 | https://github.com/aspnet/vsweb-publish/ 17 | https://github.com/aspnet/vsweb-publish/blob/master/LICENSE.txt 18 | false 19 | Copyright © Microsoft Corporation 20 | msbuild 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /samples/default-publish.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding(SupportsShouldProcess=$true)] 5 | param($publishProperties=@{}, $packOutput,$pubProfilePath, $nugetUrl) 6 | 7 | # to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327 8 | $publishModuleVersion = '1.1.1' 9 | 10 | function Get-PublishModulePath{ 11 | [cmdletbinding()] 12 | param() 13 | process{ 14 | $keysToCheck = @('hklm:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\{0}', 15 | 'hklm:\SOFTWARE\Microsoft\VisualStudio\{0}', 16 | 'hklm:\SOFTWARE\Wow6432Node\Microsoft\VWDExpress\{0}', 17 | 'hklm:\SOFTWARE\Microsoft\VWDExpress\{0}' 18 | ) 19 | $versions = @('14.0', '15.0') 20 | 21 | [string]$publishModulePath=$null 22 | :outer foreach($keyToCheck in $keysToCheck){ 23 | foreach($version in $versions){ 24 | if(Test-Path ($keyToCheck -f $version) ){ 25 | $vsInstallPath = (Get-itemproperty ($keyToCheck -f $version) -Name InstallDir -ErrorAction SilentlyContinue | select -ExpandProperty InstallDir -ErrorAction SilentlyContinue) 26 | 27 | if($vsInstallPath){ 28 | $installedPublishModulePath = "{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f $vsInstallPath, $publishModuleVersion 29 | if(!(Test-Path $installedPublishModulePath)){ 30 | $vsInstallPath = $vsInstallPath + 'VWDExpress' 31 | $installedPublishModulePath = "{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f $vsInstallPath, $publishModuleVersion 32 | } 33 | if(Test-Path $installedPublishModulePath){ 34 | $publishModulePath = $installedPublishModulePath 35 | break outer; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | 42 | $publishModulePath 43 | } 44 | } 45 | 46 | $publishModulePath = Get-PublishModulePath 47 | 48 | $defaultPublishSettings = New-Object psobject -Property @{ 49 | LocalInstallDir = $publishModulePath 50 | } 51 | 52 | function Enable-PackageDownloader{ 53 | [cmdletbinding()] 54 | param( 55 | $toolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader-$publishModuleVersion\", 56 | $pkgDownloaderDownloadUrl = 'https://go.microsoft.com/fwlink/?LinkId=524325') # package-downloader.psm1 57 | process{ 58 | if(get-module package-downloader){ 59 | remove-module package-downloader | Out-Null 60 | } 61 | 62 | if(!(get-module package-downloader)){ 63 | if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory -WhatIf:$false } 64 | 65 | $expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1') 66 | if(!(Test-Path $expectedPath)){ 67 | 'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose 68 | (New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath) 69 | } 70 | 71 | if(!$expectedPath){throw ('Unable to download package-downloader.psm1')} 72 | 73 | 'importing module [{0}]' -f $expectedPath | Write-Output 74 | Import-Module $expectedPath -DisableNameChecking -Force 75 | } 76 | } 77 | } 78 | 79 | function Enable-PublishModule{ 80 | [cmdletbinding()] 81 | param() 82 | process{ 83 | if(get-module publish-module){ 84 | remove-module publish-module | Out-Null 85 | } 86 | 87 | if(!(get-module publish-module)){ 88 | $localpublishmodulepath = Join-Path $defaultPublishSettings.LocalInstallDir 'publish-module.psm1' 89 | if(Test-Path $localpublishmodulepath){ 90 | 'importing module [publish-module="{0}"] from local install dir' -f $localpublishmodulepath | Write-Verbose 91 | Import-Module $localpublishmodulepath -DisableNameChecking -Force 92 | $true 93 | } 94 | } 95 | } 96 | } 97 | 98 | try{ 99 | 100 | if (!(Enable-PublishModule)){ 101 | Enable-PackageDownloader 102 | Enable-NuGetModule -name 'publish-module' -version $publishModuleVersion -nugetUrl $nugetUrl 103 | } 104 | 105 | 'Calling Publish-AspNet' | Write-Verbose 106 | # call Publish-AspNet to perform the publish operation 107 | Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath 108 | } 109 | catch{ 110 | "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error 111 | } -------------------------------------------------------------------------------- /samples/old/end-to-end-01.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param( 3 | $pubTempDir = 'c:\temp\publishtemp\e2e01', 4 | $packOutDir = (Join-Path $pubTempDir 'packout') 5 | ) 6 | 7 | if(Test-Path $pubTempDir){ Remove-Item $pubTempDir -Recurse -Force } 8 | if(Test-Path $packOutDir){ Remove-Item $packOutDir -Recurse -Force } 9 | 10 | New-Item $pubTempDir -ItemType Directory 11 | New-Item $packOutDir -ItemType Directory 12 | 13 | $packOutDir = (Get-Item $packOutDir).FullName 14 | 15 | Push-Location 16 | 17 | Set-Location $pubTempDir 18 | git clone git@github.com:ligershark/aspnet_vnext_samples.git 19 | 20 | Pop-Location 21 | function BuildAndPack{ 22 | [cmdletbinding()] 23 | param( 24 | $rootSrcdir, 25 | $name, 26 | $packOutdir 27 | ) 28 | begin{ Push-Location } 29 | end{ Pop-Location } 30 | process{ 31 | $srcDir = (get-item (join-path $rootSrcdir $name)).FullName 32 | Set-Location $srcDir 33 | '********************************************* 34 | building and packing [{0}] 35 | *********************************************' -f $srcDir | Write-Output 36 | '***** restoring nuget packages ****' | Write-Output 37 | kpm restore 38 | 39 | '**** building project ****' | Write-Output 40 | kpm build 41 | 42 | '**** packing to [{0}] ****' -f $outdir | Write-Output 43 | $outdir = (new-item (join-path $packOutDir $name) -ItemType Directory).FullName 44 | kpm @('pack', '-o', "$outdir") 45 | Set-Location $outdir 46 | } 47 | } 48 | 49 | BuildAndPack -rootSrcdir "$pubTempDir\aspnet_vnext_samples" -name 'console' -packOutdir $packOutDir 50 | BuildAndPack -rootSrcdir "$pubTempDir\aspnet_vnext_samples" -name 'web' -packOutdir $packOutDir 51 | BuildAndPack -rootSrcdir "$pubTempDir\aspnet_vnext_samples" -name 'mvc' -packOutdir $packOutDir 52 | 'Pack complete to root [{0}]' -f $pubTempDir | Write-Output 53 | 54 | start "$pubTempDir" 55 | -------------------------------------------------------------------------------- /samples/old/publish-to-multiple-sites.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param( 3 | $srcDir = 'C:\Data\personal\mycode\aspnet_vnext_samples\web', 4 | $packOutDir = "c:\temp\publishtemp\packout-pub-multiple" 5 | ) 6 | 7 | function BuildAndPack{ 8 | [cmdletbinding()] 9 | param( 10 | $rootSrcdir, 11 | $packOutdir, 12 | [switch] 13 | $nosource 14 | ) 15 | begin{ Push-Location } 16 | end{ Pop-Location } 17 | process{ 18 | $srcDir = (get-item $rootSrcdir).FullName 19 | Set-Location $srcDir 20 | '********************************************* 21 | building and packing [{0}] 22 | *********************************************' -f $srcDir | Write-Output 23 | '***** restoring nuget packages ****' | Write-Output 24 | kpm restore 25 | 26 | '**** building project ****' | Write-Output 27 | kpm build 28 | 29 | '**** packing to [{0}] ****' -f $outdir | Write-Output 30 | if(!(Test-Path $packOutdir)){New-Item $packOutdir -ItemType Directory} 31 | $outdir = (get-item $packOutdir).FullName 32 | $kpmPackArgs = @('pack', '-o', "$outdir") 33 | if($nosource){ 34 | $kpmPackArgs+='--no-source' 35 | } 36 | 'calling kpm pack with the args [kpm {0}]' -f ($kpmPackArgs -join (' ')) | Write-Output 37 | kpm $kpmPackArgs 38 | } 39 | } 40 | 41 | ################################################# 42 | # Begin script 43 | ################################################# 44 | 45 | if(!(Test-Path $srcDir)){ 46 | throw ('srcDir [{0}] not found' -f $srcDir) 47 | } 48 | 49 | if(Test-Path $packOutDir){Remove-Item $packOutDir -Recurse -Force} 50 | New-Item $packOutDir -ItemType Directory 51 | 52 | $outDirWithSoure = (new-item (join-path $packOutDir 'withsource') -ItemType Directory).FullName 53 | BuildAndPack -rootSrcdir $srcDir -packOutdir $outDirWithSoure 54 | 55 | $outDirNoSoure = (new-item (join-path $packOutDir 'nosource') -ItemType Directory).FullName 56 | BuildAndPack -rootSrcdir $srcDir -packOutdir $outDirNoSoure -nosource 57 | 58 | start "$packOutDir" 59 | <# 60 | 61 | 62 | 63 | 64 | Push-Location 65 | Set-Location $srcDir 66 | Pop-Location 67 | 68 | if(Test-Path $pubTempDir){ Remove-Item $pubTempDir -Recurse -Force } 69 | if(Test-Path $packOutDir){ Remove-Item $packOutDir -Recurse -Force } 70 | 71 | New-Item $pubTempDir -ItemType Directory 72 | New-Item $packOutDir -ItemType Directory 73 | 74 | $packOutDir = (Get-Item $packOutDir).FullName 75 | 76 | Push-Location 77 | 78 | Set-Location $pubTempDir 79 | git clone git@github.com:ligershark/aspnet_vnext_samples.git 80 | 81 | Pop-Location 82 | 83 | 84 | BuildAndPack -rootSrcdir "$pubTempDir\aspnet_vnext_samples" -name 'console' -packOutdir $packOutDir 85 | BuildAndPack -rootSrcdir "$pubTempDir\aspnet_vnext_samples" -name 'web' -packOutdir $packOutDir 86 | BuildAndPack -rootSrcdir "$pubTempDir\aspnet_vnext_samples" -name 'mvc' -packOutdir $packOutDir 87 | 'Pack complete to root [{0}]' -f $pubTempDir | Write-Output 88 | 89 | start "$pubTempDir" 90 | #> -------------------------------------------------------------------------------- /samples/publish-and-backup.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding(SupportsShouldProcess=$true)] 5 | param($publishProperties, $packOutput, $nugetUrl) 6 | 7 | $env:msdeployinstallpath = 'C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\' 8 | 9 | # to learn more about this file visit http://go.microsoft.com/fwlink/?LinkId=524327 10 | $publishModuleVersion = '1.1.1' 11 | function Get-VisualStudio2015InstallPath{ 12 | [cmdletbinding()] 13 | param() 14 | process{ 15 | $keysToCheck = @('hklm:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0','hklm:\SOFTWARE\Microsoft\VisualStudio\14.0') 16 | [string]$vsInstallPath=$null 17 | 18 | foreach($keyToCheck in $keysToCheck){ 19 | if(Test-Path $keyToCheck){ 20 | $vsInstallPath = (Get-itemproperty $keyToCheck -Name InstallDir | select -ExpandProperty InstallDir) 21 | } 22 | 23 | if($vsInstallPath){ 24 | break; 25 | } 26 | } 27 | 28 | $vsInstallPath 29 | } 30 | } 31 | 32 | $defaultPublishSettings = New-Object psobject -Property @{ 33 | LocalInstallDir = ("{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f (Get-VisualStudio2015InstallPath),'1.1.1' ) 34 | } 35 | 36 | function Enable-PackageDownloader{ 37 | [cmdletbinding()] 38 | param( 39 | $toolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader-$publishModuleVersion\", 40 | $pkgDownloaderDownloadUrl = 'http://go.microsoft.com/fwlink/?LinkId=524325') # package-downloader.psm1 41 | process{ 42 | if(get-module package-downloader){ 43 | remove-module package-downloader | Out-Null 44 | } 45 | 46 | if(!(get-module package-downloader)){ 47 | if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory -WhatIf:$false } 48 | 49 | $expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1') 50 | if(!(Test-Path $expectedPath)){ 51 | 'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose 52 | (New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath) 53 | } 54 | 55 | if(!$expectedPath){throw ('Unable to download package-downloader.psm1')} 56 | 57 | 'importing module [{0}]' -f $expectedPath | Write-Output 58 | Import-Module $expectedPath -DisableNameChecking -Force 59 | } 60 | } 61 | } 62 | 63 | function Enable-PublishModule{ 64 | [cmdletbinding()] 65 | param() 66 | process{ 67 | if(get-module publish-module){ 68 | remove-module publish-module | Out-Null 69 | } 70 | 71 | if(!(get-module publish-module)){ 72 | $localpublishmodulepath = Join-Path $defaultPublishSettings.LocalInstallDir 'publish-module.psm1' 73 | if(Test-Path $localpublishmodulepath){ 74 | 'importing module [publish-module="{0}"] from local install dir' -f $localpublishmodulepath | Write-Verbose 75 | Import-Module $localpublishmodulepath -DisableNameChecking -Force 76 | $true 77 | } 78 | } 79 | } 80 | } 81 | 82 | try{ 83 | 84 | if (!(Enable-PublishModule)){ 85 | Enable-PackageDownloader 86 | Enable-NuGetModule -name 'publish-module' -version $publishModuleVersion -nugetUrl $nugetUrl 87 | } 88 | 89 | 'Calling Publish-AspNet' | Write-Verbose 90 | # call Publish-AspNet to perform the publish operation 91 | Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -Verbose 92 | 93 | # publish with file system to backup the contents after publish 94 | $backupdir='c:\temp\publish\backup' 95 | 'backing up the site to {0}' -f $backupdir | Write-Output 96 | Publish-AspNet -packOutput $packOutput -publishProperties @{'WebPublishMethod'='FileSystem';'publishUrl'="$backupdir"} 97 | } 98 | catch{ 99 | "An error occured during publish.`n{0}" -f $_.Exception.Message | Write-Error 100 | } -------------------------------------------------------------------------------- /samples/publish-optimize-images.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding(SupportsShouldProcess=$true)] 5 | param($publishProperties, $packOutput, $nugetUrl) 6 | 7 | $env:msdeployinstallpath = 'C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\' 8 | 9 | # to learn more about this file visit http://go.microsoft.com/fwlink/?LinkId=524327 10 | $publishModuleVersion = '1.1.1' 11 | function Get-VisualStudio2015InstallPath{ 12 | [cmdletbinding()] 13 | param() 14 | process{ 15 | $keysToCheck = @('hklm:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0','hklm:\SOFTWARE\Microsoft\VisualStudio\14.0') 16 | [string]$vsInstallPath=$null 17 | 18 | foreach($keyToCheck in $keysToCheck){ 19 | if(Test-Path $keyToCheck){ 20 | $vsInstallPath = (Get-itemproperty $keyToCheck -Name InstallDir | select -ExpandProperty InstallDir) 21 | } 22 | 23 | if($vsInstallPath){ 24 | break; 25 | } 26 | } 27 | 28 | $vsInstallPath 29 | } 30 | } 31 | 32 | $defaultPublishSettings = New-Object psobject -Property @{ 33 | LocalInstallDir = ("{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f (Get-VisualStudio2015InstallPath),'1.1.1' ) 34 | } 35 | 36 | function Enable-PackageDownloader{ 37 | [cmdletbinding()] 38 | param( 39 | $toolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader-$publishModuleVersion\", 40 | $pkgDownloaderDownloadUrl = 'http://go.microsoft.com/fwlink/?LinkId=524325') # package-downloader.psm1 41 | process{ 42 | if(get-module package-downloader){ 43 | remove-module package-downloader | Out-Null 44 | } 45 | 46 | if(!(get-module package-downloader)){ 47 | if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory -WhatIf:$false } 48 | 49 | $expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1') 50 | if(!(Test-Path $expectedPath)){ 51 | 'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose 52 | (New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath) 53 | } 54 | 55 | if(!$expectedPath){throw ('Unable to download package-downloader.psm1')} 56 | 57 | 'importing module [{0}]' -f $expectedPath | Write-Output 58 | Import-Module $expectedPath -DisableNameChecking -Force 59 | } 60 | } 61 | } 62 | 63 | function Enable-PublishModule{ 64 | [cmdletbinding()] 65 | param() 66 | process{ 67 | if(get-module publish-module){ 68 | remove-module publish-module | Out-Null 69 | } 70 | 71 | if(!(get-module publish-module)){ 72 | $localpublishmodulepath = Join-Path $defaultPublishSettings.LocalInstallDir 'publish-module.psm1' 73 | if(Test-Path $localpublishmodulepath){ 74 | 'importing module [publish-module="{0}"] from local install dir' -f $localpublishmodulepath | Write-Verbose 75 | Import-Module $localpublishmodulepath -DisableNameChecking -Force 76 | $true 77 | } 78 | } 79 | } 80 | } 81 | 82 | try{ 83 | 84 | if (!(Enable-PublishModule)){ 85 | Enable-PackageDownloader 86 | Enable-NuGetModule -name 'publish-module' -version $publishModuleVersion -nugetUrl $nugetUrl 87 | } 88 | 89 | # instal nuget-powershell 90 | (new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/ligershark/nuget-powershell/master/get-nugetps.ps1") | iex 91 | $imgOptExe = (Join-Path (Get-NuGetPackage AzureImageOptimizer -prerelease) 'bin\ImageCompressor.Job.exe') 92 | 'Optimizing Images' | Write-Output 93 | &$imgOptExe /d $packOutput --force 94 | 95 | 'Calling Publish-AspNet' | Write-Verbose 96 | # call Publish-AspNet to perform the publish operation 97 | Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -Verbose 98 | } 99 | catch{ 100 | "An error occured during publish.`n{0}" -f $_.Exception.Message | Write-Error 101 | } -------------------------------------------------------------------------------- /samples/publish-to-blob-storage.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 2 | # Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | [cmdletbinding(SupportsShouldProcess=$true)] 5 | param($publishProperties, $packOutput, $nugetUrl) 6 | 7 | $env:msdeployinstallpath = 'C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\' 8 | 9 | # to learn more about this file visit http://go.microsoft.com/fwlink/?LinkId=524327 10 | $publishModuleVersion = '1.1.1' 11 | function Get-VisualStudio2015InstallPath{ 12 | [cmdletbinding()] 13 | param() 14 | process{ 15 | $keysToCheck = @('hklm:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0','hklm:\SOFTWARE\Microsoft\VisualStudio\14.0') 16 | [string]$vsInstallPath=$null 17 | 18 | foreach($keyToCheck in $keysToCheck){ 19 | if(Test-Path $keyToCheck){ 20 | $vsInstallPath = (Get-itemproperty $keyToCheck -Name InstallDir | select -ExpandProperty InstallDir) 21 | } 22 | 23 | if($vsInstallPath){ 24 | break; 25 | } 26 | } 27 | 28 | $vsInstallPath 29 | } 30 | } 31 | 32 | $defaultPublishSettings = New-Object psobject -Property @{ 33 | LocalInstallDir = ("{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f (Get-VisualStudio2015InstallPath),'1.1.1' ) 34 | } 35 | 36 | function Enable-PackageDownloader{ 37 | [cmdletbinding()] 38 | param( 39 | $toolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader-$publishModuleVersion\", 40 | $pkgDownloaderDownloadUrl = 'http://go.microsoft.com/fwlink/?LinkId=524325') # package-downloader.psm1 41 | process{ 42 | if(get-module package-downloader){ 43 | remove-module package-downloader | Out-Null 44 | } 45 | 46 | if(!(get-module package-downloader)){ 47 | if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory -WhatIf:$false } 48 | 49 | $expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1') 50 | if(!(Test-Path $expectedPath)){ 51 | 'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose 52 | (New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath) 53 | } 54 | 55 | if(!$expectedPath){throw ('Unable to download package-downloader.psm1')} 56 | 57 | 'importing module [{0}]' -f $expectedPath | Write-Output 58 | Import-Module $expectedPath -DisableNameChecking -Force 59 | } 60 | } 61 | } 62 | 63 | function Enable-PublishModule{ 64 | [cmdletbinding()] 65 | param() 66 | process{ 67 | if(get-module publish-module){ 68 | remove-module publish-module | Out-Null 69 | } 70 | 71 | if(!(get-module publish-module)){ 72 | $localpublishmodulepath = Join-Path $defaultPublishSettings.LocalInstallDir 'publish-module.psm1' 73 | if(Test-Path $localpublishmodulepath){ 74 | 'importing module [publish-module="{0}"] from local install dir' -f $localpublishmodulepath | Write-Verbose 75 | Import-Module $localpublishmodulepath -DisableNameChecking -Force 76 | $true 77 | } 78 | } 79 | } 80 | } 81 | 82 | function Publish-FolderToBlobStorage{ 83 | [cmdletbinding()] 84 | param( 85 | [Parameter(Mandatory=$true,Position=0)] 86 | [ValidateScript({Test-Path $_ -PathType Container})] 87 | $folder, 88 | [Parameter(Mandatory=$true,Position=1)] 89 | $storageAcctName, 90 | [Parameter(Mandatory=$true,Position=2)] 91 | $storageAcctKey, 92 | [Parameter(Mandatory=$true,Position=3)] 93 | $containerName 94 | ) 95 | begin{ 96 | 'Publishing folder to blob storage. [folder={0},storageAcctName={1},storageContainer={2}]' -f $folder,$storageAcctName,$containerName | Write-Output 97 | Push-Location 98 | Set-Location $folder 99 | $destContext = New-AzureStorageContext -StorageAccountName $storageAcctName -StorageAccountKey $storageAcctKey 100 | } 101 | end{ Pop-Location } 102 | process{ 103 | $allFiles = (Get-ChildItem $folder -Recurse -File).FullName 104 | 105 | foreach($file in $allFiles){ 106 | $relPath = (Resolve-Path $file -Relative).TrimStart('.\') 107 | "relPath: [$relPath]" | Write-Output 108 | 109 | Set-AzureStorageBlobContent -Blob $relPath -File $file -Container $containerName -Context $destContext 110 | } 111 | } 112 | } 113 | 114 | try{ 115 | 116 | if (!(Enable-PublishModule)){ 117 | Enable-PackageDownloader 118 | Enable-NuGetModule -name 'publish-module' -version $publishModuleVersion -nugetUrl $nugetUrl 119 | } 120 | 121 | 'Registering blob storage handler' | Write-Verbose 122 | Register-AspnetPublishHandler -name 'BlobStorage' -handler { 123 | [cmdletbinding()] 124 | param( 125 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 126 | $publishProperties, 127 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 128 | $packOutput 129 | ) 130 | 131 | '[op={0},san={1},con={2}' -f $packOutput,$publishProperties['StorageAcctName'],$publishProperties['StorageContainer'] | Write-Output 132 | 133 | Publish-FolderToBlobStorage -folder $packOutput -storageAcctName $publishProperties['StorageAcctName'] -storageAcctKey $publishProperties['StorageAcctKey'] -containerName $publishProperties['StorageContainer'] 134 | } 135 | 136 | 'Calling Publish-AspNet' | Write-Verbose 137 | # call Publish-AspNet to perform the publish operation 138 | Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -Verbose 139 | } 140 | catch{ 141 | "An error occured during publish.`n{0}" -f $_.Exception.Message | Write-Error 142 | } -------------------------------------------------------------------------------- /samples/publish-to-blob-storage.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | Any CPU 11 | 12 | True 13 | False 14 | False 15 | True 16 | wwwroot 17 | c:\temp\publish\08 18 | False 19 | 20 | BlobStorage 21 | 22 | $(storageacctname) 23 | $(storageacctkey) 24 | $(storagecontainer) 25 | 26 | -------------------------------------------------------------------------------- /samples/samples.md: -------------------------------------------------------------------------------- 1 | # Publish Samples 2 | 3 | These samples rely on the following. 4 | 5 | - set ```$env:PublishPwd``` env var 6 | - Publish using VS and set the ```$packOutput``` variable before calling the samples. Note this should ***not*** have ```wwwroot```. 7 | 8 | ### Standard MSDeploy publish 9 | 10 | ``` 11 | .\Properties\PublishProfiles\sayedkdemo2.ps1 -packOutput $packOutput -publishProperties @{ 12 | 'WebPublishMethod'='MSDeploy' 13 | 'MSDeployServiceURL'='sayedkdemo2.scm.azurewebsites.net:443'; 14 | 'DeployIisAppPath'='sayedkdemo2';'Username'='$sayedkdemo2';'Password'="$env:PublishPwd"} -Verbose 15 | ``` 16 | 17 | ### Standard file system publish 18 | 19 | ``` 20 | .\Properties\PublishProfiles\sayedkdemo2.ps1 -packOutput $packOutput -publishProperties @{ 21 | 'WebPublishMethod'='FileSystem' 22 | 'publishUrl'='C:\temp\publish\new' 23 | } -Verbose 24 | ``` 25 | 26 | ## Skipping files 27 | 28 | ### MSDeploy publish skipping two files 29 | 30 | ``` 31 | .\Properties\PublishProfiles\sayedkdemo2.ps1 -packOutput $packOutput -publishProperties @{ 32 | 'WebPublishMethod'='MSDeploy' 33 | 'MSDeployServiceURL'='sayedkdemo2.scm.azurewebsites.net:443';` 34 | 'DeployIisAppPath'='sayedkdemo2';'Username'='$sayedkdemo2';'Password'="$env:PublishPwd" 35 | 'ExcludeFiles'=@( 36 | @{'Filepath'='wwwroot\\test.txt'}, 37 | @{'Filepath'='wwwroot\\_references.js'} 38 | )} -Verbose 39 | ``` 40 | 41 | ### File system publish skipping two files 42 | 43 | ``` 44 | .\Properties\PublishProfiles\sayedkdemo2.ps1 -packOutput $packOutput -publishProperties @{ 45 | 'WebPublishMethod'='FileSystem' 46 | 'publishUrl'='C:\temp\publish\new' 47 | 'ExcludeFiles'=@( 48 | @{'Filepath'='.*.cmd'}, 49 | @{'Filepath'='wwwroot\test.txt'} 50 | )} -Verbose 51 | ``` 52 | 53 | 54 | -------------------------------------------------------------------------------- /tests/EFMigration.tests.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param() 3 | 4 | function Get-ScriptDirectory 5 | { 6 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 7 | Split-Path $Invocation.MyCommand.Path 8 | } 9 | 10 | function InternalNew-TestFolder { 11 | [cmdletbinding()] 12 | param( 13 | [Parameter(Mandatory = $true,Position=0)] 14 | [string]$testDrivePath, 15 | [Parameter(Mandatory = $true,Position=1)] 16 | [string]$folderName 17 | ) 18 | process { 19 | if ([string]::IsNullOrWhiteSpace($folderName)) { 20 | throw 'folder name cannot be empty or white space' 21 | } 22 | if (!(Test-Path -Path $testDrivePath)) { 23 | throw 'The path of test drive does not exist' 24 | } 25 | $targetFoler = Join-Path $testDrivePath $folderName 26 | if (!(Test-Path -Path $targetFoler)) { 27 | New-Item -Path $testDrivePath -Name $folderName -ItemType "directory" | Out-Null 28 | } 29 | } 30 | } 31 | $scriptDir = ((Get-ScriptDirectory) + "\") 32 | $moduleName = 'publish-module' 33 | $modulePath = (Join-Path $scriptDir ('..\{0}.psm1' -f $moduleName)) 34 | 35 | $env:IsDeveloperMachine = $true 36 | 37 | if(Test-Path $modulePath){ 38 | 'Importing module from [{0}]' -f $modulePath | Write-Verbose 39 | 40 | if((Get-Module $moduleName)){ Remove-Module $moduleName -Force } 41 | 42 | Import-Module $modulePath -PassThru -DisableNameChecking | Out-Null 43 | } 44 | else{ 45 | throw ('Unable to find module at [{0}]' -f $modulePath ) 46 | } 47 | 48 | Describe 'create/update appSettings.Production.Json file test' { 49 | It 'create a new appSettings.production.json file - null connection string object' { 50 | $testFolderName = 'ConfigProdJsonCase01' 51 | $rootDir = Join-Path $TestDrive $testFolderName 52 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 53 | 54 | $environmentName = 'Production' 55 | $configProdJsonFile = 'appsettings.{0}.json' -f $environmentName 56 | 57 | # null connection string 58 | $defaultConnStrings = $null 59 | GenerateInternal-AppSettingsFile -packOutput $rootDir -environmentName $environmentName -connectionStrings $defaultConnStrings 60 | # verify 61 | $result = Get-Content (Join-Path $rootDir $configProdJsonFile) -Raw 62 | $emptyTarget = @' 63 | { 64 | 65 | } 66 | '@ 67 | ($result.Trim() -eq $emptyTarget) | should be $true 68 | } 69 | 70 | It 'create a new appSettings.production.json file - empty connection string object' { 71 | $testFolderName = 'ConfigProdJsonCase11' 72 | $rootDir = Join-Path $TestDrive $testFolderName 73 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 74 | 75 | $environmentName = 'Production' 76 | $configProdJsonFile = 'appsettings.{0}.json' -f $environmentName 77 | 78 | # empty connection string object 79 | $defaultConnStrings = New-Object 'system.collections.generic.dictionary[[string],[string]]' 80 | 81 | GenerateInternal-AppSettingsFile -packOutput $rootDir -environmentName $environmentName -connectionStrings $defaultConnStrings 82 | 83 | $result = Get-Content (Join-Path $rootDir $configProdJsonFile) -Raw 84 | $emptyTarget = @' 85 | { 86 | 87 | } 88 | '@ 89 | ($result.Trim() -eq $emptyTarget) | should be $true 90 | } 91 | 92 | It 'create a new appSettings.production.json file - non-empty connection string object' { 93 | $testFolderName = 'ConfigProdJsonCase21' 94 | $rootDir = Join-Path $TestDrive $testFolderName 95 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 96 | 97 | $environmentName = 'Production' 98 | $configProdJsonFile = 'appsettings.{0}.json' -f $environmentName 99 | # non-empty connection string object 100 | $defaultConnStrings = New-Object 'system.collections.generic.dictionary[[string],[string]]' 101 | $defaultConnStrings.Add("connection1","server=server1;database=db1;") 102 | $defaultConnStrings.Add("connection2","server=server2;database=db2;") 103 | 104 | GenerateInternal-AppSettingsFile -packOutput $rootDir -environmentName $environmentName -connectionStrings $defaultConnStrings 105 | 106 | $finalJsonContent = Get-Content (join-path $rootDir $configProdJsonFile) -Raw 107 | $emptyTarget = @' 108 | { 109 | 110 | } 111 | '@ 112 | ($finalJsonContent.Trim() -ne $emptyTarget) | should be $true 113 | $finalJsonObj = ConvertFrom-Json -InputObject $finalJsonContent 114 | ($finalJsonObj.ConnectionStrings.connection1 -eq 'server=server1;database=db1;') | should be $true 115 | ($finalJsonObj.ConnectionStrings.connection2 -eq 'server=server2;database=db2;') | should be $true 116 | 117 | } 118 | 119 | It 'update existing appSettings.production.json file - null connection string object' { 120 | $testFolderName = 'ConfigProdJsonCase31' 121 | $rootDir = Join-Path $TestDrive $testFolderName 122 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 123 | 124 | $environmentName = 'Production' 125 | $configProdJsonFile = 'appSettings.{0}.json' -f $environmentName 126 | # null connection string object 127 | 128 | # prepare content of appSettings.production.json for test purpose 129 | $configProdJsonPath = Join-Path $rootDir $configProdJsonFile 130 | $originalJsonContent = @' 131 | { 132 | "ConnectionStrings": { 133 | "DefaultConnection": "a-sql-server-connection-string-in-config-json" 134 | }, 135 | "TestData" : "TestValue" 136 | } 137 | '@ 138 | # create appSettings.production.json for test purpose 139 | $originalJsonContent | Set-Content -Path $configProdJsonPath -Force 140 | 141 | GenerateInternal-AppSettingsFile -packOutput $rootDir -environmentName $environmentName 142 | 143 | $finalJsonContent = Get-Content (join-path $rootDir $configProdJsonFile) -Raw 144 | $emptyTarget = @' 145 | { 146 | 147 | } 148 | '@ 149 | ($finalJsonContent -ne $emptyTarget) | should be $true 150 | $finalJsonObj = ConvertFrom-Json -InputObject $finalJsonContent 151 | ($finalJsonObj.ConnectionStrings.DefaultConnection -eq 'a-sql-server-connection-string-in-config-json') | should be $true 152 | ($finalJsonObj.TestData -eq 'TestValue') | should be $true 153 | 154 | } 155 | 156 | It 'update existing appSettings.production.json file - empty connection string object' { 157 | $testFolderName = 'ConfigProdJsonCase41' 158 | $rootDir = Join-Path $TestDrive $testFolderName 159 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 160 | 161 | $environmentName = 'Production' 162 | $configProdJsonFile = 'appSettings.{0}.json' -f $environmentName 163 | # empty connection string object 164 | $defaultConnStrings = New-Object 'system.collections.generic.dictionary[[string],[string]]' 165 | # prepare content of appSettings.production.json for test purpose 166 | $originalJsonContent = @' 167 | { 168 | "ConnectionStrings": { 169 | "DefaultConnection": "a-sql-server-connection-string-in-config-json" 170 | }, 171 | "TestData" : "TestValue" 172 | } 173 | '@ 174 | # create appSettings.Production.json for test purpose 175 | $originalJsonContent | Set-Content -Path (Join-Path $rootDir $configProdJsonFile) -Force 176 | 177 | GenerateInternal-AppSettingsFile -packOutput $rootDir -environmentName $environmentName -connectionStrings $defaultConnStrings 178 | 179 | $finalJsonContent = Get-Content (join-path $rootDir $configProdJsonFile) -Raw 180 | $emptyTarget = @' 181 | { 182 | 183 | } 184 | '@ 185 | ($finalJsonContent -ne $emptyTarget) | should be $true 186 | $finalJsonObj = ConvertFrom-Json -InputObject $finalJsonContent 187 | ($finalJsonObj.ConnectionStrings.DefaultConnection -eq 'a-sql-server-connection-string-in-config-json') | should be $true 188 | ($finalJsonObj.TestData -eq 'TestValue') | should be $true 189 | } 190 | 191 | It 'update existing appSettings.production.json file - non-empty connection string object' { 192 | $testFolderName = 'ConfigProdJsonCase51' 193 | $rootDir = Join-Path $TestDrive $testFolderName 194 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 195 | 196 | $environmentName = 'Production' 197 | $compileSource = $true 198 | $projectName = 'TestWebApp' 199 | $projectVersion = '1.0.0' 200 | $configProdJsonFile = 'appSettings.{0}.json' -f $environmentName 201 | $defaultConnStrings = New-Object 'system.collections.generic.dictionary[[string],[string]]' 202 | $defaultConnStrings.Add("connection1","server=server1;database=db1;") 203 | $defaultConnStrings.Add("connection2","server=server2;database=db2;") 204 | 205 | $originalJsonContent = @' 206 | { 207 | "ConnectionStrings": { 208 | "DefaultConnection": "a-sql-server-connection-string-in-config-json", 209 | "connection1": "random text" 210 | }, 211 | "TestData" : "TestValue" 212 | } 213 | '@ 214 | # create appSettings.Production.Json for test purpose 215 | $originalJsonContent | Set-Content -Path (Join-Path $rootDir $configProdJsonFile) -Force 216 | 217 | GenerateInternal-AppSettingsFile -packOutput $rootDir -environmentName $environmentName -connectionStrings $defaultConnStrings 218 | 219 | $finalJsonContent = Get-Content (Join-Path $rootDir $configProdJsonFile) -Raw 220 | $emptyTarget = @' 221 | { 222 | 223 | } 224 | '@ 225 | ($finalJsonContent -ne $emptyTarget) | should be $true 226 | $finalJsonObj = ConvertFrom-Json -InputObject $finalJsonContent 227 | ($finalJsonObj.ConnectionStrings.DefaultConnection -eq 'a-sql-server-connection-string-in-config-json') | should be $true 228 | ($finalJsonObj.TestData -eq 'TestValue') | should be $true 229 | ($finalJsonObj.ConnectionStrings.connection1 -eq 'server=server1;database=db1;') | should be $true 230 | ($finalJsonObj.ConnectionStrings.connection2 -eq 'server=server2;database=db2;') | should be $true 231 | } 232 | } 233 | 234 | Describe 'generate EF migration TSQL script test' { 235 | 236 | It 'EF T-SQL will be copied to script folder in file system publishing test' { 237 | $DBContextName = 'BlogsContext' 238 | $testFolderName = 'EFMigrationsInFileSystem00' 239 | $outputFolderName = 'EFMigrationsInFileSystem00-output' 240 | $rootDir = Join-Path $TestDrive $testFolderName 241 | $outputDir = Join-Path $TestDrive $outputFolderName 242 | # create test folder 243 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 244 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $outputFolderName 245 | # copy sample to test folder 246 | Copy-Item .\SampleFiles\DotNetWebApp\* $rootDir -recurse -Force 247 | 248 | $originalExePath = $env:dotnetinstallpath 249 | 250 | try 251 | { 252 | $env:dotnetinstallpath = '' # force the script to find dotnet.exe 253 | $EFConnectionString = @{"$DBContextName"='some-EF-migrations-string'} 254 | #run dotnet restore first to generate project.lock.json 255 | $dotnetpath = GetInternal-DotNetExePath 256 | (Test-Path -Path $dotnetpath) | should be $true 257 | Execute-Command $dotnetpath 'restore' "$rootDir\src" 258 | 259 | Publish-AspNet -packOutput $outputDir -publishProperties @{ 260 | 'WebPublishMethod'='FileSystem' 261 | 'publishUrl'="$outputDir" 262 | 'ProjectPath'="$rootDir\src" 263 | 'EfMigrations'=$EFConnectionString 264 | } 265 | } 266 | finally 267 | { 268 | $env:dotnetinstallpath = $originalExePath 269 | } 270 | 271 | (Test-Path "$outputDir") | should be $true 272 | # (Test-Path "$outputDir\$DBContextName.sql") | should be $true 273 | } 274 | 275 | It 'Invalid dotnetExePath system variable test' { 276 | $testFolderName = 'EFMigrations00' 277 | $rootDir = Join-Path $TestDrive $testFolderName 278 | # create test folder 279 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 280 | 281 | $originalExePath = $env:dotnetinstallpath 282 | 283 | try 284 | { 285 | $env:dotnetinstallpath = 'pretend-invalid-path' 286 | $EFConnectionString = @{'dbContext1'='some-EF-connection-string'} 287 | {GenerateInternal-EFMigrationScripts -projectPath '' -packOutput $rootDir -EFMigrations $EFConnectionString} | should throw 288 | } 289 | finally 290 | { 291 | $env:dotnetinstallpath = $originalExePath 292 | } 293 | } 294 | 295 | It 'generate ef migration file test' { 296 | $testFolderName = 'EFMigrations01' 297 | $rootDir = Join-Path $TestDrive $testFolderName 298 | # create test folder 299 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 300 | 301 | # copy sample to test folder 302 | Copy-Item .\SampleFiles\DotNetWebApp\* $rootDir -recurse -Force 303 | 304 | $originalExePath = $env:dotnetinstallpath 305 | 306 | try 307 | { 308 | $EFConnectionString = @{'BlogsContext'='some-EF-migrations-string'} 309 | $dotnetpath = GetInternal-DotNetExePath 310 | (Test-Path -Path $dotnetpath) | should be $true 311 | Execute-Command $dotnetpath 'restore' "$rootDir\src" 312 | $sqlFiles = GenerateInternal-EFMigrationScripts -projectPath "$rootDir\src" -packOutput "$rootDir\src" -EFMigrations $EFConnectionString 313 | ($sqlFiles -eq $null) | Should be $false 314 | # ($sqlFiles.Values.Count -gt 0) | should be $true 315 | foreach ($file in $sqlFiles.Values) { 316 | (Test-Path -Path $file) | should be $true 317 | } 318 | } 319 | finally 320 | { 321 | $env:dotnetinstallpath = $originalExePath 322 | } 323 | } 324 | } 325 | 326 | Describe 'create manifest xml file tests' { 327 | It 'generate source manifest file for iisApp provider and one dbFullSql provider' { 328 | $testFolderName = 'ManifestFileCase10' 329 | $rootDir = Join-Path $TestDrive $testFolderName 330 | # create test folder 331 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 332 | 333 | $webRootName = 'wwwroot' 334 | $iisAppPath = $rootDir 335 | $publishProperties =@{ 336 | 'WebPublishMethod'='MSDeploy' 337 | 'WwwRootOut'="$webRootName" 338 | } 339 | $sqlFile = 'c:\Samples\dbContext.sql' 340 | $EFMigration = @{ 341 | 'dbContext1'="$sqlFile" 342 | } 343 | $efData = @{ 344 | 'EFSqlFile'=$EFMigration 345 | } 346 | [System.Collections.ArrayList]$providerDataArray = @() 347 | $providerDataArray.Add(@{"iisApp" = @{"path"=$iisAppPath}}) | Out-Null 348 | $providerDataArray.Add(@{"dbfullsql" = @{"path"=$sqlFile}}) | Out-Null 349 | 350 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' 351 | # verify 352 | (Test-Path -Path $xmlFile) | should be $true 353 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase10') 354 | ((Join-Path $pubArtifactDir 'SourceManifest.xml') -eq $xmlFile.FullName) | should be $true 355 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 356 | ($xmlResult.sitemanifest.iisApp.path -eq "$iisAppPath") | should be $true 357 | ($xmlResult.sitemanifest.dbFullSql.path -eq "$sqlFile") | should be $true 358 | } 359 | 360 | It 'generate dest manifest file for iisApp provider and one dbFullSql provider' { 361 | $testFolderName = 'ManifestFileCase11' 362 | $rootDir = Join-Path $TestDrive $testFolderName 363 | # create test folder 364 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 365 | 366 | $sqlConnString = 'server=serverName;database=dbName;user id=userName;password=userPassword;' 367 | $EFMigration = @{ 368 | 'connString1'="$sqlConnString" 369 | } 370 | $DBConnStrings = @{ 371 | 'connString1'="$sqlConnString" 372 | } 373 | $efData = @{ 374 | 'EFSqlFile'=$EFMigration 375 | } 376 | $publishProperties =@{ 377 | 'WebPublishMethod'='MSDeploy' 378 | 'DeployIisAppPath'='WebSiteName' 379 | 'EfMigrations'=$EFMigration 380 | 'DestinationConnectionStrings'=$DBConnStrings 381 | } 382 | 383 | [System.Collections.ArrayList]$providerDataArray = @() 384 | $providerDataArray.Add(@{"iisApp" = @{"path"=$publishProperties['DeployIisAppPath']}}) | Out-Null 385 | $providerDataArray.Add(@{"dbfullsql" = @{"path"=$sqlConnString}}) | Out-Null 386 | 387 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml' 388 | 389 | # verify 390 | (Test-Path -Path $xmlFile) | should be $true 391 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase11') 392 | ((Join-Path $pubArtifactDir 'DestinationManifest.xml') -eq $xmlFile.FullName) | should be $true 393 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 394 | ($xmlResult.sitemanifest.iisApp.path -eq 'WebSiteName') | should be $true 395 | ($xmlResult.sitemanifest.dbFullSql.path -eq "$sqlConnString") | should be $true 396 | } 397 | 398 | It 'generate source manifest file for iisApp provider and two dbFullSql providers' { 399 | $testFolderName = 'ManifestFileCase12' 400 | $rootDir = Join-Path $TestDrive $testFolderName 401 | # create test folder 402 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 403 | 404 | $webRootName = 'wwwroot' 405 | $iisAppPath = $rootDir 406 | $sqlFile1 = 'c:\Samples\dbContext1.sql' 407 | $sqlFile2 = 'c:\Samples\dbContext2.sql' 408 | $EFMigration = @{ 409 | 'dbContext1'="$sqlFile1" 410 | 'dbContext2'="$sqlFile2" 411 | } 412 | $efData = @{ 413 | 'EFSqlFile'=$EFMigration 414 | } 415 | $publishProperties =@{ 416 | 'WebPublishMethod'='MSDeploy' 417 | 'WwwRootOut'="$webRootName" 418 | 'EfMigrations'=$EFMigration 419 | } 420 | 421 | [System.Collections.ArrayList]$providerDataArray = @() 422 | $providerDataArray.Add(@{"iisApp" = @{"path"=$iisAppPath}}) | Out-Null 423 | $providerDataArray.Add(@{"dbfullsql" = @{"path"=$sqlFile1}}) | Out-Null 424 | $providerDataArray.Add(@{"dbfullsql" = @{"path"=$sqlFile2}}) | Out-Null 425 | 426 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' 427 | 428 | # verify 429 | (Test-Path -Path $xmlFile) | should be $true 430 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase12') 431 | ((Join-Path $pubArtifactDir 'SourceManifest.xml') -eq $xmlFile.FullName) | should be $true 432 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 433 | ($xmlResult.sitemanifest.iisApp.path -eq "$iisAppPath") | should be $true 434 | ($xmlResult.sitemanifest.dbFullSql[0].path -eq "$sqlFile1") | should be $true 435 | ($xmlResult.sitemanifest.dbFullSql[1].path -eq "$sqlFile2") | should be $true 436 | } 437 | 438 | It 'generate dest manifest file for iisApp provider and two dbFullSql providers' { 439 | $testFolderName = 'ManifestFileCase13' 440 | $rootDir = Join-Path $TestDrive $testFolderName 441 | # create test folder 442 | InternalNew-TestFolder -testDrivePath $TestDrive -folderName $testFolderName 443 | 444 | $firstString = 'server=aaa;database=bbb;user id=ccc;password=ddd;' 445 | $secondString = 'server=www;database=xxx;user id=yyy;password=zzz;' 446 | $connStrings = @{ 447 | 'dbContext1'="$firstString" 448 | 'dbContext2'="$secondString" 449 | } 450 | $EFMigration = @{ 451 | 'dbContext1'="$firstString" 452 | 'dbContext2'="$secondString" 453 | } 454 | $efData = @{} 455 | $publishProperties =@{ 456 | 'WebPublishMethod'='MSDeploy' 457 | 'DeployIisAppPath'='WebSiteName' 458 | 'EfMigrations'=$EFMigration 459 | 'DestinationConnectionStrings'=$connStrings 460 | } 461 | 462 | [System.Collections.ArrayList]$providerDataArray = @() 463 | $providerDataArray.Add(@{"iisApp" = @{"path"=$publishProperties['DeployIisAppPath']}}) | Out-Null 464 | $providerDataArray.Add(@{"dbfullsql" = @{"path"=$firstString}}) | Out-Null 465 | $providerDataArray.Add(@{"dbfullsql" = @{"path"=$secondString}}) | Out-Null 466 | 467 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml' 468 | 469 | # verify 470 | (Test-Path -Path $xmlFile) | should be $true 471 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase13') 472 | ((Join-Path $pubArtifactDir 'DestinationManifest.xml') -eq $xmlFile.FullName) | should be $true 473 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 474 | ($xmlResult.sitemanifest.iisApp.path -eq 'WebSiteName') | should be $true 475 | ($xmlResult.sitemanifest.dbFullSql[0].path -eq "$firstString") | should be $true 476 | ($xmlResult.sitemanifest.dbFullSql[1].path -eq "$secondString") | should be $true 477 | } 478 | } -------------------------------------------------------------------------------- /tests/MSDeploy.tests.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param() 3 | 4 | function Get-ScriptDirectory 5 | { 6 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 7 | Split-Path $Invocation.MyCommand.Path 8 | } 9 | 10 | $scriptDir = ((Get-ScriptDirectory) + "\") 11 | $moduleName = 'publish-module' 12 | $modulePath = (Join-Path $scriptDir ('..\{0}.psm1' -f $moduleName)) 13 | $samplesdir = (Join-Path $scriptDir 'SampleFiles') 14 | 15 | if(Test-Path $modulePath){ 16 | "Importing module from [{0}]" -f $modulePath | Write-Verbose 17 | 18 | if((Get-Module $moduleName)){ Remove-Module $moduleName -Force } 19 | 20 | Import-Module $modulePath -PassThru -DisableNameChecking | Out-Null 21 | } 22 | else{ 23 | throw ('Unable to find module at [{0}]' -f $modulePath ) 24 | } 25 | 26 | Describe 'MSDeploy unit tests' { 27 | $global:lastCommandToGetMSDeploy = $null 28 | [string]$mvcSourceFolder = (resolve-path (Join-Path $samplesdir 'MvcApplication')) 29 | [string]$mvcPackDir = (resolve-path (Join-Path $samplesdir 'MvcApplication-packOutput')) 30 | 31 | 32 | Mock Print-CommandString { 33 | return { 34 | $command 35 | } 36 | } -param { $global:lastCommandToGetMSDeploy = $command } -ModuleName 'publish-module' 37 | 38 | Mock Execute-CommandString { 39 | return { 40 | $command 41 | } 42 | } -ModuleName 'publish-module' 43 | 44 | 45 | It 'Verify computername and other basic parameters are in args to msdeploy' { 46 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\Basic01') 47 | 48 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 49 | 'WebPublishMethod'='MSDeploy' 50 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` 51 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="somepassword-here" 52 | } 53 | 54 | [string]$lastCommand = ($global:lastCommandToGetMSDeploy) 55 | $lastCommand.Contains("ComputerName='https://contoso.scm.azurewebsites.net/msdeploy.axd?site=contoso'") | Should Be $true 56 | $lastCommand.Contains('UserName=''$contoso''') | Should Be $true 57 | $lastCommand.Contains("AuthType='Basic'") | Should Be $true 58 | $lastCommand.Contains('-verb:sync') | Should Be $true 59 | } 60 | 61 | It 'Default parameters in args to msdeploy' { 62 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\Basic01') 63 | 64 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 65 | 'WebPublishMethod'='MSDeploy' 66 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` 67 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="somepassword-here" 68 | } 69 | 70 | [string]$lastCommand = ($global:lastCommandToGetMSDeploy) 71 | $lastCommand.Contains('-usechecksum') | Should Be $false 72 | $lastCommand.Contains("-enableRule:DoNotDeleteRule") | Should Be $true 73 | $lastCommand.Contains("-retryAttempts:2") | Should Be $true 74 | $lastCommand.Contains('-disablerule:BackupRule') | Should Be $true 75 | } 76 | 77 | It 'Can publish and not pass contentLibExtension' { 78 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\Basic01') 79 | 80 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 81 | 'WebPublishMethod'='MSDeploy' 82 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` 83 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="somepassword-here" 84 | 'EnableLinkContentLibExtension'=$false 85 | } 86 | 87 | [string]$lastCommand = ($global:lastCommandToGetMSDeploy) 88 | $lastCommand.Contains('-usechecksum') | Should Be $false 89 | $lastCommand.Contains('-enableLink:contentLibExtension') | Should Not Be $true 90 | $lastCommand.Contains("-enableRule:DoNotDeleteRule") | Should Be $true 91 | $lastCommand.Contains("-retryAttempts:2") | Should Be $true 92 | $lastCommand.Contains('-disablerule:BackupRule') | Should Be $true 93 | } 94 | 95 | <# 96 | It 'Passing whatif passes the appropriate switch' { 97 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 98 | 'WebPublishMethod'='MSDeploy' 99 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` 100 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="somepassword-here" 101 | } -WhatIf 102 | 103 | [string]$lastCommand = ($global:lastCommandToGetMSDeploy -join ' ') 104 | $lastCommand.Contains('-whatif') | Should Be $true 105 | } 106 | #> 107 | 108 | It 'Can overriding webpublish with publishProperties[''WebPublishMethodOverride'']' { 109 | [string]$overrideValue = 'MSDeploy' 110 | $global:pubMethod = $null 111 | 112 | Mock Publish-AspNetMSDeploy { 113 | $global:pubMethod = ($PublishProperties['WebPublishMethod']) 114 | } -ModuleName publish-module 115 | 116 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 117 | 'WebPublishMethod'='FileSystem' 118 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` 119 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="somepassword-here" 120 | 'WebPublishMethodOverride'="$overrideValue" 121 | } 122 | 123 | $global:pubMethod | Should Be $overrideValue 124 | } 125 | 126 | 127 | } 128 | 129 | Describe 'Encrypt web.config' { 130 | [string]$mvcSourceFolder = (resolve-path (Join-Path $samplesdir 'MvcApplication')) 131 | [string]$mvcPackDir = (resolve-path (Join-Path $samplesdir 'MvcApplication-packOutput')) 132 | 133 | Mock Print-CommandString { 134 | return { 135 | $command 136 | } 137 | } -param { $global:lastCommandToGetMSDeploy = $command } -ModuleName 'publish-module' 138 | 139 | Mock Execute-CommandString { 140 | return { 141 | $command 142 | } 143 | } -ModuleName 'publish-module' 144 | 145 | InternalReset-AspNetPublishHandlers 146 | It 'Can encrypt web.config' { 147 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 148 | 'WebPublishMethod'='MSDeploy' 149 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` 150 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="somepassword-here" 151 | 'EncryptWebConfig'="$true" 152 | } 153 | 154 | [string]$lastCommand = ($global:lastCommandToGetMSDeploy).ToLowerInvariant() 155 | $lastCommand.Contains('-EnableRule:EncryptWebConfig'.ToLowerInvariant()) | Should Be $true 156 | } 157 | } 158 | 159 | Describe 'MSDeploy App Offline' { 160 | [string]$mvcSourceFolder = (resolve-path (Join-Path $samplesdir 'MvcApplication')) 161 | [string]$mvcPackDir = (resolve-path (Join-Path $samplesdir 'MvcApplication-packOutput')) 162 | 163 | Mock Print-CommandString { 164 | return { 165 | $command 166 | } 167 | } -param { $global:lastCommandToGetMSDeploy = $command } -ModuleName 'publish-module' 168 | 169 | Mock Execute-CommandString { 170 | return { 171 | $command 172 | } 173 | } -ModuleName 'publish-module' 174 | 175 | It 'AppOffline default' { 176 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 177 | 'WebPublishMethod'='MSDeploy' 178 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` 179 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="somepassword-here" 180 | 'EnableMSDeployAppOffline'='true' 181 | } 182 | 183 | [string]$lastCommand = ($global:lastCommandToGetMSDeploy).ToLowerInvariant() 184 | $lastCommand.Contains('-enablerule:appoffline') | Should Be $true 185 | $lastCommand.Contains('appofflinetemplate') | Should Be $false 186 | } 187 | 188 | It 'AppOffline with custom file' { 189 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 190 | 'WebPublishMethod'='MSDeploy' 191 | 'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';` 192 | 'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'="somepassword-here" 193 | 'EnableMSDeployAppOffline'='true' 194 | 'AppOfflineTemplate'='offline-template.html' 195 | } 196 | 197 | [string]$lastCommand = ($global:lastCommandToGetMSDeploy).ToLowerInvariant() 198 | $lastCommand.Contains('-enablerule:appoffline') | Should Be $true 199 | } 200 | } 201 | 202 | Describe 'Get-MSDeploy tests'{ 203 | It 'can call Get-MSDeploy and get a path to a file that exists' { 204 | $msdeployPath = Get-MSDeploy 205 | 206 | 207 | $msdeployPath | Should Exist 208 | (Get-Item $msdeployPath) -is [System.IO.FileInfo] | Should Be $true 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /tests/ManifestProvider.tests.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param() 3 | 4 | function Get-ScriptDirectory 5 | { 6 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 7 | Split-Path $Invocation.MyCommand.Path 8 | } 9 | 10 | $scriptDir = ((Get-ScriptDirectory) + "\") 11 | $moduleName = 'publish-module' 12 | $modulePath = (Join-Path $scriptDir ('..\{0}.psm1' -f $moduleName)) 13 | 14 | $env:IsDeveloperMachine = $true 15 | 16 | if(Test-Path $modulePath){ 17 | 'Importing module from [{0}]' -f $modulePath | Write-Verbose 18 | 19 | if((Get-Module $moduleName)){ Remove-Module $moduleName -Force } 20 | 21 | Import-Module $modulePath -PassThru -DisableNameChecking | Out-Null 22 | } 23 | else{ 24 | throw ('Unable to find module at [{0}]' -f $modulePath ) 25 | } 26 | 27 | Describe 'Create manifest xml file tests' { 28 | It 'generate source manifest file for iisApp provider' { 29 | $rootDir = Join-Path $TestDrive 'ManifestFileCase00' 30 | $iisAppPath = $rootDir 31 | $publishProperties =@{ 32 | 'WebPublishMethod'='MSDeploy' 33 | } 34 | if(!(Test-Path rootDir)) 35 | { 36 | mkdir $rootDir 37 | } 38 | 39 | [System.Collections.ArrayList]$providerDataArray = @() 40 | 41 | $iisAppSourceKeyValue=@{"iisApp" = @{"path"=$iisAppPath}} 42 | $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null 43 | 44 | 45 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' 46 | # verify 47 | (Test-Path -Path $xmlFile) | should be $true 48 | 49 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase00') 50 | ((Join-Path $pubArtifactDir 'SourceManifest.xml') -eq $xmlFile.FullName) | should be $true 51 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 52 | ($xmlResult.sitemanifest.iisApp.path -eq "$iisAppPath") | should be $true 53 | } 54 | 55 | It 'generate dest manifest file for iisApp provider' { 56 | $rootDir = Join-Path $TestDrive 'ManifestFileCase01' 57 | $publishProperties =@{ 58 | 'WebPublishMethod'='MSDeploy' 59 | 'DeployIisAppPath'='WebSiteName' 60 | } 61 | if(!(Test-Path rootDir)) 62 | { 63 | mkdir $rootDir 64 | } 65 | 66 | [System.Collections.ArrayList]$providerDataArray = @() 67 | 68 | $iisAppDestinationKeyValue=@{"iisApp" = @{"path"=$publishProperties['DeployIisAppPath']}} 69 | $providerDataArray.Add($iisAppDestinationKeyValue) | Out-Null 70 | 71 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml' 72 | # verify 73 | (Test-Path -Path $xmlFile) | should be $true 74 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase01') 75 | ((Join-Path $pubArtifactDir 'DestinationManifest.xml') -eq $xmlFile.FullName) | should be $true 76 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 77 | ($xmlResult.sitemanifest.iisApp.path -eq 'WebSiteName') | should be $true 78 | } 79 | 80 | It 'generate source manifest file for FileSystem provider' { 81 | $rootDir = Join-Path $TestDrive 'ManifestFileCase20' 82 | $webRootName = 'wwwroot' 83 | $publishProperties =@{ 84 | 'WebPublishMethod'='FileSystem' 85 | } 86 | if(!(Test-Path rootDir)) 87 | { 88 | mkdir $rootDir 89 | } 90 | 91 | [System.Collections.ArrayList]$providerDataArray = @() 92 | $contentPathSourceKeyValue=@{"contentPath" = @{"path"=$rootDir}} 93 | $providerDataArray.Add($contentPathSourceKeyValue) | Out-Null 94 | 95 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' 96 | # verify 97 | (Test-Path -Path $xmlFile) | should be $true 98 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase20') 99 | ((Join-Path $pubArtifactDir 'SourceManifest.xml') -eq $xmlFile.FullName) | should be $true 100 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 101 | ($xmlResult.sitemanifest.contentPath.path -eq "$rootDir") | should be $true 102 | } 103 | 104 | It 'generate dest manifest file for FileSystem provider' { 105 | $rootDir = Join-Path $TestDrive 'ManifestFileCase21' 106 | if(!(Test-Path rootDir)) 107 | { 108 | mkdir $rootDir 109 | } 110 | $webRootName = 'wwwroot' 111 | $publishURL = 'c:\Samples' 112 | $publishProperties =@{ 113 | 'WebPublishMethod'='FileSystem' 114 | 'publishUrl'="$publishURL" 115 | } 116 | 117 | [System.Collections.ArrayList]$providerDataArray = @() 118 | $contentPathDestinationKeyValue=@{"contentPath" = @{"path"=$publishUrl}} 119 | $providerDataArray.Add($contentPathDestinationKeyValue) | Out-Null 120 | 121 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml' 122 | # verify 123 | (Test-Path -Path $xmlFile) | should be $true 124 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase21') 125 | ((Join-Path $pubArtifactDir 'DestinationManifest.xml') -eq $xmlFile.FullName) | should be $true 126 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 127 | ($xmlResult.sitemanifest.contentPath.path -eq "$publishURL") | should be $true 128 | } 129 | 130 | It 'generate source manifest file for Package provider' { 131 | $rootDir = Join-Path $TestDrive 'ManifestFileCase30' 132 | if(!(Test-Path rootDir)) 133 | { 134 | mkdir $rootDir 135 | } 136 | $iisAppPath = $rootDir 137 | $publishProperties =@{ 138 | 'WebPublishMethod'='Package' 139 | } 140 | 141 | [System.Collections.ArrayList]$providerDataArray = @() 142 | $iisAppSourceKeyValue=@{"iisApp" = @{"path"=$rootDir}} 143 | $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null 144 | $xmlFile = GenerateInternal-ManifestFile -packOutput $rootDir -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' 145 | # verify 146 | (Test-Path -Path $xmlFile) | should be $true 147 | $pubArtifactDir = [io.path]::combine([io.path]::GetTempPath(),'PublishTemp','obj','ManifestFileCase30') 148 | ((Join-Path $pubArtifactDir 'SourceManifest.xml') -eq $xmlFile.FullName) | should be $true 149 | $xmlResult = [xml](Get-Content $xmlFile -Raw) 150 | ($xmlResult.sitemanifest.iisApp.path -eq "$iisAppPath") | should be $true 151 | } 152 | } -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Controllers/BlogsController.cs: -------------------------------------------------------------------------------- 1 | 2 | using Microsoft.AspNetCore.Mvc; 3 | using System.Linq; 4 | 5 | namespace RC2_WebApp_EF 6 | { 7 | public class BlogsController : Controller 8 | { 9 | private BlogsContext _context; 10 | 11 | public BlogsController(BlogsContext context) 12 | { 13 | _context = context; 14 | } 15 | 16 | public IActionResult Index() 17 | { 18 | return View(_context.Blogs.ToList()); 19 | } 20 | 21 | public IActionResult Create() 22 | { 23 | return View(); 24 | } 25 | 26 | [HttpPost] 27 | [ValidateAntiForgeryToken] 28 | public IActionResult Create(Blog blog) 29 | { 30 | if (!ModelState.IsValid) 31 | { 32 | return View(blog); 33 | } 34 | 35 | try 36 | { 37 | _context.Blogs.Add(blog); 38 | _context.SaveChanges(); 39 | } 40 | catch 41 | { 42 | ModelState.AddModelError("", "Failed to create"); 43 | return View(blog); 44 | } 45 | return RedirectToAction("Index"); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 |  2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace RC2_WebApp_EF.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | public IActionResult Index() 9 | { 10 | return View(); 11 | } 12 | 13 | public IActionResult About() 14 | { 15 | ViewData["Message"] = "Your application description page."; 16 | 17 | return View(); 18 | } 19 | 20 | public IActionResult Contact() 21 | { 22 | ViewData["Message"] = "Your contact page."; 23 | 24 | return View(); 25 | } 26 | 27 | public IActionResult Error() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Migrations/20160406182601_first.Designer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using RC2_WebApp_EF; 7 | 8 | namespace RC2WebAppEF.Migrations 9 | { 10 | [DbContext(typeof(BlogsContext))] 11 | [Migration("20160406182601_first")] 12 | partial class first 13 | { 14 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 15 | { 16 | modelBuilder 17 | .HasAnnotation("ProductVersion", "1.0.0-rc2-20466") 18 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 19 | 20 | modelBuilder.Entity("RC2_WebApp_EF.Blog", b => 21 | { 22 | b.Property("Id") 23 | .ValueGeneratedOnAdd(); 24 | 25 | b.Property("Url") 26 | .IsRequired() 27 | .HasAnnotation("MaxLength", 100); 28 | 29 | b.HasKey("Id"); 30 | 31 | b.ToTable("Blogs"); 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Migrations/20160406182601_first.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.EntityFrameworkCore.Migrations; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | 6 | namespace RC2WebAppEF.Migrations 7 | { 8 | public partial class first : Migration 9 | { 10 | protected override void Up(MigrationBuilder migrationBuilder) 11 | { 12 | migrationBuilder.CreateTable( 13 | name: "Blogs", 14 | columns: table => new 15 | { 16 | Id = table.Column(nullable: false) 17 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 18 | Url = table.Column(nullable: false) 19 | }, 20 | constraints: table => 21 | { 22 | table.PrimaryKey("PK_Blogs", x => x.Id); 23 | }); 24 | } 25 | 26 | protected override void Down(MigrationBuilder migrationBuilder) 27 | { 28 | migrationBuilder.DropTable( 29 | name: "Blogs"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Migrations/20160406212008_second.Designer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using RC2_WebApp_EF; 7 | 8 | namespace RC2WebAppEF.Migrations 9 | { 10 | [DbContext(typeof(BlogsContext))] 11 | [Migration("20160406212008_second")] 12 | partial class second 13 | { 14 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 15 | { 16 | modelBuilder 17 | .HasAnnotation("ProductVersion", "1.0.0-rc2-20466") 18 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 19 | 20 | modelBuilder.Entity("RC2_WebApp_EF.Blog", b => 21 | { 22 | b.Property("Id") 23 | .ValueGeneratedOnAdd(); 24 | 25 | b.Property("Url") 26 | .IsRequired() 27 | .HasAnnotation("MaxLength", 100); 28 | 29 | b.HasKey("Id"); 30 | 31 | b.ToTable("Blogs"); 32 | }); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Migrations/20160406212008_second.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.EntityFrameworkCore.Migrations; 4 | 5 | namespace RC2WebAppEF.Migrations 6 | { 7 | public partial class second : Migration 8 | { 9 | protected override void Up(MigrationBuilder migrationBuilder) 10 | { 11 | 12 | } 13 | 14 | protected override void Down(MigrationBuilder migrationBuilder) 15 | { 16 | 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Migrations/BlogsContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using RC2_WebApp_EF; 7 | 8 | namespace RC2WebAppEF.Migrations 9 | { 10 | [DbContext(typeof(BlogsContext))] 11 | partial class BlogsContextModelSnapshot : ModelSnapshot 12 | { 13 | protected override void BuildModel(ModelBuilder modelBuilder) 14 | { 15 | modelBuilder 16 | .HasAnnotation("ProductVersion", "1.0.0-rc2-20466") 17 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 18 | 19 | modelBuilder.Entity("RC2_WebApp_EF.Blog", b => 20 | { 21 | b.Property("Id") 22 | .ValueGeneratedOnAdd(); 23 | 24 | b.Property("Url") 25 | .IsRequired() 26 | .HasAnnotation("MaxLength", 100); 27 | 28 | b.HasKey("Id"); 29 | 30 | b.ToTable("Blogs"); 31 | }); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Models/BlogsContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace RC2_WebApp_EF 5 | { 6 | public class BlogsContext : DbContext 7 | { 8 | public BlogsContext(DbContextOptions options) 9 | :base(options) 10 | {} 11 | 12 | public DbSet Blogs { get; set; } 13 | 14 | protected override void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | } 17 | } 18 | 19 | public class Blog 20 | { 21 | [Required] 22 | public int Id { get; set; } 23 | [Required] 24 | [StringLength(100)] 25 | public string Url { get; set; } 26 | 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Properties/PublishProfiles/WebApp-publish.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding(SupportsShouldProcess=$true)] 2 | param($publishProperties, $packOutput, $nugetUrl) 3 | 4 | # to learn more about this file visit http://go.microsoft.com/fwlink/?LinkId=524327 5 | $publishModuleVersion = '1.1.0' 6 | function Get-VisualStudio2015InstallPath{ 7 | [cmdletbinding()] 8 | param() 9 | process{ 10 | $keysToCheck = @('hklm:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0', 11 | 'hklm:\SOFTWARE\Microsoft\VisualStudio\14.0', 12 | 'hklm:\SOFTWARE\Wow6432Node\Microsoft\VWDExpress\14.0', 13 | 'hklm:\SOFTWARE\Microsoft\VWDExpress\14.0' 14 | ) 15 | [string]$vsInstallPath=$null 16 | 17 | foreach($keyToCheck in $keysToCheck){ 18 | if(Test-Path $keyToCheck){ 19 | $vsInstallPath = (Get-itemproperty $keyToCheck -Name InstallDir -ErrorAction SilentlyContinue | select -ExpandProperty InstallDir -ErrorAction SilentlyContinue) 20 | } 21 | 22 | if($vsInstallPath){ 23 | break; 24 | } 25 | } 26 | 27 | $vsInstallPath 28 | } 29 | } 30 | 31 | $vsInstallPath = Get-VisualStudio2015InstallPath 32 | $publishModulePath = "{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f $vsInstallPath, $publishModuleVersion 33 | 34 | if(!(Test-Path $publishModulePath)){ 35 | $publishModulePath = "{0}VWDExpressExtensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f $vsInstallPath, $publishModuleVersion 36 | } 37 | 38 | $defaultPublishSettings = New-Object psobject -Property @{ 39 | LocalInstallDir = $publishModulePath 40 | } 41 | 42 | function Enable-PackageDownloader{ 43 | [cmdletbinding()] 44 | param( 45 | $toolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader-$publishModuleVersion\", 46 | $pkgDownloaderDownloadUrl = 'http://go.microsoft.com/fwlink/?LinkId=524325') # package-downloader.psm1 47 | process{ 48 | if(get-module package-downloader){ 49 | remove-module package-downloader | Out-Null 50 | } 51 | 52 | if(!(get-module package-downloader)){ 53 | if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory -WhatIf:$false } 54 | 55 | $expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1') 56 | if(!(Test-Path $expectedPath)){ 57 | 'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose 58 | (New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath) 59 | } 60 | 61 | if(!$expectedPath){throw ('Unable to download package-downloader.psm1')} 62 | 63 | 'importing module [{0}]' -f $expectedPath | Write-Output 64 | Import-Module $expectedPath -DisableNameChecking -Force 65 | } 66 | } 67 | } 68 | 69 | function Enable-PublishModule{ 70 | [cmdletbinding()] 71 | param() 72 | process{ 73 | if(get-module publish-module){ 74 | remove-module publish-module | Out-Null 75 | } 76 | 77 | if(!(get-module publish-module)){ 78 | $localpublishmodulepath = Join-Path $defaultPublishSettings.LocalInstallDir 'publish-module.psm1' 79 | if(Test-Path $localpublishmodulepath){ 80 | 'importing module [publish-module="{0}"] from local install dir' -f $localpublishmodulepath | Write-Verbose 81 | Import-Module $localpublishmodulepath -DisableNameChecking -Force 82 | $true 83 | } 84 | } 85 | } 86 | } 87 | 88 | try{ 89 | 90 | if (!(Enable-PublishModule)){ 91 | Enable-PackageDownloader 92 | Enable-NuGetModule -name 'publish-module' -version $publishModuleVersion -nugetUrl $nugetUrl 93 | } 94 | 95 | 'Calling Publish-AspNet' | Write-Verbose 96 | # call Publish-AspNet to perform the publish operation 97 | Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput 98 | } 99 | catch{ 100 | "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error 101 | } -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Properties/PublishProfiles/WebApp.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | MSDeploy 9 | False 10 | AzureWebSite 11 | Release 12 | Any CPU 13 | http://webdeploytest.hosamswebdeploy.antares-test.windows-int.net 14 | True 15 | False 16 | <_DefaultDNXVersion /> 17 | True 18 | wwwroot 19 | wwwroot 20 | False 21 | False 22 | False 23 | webdeploytest.scm.hosamswebdeploy.antares-test.windows-int.net:443 24 | webdeploytest 25 | 26 | True 27 | WMSVC 28 | True 29 | $webdeploytest 30 | ZwlSjJNlngdfBe6xuh4CB744roqSF3c77y4il3AM3bYoSNCwpaeiYzSDxRMl 31 | true 32 | <_SavePWD>True 33 | <_DestinationType>AzureWebSite 34 | 35 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:21611/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "Hosting:Environment": "Development" 16 | } 17 | }, 18 | "web": { 19 | "commandName": "web", 20 | "environmentVariables": { 21 | "Hosting:Environment": "Development" 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.EntityFrameworkCore; 8 | using Microsoft.EntityFrameworkCore.Infrastructure; 9 | 10 | namespace RC2_WebApp_EF 11 | { 12 | public class Startup 13 | { 14 | public Startup(IHostingEnvironment env) 15 | { 16 | // Set up configuration sources. 17 | var builder = new ConfigurationBuilder() 18 | .SetBasePath(Directory.GetCurrentDirectory()) 19 | .AddJsonFile("appsettings.json") 20 | .AddEnvironmentVariables(); 21 | Configuration = builder.Build(); 22 | } 23 | 24 | public IConfigurationRoot Configuration { get; set; } 25 | 26 | // This method gets called by the runtime. Use this method to add services to the container. 27 | public void ConfigureServices(IServiceCollection services) 28 | { 29 | string connstr = Configuration["DefaultConnection:ConnectionString"]; 30 | 31 | services.AddEntityFramework() 32 | .AddDbContext(o => o.UseSqlServer(connstr)); 33 | 34 | services.AddMvc(); 35 | } 36 | 37 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 38 | public void Configure(IApplicationBuilder app) 39 | { 40 | app.UseStaticFiles(); 41 | 42 | app.UseMvc(routes => 43 | { 44 | routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); 45 | }); 46 | } 47 | 48 | public static void Main(string[] args) 49 | { 50 | var host = new WebHostBuilder() 51 | .UseKestrel() 52 | .UseDefaultHostingConfiguration(args) 53 | .UseContentRoot(Directory.GetCurrentDirectory()) 54 | .UseStartup() 55 | .Build(); 56 | 57 | host.Run(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/Blogs/Create.cshtml: -------------------------------------------------------------------------------- 1 | @model RC2_WebApp_EF.Blog 2 | 3 | @{ 4 | ViewBag.Title = "New Blog"; 5 | } 6 | 7 |

@ViewData["Title"]

8 | 9 |
10 |
11 |
12 |
13 | 14 |
15 | 16 | 17 |
18 |
19 |
20 | 21 |
22 | 23 | 24 |
25 |
26 |
27 |
28 | 29 |
30 |
31 |
32 |
-------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/Blogs/index.cshtml: -------------------------------------------------------------------------------- 1 | @model IEnumerable 2 | 3 | @{ 4 | ViewBag.Title = "Blogs"; 5 | } 6 | 7 |

Blogs

8 | 9 |

10 | Create New 11 |

12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | @foreach (var item in Model) 20 | { 21 | 22 | 25 | 28 | 29 | } 30 |
IdUrl
23 | @Html.DisplayFor(modelItem => item.Id) 24 | 26 | @Html.DisplayFor(modelItem => item.Url) 27 |
-------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "About"; 3 | } 4 |

@ViewData["Title"].

5 |

@ViewData["Message"]

6 | 7 |

Use this area to provide additional information.

8 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Contact"; 3 | } 4 |

@ViewData["Title"].

5 |

@ViewData["Message"]

6 | 7 |
8 | One Microsoft Way
9 | Redmond, WA 98052-6399
10 | P: 11 | 425.555.0100 12 |
13 | 14 |
15 | Support: Support@example.com
16 | Marketing: Marketing@example.com 17 |
18 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 | 67 | 68 | 111 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Error"; 3 | } 4 | 5 |

Error.

6 |

An error occurred while processing your request.

7 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - RC2_WebApp_EF 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 41 |
42 | @RenderBody() 43 |
44 |
45 |

© 2016 - RC2_WebApp_EF

46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 63 | 64 | 65 | 66 | @RenderSection("scripts", required: false) 67 | 68 | 69 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using RC2_WebApp_EF 2 | @addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers" 3 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "DefaultConnection": { 3 | "ConnectionString": "Data Source=(localdb)\\mssqllocaldb;Integrated Security=True;" 4 | }, 5 | 6 | "Logging": { 7 | "IncludeScopes": true, 8 | "LogLevel": { 9 | "Default": "Verbose", 10 | "System": "Information", 11 | "Microsoft": "Information" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | 4 | "description": "This is a web app sample on RC2 and dotnet.exe", 5 | 6 | "compilationOptions": { 7 | "preserveCompilationContext": true, 8 | "emitEntryPoint": true 9 | }, 10 | 11 | "content": [ 12 | "wwwroot", 13 | "Views", 14 | "appSettings.json", 15 | "web.config" 16 | ], 17 | 18 | "dependencies": { 19 | "Microsoft.AspNetCore.Mvc": "1.0.0-*", 20 | "Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0-*", 21 | "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*", 22 | "Microsoft.AspNetCore.StaticFiles": "1.0.0-*", 23 | "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-*", 24 | "Microsoft.Extensions.Configuration.Json": "1.0.0-*", 25 | "Microsoft.EntityFrameworkCore": "1.0.0-*", 26 | "Microsoft.EntityFrameworkCore.Tools": { "version": "1.0.0-*", "type": "build" }, 27 | "Microsoft.EntityFrameworkCore.Commands": "1.0.0-*", 28 | "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-*", 29 | "Microsoft.NETCore.App": { 30 | "type": "platform", 31 | "version": "1.0.0-*" 32 | } 33 | }, 34 | 35 | "frameworks": { 36 | "netcoreapp1.0": { 37 | "imports": [ 38 | "portable-net45+wp80+win8+wpa81+dnxcore50", 39 | "portable-net451+win8", 40 | "netcore50" 41 | ] 42 | } 43 | }, 44 | 45 | "runtimes" : { 46 | "win7-x64" : {} 47 | }, 48 | 49 | "tools": { 50 | "Microsoft.AspNetCore.Server.IISIntegration.Tools": { 51 | "version": "1.0.0-*", 52 | "imports": "portable-net45+wp80+win8+wpa81+dnxcore50" 53 | }, 54 | "Microsoft.EntityFrameworkCore.Tools": { 55 | "version": "1.0.0-*", 56 | "imports": "portable-net452+win81" 57 | } 58 | }, 59 | 60 | "scripts": { 61 | "postpublish": "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" 62 | } 63 | } -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/SampleFiles/DotNetWebApp/src/wwwroot/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.AspNet.Server.IIS": { 4 | "version": "1.0.0-beta1", 5 | "sha": "GF//gEBd+ofIVVlpKkfIoqzW4Rqsqh8TuID8wTzPdbkQgSqOxnA9XQEPYRwrTUibtYx736EQo/02R1nxVn9VYw==" 6 | }, 7 | "Microsoft.AspNet.Mvc": { 8 | "version": "6.0.0-beta1", 9 | "sha": "2alHi02Pe4wesXdyqSLdj/KOqNPXN5obxYoCgapuqxr6MqQgJ9NsqYxr1CexDzguT9lw9ooM5vz1eOr+blIUtA==" 10 | }, 11 | "Microsoft.AspNet.Hosting": { 12 | "version": "1.0.0-beta1", 13 | "sha": "BLWUBzddywFaFqmIkKC0VVpuPDCgUorXqwHbh3xoNd1HPIQ0aeLYiC9ctmnkPuoRmLXsE9FzZsdrxtkSlbvDzA==" 14 | }, 15 | "Microsoft.AspNet.Security.Cookies": { 16 | "version": "1.0.0-beta1", 17 | "sha": "o/rlhjtdrJ52If6AkaX6lQ7eHrbvL8kIRUDaRvnYULyqxKS3ypbSM9xZO0UnT48HnssuJV4GdwvWiRw2PdKeVg==" 18 | }, 19 | "Microsoft.AspNet.Server.WebListener": { 20 | "version": "1.0.0-beta1", 21 | "sha": "Ps2ArAzmk/zO8XoZBJWfsXj8lmKD3ijEBGjOk5lxhR3zvUIZBpypBTCiJtQH8nSuwxKxi+Ibph22mG1YsFU1jg==" 22 | }, 23 | "Microsoft.AspNet.StaticFiles": { 24 | "version": "1.0.0-beta1", 25 | "sha": "EDy/zaOom/l/jFgrp3PynnDneFwvkywy3nA6JClgJWv7vU64LdLWOM8Fnkv3f8cG9cwTRmQqFcaBmwsuL1qLHQ==" 26 | }, 27 | "Kestrel": { 28 | "version": "1.0.0-beta1", 29 | "sha": "D7CELJJRg8NGAB+8bcNHKAfSlU2VUju+BnXuc0O7/9jY7L2ASpWhPt10OpM9FhX/pq5XU9NLBA+RgV8hYNJEFQ==" 30 | }, 31 | "Microsoft.AspNet.Loader.IIS.Interop": { 32 | "version": "1.0.0-beta1", 33 | "sha": "l1IwSlGyqCa/1X/3Frk+Z6TnaHKZ6sjoLjqHC4i4MGIpaqTbTXk4ImXRdZc0DL1E1mFP3gk7uDIX9PzcdGmofA==" 34 | }, 35 | "Microsoft.AspNet.Loader.IIS": { 36 | "version": "1.0.0-beta1", 37 | "sha": "Rk7R0PUyTGanleD13fNJpkHhzRZGUyRF/637vg707zDa+WAOzkoroQDqLCiq1Gj04rKLUAad4aGOhmnj2kO9NQ==" 38 | }, 39 | "Microsoft.AspNet.Mvc.Razor": { 40 | "version": "6.0.0-beta1", 41 | "sha": "tURRutSW/O2wzPDZlZEdj/QPA5ue4OwbLao12t1Q1X/olLsLZ9xzzbgB3LZ8uAYIL7IxPCGNPDM7fdQjABnMMQ==" 42 | }, 43 | "Microsoft.AspNet.FeatureModel": { 44 | "version": "1.0.0-beta1", 45 | "sha": "1IiLyUM4yuVi8ZnOPvTtXKq/VRQo02TF8IgqGgA7ceaBs3cV2gSiLW9zxxqyadqiqF46cRUtjpsjtNISVtpnRA==" 46 | }, 47 | "Microsoft.AspNet.Http": { 48 | "version": "1.0.0-beta1", 49 | "sha": "XVDRfSn266YR0lIxvXFh1vem3z4Bcpv3xS1nVFD5cr1edCKTi6XSRh0y270Ox4CBscqwjlwzhzcnVbtc3yu9lg==" 50 | }, 51 | "Microsoft.AspNet.PipelineCore": { 52 | "version": "1.0.0-beta1", 53 | "sha": "aA3NQNbT8vX8w6ZbKprumA0nr4IXR5jm6rSvLEbGCp5J81mmJynG/mU6TA+7vMRGQE8YZbou4zvlJhEmPODQJA==" 54 | }, 55 | "Microsoft.AspNet.Security.DataProtection": { 56 | "version": "1.0.0-beta1", 57 | "sha": "sTyK71Z3Jmb88J0Lw+lV0qtSGfDpHG3Xen8NsNZK5lmU5pXlYSiwy2VzPbqk+cZU/2UaM9pgwqMFKOpZ42yPvA==" 58 | }, 59 | "Microsoft.Framework.ConfigurationModel": { 60 | "version": "1.0.0-beta1", 61 | "sha": "UP3RqnOCzUdE7oh8PA5KtLOZrd4jSLTy+2DbH1yIqM9uCRTxa/2vwyQm0bHRXQRjLqBhzeGw/c3uYD47M/Rc6A==" 62 | }, 63 | "Microsoft.Framework.DependencyInjection": { 64 | "version": "1.0.0-beta1", 65 | "sha": "hvIfCfKqbBTQrAyrsVjrZNyy9wsiAU3UyWsOqlT1nzAQStL4mXh7DDEujZfr4u6HJfToviuXX6cGF7hjYq1hlA==" 66 | }, 67 | "Microsoft.Framework.Logging": { 68 | "version": "1.0.0-beta1", 69 | "sha": "QeTai2SoFJipnGc4kOATmiU0CdnIjvTQxysXjqeLJgNYX6ppufRIKSX9FR7JA+b//f7cdUjJN3H5uLOTyHtS3Q==" 70 | }, 71 | "Microsoft.Framework.OptionsModel": { 72 | "version": "1.0.0-beta1", 73 | "sha": "5laJOaDVNaHtWP1oWf84JXFjj1pWbpMkK8fvUOmjKgOYdl0OPzmBdswMxaF9DzyvQFoJ1Za9fv3LsRrQBpgoHg==" 74 | }, 75 | "Newtonsoft.Json": { 76 | "version": "6.0.6", 77 | "sha": "w26uZNyCG5VeoKiEOJ4+9/o8koSofLKwHl7WLreIcp0U6r57L7WiRXmjp8MTKFw6dYNZ9AE0lw69WYbIhUsU9Q==" 78 | }, 79 | "Microsoft.AspNet.Http.Extensions": { 80 | "version": "1.0.0-beta1", 81 | "sha": "Ct97LsjoEDEkAdKIkK4FVeYNFISkbSZ+ZrL0aUwD0M1Z+vjiyteatX+eC/ojS18oJna1fHRFFcW6uXkFWYxsFQ==" 82 | }, 83 | "Microsoft.AspNet.Security": { 84 | "version": "1.0.0-beta1", 85 | "sha": "tage2b/8tAXZKcA5hpp9C+J/km3DAVngcHlcrYwXmPrdS3Wrh7URp6AMlXjTf4vJziHthhNdWrJfP5M36hVEGQ==" 86 | }, 87 | "Microsoft.Net.Http.Server": { 88 | "version": "1.0.0-beta1", 89 | "sha": "X5LRCDQoQGJzcCZJZ35VapMi6HH68hAyzkidnqSi1m8v7cpnAbU+XZVM/QmGOBbqRcl+uqvN4upwSjZLfkodzg==" 90 | }, 91 | "Microsoft.Net.WebSocketAbstractions": { 92 | "version": "1.0.0-beta1", 93 | "sha": "Iy+HLQJhLI3mBVwdSaexxRT/3cnz2XPRaleCGV6Cqx10IqFvsEBSXwjcs605Bqb/GDIGcufTo7wAMuucQAjv/A==" 94 | }, 95 | "Microsoft.AspNet.FileSystems": { 96 | "version": "1.0.0-beta1", 97 | "sha": "wDawKHvyxNp3gunw8B6Gw05Nyxyx8VyaODLJOnzt09mUfBl0n4HIEtx11MPbm1ARQfolQl1AoMsEdUHZCWMD6A==" 98 | }, 99 | "Microsoft.AspNet.Server.Kestrel": { 100 | "version": "1.0.0-beta1", 101 | "sha": "z2CdMRZ7YYh6wcEAFYVPlcZ8NQYYK4Rfvt88XGWejMS/lCvcE32raTUCTOpb3I/BgOi6PVvcD93sq5v2cit4MA==" 102 | }, 103 | "Microsoft.AspNet.HttpFeature": { 104 | "version": "1.0.0-beta1", 105 | "sha": "tx0xgmiTbv1e/8IgulYYc4McqoJzMPGR7QqbKGxtdCoSsi3KUEcpW7MrNyTKXPyW8iOw7Ee7vif3rN6GQQkq1g==" 106 | }, 107 | "Microsoft.Framework.Runtime.Interfaces": { 108 | "version": "1.0.0-beta1", 109 | "sha": "dYDxol26nJZG/f9uSdWw7wxoZWp+iemdXeJel8dbwuSbKLDx6oETpq5l36YTV5ghTnualLuHOWhAPJDTBNUMPg==" 110 | }, 111 | "Microsoft.AspNet.Mvc.Core": { 112 | "version": "6.0.0-beta1", 113 | "sha": "rUsJSh8XGm4rqlExG+oP4+icR+tPOHLwORj5HX+D7hwqWIfQyJve4/vVxVpB9b7sG6XdbsjgO4+Df6Jp8alP3Q==" 114 | }, 115 | "Microsoft.AspNet.Mvc.Razor.Host": { 116 | "version": "6.0.0-beta1", 117 | "sha": "hF1VG176flq3hbdo2i7/kbblDRlm57KA1TfE1AEEF/6+ka6SL2QUeZXoob1R2pGxLatxBfQJNB8OeoxumkIHqw==" 118 | }, 119 | "Microsoft.CodeAnalysis.CSharp": { 120 | "version": "1.0.0-beta1-20141031-01", 121 | "sha": "8MncO8CXJfjLmHwitzkzW9/5YfR89MyygN9i21eFXMXloCvkYmCd07YisLUvgxpXiefuq/mCk8c5qRhqaJMmNQ==" 122 | }, 123 | "Microsoft.AspNet.WebUtilities": { 124 | "version": "1.0.0-beta1", 125 | "sha": "hLHwNhnfKSbHbcQMn+I82C+s9+xdFDaTLHa5Fn2F+iwhl0Nq8clLsPzCO1nTQao1Wu29cF2khP2Ig8eVZ0wIVg==" 126 | }, 127 | "Microsoft.Framework.Logging.Interfaces": { 128 | "version": "1.0.0-beta1", 129 | "sha": "0+W2J4zzMOQZEBXlYLni0knjAH5lz2J40ixEzhh6d7C7wJtQ7LK5VGwU8gu2vHpjggK1iF4/6/4plkxk67Wk2g==" 130 | }, 131 | "Microsoft.AspNet.RequestContainer": { 132 | "version": "1.0.0-beta1", 133 | "sha": "tLfutmaO/WsYPAQxxuAPxHSDuAqqz9b4wPqpMZI9Xt7cGP1ZGpDznCzZvaqQauYR1MPnL4MCY+u1smAAGtvxTQ==" 134 | }, 135 | "Microsoft.Net.WebSockets": { 136 | "version": "1.0.0-beta1", 137 | "sha": "yDkvgkc1Ywb5v0j9eHMoFFfZRDDbHs+0UdFb9gcuICABt4iKrt00jXIxw346JxUq1T77TtPrPIbCu2sCL+pV4g==" 138 | }, 139 | "Microsoft.AspNet.Mvc.HeaderValueAbstractions": { 140 | "version": "1.0.0-beta1", 141 | "sha": "s703UTwYVMT8ZRQVy5SPlCnjxcsQMIx7KzZJhEiTRRYOcK7eoWapkiV2riixQNOANWhYHvZwGxKlJTbniZ/1hA==" 142 | }, 143 | "Microsoft.AspNet.Mvc.ModelBinding": { 144 | "version": "6.0.0-beta1", 145 | "sha": "Lq4kkTXkksbQHt979Ug3Yt5lqBxC4BpUNSZZz/kLv+qW3e+S+lzBX9OWkAFKn4k2VAkehiuaLFNHBfqxyYSacg==" 146 | }, 147 | "Microsoft.AspNet.Routing": { 148 | "version": "1.0.0-beta1", 149 | "sha": "DxQNo7NuJFbgeyDQQEAVl/sanXflm1GN4yz1JtCzEoODPmpfhfSwmnVT+V6WsvBOhdUS7qL6HfcKhlXjwJJqjw==" 150 | }, 151 | "Microsoft.AspNet.Razor.Runtime": { 152 | "version": "4.0.0-beta1", 153 | "sha": "VBFty8DsYue9pFfHNLqdLMCeABEyQ5se3Nxus34XdOIO7Dv73gprk64p83+7JrBhKSXgUT97DxrspUiicwDOFQ==" 154 | }, 155 | "Microsoft.CodeAnalysis.Common": { 156 | "version": "1.0.0-beta1-20141031-01", 157 | "sha": "ltX+QGdlcYU6Dy1Nj9vuX1m0mtwbGFsz4ApOOx0GqVSPvUrRLZuhDaUWWrz/tmJ/MFpLWEHZzcWmakaxXaKWYA==" 158 | }, 159 | "Microsoft.DataAnnotations": { 160 | "version": "1.0.0-beta1", 161 | "sha": "ZvLzh5xkQSGkwHdrycpVU+o6bQNTsxVvIWCMgSiDE6Cbz9CyaxL2gwWukws4y6Dm8mwE5AFK4HWBSS79F9H1qA==" 162 | }, 163 | "Microsoft.AspNet.Razor": { 164 | "version": "4.0.0-beta1", 165 | "sha": "Tpe3WPuAUk+9V4R/sE7Vq5scXaChrcKeUxvhA6gcrSQxq4DoeHm4hx7MslzmPRkmKuatT1uwPr15UIGY30TOVg==" 166 | }, 167 | "System.Collections.Immutable": { 168 | "version": "1.1.32-beta", 169 | "sha": "ckfFUM6keywtdZ+DT7/KWSmQ0YRLHu4OCnKKWbumvO8uDcKtCoxjLKcaWNzguGCSTy2r2Ap9gojazgCwMYw0bQ==" 170 | }, 171 | "System.Reflection.Metadata": { 172 | "version": "1.0.17-beta", 173 | "sha": "PyXG0gfs9gDDj4Km2PKadmPOMsH7IL+S4zckKMESdgv34f0I063VKi+RgmZ8f4wtgBVQTw8UrYE911lpePFAgA==" 174 | }, 175 | "System.ComponentModel.Annotations": { 176 | "version": "4.0.10-beta-22231", 177 | "sha": "UISJ/QJdrIgjkcEtmxrILc+h/DsfgxnJsEjKUyGi7E06qoPL8bpU4KdJfxmFnh+F7R776h760Mnd+TFnKWgQwA==" 178 | }, 179 | "System.ComponentModel": { 180 | "version": "4.0.0-beta-22231", 181 | "sha": "8omvXlxhrl662ZFNZV3mv64oFaKtzPjiTBduUv566kfL8fxQcY3pBMtt9/Ir2OgalqJXOgExp8pdC5uXWE7Jqw==" 182 | } 183 | }, 184 | "packages": "packages" 185 | } -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/src/MvcApplication/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Mvc; 2 | using MvcSample.Web.Models; 3 | 4 | namespace MvcSample.Web 5 | { 6 | public class HomeController : Controller 7 | { 8 | public IActionResult Index() 9 | { 10 | return View(User()); 11 | } 12 | 13 | public User User() 14 | { 15 | User user = new User() 16 | { 17 | Name = "My name", 18 | Address = "My address" 19 | }; 20 | 21 | return user; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/src/MvcApplication/Models/User.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace MvcSample.Web.Models 4 | { 5 | public class User 6 | { 7 | [Required] 8 | [MinLength(4)] 9 | public string Name { get; set; } 10 | public string Address { get; set; } 11 | public int Age { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/src/MvcApplication/Properties/PublishProfiles/ToFileSys.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | Any CPU 11 | 12 | True 13 | False 14 | False 15 | KRE-CLR-x86.1.0.0-beta2-10768 16 | False 17 | wwwroot 18 | c:\temp\publish\05 19 | False 20 | 21 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/src/MvcApplication/Properties/debugSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Profiles": [] 3 | } -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/src/MvcApplication/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Builder; 2 | using Microsoft.AspNet.Routing; 3 | using Microsoft.Framework.DependencyInjection; 4 | 5 | namespace KWebStartup 6 | { 7 | public class Startup 8 | { 9 | public void Configure(IApplicationBuilder app) 10 | { 11 | app.UseStaticFiles(); 12 | 13 | app.UseServices(services => 14 | { 15 | services.AddMvc(); 16 | }); 17 | 18 | // Add MVC to the request pipeline 19 | app.UseMvc(routes => 20 | { 21 | routes.MapRoute( 22 | name: "default", 23 | template: "{controller}/{action}/{id?}", 24 | defaults: new { controller = "Home", action = "Index" }); 25 | 26 | routes.MapRoute( 27 | name: "api", 28 | template: "{controller}/{id?}"); 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/src/MvcApplication/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using MvcSample.Web.Models 2 | @model User 3 | @{ 4 | Layout = "/Views/Shared/_Layout.cshtml"; 5 | ViewBag.Title = "Home Page"; 6 | string helloClass = null; 7 | } 8 | 9 |
10 |

ASP.NET

11 |

ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.

12 |

Learn more »

13 |
14 |
15 |
16 |

Hello @Model.Name!

17 |
18 |
19 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/src/MvcApplication/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title - My ASP.NET Application 7 | 8 | 9 | 10 | 11 | 12 | 29 |
30 | @RenderBody() 31 |
32 |
33 | @if (@Model != null) 34 | { 35 | @Model.Address 36 | } 37 |
38 |
39 |

© @DateTime.Now.Year - My ASP.NET Application

40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/approot/src/MvcApplication/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "webroot": "../../../wwwroot", 3 | "exclude": "wwwroot/**/*.*", 4 | "dependencies": { 5 | "Microsoft.AspNet.Server.IIS": "1.0.0-beta1", 6 | "Microsoft.AspNet.Mvc": "6.0.0-beta1", 7 | "Microsoft.AspNet.Hosting": "1.0.0-beta1", 8 | "Microsoft.AspNet.Security.Cookies": "1.0.0-beta1", 9 | "Microsoft.AspNet.Server.WebListener": "1.0.0-beta1", 10 | "Microsoft.AspNet.StaticFiles": "1.0.0-beta1", 11 | "Kestrel": "1.0.0-beta1" 12 | }, 13 | "commands": { 14 | "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5001", 15 | "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" 16 | }, 17 | "frameworks": { 18 | "aspnet50": {} 19 | } 20 | } -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/kestrel.cmd: -------------------------------------------------------------------------------- 1 | 2 | @"%~dp0approot\packages\KRE-CLR-x86.1.0.0-beta2-10768\bin\klr.exe" --appbase "%~dp0approot\src\MvcApplication" Microsoft.Framework.ApplicationHost kestrel %* 3 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/web.cmd: -------------------------------------------------------------------------------- 1 | 2 | @"%~dp0approot\packages\KRE-CLR-x86.1.0.0-beta2-10768\bin\klr.exe" --appbase "%~dp0approot\src\MvcApplication" Microsoft.Framework.ApplicationHost web %* 3 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/wwwroot/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/vsweb-publish/208f66f0d0d59fc35507f88ac54ed65fb1fc9769/tests/SampleFiles/MvcApplication-packOutput/wwwroot/.gitignore -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/wwwroot/tobereplaced.txt: -------------------------------------------------------------------------------- 1 | Some 2 | Random 3 | Text 4 | Here -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication-packOutput/wwwroot/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Mvc; 2 | using MvcSample.Web.Models; 3 | 4 | namespace MvcSample.Web 5 | { 6 | public class HomeController : Controller 7 | { 8 | public IActionResult Index() 9 | { 10 | return View(User()); 11 | } 12 | 13 | public User User() 14 | { 15 | User user = new User() 16 | { 17 | Name = "My name", 18 | Address = "My address" 19 | }; 20 | 21 | return user; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/Models/User.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace MvcSample.Web.Models 4 | { 5 | public class User 6 | { 7 | [Required] 8 | [MinLength(4)] 9 | public string Name { get; set; } 10 | public string Address { get; set; } 11 | public int Age { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/Properties/PublishProfiles/ToFileSys.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | Any CPU 11 | 12 | True 13 | False 14 | False 15 | KRE-CLR-x86.1.0.0-beta2-10768 16 | False 17 | wwwroot 18 | c:\temp\publish\05 19 | False 20 | 21 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/Properties/debugSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Profiles": [] 3 | } -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Builder; 2 | using Microsoft.AspNet.Routing; 3 | using Microsoft.Framework.DependencyInjection; 4 | 5 | namespace KWebStartup 6 | { 7 | public class Startup 8 | { 9 | public void Configure(IApplicationBuilder app) 10 | { 11 | app.UseStaticFiles(); 12 | 13 | app.UseServices(services => 14 | { 15 | services.AddMvc(); 16 | }); 17 | 18 | // Add MVC to the request pipeline 19 | app.UseMvc(routes => 20 | { 21 | routes.MapRoute( 22 | name: "default", 23 | template: "{controller}/{action}/{id?}", 24 | defaults: new { controller = "Home", action = "Index" }); 25 | 26 | routes.MapRoute( 27 | name: "api", 28 | template: "{controller}/{id?}"); 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using MvcSample.Web.Models 2 | @model User 3 | @{ 4 | Layout = "/Views/Shared/_Layout.cshtml"; 5 | ViewBag.Title = "Home Page"; 6 | string helloClass = null; 7 | } 8 | 9 |
10 |

ASP.NET

11 |

ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.

12 |

Learn more »

13 |
14 |
15 |
16 |

Hello @Model.Name!

17 |
18 |
19 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title - My ASP.NET Application 7 | 8 | 9 | 10 | 11 | 12 | 29 |
30 | @RenderBody() 31 |
32 |
33 | @if (@Model != null) 34 | { 35 | @Model.Address 36 | } 37 |
38 |
39 |

© @DateTime.Now.Year - My ASP.NET Application

40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "webroot": "wwwroot", 3 | "exclude": "wwwroot/**/*.*", 4 | "dependencies": { 5 | "Microsoft.AspNet.Server.IIS":"1.0.0-beta1", 6 | "Microsoft.AspNet.Mvc": "6.0.0-beta1", 7 | "Microsoft.AspNet.Hosting": "1.0.0-beta1", 8 | "Microsoft.AspNet.Security.Cookies": "1.0.0-beta1", 9 | "Microsoft.AspNet.Server.WebListener": "1.0.0-beta1", 10 | "Microsoft.AspNet.StaticFiles": "1.0.0-beta1", 11 | "Kestrel": "1.0.0-beta1" 12 | }, 13 | "commands": { 14 | "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5001", 15 | "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" 16 | }, 17 | "frameworks": { 18 | "aspnet50": { } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/SampleFiles/MvcApplication/wwwroot/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/vsweb-publish/208f66f0d0d59fc35507f88ac54ed65fb1fc9769/tests/SampleFiles/MvcApplication/wwwroot/.gitignore -------------------------------------------------------------------------------- /tests/e2e-FileSystem.tests.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param() 3 | 4 | function Get-ScriptDirectory 5 | { 6 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 7 | Split-Path $Invocation.MyCommand.Path 8 | } 9 | 10 | $scriptDir = ((Get-ScriptDirectory) + "\") 11 | $moduleName = 'publish-module' 12 | $modulePath = (Join-Path $scriptDir ('..\{0}.psm1' -f $moduleName)) 13 | $samplesdir = (Join-Path $scriptDir 'SampleFiles') 14 | 15 | if(Test-Path $modulePath){ 16 | "Importing module from [{0}]" -f $modulePath | Write-Verbose 17 | 18 | if((Get-Module $moduleName)){ Remove-Module $moduleName -Force } 19 | 20 | Import-Module $modulePath -PassThru -DisableNameChecking | Out-Null 21 | } 22 | else{ 23 | throw ('Unable to find module at [{0}]' -f $modulePath ) 24 | } 25 | 26 | Describe 'FileSystem e2e publish tests' { 27 | [string]$mvcSourceFolder = (resolve-path (Join-Path $samplesdir 'MvcApplication')) 28 | [string]$mvcPackDir = (resolve-path (Join-Path $samplesdir 'MvcApplication-packOutput')) 29 | [int]$numPublishFiles = ((Get-ChildItem $mvcPackDir -Recurse) | Where-Object { !$_.PSIsContainer }).Length 30 | 31 | It 'Publish file system' { 32 | # publish the pack output to a new temp folder 33 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\Basic01') 34 | # verify the folder is empty 35 | $filesbefore = (Get-ChildItem $publishDest -Recurse -ErrorAction SilentlyContinue) | Where-Object { !$_.PSIsContainer } 36 | $filesbefore | Should BeNullOrEmpty 37 | 38 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 39 | 'WebPublishMethod'='FileSystem' 40 | 'publishUrl'="$publishDest" 41 | } 42 | 43 | # check to see that the files exist 44 | $filesafter = (Get-ChildItem $publishDest -Recurse) | Where-Object { !$_.PSIsContainer } 45 | $filesafter.length | Should Be $numPublishFiles 46 | } 47 | 48 | It 'Can publish with a relative path for publishUrl' { 49 | # publish the pack output to a new temp folder 50 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\relpathPublishUrl') 51 | # verify the folder is empty 52 | $filesbefore = (Get-ChildItem $publishDest -Recurse -ErrorAction SilentlyContinue) | Where-Object { !$_.PSIsContainer } 53 | $filesbefore | Should BeNullOrEmpty 54 | 55 | Push-Location 56 | mkdir $publishDest 57 | Set-Location $publishDest 58 | 59 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 60 | 'WebPublishMethod'='FileSystem' 61 | 'publishUrl'='.\' 62 | } 63 | 64 | Pop-Location 65 | 66 | # check to see that the files exist 67 | $filesafter = (Get-ChildItem $publishDest -Recurse) | Where-Object { !$_.PSIsContainer } 68 | $filesafter.length | Should Be $numPublishFiles 69 | } 70 | 71 | It 'Publish file system can publish to a dir with a space' { 72 | # publish the pack output to a new temp folder 73 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\PublishUrl WithSpace\') 74 | # verify the folder is empty 75 | $filesbefore = (Get-ChildItem $publishDest -Recurse -File -ErrorAction SilentlyContinue) 76 | $filesbefore.length | Should Be 0 77 | 78 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 79 | 'WebPublishMethod'='FileSystem' 80 | 'publishUrl'="$publishDest" 81 | } 82 | 83 | # check to see that the files exist 84 | $filesafter = (Get-ChildItem $publishDest -Recurse -File) 85 | $filesafter.length | Should Be $numPublishFiles 86 | } 87 | 88 | It 'Can publish with a relative path for publishUrl' { 89 | # publish the pack output to a new temp folder 90 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\relpathPackOutput') 91 | # verify the folder is empty 92 | $filesbefore = (Get-ChildItem $publishDest -Recurse -ErrorAction SilentlyContinue) | Where-Object { !$_.PSIsContainer } 93 | $filesbefore | Should BeNullOrEmpty 94 | 95 | Push-Location 96 | Set-Location $mvcPackDir 97 | 98 | Publish-AspNet -packOutput .\ -publishProperties @{ 99 | 'WebPublishMethod'='FileSystem' 100 | 'publishUrl'="$publishDest" 101 | } 102 | 103 | Pop-Location 104 | 105 | # check to see that the files exist 106 | $filesafter = (Get-ChildItem $publishDest -Recurse) | Where-Object { !$_.PSIsContainer } 107 | $filesafter.length | Should Be $numPublishFiles 108 | } 109 | 110 | It 'Can exclude files when a single file is passed in' { 111 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\exclude01') 112 | # verify the folder is empty 113 | $filesbefore = (Get-ChildItem $publishDest -Recurse -ErrorAction SilentlyContinue) | Where-Object { !$_.PSIsContainer } 114 | $filesbefore | Should BeNullOrEmpty 115 | 116 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 117 | 'WebPublishMethod'='FileSystem' 118 | 'publishUrl'="$publishDest" 119 | 'ExcludeFiles'=@( 120 | @{'absolutepath'='approot\\src\\MvcApplication\\Views\\Home'} 121 | ) 122 | } 123 | 124 | # check to see that the files exist 125 | $filesafter = (Get-ChildItem $publishDest -Recurse) | Where-Object { !$_.PSIsContainer } 126 | $filesafter.length | Should Be ($numPublishFiles-1) 127 | } 128 | 129 | It 'Can exclude files when a multiple files are passed in' { 130 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\exclude02') 131 | # verify the folder is empty 132 | $filesbefore = (Get-ChildItem $publishDest -Recurse -ErrorAction SilentlyContinue) 133 | $filesbefore | Should BeNullOrEmpty 134 | 135 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 136 | 'WebPublishMethod'='FileSystem' 137 | 'publishUrl'="$publishDest" 138 | 'ExcludeFiles'=@( 139 | @{'absolutepath'='approot\\src\\MvcApplication\\Views\\Home'}, 140 | @{'absolutepath'='wwwroot\\web.config'} 141 | ) 142 | } 143 | 144 | # check to see that the files exist 145 | $filesafter = (Get-ChildItem $publishDest -Recurse) | Where-Object { !$_.PSIsContainer } 146 | $filesafter.length | Should Be ($numPublishFiles-2) 147 | } 148 | 149 | It 'Performs replacements when one replacement is passed' { 150 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\replace01') 151 | 152 | $textToReplace = 'Random' 153 | $textReplacemnet = 'Replaced' 154 | 155 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 156 | 'WebPublishMethod'='FileSystem' 157 | 'publishUrl'="$publishDest" 158 | 'Replacements' = @( 159 | @{'file'='tobereplaced.txt$';'match'="$textToReplace";'newValue'="$textReplacemnet"}) 160 | } 161 | 162 | $filePathInPackDir = (resolve-path (Join-Path $mvcPackDir 'wwwroot\tobereplaced.txt')) 163 | $filePathInPackDir | Should Contain $textToReplace 164 | $filePathInPackDir | Should Not Contain $textReplacemnet 165 | 166 | $filePathInPublishDir = (resolve-path (Join-Path $publishDest 'wwwroot\tobereplaced.txt')) 167 | $filePathInPublishDir | Should Not Contain $textToReplace 168 | $filePathInPublishDir | Should Contain $textReplacemnet 169 | } 170 | 171 | It 'Performs replacements when more than one replacement is passed' { 172 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\replace02') 173 | 174 | $textToReplaceTextFile = 'Random' 175 | $textReplacemnetTextFile = 'Replaced' 176 | $textToReplaceWebConfig = '1.0.0-beta1' 177 | $textReplacemnetWebConfig = '1.0.0-custom1' 178 | 179 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 180 | 'WebPublishMethod'='FileSystem' 181 | 'publishUrl'="$publishDest" 182 | 'Replacements' = @( 183 | @{'file'='tobereplaced.txt$';'match'="$textToReplaceTextFile";'newValue'="$textReplacemnetTextFile"}, 184 | @{'file'='web.config$';'match'="$textToReplaceWebConfig";'newValue'="$textReplacemnetWebConfig"}) 185 | } 186 | 187 | $textFileInPackDir = (resolve-path (Join-Path $mvcPackDir 'wwwroot\tobereplaced.txt')) 188 | $textFileInPackDir | Should Contain $textToReplaceTextFile 189 | $textFileInPackDir | Should Not Contain $textReplacemnetTextFile 190 | 191 | $webConfigInPackDir = (resolve-path (Join-Path $mvcPackDir 'wwwroot\web.config')) 192 | $webConfigInPackDir | Should Contain $textToReplaceWebConfig 193 | $webConfigInPackDir | Should Not Contain $textReplacemnetWebConfig 194 | 195 | 196 | $textFileInPublishDir = (resolve-path (Join-Path $publishDest 'wwwroot\tobereplaced.txt')) 197 | $textFileInPublishDir | Should Not Contain $textToReplaceTextFile 198 | $textFileInPublishDir | Should Contain $textReplacemnetTextFile 199 | 200 | $webConfigInPublishDir = (resolve-path (Join-Path $publishDest 'wwwroot\web.config')) 201 | $webConfigInPublishDir | Should Not Contain $textToReplaceWebConfig 202 | $webConfigInPublishDir | Should Contain $textReplacemnetWebConfig 203 | } 204 | 205 | It 'throws if publishUrl is empty' { 206 | # publish the pack output to a new temp folder 207 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\THrowIfPublishUrlEmpty') 208 | 209 | {Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 210 | 'WebPublishMethod'='FileSystem' 211 | }} | Should throw 212 | } 213 | $script:samplepubxmlfilesys01 = @' 214 | 215 | 216 | 217 | FileSystem 218 | wwwroot 219 | {0} 220 | False 221 | 222 | 223 | '@ 224 | It 'Publish file system using .pubxml' { 225 | # publish the pack output to a new temp folder 226 | $publishDest = (Join-Path $TestDrive 'e2eFileSystem\Pubfilesyspubxml') 227 | $contents = ($script:samplepubxmlfilesys01 -f $publishDest) 228 | $samplePath = 'get-propsfrompubxml\sample02.pubxml' 229 | Setup -File -Path $samplePath -Content $contents 230 | $pubxmlpath = Join-Path $TestDrive $samplePath 231 | 232 | # verify the folder is empty 233 | $filesbefore = (Get-ChildItem $publishDest -Recurse -ErrorAction SilentlyContinue) | Where-Object { !$_.PSIsContainer } 234 | $filesbefore | Should BeNullOrEmpty 235 | 236 | Publish-AspNet -packOutput $mvcPackDir -pubProfilePath $pubxmlpath 237 | 238 | # check to see that the files exist 239 | $filesafter = (Get-ChildItem $publishDest -Recurse) | Where-Object { !$_.PSIsContainer } 240 | $filesafter.length | Should Be $numPublishFiles 241 | } 242 | } 243 | 244 | -------------------------------------------------------------------------------- /tests/e2e-Package.tests.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param( 3 | $useCustomMSDeploy 4 | ) 5 | 6 | if($env:e2ePkgTestUseCustomMSDeploy){ 7 | $useCustomMSDeploy = $true 8 | } 9 | 10 | function Get-ScriptDirectory 11 | { 12 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 13 | Split-Path $Invocation.MyCommand.Path 14 | } 15 | 16 | $scriptDir = ((Get-ScriptDirectory) + "\") 17 | $moduleName = 'publish-module' 18 | $modulePath = (Join-Path $scriptDir ('..\{0}.psm1' -f $moduleName)) 19 | $samplesdir = (Join-Path $scriptDir 'SampleFiles') 20 | $msdeployDownloadUrl = 'https://sayed02.blob.core.windows.net/download/msdeploy-v3-01-.zip' 21 | 22 | if(Test-Path $modulePath){ 23 | "Importing module from [{0}]" -f $modulePath | Write-Verbose 24 | 25 | if((Get-Module $moduleName)){ Remove-Module $moduleName -Force } 26 | 27 | Import-Module $modulePath -PassThru -DisableNameChecking | Out-Null 28 | } 29 | else{ 30 | throw ('Unable to find module at [{0}]' -f $modulePath ) 31 | } 32 | 33 | function Extract-ZipFile { 34 | [cmdletbinding()] 35 | param( 36 | [Parameter(Position=0,Mandatory=$true)] 37 | $file, 38 | [Parameter(Position=1,Mandatory=$true)] 39 | $destination 40 | ) 41 | begin{ 42 | [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null 43 | } 44 | process{ 45 | 'Extracting zip file [{0}] to {1}' -f $file,$destination | Write-Verbose 46 | if(!(Test-Path $destination)){ 47 | New-Item -ItemType Directory -Path $destination | Out-Null 48 | } 49 | [System.IO.Compression.ZipFile]::ExtractToDirectory($file,$destination) | Out-Null 50 | } 51 | } 52 | 53 | Describe 'Package e2e publish tests' { 54 | if($useCustomMSDeploy){ 55 | # download the .zip file and extract it 56 | $downloadDest = (Join-Path $TestDrive 'msdeploy.zip') 57 | (New-Object System.Net.WebClient).DownloadFile($msdeployDownloadUrl, $downloadDest) 58 | if(!(Test-Path $downloadDest)){ 59 | throw ('Unable to download msdeploy to [{0}]' -f $downloadDest) 60 | } 61 | $msdExtractFolder = (New-Item -ItemType Directory -Path (join-path $TestDrive 'MSDeployBin')).FullName 62 | Unblock-File $downloadDest 63 | Extract-ZipFile -file $downloadDest -destination $msdExtractFolder 64 | $msdeployExePath = (Join-Path $msdExtractFolder 'msdeploy.exe') 65 | if(!(Test-Path $msdeployExePath)){ 66 | throw ('could not find msdeploy.exe at [{0}]' -f $msdeployExePath) 67 | } 68 | 69 | 'Updating msdeploy.exe to point to [{0}]' -f $msdeployExePath | Write-Verbose 70 | $env:msdeployinstallpath = $msdExtractFolder 71 | } 72 | 73 | [string]$mvcSourceFolder = (resolve-path (Join-Path $samplesdir 'MvcApplication')) 74 | [string]$mvcPackDir = (resolve-path (Join-Path $samplesdir 'MvcApplication-packOutput')) 75 | [int]$numPublishFiles = ((Get-ChildItem $mvcPackDir -Recurse) | Where-Object { !$_.PSIsContainer }).Length 76 | 77 | It 'Can publish to a package' { 78 | # publish the pack output to a new temp folder 79 | $pubishDir = (New-Item -ItemType Directory -Path (Join-Path $TestDrive 'e2ePackage\Basic01\')) 80 | $publishDest = (Join-Path $pubishDir 'pkg.zip') 81 | 82 | Test-Path $publishDest | Should be False 83 | 84 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 85 | 'WebPublishMethod'='Package' 86 | 'DesktopBuildPackageLocation'="$publishDest" 87 | } 88 | Test-Path $publishDest | Should be True 89 | 90 | $extractDir = (New-Item -ItemType Directory -Path (Join-Path $TestDrive 'e2ePackage\Basic01-CopiedFiles\')) 91 | Extract-ZipFile -file $publishDest -destination ($extractDir.FullName) 92 | # check to see that the files exist 93 | $filesafter = (Get-ChildItem $extractDir -Recurse) | Where-Object { !$_.PSIsContainer } 94 | $filesafter.length - 2 | Should Be $numPublishFiles 95 | } 96 | 97 | It 'The result is in package under website folder' { 98 | # publish the pack output to a new temp folder 99 | $pubishDir = (New-Item -ItemType Directory -Path (Join-Path $TestDrive 'e2ePackage\Basic02\')) 100 | $publishDest = (Join-Path $pubishDir 'pkg.zip') 101 | 102 | Test-Path $publishDest | Should be False 103 | 104 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 105 | 'WebPublishMethod'='Package' 106 | 'DesktopBuildPackageLocation'="$publishDest" 107 | } 108 | 109 | Test-Path $publishDest | Should be True 110 | 111 | $extractDir = (New-Item -ItemType Directory -Path (Join-Path $TestDrive 'e2ePackage\Basic02-CopiedFiles\')) 112 | Extract-ZipFile -file $publishDest -destination ($extractDir.FullName) 113 | Test-Path (Join-Path $extractDir Content) | Should Be $true 114 | } 115 | 116 | <# 117 | It 'Can publish to a relative path for' { 118 | } 119 | #> 120 | 121 | # reset this back to the default 122 | $env:msdeployinstallpath = $null 123 | } 124 | 125 | -------------------------------------------------------------------------------- /tests/e2e.Package.tests.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param() 3 | 4 | function Get-ScriptDirectory 5 | { 6 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 7 | Split-Path $Invocation.MyCommand.Path 8 | } 9 | 10 | $scriptDir = ((Get-ScriptDirectory) + "\") 11 | $moduleName = 'publish-module' 12 | $modulePath = (Join-Path $scriptDir ('..\{0}.psm1' -f $moduleName)) 13 | $samplesdir = (Join-Path $scriptDir 'SampleFiles') 14 | 15 | if(Test-Path $modulePath){ 16 | "Importing module from [{0}]" -f $modulePath | Write-Verbose 17 | 18 | if((Get-Module $moduleName)){ Remove-Module $moduleName -Force } 19 | 20 | Import-Module $modulePath -PassThru -DisableNameChecking | Out-Null 21 | } 22 | else{ 23 | throw ('Unable to find module at [{0}]' -f $modulePath ) 24 | } 25 | 26 | Describe 'Package e2e publish tests' { 27 | [string]$mvcSourceFolder = (resolve-path (Join-Path $samplesdir 'MvcApplication')) 28 | [string]$mvcPackDir = (resolve-path (Join-Path $samplesdir 'MvcApplication-packOutput')) 29 | [int]$numPublishFiles = ((Get-ChildItem $mvcPackDir -Recurse) | Where-Object { !$_.PSIsContainer }).Length 30 | 31 | It 'Package publish 1' { 32 | $publishDest = (Join-Path $TestDrive 'e2ePackage\Basic01\webpkg.zip') 33 | 34 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 35 | 'WebPublishMethod'='Package' 36 | 'DesktopBuildPackageLocation'="$publishDest" 37 | } 38 | $publishDest | Should Exist 39 | } 40 | 41 | It 'Can publish with a relative path for DesktopBuildPackageLocation' { 42 | # publish the pack output to a new temp folder 43 | $publishDest = (Join-Path $TestDrive "e2ePackage\relpath\result.zip") 44 | 45 | Push-Location 46 | mkdir $publishDest 47 | Set-Location $publishDest 48 | 49 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 50 | 'WebPublishMethod'='Package' 51 | 'DesktopBuildPackageLocation'='.\webpkg.zip' 52 | } 53 | 54 | Pop-Location 55 | 56 | "$publishDest\webpkg.zip" | Should Exist 57 | } 58 | 59 | It 'throws when DesktopBuildPackageLocation is missing'{ 60 | {Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 61 | 'WebPublishMethod'='Package' 62 | }} | Should Throw 63 | } 64 | 65 | It 'Can package to a path with a space' { 66 | # publish the pack output to a new temp folder 67 | $publishDest = (Join-Path $TestDrive 'e2ePackage\PublishUrl WithSpace\webpkg.zip') 68 | 69 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 70 | 'WebPublishMethod'='Package' 71 | 'DesktopBuildPackageLocation'="$publishDest" 72 | } 73 | 74 | $publishDest | Should Exist 75 | } 76 | 77 | It 'Can exclude files when a single file is passed in' { 78 | $publishDest = (Join-Path $TestDrive 'e2ePackage\exclude01\pkg.zip') 79 | 80 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 81 | 'WebPublishMethod'='Package' 82 | 'DesktopBuildPackageLocation'="$publishDest" 83 | 'ExcludeFiles'=@( 84 | @{'absolutepath'='approot\\src\\MvcApplication\\Views\\Home'} 85 | ) 86 | } 87 | 88 | # todo: check to see that the file was skipped 89 | } 90 | 91 | It 'Can exclude files when a multiple files are passed in' { 92 | $publishDest = (Join-Path $TestDrive 'e2ePackage\exclude02\pkg.zip') 93 | 94 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 95 | 'WebPublishMethod'='Package' 96 | 'DesktopBuildPackageLocation'="$publishDest" 97 | 'ExcludeFiles'=@( 98 | @{'absolutepath'='approot\\src\\MvcApplication\\Views\\Home'}, 99 | @{'absolutepath'='wwwroot\\web.config'} 100 | ) 101 | } 102 | 103 | # todo: check to see that the files were skipped 104 | } 105 | 106 | It 'Performs replacements when one replacement is passed' { 107 | $publishDest = (Join-Path $TestDrive 'e2ePackage\replace01\pkg.zip') 108 | 109 | $textToReplace = 'Random' 110 | $textReplacemnet = 'Replaced' 111 | 112 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 113 | 'WebPublishMethod'='Package' 114 | 'DesktopBuildPackageLocation'="$publishDest" 115 | 'Replacements' = @( 116 | @{'file'='tobereplaced.txt$';'match'="$textToReplace";'newValue'="$textReplacemnet"}) 117 | } 118 | 119 | $publishDest | Should Exist 120 | # todo: check that the text was replaced see file system tests 121 | } 122 | 123 | It 'Performs replacements when more than one replacement is passed' { 124 | $publishDest = (Join-Path $TestDrive 'e2ePackage\replace02\pkg.zip') 125 | 126 | $textToReplaceTextFile = 'Random' 127 | $textReplacemnetTextFile = 'Replaced' 128 | $textToReplaceWebConfig = '1.0.0-beta1' 129 | $textReplacemnetWebConfig = '1.0.0-custom1' 130 | 131 | Publish-AspNet -packOutput $mvcPackDir -publishProperties @{ 132 | 'WebPublishMethod'='Package' 133 | 'DesktopBuildPackageLocation'="$publishDest" 134 | 'Replacements' = @( 135 | @{'file'='tobereplaced.txt$';'match'="$textToReplaceTextFile";'newValue'="$textReplacemnetTextFile"}, 136 | @{'file'='web.config$';'match'="$textToReplaceWebConfig";'newValue'="$textReplacemnetWebConfig"}) 137 | } 138 | 139 | $publishDest | Should Exist 140 | # todo: check that the text was replaced see file system tests 141 | } 142 | } -------------------------------------------------------------------------------- /tests/publish-module.tests.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding()] 2 | param() 3 | 4 | function Get-ScriptDirectory 5 | { 6 | $Invocation = (Get-Variable MyInvocation -Scope 1).Value 7 | Split-Path $Invocation.MyCommand.Path 8 | } 9 | 10 | $scriptDir = ((Get-ScriptDirectory) + "\") 11 | $moduleName = 'publish-module' 12 | $modulePath = (Join-Path $scriptDir ('..\{0}.psm1' -f $moduleName)) 13 | 14 | $env:IsDeveloperMachine = $true 15 | 16 | if(Test-Path $modulePath){ 17 | 'Importing module from [{0}]' -f $modulePath | Write-Verbose 18 | 19 | if((Get-Module $moduleName)){ Remove-Module $moduleName -Force } 20 | 21 | Import-Module $modulePath -PassThru -DisableNameChecking | Out-Null 22 | } 23 | else{ 24 | throw ('Unable to find module at [{0}]' -f $modulePath ) 25 | } 26 | 27 | Describe 'Register-AspnetPublishHandler tests' { 28 | It 'Adds a handler and verifies it' { 29 | [scriptblock]$customhandler = { 30 | [cmdletbinding()] 31 | param( 32 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 33 | $publishProperties, 34 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 35 | $packOutput 36 | ) 37 | 38 | 'Inside custom handler here' | Write-Output 39 | } 40 | 41 | Register-AspnetPublishHandler -name 'customhandler' -handler $customhandler 42 | 43 | Get-AspnetPublishHandler -name 'customhandler' | Should Not Be $null 44 | Get-AspnetPublishHandler -name 'customhandler' | Should Be $customhandler 45 | InternalReset-AspNetPublishHandlers 46 | } 47 | 48 | It 'If a handler is already registered with that name the new one is ignored' { 49 | [scriptblock]$handler1 = { 50 | [cmdletbinding()] 51 | param( 52 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 53 | $publishProperties, 54 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 55 | $packOutput 56 | ) 57 | 58 | 'Inside custom handler1 here' | Write-Output 59 | } 60 | 61 | [scriptblock]$handler2 = { 62 | [cmdletbinding()] 63 | param( 64 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 65 | $publishProperties, 66 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 67 | $packOutput 68 | ) 69 | 70 | 'Inside custom handler2 here' | Write-Output 71 | } 72 | 73 | Register-AspnetPublishHandler -name 'customhandler' -handler $handler1 74 | Register-AspnetPublishHandler -name 'customhandler' -handler $handler2 75 | 76 | Get-AspnetPublishHandler -name 'customhandler' | Should Be $handler1 77 | } 78 | 79 | It 'If a handler is already registered with that name the new will override with force' { 80 | [scriptblock]$handler1 = { 81 | [cmdletbinding()] 82 | param( 83 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 84 | $publishProperties, 85 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 86 | $packOutput 87 | ) 88 | 89 | 'Inside custom handler1 here' | Write-Output 90 | } 91 | 92 | [scriptblock]$handler2 = { 93 | [cmdletbinding()] 94 | param( 95 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 96 | $publishProperties, 97 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 98 | $packOutput 99 | ) 100 | 101 | 'Inside custom handler2 here' | Write-Output 102 | } 103 | 104 | Register-AspnetPublishHandler -name 'customhandler' -handler $handler1 105 | Register-AspnetPublishHandler -name 'customhandler' -handler $handler2 -force 106 | 107 | Get-AspnetPublishHandler -name 'customhandler' | Should Be $handler2 108 | } 109 | } 110 | 111 | 112 | Describe 'InternalReset-AspNetPublishHandlers' { 113 | It 'Resets the handlers' { 114 | Register-AspnetPublishHandler -name 'customhandler2' -handler { 115 | [cmdletbinding()] 116 | param( 117 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 118 | $publishProperties, 119 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 120 | $packOutput 121 | ) 122 | 123 | 'Inside custom handler here' | Write-Output 124 | } 125 | 126 | Get-AspnetPublishHandler -name 'customhandler2'| Should Not Be $null 127 | 128 | InternalReset-AspNetPublishHandlers 129 | {Get-AspnetPublishHandler -name 'customhandler2'} | Should Throw 130 | Get-AspnetPublishHandler -name 'MSDeploy' | Should Not Be $null 131 | Get-AspnetPublishHandler -name 'FileSystem' | Should Not Be $null 132 | } 133 | } 134 | 135 | Describe 'Get-AspnetPublishHandler tests' { 136 | It 'Returns the known handlers' { 137 | Get-AspnetPublishHandler -name 'MSDeploy' | Should Not Be $null 138 | Get-AspnetPublishHandler -name 'FileSystem' | Should Not Be $null 139 | } 140 | 141 | It 'Returns the custom handlers' { 142 | [ScriptBlock]$handlerBlock = { 143 | [cmdletbinding()] 144 | param( 145 | [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] 146 | $publishProperties, 147 | [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)] 148 | $packOutput 149 | ) 150 | 151 | 'Inside custom handler here' | Write-Output 152 | } 153 | 154 | Register-AspnetPublishHandler -name 'customhandler2' -handler $handlerBlock 155 | 156 | Get-AspnetPublishHandler -name 'customhandler2' | Should Be $handlerBlock 157 | InternalReset-AspNetPublishHandlers 158 | } 159 | 160 | It 'throws when the handler was not found' { 161 | {Get-AspnetPublishHandler -name 'some-unregistered-name'} | Should Throw 162 | } 163 | } 164 | 165 | Describe 'Get-MSDeploy tests' { 166 | It 'Returns a value' { 167 | Get-MSDeploy | Should Not Be $null 168 | } 169 | } 170 | 171 | Describe 'InternalNormalize-MSDeployUrl tests'{ 172 | # TODO: When we add support for all msdeploy sites we should beef up these test cases 173 | It 'Returns the correct value for Azure Web Apps' { 174 | # 'https://{0}/msdeploy.axd' -f $msdeployServiceUrl.TrimEnd(':443') 175 | $msdeployServiceUrl = 'sayedkdemo2.scm.azurewebsites.net:443' 176 | $expected = ('https://{0}/msdeploy.axd' -f $msdeployServiceUrl.TrimEnd(':443')) 177 | 178 | InternalNormalize-MSDeployUrl -serviceUrl $msdeployServiceUrl | Should Be $expected 179 | } 180 | 181 | It 'can use wmsvc'{ 182 | $expectedActual = [ordered]@{ 183 | 'contoso'='https://contoso:8172/msdeploy.axd' 184 | 'deploy0924.contoso.com:8172'='https://deploy0924.contoso.com:8172/msdeploy.axd' 185 | 'deploy0924.contoso.com'='https://deploy0924.contoso.com:8172/msdeploy.axd' 186 | 'deploy0924.contoso.com:8172/msdeploy.axd'='https://deploy0924.contoso.com:8172/msdeploy.axd' 187 | 'deploy0924.contoso.com:304'='https://deploy0924.contoso.com:304/msdeploy.axd' 188 | 's2.publish.antdir0.antares-test.contoso.net:444'='https://s2.publish.antdir0.antares-test.contoso.net:444/msdeploy.axd' 189 | 's2.publish.antdir0.antares-test.contoso.net:443'='https://s2.publish.antdir0.antares-test.contoso.net/msdeploy.axd' 190 | 's2.publish.antdir0.antares-test.contoso.net:80'='https://s2.publish.antdir0.antares-test.contoso.net:80/msdeploy.axd' 191 | } 192 | 193 | foreach($key in $expectedActual.Keys){ 194 | $serviceurl = $key 195 | $expected = $expectedActual[$key] 196 | 197 | InternalNormalize-MSDeployUrl -serviceUrl $serviceUrl -serviceMethod WMSVC | Should be $expected 198 | } 199 | } 200 | 201 | It 'can use RemoteAgent'{ 202 | $expectedActual = [ordered]@{ 203 | 'http://contoso'='http://contoso/MSDEPLOYAGENTSERVICE' 204 | 'contoso'='http://contoso/MSDEPLOYAGENTSERVICE' 205 | 'contoso.com'='http://contoso.com/MSDEPLOYAGENTSERVICE' 206 | } 207 | 208 | foreach($key in $expectedActual.Keys){ 209 | $serviceurl = $key 210 | $expected = $expectedActual[$key] 211 | 212 | InternalNormalize-MSDeployUrl -serviceUrl $serviceUrl -serviceMethod RemoteAgent | Should be $expected 213 | } 214 | } 215 | 216 | It 'can use RemoteAgent old'{ 217 | $msdeployServiceUrl = 'contoso.com' 218 | $expected = ('http://{0}/MSDEPLOYAGENTSERVICE' -f $msdeployServiceUrl) 219 | $actual = InternalNormalize-MSDeployUrl -serviceUrl $msdeployServiceUrl -serviceMethod RemoteAgent 220 | $actual | Should be $expected 221 | } 222 | } 223 | 224 | Describe "Execute-CommandString tests"{ 225 | It 'executes the command'{ 226 | $strToPrint = 'contoso' 227 | $commandToExec = ('echo {0}' -f $strToPrint) 228 | $result = (Execute-CommandString -command $commandToExec) 229 | 230 | $result | Should be $strToPrint 231 | 232 | $result = (Execute-CommandString $commandToExec -useInvokeExpression) 233 | $result | Should be $strToPrint 234 | } 235 | 236 | It 'fails when the command is invalid' { 237 | $strToPrint = 'contoso' 238 | $commandToExec = ('echodddd {0}' -f $strToPrint) 239 | {Execute-CommandString -command $commandToExec} | Should Throw 240 | {Execute-CommandString -command $commandToExec -useInvokeExpression} | Should Throw 241 | } 242 | 243 | It 'does not throw on invalid commands if ignoreExitCode is passed' { 244 | $strToPrint = 'contoso' 245 | $commandToExec = ('echodddd {0}' -f $strToPrint) 246 | {Execute-CommandString -command $commandToExec -ignoreErrors} | Should Not Throw 247 | {Execute-CommandString -command $commandToExec -ignoreErrors -useInvokeExpression} | Should Not Throw 248 | } 249 | 250 | It 'accepts a single value from the pipeline'{ 251 | 'echo contoso' | Execute-CommandString 252 | 'echo contoso' | Execute-CommandString -useInvokeExpression 253 | } 254 | 255 | It 'accepts a multiple values from the pipeline'{ 256 | @('echo contoso','echo contoso-u') | Execute-CommandString 257 | @('echo contoso','echo contoso-u') | Execute-CommandString -useInvokeExpression 258 | } 259 | } 260 | 261 | Describe 'settings tests'{ 262 | It 'can override setting via env var 1'{ 263 | if((Get-Module $moduleName)){ Remove-Module $moduleName -Force } 264 | # $global:AspNetPublishSettings 265 | # InternalOverrideSettingsFromEnv 266 | $env:PublishMSDeployUseChecksum = $true 267 | 268 | # InternalOverrideSettingsFromEnv 269 | Import-Module $modulePath -Global -DisableNameChecking | Out-Null 270 | 271 | $global:AspNetPublishSettings.MsdeployDefaultProperties.MSDeployUseChecksum | Should be $env:PublishMSDeployUseChecksum 272 | 273 | Remove-Item -Path env:PublishMSDeployUseChecksum 274 | 275 | Remove-Module $moduleName -Force | Out-Null 276 | Import-Module $modulePath -Global -DisableNameChecking | Out-Null 277 | } 278 | } 279 | 280 | Describe 'Escape-TextForRegularExpressions tests'{ 281 | It 'will escape\'{ 282 | $input = 'c:\temp\some\dir\here' 283 | $expected = 'c:\\temp\\some\\dir\\here' 284 | 285 | Escape-TextForRegularExpressions -text $input | Should be $expected 286 | } 287 | } 288 | 289 | Describe 'Get-PropertiesFromPublishProfile tests'{ 290 | $script:samplepubxml01 = @' 291 | 292 | 293 | 294 | MSDeploy 295 | Release 296 | Any CPU 297 | http://sayedhademo01.azurewebsites.net 298 | True 299 | False 300 | False 301 | True 302 | wwwroot 303 | sayedhademo01.scm.azurewebsites.net:443 304 | sayedhademo01 305 | 306 | True 307 | WMSVC 308 | True 309 | $sayedhademo01 310 | <_SavePWD>True 311 | <_DestinationType>AzureWebSite 312 | 313 | 314 | '@ 315 | $script:samplepubxmlfilesys01 = @' 316 | 317 | 318 | 319 | FileSystem 320 | wwwroot 321 | {0} 322 | False 323 | 324 | 325 | '@ 326 | It 'Can read a .pubxml file.'{ 327 | $samplepath = 'get-propsfrompubxml\sample01.pubxml' 328 | Setup -File -Path $samplepath -Content $script:samplepubxml01 329 | $path = Join-Path $TestDrive $samplepath 330 | 331 | $result = Get-PropertiesFromPublishProfile $path 332 | 333 | $result | Should not be $null 334 | $result.Count | Should be 18 335 | $result['WebPublishMethod'] | Should be 'MSDeploy' 336 | $result['WebRoot'] | Should be 'wwwroot' 337 | $result['MSDeployPublishMethod'] | Should be 'WMSVC' 338 | $result['_SavePWD'] | Should be 'True' 339 | } 340 | 341 | It 'can publish to file sys with pubxml'{ 342 | $tempdir = (Join-Path $TestDrive 'pubxmlfilesystemp01') 343 | New-Item -ItemType Directory -Path $tempdir 344 | $contents = ($script:samplepubxml01 -f $tempdir) 345 | $samplePath = 'get-propsfrompubxml\sample02.pubxml' 346 | Setup -File -Path $samplePath -Content $contents 347 | $path = Join-Path $TestDrive $samplePath 348 | 349 | #Publish-AspNet -Confirm 350 | } 351 | } -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | 2 | # Ideas for improvements 3 | 4 | - Can we add an MSBuild property to pass ```-Verbose``` and ```-Debug```, that would enable 5 | flowing messages from ```Write-Verbose``` and ```Write-Debg```. The idea is to let users set that in the .pubxml file. 6 | 7 | - In this script there is a call to ```Get-MSDeploy```. It will look at an env var 8 | named MSDeployPath. I was thinking that VS can set this env var so that we 9 | ensure the correct version of MSDeploy is picked up. Env var is preferred to passing this via ```$publishProperties``` because it applies across projects and is specific to the client. 10 | 11 | - How can we pass in the UserAgent string? We should have a different value 12 | for script execution versus from VS. We should pass this in ```$publishProperties``` and have a default that is set in the script. 13 | 14 | - There is a string casing issue when accessing dictionary objects when executing with VS. ```$publishProperties['publishUrl'] != $publishProperties['PublishUrl']``` for some reason. 15 | 16 | - Pass that path to the project in ```$publishProperties``` 17 | 18 | - My thoughts are that we can add a new MSBuild property in .pubxml ```EnableCallKpmPackOnPublish``` 19 | which is set to true by default in our .targets file. If the user adds that to .pubmxl 20 | it will not call kpm pack. 21 | 1. VS/MSBuild call KPM pack and then call .ps1. The idea is that the user will take 22 | the output and then publish to the web server 23 | 2. User want's to completely customize publish and VS/MSBuild calling kpm pack is 24 | not needed. Instead they just need the path to the source folder. 25 | 26 | - There should be a way to cancel the script after it has started. Currently if I have a long running script and I made an error in it I have to wait for it to exit or kill vs. 27 | 28 | - We should have a way to disable launching the browser after publish is already completed. Note: we probably already have an MSBuild property for this 29 | 30 | - Import-Module must be in the publish .ps1 file. If you call Import-Module from an imported .psm1 file the imported module is not visible to the publish script. 31 | 32 | - We should investigate issues with the PS assembly not being available on win7/win2012 server 33 | 34 | - If there is an error in the .ps1 file there is no indication of this in the output. It would be better to give an error message here and make it clear that the publish operation failed due to the script. --------------------------------------------------------------------------------