Migrate Subversion repository to git and Bitbucket

This Powershell script needs subgit >= 2.0.0 and msysgit >= 1.7.10. The first one enables the migration of a remote SVN repository, and the second restriction is for correct migration of UTF-8 files and filenames. Caveats:

  • It assumes that the SVN repo is standard, that is, you have Project/trunk, Project/tags and Project/branches with the usual roles. Were this not the case, you must specify the rules in the $gitTmpRemoteRepo\subgit\config files after the subgit configure command.
  • If the SVN repo needs authentication, you need to add a user in the $gitTmpRemoteRepo\subgit\passwd file after the subgit configure command.

Migrate Bitbucket repository from Mercurial to Git

At the beginning

For each repo https://bitbucket.org/$USER/$REPO

First, create a new Bitbucket git repository called git$REPO.

Then, execute the following:

Finally:

  • Rename or delete repository $REPO
  • Rename repository git$REPO to $REPO

Versioning multiple packages in single solution

Scenario: I have a solution with project A and B. Both generate NuGet packages. Project B depends on A. Configured for automatic package restore.

Problem: How do I update versions with the following restrictions?

  • Both projects must have the same version.
  • Package B version N must depend on package A version >=N.
  • No dependency hard-wiring. I don’t want to maintain a .nuspec with dependencies because they are already specified in .csproj/.vbproj files.

By the way, having a project reference AND a NuGet package reference simultaneously is not that easy. You must install the package and then remove the reference and add it again as a project reference (“Add reference…”).

I have come up with this working solution that requires 2 builds; I wonder if there is a 1 build way:


Current situation: in the feed we have package A v4.5 and package B v4.5, which depends on A v4.5.

  1. Assembly Info Patcher: The versions of all projects get updated to 4.6.
  2. Build: Compiles A and then B because of the project dependencies.
    1. Nuget Install on A: Nothing to do (A depends on nothing)
    2. Compile A: A.dll v4.6
    3. Nuget Install on B: According to packages.config of B, package A v4.5 is installed (we cannot install v4.6 because it is not in the feed!)
    4. Compile B: B.dll v4.6 (but with A.dll v4.5 in its bin folder)
  3. Pack & Publish: Packages A v4.6 and B v4.6 in the feed (but B depends on A v4.5)
  4. Update packages: Update references to the published packages, for all the projects. In particular, it installs A v4.6 and updates packages.config of B.
  5. Build #2: Compiles A and then B because of the project dependencies.
    1. Nuget Install on A: Nothing to do (A depends on nothing)
    2. Compile A: A.dll v4.6
    3. Nuget Install on B: Theoretically it does nothing because we have already updated in step 4.
    4. Compile B: B.dll v4.6 (and with A.dll v4.6 in its bin folder)
  6. Pack & Publish: Packages A v4.6 and B v4.6 in the feed (and B depends on A v4.6)
  7. Commit packages.config: These files must be commited so that developers get the appropriate package references.

It seems that a nuget update before the compilation of each project and a nuget pack/publish afterwards would do the trick. The desired sequence would be:

  1. Assembly Info Patcher: The versions of all projects get updated to 4.6.
  2. Build: Compiles A and then B because of the project dependencies.
    1. Nuget Install on A: Nothing to do (A depends on nothing)
    2. Compile A: A.dll v4.6
    3. Pack & Publish A: Package A v4.6 in the feed
    4. Nuget Update A for solution: Update references to A to last version, so it updates all packages.config that refer to A (for example the one of B).
    5. Nuget Install on B: According to packages.config of B, package A v4.6 is installed
    6. Compile B: B.dll v4.6 (with A.dll v4.6 in its bin folder)
    7. Pack & Publish B: Package B v4.6 in the feed, depends on package A v.4.6.
    8. Nuget Update B for solution: Nothing to do (nothing depends on B)
  3. Commit packages.config: These files must be commited so that developers get the appropriate package references.

TeamCity 7: problems solved

Things I got to do to start a project in TeamCity. The project is a simple class library, hosted at Bitbucket (with Mercurial), with some NUnit tests and published at NuGet.

Nuget Package Restore feature does not work

The problem is that nuget install requires an environment variable (EnablePackageRestore) that is set to true by Visual Studio but TeamCity is unaware of. The solution is to set this variable in the file .nugetNuget.targets before executing the nuget install. There is a NuGet package that modifies Nuget.targets for us. Inside Visual Studio:

Problem importing strong name key

The CI server cannot import the key because you must install it before. The MsBuild tool gives you a key (VS_KEY_xxxxxxxxxxxxxxxx) you must use. Also, you must log in with the SYSTEM account because TeamCity service runs by default on it. So:

Grab a copy of PsTools and execute the following:

The sn utility is located at %ProgramFiles%\Microsoft SDKs\Windows\v7.0A\Bin.

“DotNetFramework4.0_x86” requisite

At some point (apparently random), the agent decided that it didn’t fullfill the “DotNetFramework4.0_x86” requirement. I found these instructions to solve the problem.

  1. Stop the agent service
  2. Delete the following folders:
    • buildAgentplugins
    • buildAgentsystem
    • buildAgenttools
  3. Start the agent service
  4. Await several minutes until the agent gets upgraded and running again
  5. Restart the agent service again (I need that last one!)

Non-standard package feeds

If you have feeds different from the standard, you need to indicate them in the file .nugetNuget.targets. Search for PackageSource in this file, there is a commented example.

Deleting bin and obj using Powershell

Abbreviated version with alias and short parameters, assuming that the current directory is the root that contains all bin and obj you want to remove (usually solution folder):

I obtained the extended version, more understandable for newbies, from http://blog.slaven.net.au/2006/11/22/use-powershell-to-delete-all-bin-obj-folders/:

Nullable that works for both classes and structs

Here it is:

And, as a bonus, two extensions for converting between “classic” Nullable and Nullable2:

Generalizing String.Join with extension methods

String.Join is a basic function of .NET Framework that every developer has used uncountable times. However, the offered variants have always lacked a certain raw Win32 API call “flavor”. Before .NET 4, the overloads were:

First of all, we got the limitation of having to work with arrays, which forced to convert into array every other enumerable (e.g. lists), by means of a call to ToArray. At least that was solved in .NET 4, with the new versions for IEnumerable and another one that accepted a parametric array:

But what I found more displeasing is the notation, so non-OO. Thanks to the extension methods I have been able to write a little function library for string joining.

These functions add the possibility of adding prefixes and suffixes for the elements, as well as global prefixes and suffixes that surround the result unless it has zero elements.

The funtions are called JoinStr instead Join because LINQ introduced a function with the latter name to make set joins.