19

我使用 VSTS 作为构建服务器,在构建时我想将 bin 文件夹内容复制到目标的根目录,并将自定义文件从另一个文件夹复制到这个目标。MSDN建议我使用 minimatch 模式,但它使用子目录结构复制文件。我对恢复结构不感兴趣。

例如,我得到这个文件夹结构:

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

但我想收到这个文件夹结构:

Project.exe
SomeScripts
    script.ps1

我可以使用哪种 minimatch 模式来满足我的要求?

4

7 回答 7

28

如果您只想复制没有文件夹结构的文件,则需要指定复制根目录。由于 project.exe 与 script.ps1 文件位于不同的路径中,因此您需要将它们复制到不同的复制任务中。

按照以下步骤操作:

  1. 添加“复制文件”步骤以复制“project.exe”。如下设置: 在此处输入图像描述
  2. 添加“复制文件”步骤以复制“SomeScripts”文件夹。如下设置: 在此处输入图像描述
  3. 添加“复制和发布构建工件”步骤以将这些文件复制到“放置”。如下设置: 在此处输入图像描述

现在您应该在放置文件夹中获得以下内容:

Project.exe
SomeScripts
    script.ps1
于 2016-01-05T02:39:35.983 回答
7

“复制文件”步骤的“高级”部分中的“展平文件夹”选项。

如果您使用的是 TFS Online (Visual Studio Online) 并且不需要复制文件夹结构,请使用构建定义中“复制文件”步骤的“高级”部分中的“展平文件夹”选项

于 2017-02-11T01:05:44.317 回答
4

使用新的基于 Web 的构建系统,您可以在一个步骤中使用多种模式。因此,您可以为您的情况做这样的事情:

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

或者,如果您在构建步骤中也使用了变量(例如BuildPlatform/ )中的构建平台和配置,则可以在模式中使用它们:BuildConfiguration

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

如果您希望project.exe位于根目录而不是结构中,则需要首先使用 aCopy Task将文件暂存到所需的结构中。您可以$(Build.StagingDirectory)用作此目标。然后使用 Publish 任务$(Build.StagingDirectory)作为复制根并将所有从这个根发布到 drop。

于 2016-01-04T09:19:36.330 回答
2

“flattenFolders”选项也可用作 YAML 任务参数。以下代码摘录显示了一个 CopyFiles@2 任务,该任务将构建输出复制到 $(Build.ArtifactStagingDirectory)。当我指定选项flattenFolders: true嵌套文件夹结构bin\release\...\My.exe被展平时,意味着 exe 文件被复制到 $(Build.ArtifactStagingDirectory) 的根目录。

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

可以在此处找到有关 CopyFiles 任务的更多文档: https ://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/copy-files?view=vsts&tabs=yaml

于 2019-01-16T13:51:08.243 回答
2

对于那些希望在构建服务器中使用 PowerShell 脚本的人,这里有一个工作示例(至少在我的构建服务器上;))示例:

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)
        }
    }
}

这是 PowerShell 构建步骤中使用的脚本:

TFS 2015 Build - 输出到单个文件夹步骤

于 2016-06-17T07:04:32.607 回答
1

使用TFS2017update1及更高版本VSTS,您只需在Copy Files Task中的 Advanced 选项下检查Flatten Folders。目前最简单的解决方案。

在此处输入图像描述

这将展平文件夹结构并将所有文件复制到指定的目标文件夹中。

于 2017-09-15T02:33:10.363 回答
0

制作要复制的每个文件的工件。然后为这些工件的每个文件创建一个“复制文件”任务。然后它不会复制源树结构。

于 2017-01-09T09:33:19.637 回答