Atomic dependency build
I have 1 build that is an assembly build of a ton of snapshot dependent builds with multiple levels of dependencies. It does the assembly by grabbing the dependent artifacts from a Maven repo (Arifactory). A dependent build creates artifacts and uploads them to the repo. When all of them are done the assembly build runs and extracts it components from the repo.
Normally, what you would do is to use an artifactory dependency in the assembly build to get its components to assemble. However, I can't do it this way and have to rely on an external repo. This is for 2 reasons, 1) a requirement the build process needs to run outside of TeamCity and I can't use TeamCity constructs (artifact dependencies) to facilitate the build. I now I'm using snapshot dependencies but this is solved by a procedural call to all the builds in a script. 2) Our TeamCity server is not local to our TeamCity build agents and some of our Artifacts are huge. Transferring them over the internet is not feasible. So we have an repo local to our build agents.
The problem is that I can NOT produce an "atomic" build. So what happens is that the assembly build has a VCS trigger and when commits occur it triggers/queues the dependent builds. The dependent builds do NOT have VCS triggers. When the affected dependent builds are done.the assembly build runs grabbing freshly created artifacts from the repo. However, while the dependent builds are running more commits occur triggering/queuing another assembly build which in turn triggers/queues more dependent builds. Now if the 1st assembly build's dependent builds are not done due to multiple dependency levels, the 2nd triggered assembly build can build some of it's components before the 1st one is done. Thus the 1st assembly build can grab artifacts from the repo produced by the 2nd.
I thought I could just say to only run 1 assembly build at a time and it would fix this - the 2nd would have to wait until the 1st assembly build was done. However, that's not how snapshot dependencies get queued. Even though there is 1 assembly build running and you have it set to only run 1 at a time, it STILL queues it and it's dependency builds of the 2nd to run and thus these could run before the 1st assembly build is done. What I want it do is to NOT queue the 2nd assembly and its dependency builds until the 1st assembly build is done. Is there a way to do this?
Please sign in to leave a comment.
Hi JT,
I think I see the issue, and definitely not having access to the artifact dependencies makes it difficult, as obviously, artifact dependencies are the way we provide to deal with that exact situation.
The first idea would be to set up a quiet period in the VCS Trigger. If you can stop the specific assembly build from triggering for enough time for the rest of the builds to finish, you would effectively stop the build to trigger before the second assembly fires up its dependencies.
Another option would be to replace the snapshot dependencies for a script that calls the REST API to trigger a build of each of its dependencies. This would work around the issue, because you can set up the script to check before the queue for other instances of the build and wait until the other instances are finished before proceeding. It does incur in a heavier maintenance load but gives you the flexibility to be able to ensure that the builds will proceed in the order you require.
Another option would be to include some hint from the builds that indicates the build number, then ensuring that the assembly build only assembles the artifacts corresponding to that version, instead of the last available.