Storing Project Settings in Version Control
TeamCity allows the two-way synchronization of the project settings with the version control repository. Supported VCSs are Git, Mercurial, Perforce, Subversion, and Azure DevOps Server (formerly TFS).
When you enable two-way settings' synchronization:
Each administrative change made to the project settings in the TeamCity web UI is committed to the version control; the changes are made noting the TeamCity user as the committer.
If the settings change is committed to the version control, the TeamCity server will detect the modifications and apply them to the project on the fly.
Before applying the newly checked-in settings, validation constraints are applied. If the constraints are not met (that is, the settings are invalid), the current settings are left intact and an error is shown in the UI. Invalid settings are those that cannot be loaded because of constraints, for instance, a build configuration referencing a non-existing VCS root, of having a duplicate ID or a duplicate name.
The versioned settings are stored in the
.teamcity directory in the root of the VCS repository, in the same format as in the TeamCity Data Directory.
Synchronizing Settings with VCS
By default, the synchronization of the project settings with the version control is disabled.
To enable it, go to Project Settings | Versioned Settings.
The "Enable/disable versioned settings" permission is required (default for the System Administrator role).
The Configuration tab is used to define
whether the synchronization settings are the same as in the parent project;
- whether the synchronization is enabled;
when synchronization is enabled, you can define which settings to use when the build starts. See details below.
which VCS root is used to store the project settings: you can store the settings either in the same repository as the source code, or in a dedicated VCS root.
Enabling synchronization for a project also enables it for all its subprojects with the default "Use settings from a parent project" option selected. TeamCity synchronizes all changes to the project settings (including modifications of build configurations, templates, VCS roots, and so on) except SSH keys.
However, if for certain subprojects the "Synchronization disabled" option is selected, such subprojects will not be synchronized even if this option is enabled for their parent project.
As soon as synchronization is enabled in a project, TeamCity will make an initial commit in the selected repository for the whole project tree (the project with all its subprojects) to store the current settings from the server. If the settings for the given project are found in the specified VCS root (the VCS root for the parent project settings or the user-selected VCS root), a warning will be displayed asking if TeamCity should
overwrite the settings in the VCS with the current project settings on the TeamCity server; or
import the settings from the VCS replacing the current project settings on the TeamCity server with those from version control.
Defining Settings to Apply to Builds
There are two possible sources of build settings: (1) the current settings on the TeamCity server, that is the latest settings' changes applied to the server (either made via the UI, or via a commit to the
.teamcity directory in the VCS root), and (2) the settings in the VCS on the revision selected for a build.
Therefore, it is possible to start builds with settings different from those currently defined in the build configuration. For projects with enabled versioned settings, you can instruct TeamCity which settings to take when build starts.
This gives multiple options:
If you are using TeamCity feature branches, you can define a branch specification when creating a project from URL (Git only) or in the VCS root used for versioned settings. TeamCity will run a build in a branch using the settings from this branch.
You can start a personal build with changes made in the
.teamcitydirectory, and these changes will affect the build behavior.
When running a history build, TeamCity will attempt to use the settings corresponding to the moment of the selected change. Otherwise, the current project settings will be used.
Before starting a build, TeamCity stores configuration for this build in build internal artifacts under the
.teamcity/settings directory. These configuration files can be examined later to understand what settings were actually used by the build.
To define which settings to take when build starts, open the Project Settings | Versioned Settings page, click Show advanced options, and select one of the following options:
always use current settings: all builds use current project settings from the TeamCity server. Settings' changes in branches, history, and personal builds are ignored. Users cannot run a build with custom project settings.
use current settings by default: a build uses the latest project settings from the TeamCity server. Users can run a build with older project settings via the custom build dialog.
- use settings from VCS: builds in branches and history builds, which use settings from VCS, load settings from the versioned settings' revision calculated for the build. Users can change configuration settings in personal builds from IDE or can run a build with project settings current on the TeamCity server via the custom build dialog.
- changes in the following settings will affect the build:
- changes in the following settings coming from a branch will be ignored and will not affect the build:
VCS roots and checkout rules
build configuration level options, like hanging builds detection, enabling/disabling of triggering of personal builds, or build configuration type
Storing Secure Settings
It is recommended to store security data outside the VCS. The Project Settings | Versioned Settings | Configuration page has an option to store passwords, API tokens, and other secure settings outside of VCS. By default, this option is enabled if versioned settings are enabled for a project for the first time, and disabled for projects already storing their settings in the VCS.
If this option is enabled, TeamCity stores a randomly generated IDs in XML configuration files instead of the scrambled passwords. Actual passwords are stored on the disk under the TeamCity Data Directory and are not checked into the version control system.
If you need to add a password (or other secure value) to the versioned settings not via the TeamCity UI (for example, via Kotlin DSL), you can generate a token to be used in the settings instead of this password.
In the Project Settings, select Generate token for a secure value in the Actions drop-down menu. Enter the password and click Generate Token. The generated token will be stored on the server. You can copy and use it in the project configuration files instead of the password.
You can also generate new secure tokens on the Tokens tab of the project Versioned Settings section. The tab is available for projects with the enabled "Store secure values outside of VCS" option.
The Tokens tab allows viewing all the project tokens, including unused tokens.
When secure data of a project is stored outside of the version control system, it could potentially be detached from the project: for example, if a project with tokens is moved to another place in the hierarchy or is created from DSL on the new TeamCity server. In such case, you can specify the values for the project tokens on this tab, so the project can continue using them.
Moreover, if the required tokens are available in other projects you are permitted to edit, TeamCity will automatically find them. You can copy the secure values used in any of these projects to your current project.
When there is one or more secure values available for a token, the button appears opposite this token. Click it to review available projects and choose a project to copy a value from, and then click Copy to confirm your choice.
Secure values can be inherited by project hierarchy. If a setting in a project (VCS root, OAuth connection, cloud profile) requires a password, the token generated for this password can be used in this project and in any of its subprojects. To be able to use the inherited password, the subproject must have versioned settings enabled and store settings in the same VCS, as its parent project.
Alternatively, you can add a password parameter with the secure value and use a reference to the parameter in the nested projects.
Implications of Storing Security Data in VCS
If you decide to store secure settings in VCS, it is recommended to carefully consider the following implications:
- If the projects or build configurations with settings in a VCS have password fields defined, the values appear in the settings committed into the VCS (though, in scrambled form).
If the project settings are stored in the same repository as the source code, anyone with access to the repository will be able to see these scrambled passwords.
If the project settings are stored separately from the source code in a dedicated repository and the "Show settings changes in builds" option is enabled, any user with the "View VCS file content" permission will be able to see all the changes in the TeamCity UI using the changes difference viewer.
Being able to change the settings in an arbitrary manner via a VCS, it is possible to trigger builds of any build configurations and obtain settings of any build configurations irrespective of the build configurations permissions configured in TeamCity.
By committing wrong or malicious settings, a user can affect the entire server performance or server presentation to other users.
It is recommended to store passwords, API tokens, and other secure settings outside of VCS using the corresponding option described above.
Note that SSH keys will not be stored in the VCS repository.
To be able to select the settings format, click Show advanced options in Project Settings | Versioned Settings | Configuration.
TeamCity stores project settings:
in the XML format
in the Kotlin-based DSL format (see a dedicated page)
Committing Current Project Settings to VCS
If you want to commit the current configuration to the VCS (for example, earlier you committed misconfigured settings to the repository and TeamCity was unable to load it displaying errors and warnings), you can use the Commit current project settings option on the Versioned Settings | Configuration page.
When TeamCity commits settings into a VCS, it uses the standard commit message noting the TeamCity user as the committer and the project whose settings have changed. It is possible to add a fixed custom prefix to each settings' change committed by TeamCity via the
teamcity.versionedSettings.commitMessagePrefix internal property, for example,
TeamCity will not only synchronize the settings, but will also automatically display changes to the project settings the same way it is done for regular changes in the version control. You can configure the changes to be displayed for the affected build configurations: on the Project Settings | Versioned Settings | Configuration tab, click Show advanced options and check the Show settings changes in builds box. This option is only effective if you store versioned settings in a VCS root that is not directly attached to the current build configuration. If a VCS root is attached to this configuration, its changes will be displayed by default, unless specific build triggering rules are configured.
If you store versioned settings in a separate VCS root, not the one which is directly attached to your build configurations, then when turned ON this checkbox starts showing changes made to these VCS roots. If VCS root is already attached to your configuration, then it does nothing.
By default, the VCS trigger will ignore such changes. To enable build triggering on a settings' commit, add a trigger rule in the following format:
All changes in the VCS root, where project settings are stored, are listed on the Versioned Settings | Change log tab.
Enabling Versioned Settings after TeamCity Upgrade
The format of the XML settings files changes from one TeamCity version to another to accommodate the new features and improvements. Generally, the format is not changed within bugfix releases and is changed in major releases. When a TeamCity server is upgraded, the current settings on the TeamCity server are changed from the earlier to the current format.
It is a common practice to upgrade a TeamCity test server with production data before upgrading the production server. In order to avoid accidentally changing the format of the settings which are used on a production server of an older version, versioned settings are disabled after a TeamCity upgrade and the corresponding health item is displayed. System administrators have permissions to enable versioned settings (Administration | Server Health | Versioned settings disabled, click Enable ). When enabled, the converted settings in the format of the current TeamCity version will be checked in the version control. Note that the new settings will be committed to the default branch of the VCS root; the settings stored in other branches will have to be updated manually.
Q. Can I apply the settings from a TeamCity server of a different version?
A. No, because just like with the TeamCity Data Directory, the format of the settings differs from one TeamCity version to another.
Q. Where are the settings stored?
A. The settings are stored in the
.teamcity directory in the root of the VCS root-configured repository path. For Git and Mercurial this is always the root of the repository. The default branch configured in the VCS root is used with Git and Mercurial. You can create a dedicated VCS root to change the branch (or a repository path in case of Perforce, Subversion, or Azure DevOps — formerly TFS).
Q. Why is there a delay before a build is run after I changed to the settings in the UI?
A. When the settings are changed via the UI, TeamCity waits for the changes to be completed with a commit to the VCS before running a build with the latest changes.
Q. Who are the changes authored by?
A. If the settings are changed via the user interface, in Git and Mercurial a commit in the VCS will be performed on behalf of the user who actually made the change via the UI. For Perforce as well as Azure DevOps Server (formerly TFS), the name of the user specified in the VCS root is used, and in Subversion the commit message will also contain the username of the TeamCity user who actually made the change via the UI.