Versioned Settings on a different Repo with submodules


We're looking at using Versioned Settings for our repositories, to allow hotfix branches to build using older build definitions. After trialling, we want to re-enable UI editing. Unfortunately, we use branch protections on the master branch, and we're not keen on giving the TC user admin rights on the repo to get around branch protections.


If I have the following config:

Repo A: Contains only .teamcity - TC versioned settings is configured to save to this repo
Repo B: Contains a submodule mapped to .teamcity that points at Repo A


What will TeamCity do when running a build where the submodules current commit is older than the most recent commit in Repo A? Will it happily accept the .teamcity folder in Repo B? or will it not see it and revert to its most recent config?

Comment actions Permalink

Alternatively, to avoid an XY problem, ultimately I want to let TC push its versioned settings into somewhere (a different repo, or a different branch in the same repo) without needing to either give it admin rights and/or removing branch protections. However, I also want to TC to be able to find the config that was relevant at the point the hotfix branched off from, and use that config to execute the build.

Comment actions Permalink

Hi Fergal,


Having the settings and the code in different repos is normal and should work just fine, connected via submodules or not. The feature is designed with the idea that the repository can be fully independent and not necessarily integrated into the main one, so keeping it separate to allow the server to only commit changes into a repo where only the settings are present should be perfectly fine. 


If you try to run an older revision, teamcity knows which version of the settings was used for the specific revision and will pull those specific settings back automatically, you shouldn't need to even have it as a submodule for teamcity to be able to handle it. Having it as a VCS Root will make teamcity already pull the changes regularly and adapt the configuration to the settings. Submodules can be used if desired for the users to be able to modify the settings on the fly, but again, they are not needed if the users should not have access to modify teamcity's settings.


To answer your initial question, as TeamCity tracks the VCS Roots, resolves the contents and picks up the changes, it updates the settings on the server. As mentioned, you can have it as a separate VCS Root, to use it into Versioned Settings so that the server can just commit into it fine, and the changes can update the settings as they come. The VCS Root does *not* need to be attached to the build configurations, simply reside in a project reachable from where the versioned settings are stored. If you keep it as a single VCS Root using submodules, TeamCity will commit to the directory which might make it a bit more complex than it really needs to be.


With some limitations, it's also possible to have branch specific settings, seeing that you mentioned committing to branches:

Comment actions Permalink

When you say it pulls the changes used for the revision, do you mean just for replay builds or builds from a tag right? It's not intelligent enough to know I branch off a specific tag and to use the build version that was relevant when that tag was created?

Comment actions Permalink

Hi Fergal,


sorry for the delay. You are right, I went on to write the information about how it worked, and by the end I was considering rerunning commits rather than running a new build on a new commit branched off of an older one. My apologies for that as well.


If git keeps track on a commit of which was the relevant commit on the submodule or you can force it to do so, then using submodules should be fine, as it would basically provide the same functionality. In this scenario, having them separate would be fine, although I'm not sure how mapping would work, given that you would need to map the submodule's ".teamcity" to the root folder, given that the submodule will itself contain ".teamcity" which is the folder on which the server will expect to find the settings. You will need to ensure that the root has the .teamcity subfolder with the settings, and that the versioned settings on the server are set to always use the settings from VCS, to ensure that the server loads them whenever you run older versions of the code.


If git is not set up to track that, then every commit would always point to the latest on the submodule, rendering this complex scenario useless.


The issue with the submodule approach is that because submodules are not updated under some circumstances, it might make working with those custom settings a more cumbersome scenario, but I have to say that I have not tested this myself, so you would need to test it on your end before going through with it.


Another possibility to work around your issue. You mentioned you use protections on master. If they are only on master, you could set the default branch (used for the settings) to be something else, as it does not need to be master, then have another branch where such protections are not necessary as the default branch for the project. Changing to this would be problematic, as modifying the default branch can lead to history loss of the commits on the root, but if you are modifying the workflow to adapt to versioned settings, this might make it a better option to do now and take the loss early so that you can have the history going forward.

Comment actions Permalink

Hi Denis,

Sorry it's taken me a while to respond: I was away from work for an extended period.


This morning, I've been investigating the idea that I configure the Versioned Settings to push to a different branch in the repo entirely, one without branch protections as you suggested. I would then (probably via automation) merge the change from this branch into my main branch via a PR.  Basically:

            TC Commits changes automatically
teamcity  -------------------------------------------------------
\ PR Opened and merged with .teamcity changes
master --------------------------------------------------------

I was hoping that TC would see the .teamcity folder in the master branch and use it over the latest settings in the TC branch, or at least the master folder would overwrite the VS .teamcity folder. However, this didn't happen:


[12:04:08][Collecting changes in 2 VCS roots] Compute revision for 'Versioned Settings Root'
[12:04:08][Compute revision for 'Versioned Settings Root'] Upper limit revision: f1459f8849ff313e9208e56b50ab015e7519c6d4
[12:04:08][Compute revision for 'Versioned Settings Root'] MaxModId = 250085
[12:04:08][Compute revision for 'Versioned Settings Root'] Latest commit attached to build configuration: f1459f8849ff313e9208e56b50ab015e7519c6d4
[12:04:08][Compute revision for 'Versioned Settings Root'] Computed revision: f1459f8849ff313e9208e56b50ab015e7519c6d4
[12:04:08][Collecting changes in 2 VCS roots] Compute revision for 'Default VCS Root'
[12:04:08][Compute revision for 'Default VCS Root'] Upper limit revision: ac49b35d792cc6443783ea5abf78267170230876
[12:04:08][Compute revision for 'Default VCS Root'] MaxModId = 250085
[12:04:08][Compute revision for 'Default VCS Root'] Latest commit attached to build configuration: ac49b35d792cc6443783ea5abf78267170230876
[12:04:08][Compute revision for 'Default VCS Root'] Computed revision: ac49b35d792cc6443783ea5abf78267170230876
[12:04:08]Finalize build settings
[12:04:08][Finalize build settings] Retrieve settings, revision: f1459f8849ff313e9208e56b50ab015e7519c6d4
[12:04:08][Retrieve settings, revision: f1459f8849ff313e9208e56b50ab015e7519c6d4] Settings VCS root details
[12:04:08][Retrieve settings, revision: f1459f8849ff313e9208e56b50ab015e7519c6d4] Load settings from VCS
[12:04:08][Retrieve settings, revision: f1459f8849ff313e9208e56b50ab015e7519c6d4] Load project model
[12:04:08][Finalize build settings] Read build settings from revision f1459f8849ff313e9208e56b50ab015e7519c6d4
[12:04:08][Read build settings from revision f1459f8849ff313e9208e56b50ab015e7519c6d4] Build settings from VCS were successfully loaded
Is something like this possible?
Comment actions Permalink



I'm not sure about what is going on with the info you provided. I think it should work, I don't know which commit is which on the revisions listed on the logs, so I cannot really tell what is going on in it. I can see that "Default" and "Versioned" use different revisions, but don't know which is which. It seems both are using the latest available. Is the versioned settings root attached to the build configuration?



Comment actions Permalink

Hi Denis,

Sorry, I should have clarified. "Versioned Settings Root" is indeed the root that is being used for VS. It points at an unprotected branch on the repo (not the default branch, it's actually an orphan branch in this example). "Default VCS Root" is used for the code, it points (primarily) at the default branch on the repo. 

I'd created an "allow-unrelated-histories" merge from the VS branch into the default branch. However, the build only appeared to use what was on the VS branch, it didn't pay any attention to the files sitting in the default root during the build. In retrospect, I should try this again with a branch that isn't an orphan, to see if that makes any difference.

It's also worth mentioning (because I don't think I have already), but we're running 2018.1.1 (build 58406) - in case that makes any difference to the functionality.


Please sign in to leave a comment.