Mercurial: auto-tagging an assembly

In mercury mode, I would like to automatically tag some assemblies based on continuous integration scripts. For example a tag such as branchName-buildId

when a branch is deployed, or perhaps latest-stable

whenever a build passes all integration tests.

However, I am concerned that a simple approach would simply cause hg tag

problems:

  • Some tags can be duplicated - i.e. latest-stable

    ... I don't care which assembly is flagged in this situation, but I don't need the conflicts because the script cannot resolve them.
  • Tags trigger commits. However, this means that these commits need to be nudged, and they need to be reliable in the face of simultaneous human pushes and other scenarios. In particular, auto-clicking can create additional heads, which is not good. But by the time the extra head is detected (on push), the local tag commit has already occurred, and while the new chapters are probably trivially merged, sometimes tags cause conflicts.

How can I automatically let the CI server tag build assemblies? It is more important here that the end result is consistent (i.e. that it doesn't mess up the CI server or repo), and less important that tags are applied reliably in the face of duplicates or conflicts (which should be very unlikely anyway).

+3


source to share


2 answers


I think you are right to be careful. Robots are not always the best citizens and can often do stupid things.

What you do depends on what you see for the tags used. For example, if you only see the CI system using them, I would suggest keeping them local. No problem with pull / push / merge.

Some tags may be duplicate, that is, the most recent. I don't care which assembly is flagged in this situation, but I don't need the conflicts because the script cannot resolve them.

If a tag is already defined and you call hg tag

it again , it will fail if you don't click it, but what it does is add a newer, later definition of the same tag, and the latter wins. On the one hand this is good because the merge is simple, but think about when you do:

hg update -r latest-stable
hg update -r latest-stable
hg update -r latest-stable
hg update -r latest-stable

      

Every time you update a version, you will get the version before the tag is created (as usual), and in this version latest-stable

will point to the previous one latest-stable

. As a result, this sequence of commands will take you back in time.

Hence, I would say that it is better to either have unique tags (i.e. stable-2013-02-18

) or the tag in two commits; One to remove the old tag and one to add a new one.



hg update -r latest-stable # You're now at the commit that removed the tag.
hg update -r latest-stable # This one will error because tag doesn't exist

      

Tags trigger commits. However, this means that these commits need to be nudged, and they need to be reliable in the face of simultaneous human pushes and other scenarios. In particular, auto-clicking can create additional heads, which is not good. But by the time the extra head is detected (on push), the local tag commit has already occurred, and while the new chapters are probably trivially merged, sometimes tags cause conflicts.

The CI robot should tag; pull; merge (if necessary); push

. If the merge fails, do not press or raise the alarm. If the push doesn't work (i.e. there were more changes in the time it took to merge), pull again and merge again. I would just make sure your script is very frank about the changes it merges. This process should leave you without additional heads.

I believe that Mercurial treats a file .hgtags

differently for merging because it knows about the content, so conflicts should be very rare. Also, tag commits tend to be merged easily because anything that changes .hgtags

, so merging with the CI head should never conflict. The only reason it might be is that someone is using the same tag names as the CI server, and if they do, then they will need to pour honey on the keyboard so they can do even more damage ...

The situation I see problems with is because you are executing CI tags on multiple heads with the same tag names. for example Development and Release sections have both CI and tags tests-clean

, but have different versions and then merged later. Solution, don't do it.

Hope this is helpful.

+1


source


If you care about build history, consider creating a named branch just for the build process. In Mercurial, all tags from all branches are visible across the entire repository.

If you don't like the history of bookmarks , there is a trick to do. The build process can set a bookmark latest-stable

after running tests, and then execute hg push --bookmark latest-stable

to move that bookmark to the server.



In any case, you need to take care that you do not run tests on revisions that the child has already tested. Mercurial revsets

is a very powerful query language and should help.

0


source







All Articles