CI/CD 1С в Azure DevOps: Azure Pipelines, YAML и self-hosted агенты
Разработка - DevOps и автоматизация разработки
Azure Pipelines в связке с Azure DevOps даёт для 1С:Предприятие 8.3 полноценный CI/CD без отдельного сервера сборки «только под 1С»: pipeline описываем в YAML, job выполняем на self-hosted агентах с установленной платформой, на выходе получаем.cf и.dt с понятным версионированием. Дальше разберём, как уложить vrunner, пакетный Конфигуратор и ibcmd в модель stages, templates и variable groups, к которой привыкла команда на стеке Microsoft.
Зачем Azure DevOps, если в компании уже живёт 1С
Если рядом с 1С уже крутятся репозитории, work items и релеасе-процессы в Azure DevOps, второй CI только под конфигурацию редко окупается: отдельные агенты, отдельные секреты, отдельные люди, которые помнят другой синтаксис. Частый запрос от ведущего разработчика звучит проще: «соберите нам.cf по push в develop», а смотреть он всё равно каждый день в Azure Repos.
Azure DevOps доступен как облачный SaaS и как Azure DevOps Server в своей инфраструктуре. Для 1С это снимает спор о том, где хостить DevOps: pipeline можно держать рядом с AD и файловыми шарами кластера, не вынося строки подключения ИБ в публичный SaaS, если политика безопасности так требует. Ограничение другое: сборка 1С почти всегда Windows и self-hosted агент; Microsoft-hosted агент не заменит установленную платформу 8.3.
Один стек не отменяет специфику 1С: блокировки сеансов, разрядность платформы, хранилище конфигурации, неинтерактивный вход. Задача материала - показать, куда это ложится в YAML, а не убеждать отказаться от Конфигуратора.
Если прав администратора Azure DevOps нет, попросите у ДевОрс-инженера personal access token со scope на чтение и запись pipeline, доступ к agent pool «1C-Build», variable group без права редактирования секретов. С YAML в репозитории изменения можно предлагать через pull запрос, а секреты останутся в library.
Из чего состоит Azure DevOps и что реально нужно pipeline 1С
Azure Boards, Azure Repos, Azure Pipelines, Azure Test Plans и Azure Artifacts - один продуктовый контур. Для CI/CD 1С на практике задействованы Repos (исходники), Pipelines (YAML и запуск), Artifacts или pipeline artifacts (передача.cf между stage), Test Plans - по желанию, если гоняете Vanessa-ADD или xUnit и смотрите отчёты во вкладке Tests.

Контекст: Из чего состоит Azure DevOps и что реально нужно pipeline 1С
До первого commit в pipelines я обычно набрасываю дерево каталогов: так видно, куда класть templates и где path trigger отрежет лишнее.
Схема 3. Дерево репозитория: src, pipelines и каталог артефактов сборки

После согласования структуры path trigger на docs/ перестаёт поднимать полную пересборку на каждую правку пользовательской инструкции.
Boards в сборку не лезет, зато на work item удобно повесить ссылку на run pipeline и build number - меньше переписки «какой.cf отдали на препрод».
Расширяемость идёт через Marketplace: там порядка 2600 расширений, из них свыше 1700 для Azure Pipelines. Часть добавляет готовые tasks (SonarQube, Key Vault secrets). Для 1С одной галочки в UI обычно мало: основная работа - script steps с PowerShell или batch и vanessa-runner. Расширения подключайте точечно, когда task уже закрывает шаг (публикация тестов, загрузка секретов), а не когда вокруг него планируется вся линия.
Azure Artifacts подходит, если.cf и.cfe нужно хранить как версионированные пакеты с retention. Pipeline artifacts проще для сценария «собрали на stage Build, скачали на stage Test на другом агенте». Оба варианта совместимы с именем файла вида Config_$(Build.BuildNumber).cf.
YAML pipeline: синтаксис, препроцессор и logging commands
Pipeline в Azure DevOps - это YAML плюс встроенный препроцессор на этапе компиляции. Отсюда путаница у тех, кто привык к «чистому» YAML: часть конструкций срабатывает до старта агента, часть только на агенте.

Контекст: YAML pipeline: синтаксис, препроцессор и logging commands
Три семейства подстановок, которые я держу в шпаргалке:
{{ }}- compile time препроцессор:${{ if eq(parameters.runTests, true) }}:, циклы${{ each cfg in parameters.configurations }}, вложенные куски YAML.[ ]- runtime expressions в conditions и некоторых полях:condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop')).$( )- макросы переменных на агенте:$(Build.SourcesDirectory), пользовательские$(PlatformPath)после объявления в variables.
Logging commands - строки вида ##vso[task.setvariable variable=CfPath]$(Build.ArtifactStagingDirectory)\out.cf, которые Azure Pipelines перехватывает из stdout и stderr скрипта. Через них удобно пробросить путь к собранному.cf из PowerShell в следующий step без записи во временный файл (хотя файл тоже рабочий вариант).
На Wиндоwс-агенте для 1С я оставляю PowerShell для vrunner и batch только там, где проще дернуть 1cv8.exe с классическими параметрами. Bash на Линух-агенте для полной сборки конфигурации не поможет, если только не контейнер с Wine - для production CI это обычно лишнее.
Stages, jobs, agents: инфраструктура сборки 1С
Иерархия такая: pipeline, stages, jobs, steps и tasks. Stage Build собирает.cf, Test разворачивает копию ИБ, Deploy кладёт артефакт на стенд или в сетевую папку релизов. Между stage работают dependsOn, condition и artifacts.

Контекст: Stages, jobs, agents: инфраструктура сборки 1С
Перед тонкой настройкой шагов я проверяю, что.cf доезжает до Test без ручного копирования: иначе отладка превращается в переписку в чате.
Схема 2. Публикация и загрузка pipeline artifact между stage Build и Test

На рисунке выше - publish и download pipeline artifact: build отдаёт cf-package, job тестов забирает тот же run по имени.
Агенты сидят в pools. Для 1С заводите отдельный pool, например «1C-Windows», и demands: метка 1c.platform.8.3.24, иногда Agent.OS -equals Windows_NT. Так job не попадёт на агент без нужной версии платформы.
Требования к self-hosted Wиндоwс-агенту, без которых сборка срывается в первые минуты:
- Установленная платформа 1С той же мажорной и минорной ветки, что и на сервере ИБ; разрядность x64 или x86 совпадает с ragent и рабочим каталогом.
- OneScript и vanessa-runner в PATH или фиксированном каталоге на диске агента.
- Служебный пользователь Windows, под которым бежит агент: права на каталог временных ИБ, сетевые пути хранилища, без интерактивного входа.
- Учётная запись 1С с правами на конфигурацию и администрирование для тестовой базы; пароль только из variable group.
- При серверной ИБ - доступ агента к серверу 1С и корректная строка подключения; для файловой - UNC или локальный путь, который виден службе агента.
Triggers настраивайте осмысленно: trigger по веткам develop и release/* и paths include src/**, exclude **/*.md, чтобы правки README не гоняли vrunner полчаса.
Шаблоны и параметры: переиспользование сценариев
Один azure-pipelines.yml в корне редко живёт долго: повторяющиеся куски выносят в templates/build-1c.yml, templates/test-xunit.yml. В корне остаются parameters, resources и список stages.

Контекст: Шаблоны и параметры: переиспользование сценариев
Parameters бывают string, boolean, объект и stepList (фрагмент YAML steps). stepList удобен, когда разным продуктам нужен один template, но разный набор post-steps.
Пример с vrunner: параметр vrunnerConfig - объект со списком конфигураций и сред; препроцессор генерирует matrix strategy или несколько job через ${{ each }}. На compile time вы решаете, сколько job появится в run; на runtime каждый job читает свои переменные.
Вложенные templates: корневой файл вызывает - template: templates/stage-build.yml, внутри - - template: steps-vrunner-compile.yml. Variables пробрасывают через parameters и пары name/value в template scope.
Resources подключают другие репозитории (общий repo с json для vrunner) или pipeline как upstream trigger. Для монорепо 1С чаще хватает одного Azure Repos и path filters. Triggers и dependsOn задают порядок stage; conditions на уровне job отключают deploy на ветках фич без правки YAML вручную.
Сборочная линия 1С: от checkout до артефакта
Сквозной сценарий удобно рисовать циклом: коммит, сборка, тест, выкладка - на review сразу видно, где обрывается автоматизация.
Схема 1. Цикл CI: коммит, сборка.cf, тест на копии ИБ, выкладка

Те же шаги списком, как я закладываю их в первый рабочий pipeline:
- Checkout с depth, если история Git не нужна для сборки.
- Подстановка секретов из variable group (строка ИБ, пароль хранилища, логин агента 1С).
- Подготовка рабочей ИБ: загрузка из.dt шаблона или создание пустой, обновление конфигурации из файлов XML или загрузка из хранилища через vrunner.
- Сборка: выгрузка и загрузка,
compile,compileextдля расширений, формирование.cf и.cfe. - Publish pipeline artifact или Universal Package в Artifacts с именем по Build.BuildNumber.
- По желанию: stage Test с Vanessa-ADD или xUnit через OneScript, затем PublishTestResults@2 при наличии JUnit XML.
Deploy stage я вешаю только на релеасе-ветки, чтобы develop не трогал продуктивные каталоги публикации.
Режимы автоматизации 8.3 на агенте (версию платформы фиксируйте в variables и проверяйте в первом step):
- Пакетный запуск Конфигуратора (
/DisableStartupDialogs /DumpConfigToFiles,/LoadConfigFromFiles,/UpdateDBCfg) - классика для ХМЛ-выгрузки в Git. - Обёртка vanessa-runner (
vrunner compile,updatedb,run) - меньше возни с кавычками в cmdline. - ibcmd (с линейки 8.3.20+) - часть операций с конфигурацией и ИБ из командной строки без GUI; перед внедрением сверьте список подкоманд с документацией установленной платформы, названия mode в старых примерах из сети часто не совпадают.
Структура репозитория: либо выгрузка конфигурации в каталог src/ (XML), либо ЕДТ-проект с.project и модулями.bsl в дереве. Pipeline один, шаг загрузки разный: для EDT часто используют выгрузку в files через designer или промежуточный export step в job. Path trigger для EDT: include по каталогу проекта, exclude служебные каталоги IDE.
Ниже сокращённый, но рабочий по структуре фрагмент корневого YAML с parameters, template и шагами на PowerShell. Имена пулов и групп замените на свои.
# azure-pipelines.yml
trigger:
branches:
include: [develop, release/*]
paths:
include: [src/**, pipelines/**]
exclude: [docs/**, '**/*.md']
parameters:
- name: platformVersion
type: string
default: '8.3.24.1691'
- name: vrunnerConfig
type: object
default:
ibConnection: /S"test-server\test_ci"
configurations: [MainConfig]
- name: runTests
type: boolean
default: true
variables:
- group: 1c-ci-secrets
- name: PlatformRoot
value: 'C:\Program Files\1cv8\$(platformVersion)\bin'
stages:
- stage: Build
jobs:
- job: CompileCf
pool:
name: 1C-Windows
demands: ['1c.platform -equals $(platformVersion)']
steps:
- checkout: self
clean: true
- template: templates/steps-vrunner-build.yml
parameters:
platformRoot: $(PlatformRoot)
vrunnerConfig: ${{ parameters.vrunnerConfig }}
- ${{ if eq(parameters.runTests, true) }}:
- stage: Test
dependsOn: Build
jobs:
- job: XUnit
pool:
name: 1C-Windows
steps:
- download: current
artifact: cf-package
- task: PowerShell@2
displayName: Run xUnit via vrunner
inputs:
filePath: 'pipelines/scripts/run-tests.ps1'
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFormat: JUnit
testResultsFiles: '**/junit.xml'
Блок parameters.vrunnerConfig попадает в template на compile time через ${{ parameters.vrunnerConfig }}; секреты не в YAML, а в group 1c-ci-secrets (пароль ИБ, пароль хранилища). Demands на версию платформы спасают от ситуации, когда в pool остался агент с 8.3.22, а база уже требует 8.3.24. Условный stage Test исчезает из скомпилированного pipeline, если при ручном queue run снять галочку runTests.
В templates/steps-vrunner-build.yml обычно лежат вызов oscript с командой vrunner compile --src src/cf --out $(Build.ArtifactStagingDirectory)\out.cf (точные ключи смотрите в json vrunner), затем PublishPipelineArtifact@1 с именем cf-package. Build number в имя файла: out_$(Build.BuildNumber).cf, чтобы тестовый stage и релеасе-ветка ссылались на одну версию.
Эксплуатация: секреты, версии платформы, что смотреть при падении
Variable groups в Azure DevOps Library хранят строки подключения, пароли хранилища, учётные данные публикации на веб-сервер. Секретные поля не попадают в лог; в YAML указываете только имя группы. Если политика требует Key Vault, task AzureKeyVault@2 подтягивает секреты в variables на время job - удобно на Server с hybrid identity.
Версию платформы держите явно: parameter platformVersion, demand на агенте, первый step с 1cv8.exe /? или чтением каталога Program Files. При несовпадении версии агента и сервера ИБ типовые симптомы: ошибки формата хранилища, невозможность загрузить конфигурацию, расхождение при обновлении БД.
Когда pipeline красный, я иду по чек-листу:
- Агент online в pool, служба Azure Pipelines Agent запущена под тем же пользователем, что имеет доступ к ИБ.
- Нет висящих сеансов, блокирующих конфигурацию; для CI база должна быть выделенной, не prod.
- Путь к oscript и vrunner в PATH службы агента (интерактивный PowerShell у администратора не показатель).
- Опечатка в
/S,/N,/Pили лишний пробел в строке подключения после подстановки секрета. - Для Гит-выгрузки: закоммиченные бинарные.cf в src, конфликт merge ломает load config from files.
- PublishTestResults без junit.xml: task упадёт, если скрипт тестов не сформировал отчёт - проверьте путь маски **/junit.xml.
Vanessa-ADD и xUnit через OneScript на том же агенте, что и сборка, избавляют от второй установки платформы, но удлиняют job. Разделение по расписанию часто выигрывает: быстрый compile на каждый push, полный прогон сценариев - nightly или только release/*.
Если нет прав менять agent pool, попросите добавить capability вручную в разделе Agent capabilities в UI pool: имя 1c.platform и значение сборки платформы. Без этого demands в YAML будут висеть в queued indefinitely.
Перед первым боевым deploy проверьте вручную на агенте те же команды под тем же пользователем службы: один успешный локальный прогон PowerShell с vrunner снимает половину неясностей, которые в логе pipeline выглядят как «скрипт завершился с кодом 1».
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
См. также
10.11.2026 406 Iliaelagin 0
02.11.2026 633 vanya_gonchar 2