Copy one file in target directory on deploy from v

2020-01-25 06:07发布

I'm using VSTS as a build server, and while building I want to copy the bin folder contents to the root of the target, and also custom files from another folder to this target. MSDN suggests I use a minimatch pattern, but it's copying files with the subdirectory structure. I'm not interested in restoring the structure.

For example, I am getting this folder structure:

Project
    MyProjectFiles
    bin
        x86 (it's build configuration)
            Project.exe
    Other project files
    Project.sln
SomeScrips
    script1.ps1

But I want to receive this folder structure:

Project.exe
SomeScripts
    script.ps1

Which minimatch pattern can I use for my requirements?

7条回答
时光不老,我们不散
2楼-- · 2020-01-25 06:47

With TFS2017update1 and above, VSTS, you could simply check Flatten Folders under Advanced option in Copy Files Task. The easiest solution for now.

enter image description here

This will flatten the folder structure and copy all files into the specified target folder.

查看更多
叛逆
3楼-- · 2020-01-25 06:55

With the new web based build system you can use multiple patterns in a single step. Therefore you can do something like this for your case:

Project\bin\x86\Release\project.exe
SomeScripts\**\*

Or if you have the build platform and configuration in a variable (eg. BuildPlatform / BuildConfiguration) which you also use in the build step you could use them in the pattern:

Project\bin\$(BuildPlatform)\$(BuildConfiguration)\project.exe
SomeScripts\**\*

If you want the project.exe to be in the root instead of the structure you need to use a Copy Task to stage your files in the desired structure first. You can use $(Build.StagingDirectory) as a target for this. Afterwards use the Publish task with $(Build.StagingDirectory) as copy root and publish everything from this root to the drop.

查看更多
放荡不羁爱自由
4楼-- · 2020-01-25 06:55

"Flatten Folders" option in "Advanced" section of "Copy Files" step.

If you are using TFS Online (Visual Studio Online) and don't need to copy the folder structure use "Flatten Folders" option in "Advanced" section of "Copy Files" step in your build definition

查看更多
虎瘦雄心在
5楼-- · 2020-01-25 06:55

The "flattenFolders" option is also available as a YAML task parameter. The following code excerpt shows a CopyFiles@2 task which copyies the build output to the $(Build.ArtifactStagingDirectory). When I specify the option flattenFolders: true the nested folder structure bin\release\...\My.exe is flattened, means the exe files is copied to the root of $(Build.ArtifactStagingDirectory).

- task: CopyFiles@2
  displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
  inputs:
    SourceFolder: '$(system.defaultworkingdirectory)'
    Contents: |
     **\bin\$(BuildConfiguration)\**\*.exe
    TargetFolder: '$(Build.ArtifactStagingDirectory)'
    flattenFolders: true

Further documentation concerning the CopyFiles task can be found here: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/copy-files?view=vsts&tabs=yaml

查看更多
冷血范
6楼-- · 2020-01-25 06:56

For those who would like to have a PowerShell script to use in your build server, here is a working (at least, on my build server ;)) sample:

param
(
    [string] $buildConfiguration = "Debug",
    [string] $outputFolder = $PSScriptRoot + "\[BuildOutput]\"
)

Write-Output "Copying all build output to folder '$outputFolder'..."

$includeWildcards = @("*.dll","*.exe","*.pdb","*.sql")
$excludeWildcards = @("*.vshost.*")

# create target folder if not existing, or, delete all files if existing
if(-not (Test-Path -LiteralPath $outputFolder)) {
    New-Item -ItemType Directory -Force -Path $outputFolder | Out-Null

    # exit if target folder (still) does not exist
    if(-not (Test-Path -LiteralPath $outputFolder)) {
        Write-Error "Output folder '$outputFolder' could not be created."
        Exit 1
    }
} else {
    Get-ChildItem -LiteralPath $outputFolder -Include * -Recurse -File | foreach {
        $_.Delete()
    }
    Get-ChildItem -LiteralPath $outputFolder -Include * -Recurse -Directory | foreach {
        $_.Delete()
    }
}

# find all output files (only when in their own project directory)
$files = @(Get-ChildItem ".\" -Include $includeWildcards -Recurse -File |
    Where-Object {(
        $_.DirectoryName -inotmatch '\\obj\\' -and
        $_.DirectoryName -inotmatch '\\*Test*\\' -and
        $_.DirectoryName -ilike "*\" + $_.BaseName + "\*" -and
        $_.DirectoryName -ilike "*\" + $buildConfiguration
    )}
)

# copy output files (overwrite if destination already exists)
foreach ($file in $files) {
    Write-Output ("Copying: " + $file.FullName)
    Copy-Item $file.FullName $outputFolder -Force

    # copy all dependencies from folder (also in subfolders) to output folder as well (if not existing already)
    $dependencies = Get-ChildItem $file.DirectoryName -Include $includeWildcards -Exclude $excludeWildcards -Recurse -File
    foreach ($dependency in $dependencies) {
        $dependencyRelativePathAndFilename = $dependency.FullName.Replace($file.DirectoryName, "")
        $destinationFileName = Join-Path -Path $outputFolder -ChildPath $dependencyRelativePathAndFilename
        if (-not(Test-Path -LiteralPath $destinationFileName)) {
            Write-Output ("Copying: " + $dependencyRelativePathAndFilename + " => " + $destinationFileName)

            # create sub directory if not exists
            $destinationDirectory = Split-Path $destinationFileName -Parent
            if (-not(Test-Path -LiteralPath $destinationDirectory)) {
                New-Item -Type Directory $destinationDirectory
            }
            Copy-Item $dependency.FullName $destinationDirectory
        } else {
            Write-Debug ("Ignoring (existing destination): " + $dependency.FullName)
        }
    }
}

Here is the script being used in a PowerShell build step:

TFS 2015 Build - Output to single folder step

查看更多
唯我独甜
7楼-- · 2020-01-25 06:59

You need to specify the copy root if you want to copy files only without folder structure. Since the project.exe is in a different path with script.ps1 file, you need to copy them in different copy task.

Following the steps below:

  1. Add a "Copy Files" step to copy "project.exe". Settings like following: enter image description here
  2. Add a "Copy Files" step to copy "SomeScripts" folder. Settings like following: enter image description here
  3. Add a "Copy and Publish Build Artifacts" step to copy these files to "drop". Settings like following: enter image description here

Now you should get the things like following in drop folder:

Project.exe
SomeScripts
    script.ps1
查看更多
登录 后发表回答