开发者

C#, TeamCity - Avoiding the post build events on the TeamCity server

I have a number of projects which I have outputting to a central repository of DLLs in my development environment. This is achieved by adding an XCopy command into the Post-build event command line of the project.

XCOPY $(TargetDir)$(TargetFileName) C:\DEV\library /I /R /Y

I want this to happen in dev mode but when on the TeamCity server I want to avoid the script from being executed. What is the best way of doing this? I am going to search through Google and the documentation but was hoping that others have used TeamCity in a similar way and could advise how开发者_如何学Go it is achieved.

Thanks.

EDIT:

The XCopy is supposed to copy the dll's into a central folder (C:\DEV\library) that the peripheral projects that are dependant on them can access. I have in fact removed the xcopy from the projects because I felt it was more of a hack than a help to use it. Felt like I was forcing a square peg into a round hole.


As far as I understand it you were using XCopy to copy the build output to an external folder so that dependent solutions could use the output as assembly references. You have rightly found that using post build events and XCopy is wrong as it is starting to cause you pain. We have a similar goal in our API solutions and I will try and describe what we do with ours but bare in mind that there is no silver bullet and compromises are sometimes still required.

Project structure

The project structure is not the structure within Visual Studio but how you organise the source, library and other external items that the project requires, this pattern could be applied to most languages. The project structure should be clean, easy to understand and consistent between all projects. I use a structure consistent with a number of open source projects and normally consists of the following.

- root
|-- bin
|-- build
|-- lib
|-- src
|-- tools
  • root - The root should contain as few items as possible.
  • bin - The bin is where the output of the builds should go. This is probably only relevant when you have multiple outputs, if you have only one output such as a web project it can stay where it is. I have found no reason to use a sub folder for debug and release builds.
  • build - Contains build files such as MSBuild or NAnt scripts for building the source, running tests, code coverage, code analysis, documentation, etc.
  • lib - Contains all the third party libraries, either external or internal, that the project output is dependent on. I usually use sub folders for each library but I am not sure if I really need to.
  • src - Contains all the files required to open a project, edit, build and run within your chosen IDE. Try to keep the structure in here as flat as possible, there is no point trying to make it too complicated as other developers are unlikely to be as methodical as you and you will end up with projects in wrong folders. The most I do is to create a test folder for all the tests but even this is not really required.
  • tools - This contains all the applications, assemblies, external files that the build is dependent on but the source should not be dependent on any of it as its dependencies are on the libraries.

File paths

All file paths with in the project should be relative. As soon as you start to use absolute file paths as you have in the example you will start to feel pain. Problems will arise on development machines where the developer has his source on a different drive or on the build server where it is much harder to enforce where the project is run from.

The general rule of thumb is that a project should be self contained. In a perfect world there should be no dependencies on anything outside of the root folder. Sometimes this is hard, especially on legacy projects or where you have com, registry or service requirements but with a little thought and reworking most of these can be mitigated. Ultimately what you want to be able to do is make it as easy as possible to get a project onto a given machine and run it.

Build output

When I do an API project I have the output of the projects put into the bin folder I mentioned above. You have done this using XCopy during the post build event. This is not wrong per say as it will do what you want but with Visual Studio there is a better way. If you go to the build section of a projects property you can change where the output is put. Remember to select all build configurations before changing it.

Referencing assemblies from external projects

One of the reasons for separating out an API into its on solution and referencing the output as assembly references instead of project references is because either the solution has become too big or that you need to reference them from multiple solutions. As stated above a project should not be dependent on anything outside of the project root. Therefore you should not be dependent of the output of an external project and therefore be dependent on A. the project being present on the developers machine and B. being in the correct location.

There are a couple of ways I overcome this:

  1. Have the API project be a sub project inside the main projects using something like Git's Sub Modules or SVN's Externals. This works to some degree but there are some precautions you will need to take, there is a wealth of knowledge on the internet.
  2. Add the assemblies to the lib folder of the dependent projects and treat them as third party assemblies, which is what they really are.

Step two is my preferred root, this can either be done automatically on the build server or manually by copying the output from the build server into the project locally. It all depends on whether you want to have continuous integration or periodic integration.


You could define an Environment Variable in your build configuration or in your build agent config and trigger the copy command only if the variable is not set like it is described here: Suppressing Post-build Events


You could replace “xcopy” with your own program, say myXCopy
myXCopy could check an environmental variable to decide if it should do the copy.
You can then control when this environmental variable gets set.

Or

Write your own MsBuild task to do the copy.
Hook your task into the end of the standard compile task
Make teamcity pass in a MsBuild variable that your custom task checks

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜