ESPN DeportesKawhi Leonard: ¿Cómo será recordado cuando finalice su carrera?Daily MaverickTHE GATHERING 2026: Fixing failing cities is in business’s own interest, leaders sayESPN'Gonna let them do them': Cunningham ignoring Kanter Freedom, Whiteוואלהחיל האוויר בגל תקיפות נגד יעדי טרור בדרום לבנוןRTP DesportoPortugal perde com Espanha e falha meias da Liga Europeia de futebol de praiaInquirerBojie Dy hails Pisa improvement: ‘It’s a welcome news’BlickVon Pfäffikon ZH über Siders VS bis Susch GR: Das sind die schlimmsten Busunglücke der Schweiz20 Minuten«Wir sind ein gutes Team»: Annemarie Carpendale lobt ihren WayneAntara NewsIndian envoy: BRICS agenda aligns with Indonesia bilateral focusBillboardFlavor Flav Shares Personal 9/11 Memory & Honors ‘Heroes Who Ran Toward Danger’ on 25th AnniversaryGlobal News13-year-old charged after firearm seized at Ajax hotel: Durham policeComplete Sports2026 US Open Final: Rybakina, Sabalenka Target Grand Slam Title
The Daily Newsstand · Free, Always
Friday, September 11, 2026

Zero-конфиг в TeamCity как цель

Translate

Практические приёмы снижения копипасты и упрощения конфигурирования множества сходных проектов в TeamCity.

Статья о мышко-клацательном варианте конфигурирования TeamCity.

Большое число билд-конфигураций сложно поддерживать: проблематика та же, что описывается в принципе DRY программирования. Изначально одинаковое подвергается точечным изменениям, в итоге неочевидно, как конкретно работает каждая конфигурация в отдельности, и системное изменение проблематично произвести. Ниже приведу несколько простых приёмов, которые позволяют существенно снизить нагрузку на поддержку однотипных конфигураций.

Примеры будут про сборку C#-проектов, но специфика не особенно влияет на описываемые приёмы.

Встроенные переменные

Структура проекта и солюшна как правило предсказуема:

MySuperApp
    /src
        MySuperApp.csproj
    /test
        MySuperAppTests.csproj
    MySuperApp.sln

Если же структура от проекта к проекту у вас заметно различается, то предложил бы начать с этого — стандартизировать оформление исходников.

В примере видно, что имена директорий, проектных файлов либо совпадают с именем проекта, либо используют его как префикс со стандартным суффиксом. Если всё это хранится не в монорепе, то, скорее всего, и GIT-репозиторий называется так же. И компонент либо тег в таск-трекере. И конфиг в инструменте деплоя.

Если выделить это имя как переменную, то структура однотипных проектов, как и набор команд для работы с ними, окажутся идентичными и легко параметризуемыми. Достаточно и билд-конфигурацию в TeamCity назвать так же, как проект — «MySuperApp» в рассматриваемом примере.

TeamCity позволяет использовать автоматически наполняемые переменные сборки, чтобы получать информацию о ней. Так можно получить имя конфига:

PROJECT_KEY = %env.TEAMCITY_BUILDCONF_NAME%

а через этот параметр можно определить другие пользовательские параметры, например:

SOLUTION_NAME      = %PROJECT_KEY%.sln
TEST_PROJ          = %PROJECT_KEY%Tests.csproj
APP_BINARY_FILE    = %PROJECT_KEY%.exe
OCTOPUS_DEPLOY_CFG = %PROJECT_KEY%
SRC_REPO           = %GIT_STORAGE_URL%/%TEAM_SPACE%/%PROJECT_KEY%

соответственно, и команды в шагах сборки можно будет переписать с ad-hoc копипастовых dotnet build MySuperApp.sln на универсальное dotnet build %SOLUTION_NAME%.

Другие полезные и часто используемые переменные:

teamcity.build.checkoutDir       - куда тимсити клонировал исходники
teamcity.build.branch            - клонированная ветка VCS (GIT)
teamcity.build.branch.is_default - главная ли ветка собирается
teamcity.build.step.name         - имя данного шага конфига
system.teamcity.build.tempDir    - временная папка под конкретный билд

Временная папка полезна тем, что checkoutDir всё же задумана как кешируемая, поэтому одноразовые вещи туда лучше не складывать; времянка живёт ровно до завершения конкретного билда. Расположения разных папок важно знать, если придётся куда-то передавать полный путь к файлам.

Комбинируя такие параметры, можно налету, а не в процессе конфигурирования сборки, много чего узнавать о текущем проекте, окружении, обстоятельствах сборки. Системные параметры лучше предварительно заворачивать в свои и затем уже свои параметры рассовывать по шагам и в конкретные команды — так проще централизованно добавить суффикс или вроде того.

Параметризация

Задавать параметры конфигурации можно на нескольких уровнях:

ROOT
    /PROJECT
        ( /TEMPLATE )
            /BUILD_CONFIG

с каждого верхнего уровня параметры наследуются, проваливаются вниз. Таким образом, в конкретном билд-конфиге доступны параметры уровня группы конфигов (проекта тимсити) и общие для инстанса.

Очевидно, что для множества, если не всех проектов команды используется один и тот же таск-трекер, VCS и много чего ещё. Такие параметры уместнее задавать не в каждой конфигурации сборки, а, очевидно, на уровне сервера. Приём примитивный, тем не менее сильно упрощает ситуацию с копипастой.

На уровне «проекта» можно задать общие для конфигов параметры, обусловленные тем же принципом, по которому конфиги оказались объединены в одну группу. Здесь же можно переопределить ROOT-параметры, и это переопределение провалится вниз до конфигов.

Некоторые проекты кажутся невероятно уникальными, поскольку в них не должен выполняться некий шаг или, наоборот, в определённых обстоятельствах нужно совершить дополнительное действие. Условное выполнение вполне предусмотрено в TeamCity, вот простейший пример:

условия для запуска или игнорирования шага

условия для запуска или игнорирования шага

в эти условия можно вставлять и свои кастомные параметры.

Напомню, что значения параметров можно переопределять налету с помощью служебных текстовых команд, отправляемых в консоль:

##teamcity[setParameter name='env.MY_VAR' value='hello-world']

так, можно на предварительном «look around» этапе понять, что за проект, каковы обстоятельства сборки, при необходимости дописать что-то в пользовательские параметры, от которых зависит включение либо выключение шагов, и так получится конфигом управлять налету. Это снова расширяет взгляд на возможности стандартизации подхода к сборке множества проектов.

Шаблоны

Кусочки конфигов с несколькими шагами про одно и то же имеют больше шансов на переиспользование, чем весь конфиг целиком. Развивать, дорабатывать и устранять проблемы проще тоже в конкретном компоненте с ограниченной областью ответственности, чем конфиг на 100500 шагов. И TeamCity предоставляет такой инструмент — шаблоны (templates).

Шаги, составляющие по смыслу одно целое, имеет смысл выделять в шаблон. А для конечных конфигов применять уже «крупноблочную сборку» из нескольких шаблонов:

конфигурация из пяти шаблонов

конфигурация из пяти шаблонов

На скриншоте приведён пример конфига на 42 шага, причём кастомных шагов в нём нет совсем, все унаследованы из шаблонов.

При добавлении шаблона в конфиг, все шаги и параметры наследуются кофигом. Шаги при этом управляются как единый блок: если в примере на скриншоте передвинуть любой шаблон выше или ниже, то все его шаги встанут, соответственно, выше или ниже шагов шаблона, который он сместил. Если внести изменения в шаги или параметры на уровне шаблона, то эти изменения «провалятся» в каждый конфиг, использующий этот шаблон.

Контроль

В реальности обстоятельства вынуждают заниматься отладкой, устранением сбоев, поиском решений нестандартных задач. Так возникают вре́менные и не очень отключения шагов, оверрайды команд и параметров, кастомные ad-hoc шаги. Вре́менное всё же должно таким и оставаться, а конфигурирование сборок — стремиться к стандартизации.

Для обнаружения де-факто возникших аномалий можно использовать REST API TeamCity.

Схема взаимодействия такая:

  • получить список проектов;

  • в каждом проекте получить список конфигов;

  • для каждого конфига запросить его XML-определение;

  • в каждом конфиге осмотреть шаги, триггеры, фичи (*), VCS.

Аномалией (или ad-hoc вмешательством) является всё что не имеет признака inherited либо он выставлен в false, всё что имеет признак disabled = true. Если шаг задизаблен в шаблоне, то он в наследующих конфигах не отобразится и в XML не попадёт.

Пример запроса для получения определения конфига:

GET /app/rest/buildTypes/id:MySuperApp

Зашедулили в том же TeamCity, направили на почту — своевременно отреагировали, вернули в стойло.

* - фичи в терминах TeamCity, например, Commit status publisher

Итого

Простые практики позволяют заметно упростить и систематизировать управление билд-конфигами в TeamCity:

  • стандартизовать оформления исходников, проектов, конфигов;

  • использовать встроенные переменные тимсити;

  • размещать кастомные параметры на подоходящем уровне;

  • применять тотальную шаблонизацию;

  • отлавливать аномалии.

Так, вполне можно приблизиться к нулевому конфигурированию проектов: скопировали существующий конфиг, переименовали — готово. Да, это всё ещё копия, но абсолютно лишённая кастомизации, и при внесении изменений в шаблоны, параметры уровня сервера, она эти изменения унаследует. Собственно, к чему и стремились.

Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.