The mind is like a parachute. If it doesn't open, you're meat.

Tales of Teamcity: Adventures in Kotlin

31 Mar 2020

TeamCity is one CI system I haven’t had a lot of contact until now. As will become evident, this has now changed.

So, alongside a crash course in basic Kotlin, I now have to figure out how to get my brand of build automation working in TeamCity.

The gatekeeper

I have one criterion for accepting a build management system:

Build job specifications have to be stored in the repository

Let’s explore if TeamCity makes it past the door and how far we can take it.

First contact

First contact is always a search along the lines of “build DSL, TeamCity”. I was already aware that TeamCity offers a DSL based on Kotlin and so we landed very fast on the blog series describing these features.

This gets TeamCity through the door. It’s also a pretty cool taster for what Kotlin can do: the DSL looks clean and it looks like the web UI offers a way to get easily from clicked-together to code.

I have studiously ignored all the IDEA bait in those posts. You should not need code completion to put a few pipelines together (narrator: he was mostly wrong).

I have also skipped and jumped over the Maven references. Seriously, I have a pom allergy. It is probably going to bite me in the behind as soon as this system gets reasonably complicated and I am going to need tests, but it was all I could do to keep reading after my eyes brushed over that XML.

Reality check

OK, I’m armed with Kotlin and I’ve got a TeamCity instance and I’ve got a project and I see that all the settings are version controlled. But they all go to this one repository somewhere beyond my reach.

It turns out you need pretty wide-reaching access rights to be able to activate versioned settings. Luckily, it took about 10 seconds of pointed question asking and:

Achievement Unlocked

Seriously, I’m framing this - it was my fastest 0-to-admin time ever!

Get off my master

Turning on versioning for project settings has one drawback: Every time you change something in the web UI, Teamcity will commit the changes in the designated repository. And it does it on master.

Now, depending on the workflow you follow for your git usage this may be a good or a bad thing.

First, lets agree that in principle, no changes should be done in the UI. Also, that if, by any chance any changes are done in the UI, whatever we have in the repository should overwrite them.

This is rule of git acquisition number 23:

The repository comes first

So, when we set up versioning we set the appropriate option:

No UI changes allowed

Now, the comment accompanying the option gives me hope that things have been done properly.

The goal here is to have the build setup correspond to the state of the code base at the time of the commit you are building. The docs hit all the right notes for this setting. This remains to be tested.

As outlined in disaster resistant git I recommend using pull requests on the quest to emulate trunk-based development.

This means that master is locked, changes are allowed only via pull request and there are merge checks that mandate a successfull build.

In the TeamCity context such a setup guarantees that no changes in the UI will be accepted. But it will generate a whole bunch of errors for anyone making changes.

It also makes it difficult to explore and experiment with options and see how they translate to DSL code. Doubly so, because not all options that change the settings offer a nice ‘View DSL’ button - for example adding NuGet Feeds


Basically I have a playground repository with a scaffolded gaudi that I can use to click things together. I think I already stumbled on a bug for a runner, so expect a post on community, support and bug reports.

I’ve already put a variant of the Configuration as Code, Part 3: Creating Build Configurations Dynamically to good use and it has opened some interesting questions, so that will be the next post.

blog comments powered by Disqus