Continuous integration and software versioning - c#

I like the idea of automatically versioning my builds but I'm not sure what the right way is to get the AssemblyInfo.cs change back into source control (or should it not go into source control?). Is this something the CI server should be committing automatically for each build?
Using Bamboo at the moment.

We are using Teamcity as our CI server, and it comes with a feature called AssemblyInfo patcher
What this does, is temporarily add the teamcity build number in Assemblyinfo.cs, build generate the artifact and then revert the change. This way the generated artifact has the same version as the build number.
Source control can have the assemblyinfo.cs version entry as the current revision the developers are working on, with '*' as the build number. This can be updated after every release.
Edit 1:
Since you are using Bamboo, here is a link that describes one way of setting the build number in the generated artifact in bamboo, without having to check-in the AssemblyInfo.cs.

I'm sort of confused by your question. If you want the changes to persist you'll have to commit AssemblyInfo.cs after it gets edited by the build job. However, most build systems attempting to solve these problems do not persist the changes. They simply check out the file and edit the local version before kicking off the build task.

Related

TFVC checkin best practice

Many people told me that the best practice of checking in my code on TFVC is getting latest before.
I don't know why I think that TFS smart enough and there is no difference between getlatest then checkin or getlatest after checkin
In my opinion when working with TFVC in TFS, the process should be:
You get latest
You write your tests
You make them pass
You get latest including conflicts and resolve all conflicts
You run your tests
If they fail you fix and go back to 4
When they pass and after doing a get latest you checkin
(this process is the same for all server-based source control systems)
If you do not do this then you are not writing your code on the latest codebase so while tfvc can merge, if something has happened like a method being changed or removed, the merge won't help.
Be a good citizen and get latest before you checkin - ideally you should have a CI build which checks this and if you do you will often break the build which is bad for everyone.
Edited: I have added that when you checkout you also get all conflicts, otherwise if you have done something like added a file the project won't be downloaded when you do a get latest, this is pretty important actually with TFS.
I would share some of my opinions when working with TFS:
It's smart, it helps to perform auto-merge many times (if my code is not conflict with others). Otherwise, you can see all conflicted files and do merge yourself file by file or you can decide to take server version / local version.
If not doing get latest, you may need to perform a second shoot, example:
- You add some files to a project Business.csproj
- Your colleage also added some files to that project. TFS merges the file and requires Visual Stiduo to reload the project.
Let's imaging we often review all changes, run tests... before checking in. There are 40 files, on both cases confliction or reload project, a second check needs to be done...

Bringing C# application under assembly version and using it to create patches and manage them

We have a C# desktop application which we run for clients on various servers on a software as a service model. We are still on dot net framework 2.
The software has a architecture in which we have an independent application to catch external data thrown by some server. Then an application to make calculations based on it. Also one more application on which the client sees the output. The link between the 3 applications is another application which communicates with the DB.
The 4 solutions are on a SVN for sourcecontrol. But the release management is still manual and the patches are made manually by checking the log and including the dlls, pdbs, xml. etc for the projects for which the code has changed.
There is no assembly versioning implemented and the patch or release management is just done in the dark.
I want to know what is the industry practice for generating automatic patches from the code. Also I want a patch for each revision in the SVN. Also is assembly versioning helpful in this?
I have read much about continuous integration but it fails because we do not have unit tests and other fancy code to moniter the correctness of code.
The only thing at this time I would be interested is to implement a way to make patches which can be applied and removed easily. Also I want to know a way to determine the way we can monitor which release is at which level(or what patches have been applied) by some automated way rather than maintaining a log manually.
We use a build script which creates a SvnVersion.cs file containing the last commited revision. This file is placed in the root of the solution, and then added to all projects in the solution (but added as a link, not copied).
The template for the file (SvnVersion.Template.cs) looks like this:
using System.Reflection;
[assembly: AssemblyVersion("1.0.0.$WCREV$")]
[assembly: AssemblyFileVersion("1.0.0.$WCREV$")]
And we simply use TortoiseSVN to fill these placeholders in a batch script:
type "%TRUNKPATH%SvnVersion.Template.cs" > "%TRUNKPATH%\SvnVersion.tmp"
SubWcRev "%TRUNKPATH%\" "%TRUNKPATH%SvnVersion.tmp" "%TRUNKPATH%SvnVersion.cs" -f
IF ERRORLEVEL 1 GOTO ERROR
DEL "%TRUNKPATH%SvnVersion.tmp"
If you don't use TortoiseSVN, there are other ways to get this info in the file.
You will also need to remove this same information from your AssemblyInfo.cs files or you'll get a compile error. Also, to speed up Debug builds, this is only executed in Release builds (and in Debug builds only if the file doesn't initially exists, like after a fresh checkout).

Build or Rebuild on the build server (CI server)

I am running TeamCity to build a .NET project (several projects to be more exact).
Should i be using Rebuild target or Build target?
I would like to minimize the build time, while not producing any newer versions of projects that haven't changed.
Is this safe practice to use "Build" target? what if the previous project outputs were erased? how do i verify that i can be doing this safely?
You should use rebuild if you need to rebuild all the projects, for instance in order to get coherent timestamps or version numbers (though usually, a change in a linked AssemblyInfo.cs will trigger a build as well.)
Build is completely safe even if the build output from a previous build is gone, or even if the build happens to be done on a new build agent which has no build output. In that case, all necessary projects will be built.
However, you might have custom MSBuild steps in your sln/csproj files that depends on a (Re)build, in which case you need to be more careful, but other than that, go for Build if you want to.
You should always perform rebuild operations on Continuous Integration servers.
Contrary to what you may read, it is possible to have leakage from a prior build into the current one. The leakage is almost never the result of failing to compile source code to binaries, but depending on which tool you're using to perform the build, there may be non-code files that don't get copied over because they already exist in the output directory, or deleted files that aren't removed from it.
For similar reasons, if you can afford the cost of execution time, you should also always clean the source tree before the build. Either destroy it and check out a clean copy, or revert any changes and delete any files not under source control. If you don't do this on every build, at least do it on "idle time" builds (e.g., overnight or weekend builds), and on the builds you intend to actually deliver to customers or deploy into production (and ideally into QA).
Build produces everything needed to run the project, keeping non-changed assemblies. Rebuild forces a complete build of any assembly involved. Unless for specific circumstances (version number, dependent process on something), it is safe to use build to minize time spent.
You should use Build to build your project incrementally. It is completely safe.

Is it possible to force TeamCity to create one build for each SVN commit?

I have the follow configuration in my TeamCity:
2 Projects and each project some build configurations
My problem is that whenever TeamCity is building a project and a new Tag is created
(e.g: Tag-5.9.0 revision 533) this tag goes to the “Pending” list. If another Tag is created (e.g: Tag-5.9.1 revision 539) I have now the two Tag’s in the Pending list.
What happens is that TeamCity will always compile the newest Tag.
My output Folder was supposed to contain the follow folders:
C:\Deploy\Client\Version\Tag-5.9.0-rev.533
C:\Deploy\Client\Version\Tag-5.9.1-rev.539
However I have just the last committed Tag.
C:\Deploy\Client\Version\Tag-5.9.1-rev.539
Is there a way to force an individual build for each commit ??
Thanks,
TeamCity Version 6.5.1 (build 17834)
This feature is not implemented as answed by JetBrains developper, you can check my post to JetBrains Developer, however have some workarounds for this.
Thanks.

Build Version vs Revision number

I have an asp.net/C# app that uses subversion for source control.
My app automatically increases it's AssembleVersion and AssemblyFileVersion on each build which works like a charm, and displays the build number in the administration side of the site.
We keep track of AssembleVersion and AssemblyFileVersion's when we do deployment, however, when an issue arises and we need to roll back to a certain version, we have no idea which revision to target in subversion.
I have few ideas:
Save AssembleVersion as comment in each file
Have a keyword in commit comments that get's replaced by AssembleVersion on each commit(still need to figure out how to do it)
Any help and suggestions will be appreciated
Updated:
option "1" is actually a stupid idea,cause this will mean that everytime i build, all files will be marked as updated and when i commit, every single file will be updated
When I build, I put that build number everywhere.
I put it in a tag in svn.
I put it in the Assembly metadata of every assembly I build.
I append it to the end of the filename in my installers.
I put it in the footer of each of my deployed webpages.
I put it in the footer of my reports.
I put it in the splash screen of my client side apps.
I put it in the welcome screen for my installers.
The only thing I don't put it in is my coffee, which I take black.
All of this lets a maintainer know at a glance exactly where the code came from for what they're seeing, whether they're viewing a webpage, or looking at the properties of one of the built assemblies in Explorer, or whatever.
How about using tags.
http://svnbook.red-bean.com/en/1.1/ch04s06.html
Tags aren't really useful if you happen to build often. Maybe find a way to update Assembly version based on the svn revision instead? Also include the branch name, because they share the revisions.
And you should be able to extract the assembly version in your ASP.NET pages and print it programmatically in a footer or something.
You could tag the Subversion trunk with the AssembleVersion or AssemblyFileVersion, whichever makes the most sense.
You could also keep track of the Subversion revision number the same way you currently keep track of the AssembleVersion and AssemblyFileVersion when you deploy.
Apply a tag to your source tree after you have updated the AssemblyVersion and AssemblyFileVersion.
You could "branch for release". Before creating a release build you could branch the trunk and then create a tag on the new branch with the release version number.
+ release tag
/
+--------------------- release branch
/
----------+----------------------------------------------------- trunk
This would allow you to keep track of all individual releases in SVN. It would also allow you to make isolated bug fixes on release branches that could be released as patches. The bug fix could then be merged back into the trunk.
+ + patch release tag
/ /
+-----------------+-+---- release branch
/ | merged fix into trunk...
----------+----------------------------------------------------- trunk
Tags/branches are definately the recommended approach here.
You can also (or additionally) include the svn revision number in your AssemblyInfo. One approach is to use the AssemblyInfo task from the msbuildtasks project at http://msbuildtasks.tigris.org
For more info, google msbuild svn revision assemblyinfo
You could then do without tags/branches, as you can always check out a specific revision, and/or create a branch from a specific revision.
Another option is to use last changed revision as your build number. This means each time you build you auto-tag. It's easy with hudson/jenkins since you have an environment variable SVN_REVISION. The problem is that revision number get very large and hallway discussions about 1.0.0.20456 vs 1.0.0.20489 are a mouthful.

Categories

Resources