Reputation: 2667
I have a publish profile in visual studio 2017
I am trying to copy files from another project. No issues doing so when going to a simple relative directory. However, have a problem with the double recursion going on in the source, making it harder to determine the desired directory.
Source directory: $(MSBuildThisFileDirectory)..\..\..\..Foundation\**\App_Config\**\*
gets me the relevant files.
Goes to: <DestinationRelativePath />
using %(RecursiveDir)%(Filename)%(Extension)
Which deploys to: \**\App_Config\**\*
.
Not to my desire: \App_Config\**\*
I am missing the trick what ever I place in the <DestinationRelativePath>
won't deploy to my desired location. Where am I going wrong? Or is this not possible?
<PropertyGroup>
<PipelineCollectFilesPhaseDependsOn>
GetFoundationConfigFiles;
GetProjectConfigFiles;
$(PipelineCollectFilesPhaseDependsOn);
</PipelineCollectFilesPhaseDependsOn>
</PropertyGroup>
<Target Name="GetFoundationConfigFiles">
<Message Text="Inside of GetFoundationConfigFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles Include="$(MSBuildThisFileDirectory)..\..\..\..\Foundation\**\App_Config\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>App_Config\Include\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<Target Name="GetProjectConfigFiles">
<Message Text="Inside of GetProjectConfigFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles1 Include="$(MSBuildThisFileDirectory)..\..\..\..\Feature\**\App_Config\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles1.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
Upvotes: 3
Views: 4216
Reputation: 2667
Decided to execute Powershell was the best option. Instead of doing Web Deploy I switched to File System publish in Visual Studio 2017.
Using the publish profile I execute powershell script passing it two parameters.
What is great is I can check-in my .pubxml and use the .pubxml.user which is not checked-in file to define 2). This allows each developer to use the same publish profile locally.
If anyone knows how to have custom variables in publish profiles that'd be great, restricted to passing through what we have from publishing profiles when calling command at the moment.
Publish Profile .pubxml
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<PublishProvider>FileSystem</PublishProvider>
<LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<DeleteExistingFiles>False</DeleteExistingFiles>
<PipelineDependsOn>
CopyAssets;
$(PipelineDependsOn);
</PipelineDependsOn>
</PropertyGroup>
<Target Name="CopyAssets">
<Message Text="Inside of CopyAssets" Importance="high"/>
<Exec Command="%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe -File "$(SolutionDir)Foundation\Scripts\Powershell\CopyAssets.ps1" $(SolutionDir) $(publishUrl)"/>
</Target>
</Project>
Publish Profile .pubxml.user
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TimeStampOfAssociatedLegacyPublishXmlFile />
<_NewBackgroundProfile>False</_NewBackgroundProfile>
<_PublishTargetUrl>C:\inetpub\wwwroot\mywebapp</_PublishTargetUrl>
</PropertyGroup>
</Project>
CopyAssets.ps1
#
# CopyAssets.ps1
#
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]$solutionDirectory,
[Parameter(Mandatory=$True)]
[string]$copyTo
)
#
# Copy Assets Initializations
#
# Absolute path to copy files to and create folders in
$absolutePath = @($copyTo + "/App_Config/Include")
# Set paths we will be copy files from
$featureDirectory = Join-Path $solutionDirectory "/Feature/*/App_Config/Include"
$foundationDirectory = Join-Path $solutionDirectory "/Foundation/*/App_Config/Include"
function Create-Files {
Param ([string]$currentPath, [string]$pathTo)
Write-Host "Attempting to create files..."
# Copy files from root include folder
$files = Get-ChildItem -Path $currentPath | Where-Object {$_.PSIsContainer -eq $false}
foreach ($file in $files)
{
Write-Host "Attempting to copy file:"$file "to"$path
New-Item -ItemType File -Path $pathTo -Name $file.Name -Force
}
}
# Logic to create new directories and copy files over.
function Copy-Assets {
Param ([string]$directoryBase)
$path = $absolutePath
Write-Host "Directory copying from:" $directoryBase
Write-Host "Creating files found in include folder"
# Path hack to copy files from directoryBase
$directoryBaseHack = Join-Path $directoryBase "\*"
Create-Files -currentPath $directoryBaseHack -pathTo $path
Write-Host "Getting sub directories to copy from"
$directories = Get-ChildItem -Path $directoryBase -Recurse | Where-Object {$_.PSIsContainer -eq $true}
Write-Host "Iterating through directories"
foreach ($directory in $directories)
{
Write-Host "Checking if directory"$directory.Name "is part of absolute path."
if($absolutePath -match $directory.Name)
{
# checking if directory already exists
Write-Host "Directory is part of absolute path, confirming if path exists"
$alreadyExists = Test-Path $absolutePath
if(!$alreadyExists)
{
Write-Host "Absolute path doesn't exist creating..."
New-Item -ItemType Directory -Path $absolutePath -Force
Write-Host "All directories in path for Absolute Path created:"$absolutePath
}
Write-Host "Directory for"$directory.Name "already exists as it is part of the Absolute Path:" $absolutePath
}else{
Write-Host "Joining path with absolute path"
$path = Join-Path $absolutePath $directory.Name
Write-Host "Joined path:"$path
Write-Host "Does joined path exist:"$path
$alreadyExists = Test-Path $path
if(!$alreadyExists)
{
Write-Host "Joined path doesn't exist creating..."
New-Item -ItemType Directory -Path $path -Force
Write-Host "Created new directory:" $path
}
Write-Host "Directory for"$path "already exists."
}
Write-Host "Creating files found in:" $directory
Create-Files -currentPath $directory -pathTo $path
}
}
Write-Host "Starting Copying Foundation Files"
Copy-Assets -directoryBase $foundationDirectory
Write-Host "Starting Copying Feature Files"
Copy-Assets -directoryBase $featureDirectory
Upvotes: 4
Reputation: 76760
I am missing the trick what ever I place in the won't deploy to my desired location. Where am I going wrong? Or is this not possible?
It looks like impossible to use filter and merge in the internal double recursion.
As we all know, \**\*.*
help to get files from all the folder. RecursiveDir
help to put all the file in the respective folder. When you use **\App_Config\**
to get your files from all the parent folder and sub folder, RecursiveDir
will put all the file in the respective folder(parent folder and sub folder) by double recursion. We could not insert the filter and merge in the process of recursion. What can we do is publish all those files to a folder:
<Target Name="GetProjectConfigFiles">
<Message Text="Inside of GetProjectConfigFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles1 Include="$(MSBuildThisFileDirectory)..\..\..\..\Feature\**\App_Config\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles1.Identity)">
<DestinationRelativePath>App_Config%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
Not sure if this result is what you want, if you want to get all files without parent folder, it looks you should specify the parent folder when you get all files:
<Target Name="GetFoundationConfigFiles">
<Message Text="Inside of GetFoundationConfigFiles" Importance="high"/>
<ItemGroup>
<_CustomFiles Include="$(MSBuildThisFileDirectory)..\..\..\..\Foundation\Test1\App_Config\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>App_Config%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
Upvotes: 0