Search code examples
teamcity

How do you get TeamCity to flatten a directory when it creates artifacts


We are using TeamCity 5.0 to build a C# solution using the sln2008 build runner. We have multiple projects that produce exe files. We want to use TeamCity's artifacts feature to flatten all the directories. We want all the files to go into one folder with no sub folders no matter which folder it came from. TeamCity keeps the directory hierarchy when it created the artifacts.

Our artifacts are created using

**\bin\Release\*.*=>PublishedFiles

What we get is

  • PublishedFiles\FooProject\bin\Release\Foo.exe
  • PublishedFiles\BarProject\bin\Release\Bar.exe

What we want is

  • PublishedFiles\Foo.exe
  • PublishedFiles\Bar.exe

EDIT

TeamCity 5.1 will get us closer.

The pattern

SomeLibrary\bin\Release\*.dll => PublishedFiles

will get us

  • PublishedFiles\SomeLibrary.dll
  • PublishedFiles\SomeDependency.dll

but

**\bin\Release\*.dll => PublishedFiles

Will still keep the structure that we don't want.

Currently we use MSBuild to flatten the structure and then TeamCity to archive it. It would be nice to skip the MSBuild part.


Solution

  • From the TeamCity 2019.1 Documentation :

    The files will be published preserving the structure of the directories matched by the wildcard (directories matched by "static" text will not be created). That is, TeamCity will create directories starting from the first occurrence of the wildcard in the pattern.

    and

    The optional part starting with the => symbols and followed by the target directory name can be used to publish the files into the specified target directory. If the target directory is omitted, the files are published in the root of the build artifacts. You can use "." (dot) as a reference to the build checkout directory. The target paths cannot be absolute. Non-relative paths will produce errors during the build.

    Two key points here:

    1. If you use a wildcard in the source specifier TeamCity will preserve the directory structure from the first wildcard in the specification. Using your examples SomeLibrary\bin\Release\*.dll does not preserve the directory structure because the lone wildcard only specifies files while **\bin\Release\*.dll will preserve the directory structure because of the first wildcard that will match directories
    2. If you omit the target directory (just use =>) any found artifacts, with preserved directory structures, will be placed at the root of the artifacts tree. Using your example SomeLibrary\bin\Release\*.dll => will place SomeLibrary.dll and SomeDependency.dll at the root of the artifacts tree while **\bin\Release\*.dll => will place the two files in the folder SomeLibrary\bin\Release under the root of the artifacts tree.