PHASE 9 OF 15

Dependencies & Build Chains

Snapshot dependencies, artifact dependencies, build chain visualization, composite builds, passing parameters across chains — and a complete Build → Test → Package → Deploy pipeline

Build ChainsSnapshot DepsArtifact DepsComposite Builds
1

Snapshot Dependencies

A snapshot dependency enforces that two build configurations use the exact same source code revision. When Build B has a snapshot dependency on Build A, TeamCity guarantees:

  • Build A runs first; Build B only starts after A completes
  • Both builds check out the same commit SHA
  • If Build A fails, Build B is not triggered
// Without snapshot dep — risk of deploying a different revision than what was tested: Build checks out commit A Deploy checks out commit B (new commit arrived!) ← DANGEROUS // With snapshot dep — guaranteed same revision: Build checks out commit A → passes Deploy checks out commit A (same snapshot) ← SAFE
Adding a snapshot dependency
  1. Open the downstream build configuration (e.g., Deploy).
  2. Go to Dependencies → Add new snapshot dependency.
  3. Select the upstream build config (e.g., Build).
  4. Configure options (see table below).
  5. Save.
OptionWhat it doesRecommended
Do not run new build if suitable one existsReuses an existing passing build of the upstream config — avoids redundant rebuilds✅ Yes for most cases
Run new build even if there is a suitable oneAlways triggers a fresh build of upstreamOnly for guaranteed-fresh builds
Only use successful builds from suitable onesSkips failed upstream builds when looking for a "suitable" build to reuse✅ Yes
Run on the same agentForces the downstream to run on the same agent as the upstreamOnly needed if builds share a non-exported filesystem state
2

Snapshot Dependency Options In Depth

"Suitable build" matching

TeamCity searches for an existing build of the upstream config that used the same VCS revision. If found and successful, it reuses it (skips re-running). This is the key to efficient build chains — a commit that already passed the Build stage won't rebuild it just because Deploy was triggered again.

Clean checkout on dependency

If "Clean sources" is enabled on the downstream config, its checkout is wiped even though the snapshot ensures the same revision. This is correct behaviour — the clean checkout is about the working directory state, not the revision.

GOTCHA — Snapshot deps require same VCS Root

For the "suitable build" matching to work, both build configurations must use the same VCS Root (or at least a VCS Root pointing to the same repository URL). If Build and Deploy use different VCS Root objects (even pointing to the same repo), TeamCity cannot match revisions and will always run a fresh upstream build.

3

Artifact Dependencies

An artifact dependency copies files published by one build configuration into the working directory of another, before the build starts. It does not enforce build ordering — it just copies files. Combine with a snapshot dependency for ordered artifact passing.

Adding an artifact dependency
  1. Open the consuming build config (Deploy).
  2. Go to Dependencies → Add new artifact dependency.
  3. Select the producing build config (Build).
  4. Set artifact path pattern and target path.
# Artifact path examples (relative to producing build's artifact root):

# Copy a specific JAR into current dir
artifacts/myapp-*.jar

# Copy all files from a published directory
release/** => downloaded-release

# Copy specific files to a named directory
target/myapp.jar => libs
target/config.properties => config

# Pattern syntax:
# source-pattern           => target-dir (optional)
# source-pattern supports: *, **, ?
# target-dir: where to place files in downstream working dir
Artifact dependency build selection
OptionWhich upstream build's artifacts to use
Build from the same chainUse artifacts from the specific upstream build in the current chain. Most common — guarantees same revision.
Last successful buildUse the most recent passing build, regardless of chain. Useful for cross-project dependencies.
Last pinned buildUse the most recent build with a pin (manually marked as important).
Build with specific numberFixed build number — for pinned release builds.
Last finished buildMost recent build regardless of status — rarely useful.
4

Build Chain Visualization

TeamCity automatically generates a visual build chain diagram. To view it: click any build in the chain → Dependencies tab → Build chain view.

// Example 4-stage CI/CD pipeline (visual representation) Compile ✓ #42 └──▶ Unit Tests ✓ #42 └──▶ Integration Tests ✓ #42 └──▶ Package & Publish ✓ #42 ├──▶ Deploy Staging ✓ #42 └──▶ Deploy Prod (manual trigger) // All #42 = same source revision, guaranteed by snapshot deps

The chain view shows the status (green/red/running) of each build in the chain, the build number, start time, and duration. Failed builds are immediately visible — you can click to jump to the log.

5

Composite Build Configurations

A composite build configuration aggregates results from multiple builds into a single "pass/fail" result. It has no build steps of its own — it simply waits for all its snapshot dependencies to complete and reports a combined status.

Use cases:

  • Parallel test shards: Run 5 test configurations in parallel; the composite passes only when all 5 pass.
  • Multi-platform builds: Build on Linux, Windows, macOS simultaneously; composite aggregates results.
  • Branch gate: Set a GitHub branch protection rule requiring the composite build to pass — one check covers the whole pipeline.
Creating a composite build
  1. Create a new build configuration.
  2. In General Settings → Build configuration type, select Composite.
  3. Add snapshot dependencies on the builds you want to aggregate.
  4. No build steps needed — the composite has no agent requirements and no build steps.
  5. The Commit Status Publisher on the composite will report the aggregated status to GitHub.
// Composite for parallel test shards Build ├──▶ Tests-Shard-1 ├──▶ Tests-Shard-2 ├──▶ Tests-Shard-3 └──▶ Tests-Shard-4 all 4 ──▶ All-Tests (Composite) ──▶ Deploy (after all-tests passes)
6

Running on the Same Agent

When enabled on a snapshot dependency, TeamCity ensures the downstream build runs on the same agent as the upstream build. This is needed when:

  • Builds share a local filesystem cache (e.g., Docker layer cache between build and test)
  • Builds use a hardware device or license locked to one machine
  • The build produces files to a local path that the next step needs (avoid this with artifact publishing instead)
GOTCHA — Same-agent creates queue bottleneck

If you require same-agent for a 4-step chain, all 4 steps are tied to one agent. If that agent is busy, the entire chain queues — even if other agents are idle. Only use same-agent when genuinely necessary. Prefer artifact publishing for passing files between builds.

7

Clean Checkout with Dependencies

Clean checkout on a downstream config wipes its working directory. This is independent of the snapshot dependency — the same revision is checked out fresh. Be aware that artifact dependencies run AFTER clean checkout — the downloaded artifacts won't be deleted by clean checkout.

# Execution order within a downstream build:
# 1. Clean checkout (if enabled) — wipes working dir
# 2. VCS checkout — checks out the snapshot-matched revision
# 3. Artifact dependencies downloaded — files placed in working dir
# 4. Build steps run

# So artifact dependencies survive clean checkout — ✅ correct behaviour
8

dep.* Parameters Across the Chain

Downstream builds can read any parameter from an upstream build using the dep. prefix (see Phase 8). This includes predefined parameters like the build number:

# In Deploy build config (which has snapshot dep on Build):
# Read Build's build number:
dep.ProjectId_BuildConfigId.build.number

# Example with a real config ID:
# Project: BackendServices, Config: Build → ID: BackendServices_Build
dep.BackendServices_Build.build.number

# In a deploy step:
echo "Deploying artifact version: %dep.BackendServices_Build.build.number%"
kubectl set image deployment/myapp myapp=registry/myapp:%dep.BackendServices_Build.build.number%
9

Complete CI/CD Pipeline: Build → Test → Package → Deploy

// Build configuration structure for a Java microservice 1. Compile // Maven: clean compile └── snapshot dep 2. Unit Tests // Maven: test; publishes surefire XML └── snapshot dep 3. Integration Tests // Maven: verify -P integration; separate config └── snapshot dep (on Compile, not Unit Tests) 4. Package // Maven: package -DskipTests; artifact: target/*.jar └── snapshot dep on Compile └── artifact dep on Unit Tests (test report) └── artifact dep on Integration Tests (report) 5. Deploy Staging // SSH deploy script └── snapshot dep on Package └── artifact dep on Package: target/*.jar 6. Deploy Prod // Same as staging but manual trigger + prompt param └── snapshot dep on Deploy Staging └── artifact dep on Package: target/*.jar
Key design decisions
  • Compile is separate: Unit Tests and Integration Tests both depend on Compile, so they can run in parallel — neither waits for the other.
  • Package depends on Compile only: This enables parallel test runs. Package uses a "suitable build" — if Compile already passed, it doesn't rerun.
  • Deploy Prod requires Deploy Staging to pass: Prevents direct prod deploys. Snapshot dep on Staging = same revision all the way through.
  • Prod has prompt parameter: A developer must manually confirm before prod deploy runs.

Up Next — Phase 10: Build Features

Add build features to your configurations — Commit Status Publisher, Pull Request support, code coverage, file content replacer, Docker support, SSH Agent, and more.

Continue to Phase 10 → Back to Hub