PHASE 4 OF 15

Build Configurations & Build Steps

The anatomy of a build configuration, all runner types, step execution policies, failure conditions, artifact paths, build number formats, and a hands-on multi-step Maven exercise

Build ConfigMavenGradleRunnersArtifacts
1

Build Configuration Anatomy

A build configuration (analogous to a Jenkins Job) is the central entity in TeamCity. It ties together: source code (VCS Root), what to do (Build Steps), when to do it (Triggers), success criteria (Failure Conditions), and what to save (Artifact Paths).

SectionWhat it controlsCovered in
General SettingsBuild config name, ID, description, artifact paths, build number format, build counterThis phase
Version Control SettingsWhich VCS Root to use, checkout mode, label buildsPhase 5
Build StepsOrdered list of runners to executeThis phase
TriggersWhat causes a build to start automaticallyPhase 7
Failure ConditionsWhat counts as a failed build beyond non-zero exit codeThis phase
Build FeaturesAdd-ons: coverage, PR support, commit status, etc.Phase 10
DependenciesSnapshot and artifact dependencies on other buildsPhase 9
ParametersConfig-level parameters overriding project-level onesPhase 8
Agent RequirementsWhich agents are compatible with this buildPhase 6
2

Runner Types Overview

A runner is the type of work a build step performs. TeamCity ships with these built-in runners:

Maven
Java projects using Apache Maven
Parses test reports, incremental builds, Maven versions plugin
Gradle
Java/Kotlin/Android projects using Gradle
Supports Gradle wrapper, init scripts, build scan integration
MSBuild
.NET projects (Visual Studio solutions)
Target, platform, configuration, toolsVersion
.NET CLI
.NET Core / .NET 5+ projects
dotnet build/test/publish, project/solution file
Command Line
Any shell command or script
Executable path or script content; most flexible runner
PowerShell
Windows PowerShell / PowerShell Core scripts
Edition (Desktop/Core), version, script content or file
Ant
Legacy Java projects using Apache Ant
Build file, targets, JVM options
IntelliJ IDEA Project
Run IntelliJ inspections and code analysis
Requires IntelliJ IDEA on agent
Rake
Ruby projects using Rake
Rakefile path, tasks, bundler support
NAnt
.NET build automation with NAnt
Build file, targets, NAnt home
FTP Upload
Upload files to FTP server
Host, credentials, source/target paths
SSH Exec
Execute command on remote host via SSH
Host, port, credentials, command
3

Maven Runner

Key fields
FieldExampleNotes
Maven home%teamcity.tool.maven.DEFAULT%Use TeamCity-managed Maven tool or absolute path on agent
Goalsclean package -DskipTestsSpace-separated Maven goals and flags
Path to POM filepom.xmlRelative to checkout dir; leave blank for root pom.xml
JVM options-Xmx512m -Djava.awt.headless=trueMaven process JVM, not your app's JVM
Working directoryCheckout directoryLeave blank to use the VCS checkout root
User settings path%system.maven.settings.file%Custom settings.xml — use a parameter for portability
Incremental buildingEnabled / DisabledWhen enabled, TeamCity only rebuilds modules with changes
GOTCHA — Maven version on agent

If you set Maven Home to an absolute path (/usr/share/maven), the build will fail on any agent that doesn't have Maven at that exact path. Use %teamcity.tool.maven.DEFAULT% or define a TeamCity tool (Administration → Tools) and reference it as %teamcity.tool.maven.3.6.3%. This makes the agent requirement explicit and portable.

Maven test reports

TeamCity automatically imports Surefire/Failsafe XML reports when using the Maven runner. No extra configuration needed. Test results appear in the Tests tab of the build. Failed tests are highlighted and show stack traces inline.

4

Gradle Runner

FieldExampleNotes
Gradle tasksclean buildSpace-separated tasks
Gradle homeLeave blank (use wrapper)Leave blank to use gradlew in source; explicit path otherwise
Build filebuild.gradleLeave blank for default; specify for non-standard locations
Gradle options--parallel --continueGradle command-line options
JVM options-Xmx1gGradle daemon JVM options
Init script pathtc-init.gradleInject TeamCity-specific init script (e.g., for test reporting)
GRADLE WRAPPER — always use it

Leave Gradle home blank and check Use Gradle wrapper to run ./gradlew. This pins the Gradle version per project and avoids agent-level Gradle installation. The Gradle wrapper is the industry standard for reproducible builds.

5

Command Line Runner

The most flexible runner — runs any executable or script. Two modes:

Executable with parameters
Executable: /usr/bin/python3
Parameters: scripts/deploy.py --env staging --version %build.number%
Custom script (inline)
#!/bin/bash
set -euo pipefail

echo "Build number: %build.number%"
echo "Branch: %teamcity.build.branch%"

# Run tests
npm install
npm test

# Package
npm run build
tar -czf dist-%build.number%.tar.gz dist/
GOTCHA — set -e is critical

By default, bash scripts continue after a failing command. Without set -e (or set -euo pipefail for stricter checking), your build step may show green even when an important command failed. Always include set -euo pipefail at the top of shell scripts in CI.

6

PowerShell Runner

FieldValuesNotes
PowerShell editionDesktop / CoreDesktop = Windows PowerShell 5.x; Core = PowerShell 6+/7+
Min required version5.0Agent must have at least this version; enforces agent requirement
Script execution modeScript file / Script sourceScript source: inline PowerShell in TeamCity; Script file: path in repo
Script arguments-Env Staging -Version %build.number%Passed to script as named parameters
Format stderr asError / WarningTreat stderr output as error (fails build) or warning
# Example inline PowerShell step
param([string]$Env = "staging", [string]$Version = "0.0.0")

Write-Host "Deploying version $Version to $Env"
$ErrorActionPreference = "Stop"

# Run .NET build
dotnet build --configuration Release /p:Version=$Version

# Run tests
dotnet test --no-build --logger trx --results-directory TestResults

Write-Host "Build complete"
7

Step Execution Policy

Each build step has an Execute step setting that controls when it runs:

PolicyWhen step runsUse case
Only if build status is successfulPrevious step must have succeededDefault — compile then test only if compile passes
If all previous steps finished successfullySame as above but checks all previous, not just lastChain of steps where any failure stops the chain
Even if some of the previous steps failedAlways runs unless build was explicitly cancelledCleanup steps, notification steps, "always publish" reports
Always, even if build stop command was issuedRuns even during cancellationCritical cleanup that must always run
PATTERN — Publish reports even on failure

Set your test report publication step to Even if some of the previous steps failed. This ensures test XML files are uploaded even when tests fail — which is exactly when you need them most. Without this, a compilation failure causes all subsequent steps to be skipped, leaving you with no test output to diagnose.

8

Failure Conditions

Beyond a non-zero exit code, TeamCity can fail a build based on additional conditions:

ConditionDescriptionExample
Non-zero exit codeDefault. Any step exits non-zero → build failsAlways active
At least one test failedParses imported test results; fails build if any test redJava unit tests with Surefire
Metric changeFails if a build metric exceeds a threshold relative to previous buildFail if code coverage drops by more than 5%
Build log contains textRegex match against build log; fails if foundFail if log contains "ERROR:" or "BUILD FAILURE"
Build log not contains textFail if expected text is absentFail if "Tests run:" is not in log (test phase was skipped)

Go to Build Configuration → Failure Conditions → Add failure condition to add conditions beyond the default.

9

Artifact Paths

Artifact paths tell TeamCity which files to publish after a build. Defined in General Settings → Artifact paths. Uses Ant-style patterns.

# Syntax: source_path [=> target_path]
# source_path: relative to checkout directory or working dir

# Publish a JAR
target/myapp-*.jar

# Publish to a named subdirectory in artifacts
target/myapp-*.jar => libs

# Publish test reports
target/surefire-reports/**/* => test-reports

# Publish entire dist directory
dist/** => release

# Publish multiple patterns (one per line)
target/myapp.jar
target/surefire-reports/**/*
*.log => build-logs
GOTCHA — Artifact paths are not build steps

Artifact paths are published after all build steps complete. They are not a step themselves. If a step fails partway through, artifacts may still be published from files that were produced before the failure. Use failure conditions + step execution policies to control when artifacts should or should not be published.

Accessing artifacts in the UI

After a build completes, go to the build's Artifacts tab to download files. Artifacts are also directly accessible via URL:

http://SERVER:8111/repository/download/BuildConfigId/.lastSuccessful/path/to/file.jar
10

Build Number Format

The build number is the human-readable identifier for a build. Configured in General Settings → Build number format.

TokenExpands toExample result
{build.counter}Auto-incrementing counter (starts at 1)42
%build.vcs.number%VCS revision (Git short SHA)a3f2c91
%teamcity.build.branch%Branch namefeature/login
Any literal textLiteral text1.2.
# Common build number patterns:

# Simple counter
{build.counter}
# Result: 42

# SemVer with counter
1.2.{build.counter}
# Result: 1.2.42

# Counter + Git SHA
{build.counter}.%build.vcs.number%
# Result: 42.a3f2c91

# Branch + counter (useful for feature branch builds)
%teamcity.build.branch%.{build.counter}
# Result: feature/login.5
BUILD COUNTER

The build counter increments with every new build in that build configuration, regardless of success or failure. You can reset it manually from Administration → Build Configuration → Edit → General Settings → Build counter — useful when starting a new major version.

11

Clean Checkout Policy

Controls whether TeamCity wipes the agent's working directory before checking out source code.

SettingBehaviourWhen to use
Use default (agent settings)Clean if agent requests it or on first buildDefault — works for most cases
Always clean files before buildDeletes entire working dir on every buildWhen stale files can cause build failures (e.g., generated code)
Do not clean files before buildNever wipes; incremental checkout onlyWhen checkout time is slow; accept risk of stale files
GOTCHA — Incremental checkout + generated files

If your build generates files (code gen, JAXB, protobuf) and a new build doesn't regenerate them (e.g., the schema didn't change), stale generated files from a previous run may be used. This causes hard-to-reproduce failures that only appear on agents. Use "Always clean" for builds with code generation.

12

Hands-On: Multi-Step Maven Build

Create a build configuration that compiles, tests, packages, and publishes a Java project artifact.

Exercise: Complete Maven CI Pipeline

  1. Create a project in TeamCity linked to a GitHub Java/Maven repo.
  2. Add a VCS Root pointing to your repository (detailed in Phase 5).
  3. In the build configuration, add three build steps:

Step 1 — Compile & Test

Runner: Maven
Goals: clean verify
Maven home: %teamcity.tool.maven.DEFAULT%
JVM options: -Xmx512m

Step 2 — Package (always runs)

Runner: Maven
Goals: package -DskipTests
Execute: Even if some previous steps failed
JVM options: -Xmx512m

Step 3 — Print build info (Command Line)

Runner: Command Line
Script:
  echo "Build: %build.number%"
  echo "Branch: %teamcity.build.branch%"
  echo "Agent: %teamcity.agent.name%"
  ls -la target/*.jar 2>/dev/null || echo "No JAR produced"
Execute: Even if some previous steps failed

Artifact paths:

target/*.jar => artifacts
target/surefire-reports/**/* => test-reports

Failure conditions — add:

  • At least one test failed → fail build
  • Build log contains ERROR → fail with warning

Up Next — Phase 5: VCS Roots & GitHub Integration

Set up your GitHub VCS Root, configure branch specifications, publish commit statuses back to GitHub, build pull requests, and set up webhooks for instant build triggering.

Continue to Phase 5 → Back to Hub