Введение

В условиях современного развития программного обеспечения и необходимости ускорения выпуска обновлений, автоматизация процессов разработки и доставки (DevOps) становится критически важной. Для экосистемы 1С, характеризующейся сложностью конфигураций, наличием множества расширений и необходимостью строгого контроля качества, ручные операции по сборке, тестированию и развертыванию становятся узким местом.

Меня зовут Владимир, я эксперт по развитию финансовых и учетных систем в Группе MOEX. В этой статье предлагаю рассмотреть архитектуру, используемые инструменты, этапы конвейера, а также стратегии оптимизации и мониторинга, которые позволяют обеспечить стабильность и скорость доставки программного обеспечения.

Цель

Автоматизировать рутинные ручные операции, связанные со сборкой, тестированием, проверками и доставкой на различные стенды проектов 1С.

Не будем вдаваться в теорию процесса DevOps и для чего это нужно, это и так все знают. Сконцентрируемся на практике использования инфраструктуры и инструментов для достижения цели.

Инфраструктура

Это конкретные сервера (физические или виртуальные), на которых развернуты те или иные сервисы. Все они предоставляются другими подразделениями компании. А мы по сути используем их по модели SaaS (ПО как услуга).

Инфраструктура
Инфраструктура

С другой стороны никто не мешает развернуть все эти сервисы самостоятельно.

  1. Linux + PostgreSQL

    В рамках процессов импортозамещения в компании все наши сервера 1С переведены на Linux, а сервера баз данных на PostgreSQL. С точки зрения платформы 1С обычное дело, поддержка здесь полная.

  2. GitLab (CI/CD)

    Весь исходный код хранится в GitLab. Попадает он туда разными путями (исторически для разных проектов):

    • На проектах, работающих с хранилищами конфигураций 1С, через GitConverter.

    • На проектах, работающих по технологии Native Git (выгрузка/загрузка в XML из конфигуратора) или на проектах EDT напрямую через коммиты или merge request.

    Раз у нас есть GitLab и у него есть свой движок CI/CD, то используем его для целей DevOps без привлечения отдельных инструментов.

  3. Nexus (Docker Registry + File Storage)

    Можно считать это большим складом различных репозиториев. Для наших целей интересны 2 из них:

    • Docker Registry - храним собранные нами docker-образы с необходимыми инструментами (ниже)

    • File Storage - храним различные утилиты, дистрибутивы, модельные базы и артефакты выпущенных релизов

  4. TestOps

    Место, куда складываются результаты прогонов автотестов (дымовых, сценарных, юнит, API).

  5. SonarQube + BSL Comminuty Plugin

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

  6. Express

    Наш корпоративный мессенджер, Используем созданные в нем каналы для отправки уведомлений о ходе выполнения конвейера.

  7. API-портал

    Все публикуемые API в компании проходят через единый портал, на котором то или иное API нужно зарегистрировать. 1С не является исключением. Мы активно взаимодействуем с внешними системами по API как в качестве потребителя, так и в качестве поставщика.

Инструменты

  1. Docker

    Позволяет поместить в контейнер необходимые для выполнения задачи конвейера инструменты. Мы собираем 2 docker-образа:

    • client1c - основан на RedOS (один из согласованных дистрибутивов в компании) включает в себя платформу 1С, EDT, oscript+библиотеки, allurectl, Java JDK, Coverage41C. Используется для основной работы, в которой участвует платформа 1С (сборка, запуск тестов). Размер образа большой, порядка 10 Gb.

    • oscript - так же основан на RedOS, включает в себя oscript+библиотеки. Используется там, где платформа 1С не нужна. Достаточно легковесный, порядка 600 Mb.

    С выходом новой версии платформы или необходимости добавления библиотеки oscript собирается новый образ, новой версии. Версионность позволяет точечно менять используемые в проектах docker-образы.

    Dockerfile прилагаю:

FROM registry.red-soft.ru/ubi7/ubi-minimal
LABEL maintainer="Vladimir Bronnikov <vladimir.bronnikov@moex.com>"

WORKDIR /tmp

# Пакеты iputils (ping), procps (ps) необходимы для запуска Ванессы без ошибок
# Пакеты mesa-dri-drivers, vulkan-loader убирают ошибки GUI при запуске Ванессы

RUN set -xe \
  && yum -y update \
  && yum -y install \
    alsa-lib \
    bash \
    ca-certificates \
    cabextract \
    curl \
    fontconfig \
    git \
    iputils \
    libXtst \
    mesa-dri-drivers \
    mono-core \
    mono-locale-extras \
    msttcore-fonts-installer \
    net-tools \
    openldap-clients \
    procps \
    tar \
    unzip \
    unixODBC \
    vulkan-loader \
    which \
    x11vnc \
    xorg-x11-font-utils \
    xorg-x11-server-Xvfb \
  && yum -y clean all \
  && rm -rf /var/cache

ARG USR1CV8_UID="1000"
ARG GRP1CV8_GID="1000"

RUN groupadd -r grp1cv8 --gid=${GRP1CV8_GID} \
  && useradd -r -g grp1cv8 --uid=${USR1CV8_UID} --home-dir=/home/usr1cv8 --shell=/bin/bash usr1cv8 \
  && mkdir -p /var/log/1C /home/usr1cv8/.1cv8/1C/1cv8/conf \
  && chown -R usr1cv8:grp1cv8 /var/log/1C /home/usr1cv8

# Устанавливаем язык консоли для вывода русских символов вместо знаков ???

ENV LANG=ru_RU.UTF-8
ENV LANGUAGE=ru_RU:ru
ENV LC_ALL=ru_RU.UTF-8

# Необходимые дистрибутивы и библиотеки грузим из хранилища Nexus

ARG NEXUS_REPO

RUN set -xe; \
  curl -o /usr/local/bin/gosu ${NEXUS_REPO}/tools/gosu-amd64; \
  chmod +x /usr/local/bin/gosu; \
  curl -o /usr/local/bin/allurectl ${NEXUS_REPO}/tools/allurectl_linux_amd64; \
  chmod +x /usr/local/bin/allurectl

RUN set -xe; \
  curl -o /tmp/zulu.rpm ${NEXUS_REPO}/distr/java/zulu17.54.21-ca-fx-jdk17.0.13-linux.x86_64.rpm; \
  rpm -i ./zulu.rpm; \
  rm -rf /tmp/*

RUN set -xe; \
  curl -o /tmp/edt.tar.gz ${NEXUS_REPO}/distr/edt/1c_edt_distr_offline_2025.1.4_15_linux_x86_64.tar.gz; \
  mkdir edt; \
  tar -C edt -xvf ./edt.tar.gz; \
  ./edt/1ce-installer-cli install --ignore-signature-warnings; \
  rm -rf /tmp/*
ENV PATH="/opt/1C/1CE/components/1c-edt-2025.1.4+15-x86_64:$PATH"

RUN set -xe; \
  curl -o /tmp/v8.zip ${NEXUS_REPO}/distr/v8/server64_8_3_27_1786.zip; \
  unzip -o -d v8 v8.zip; \
  ./v8/setup-full-8.3.27.1786-x86_64.run --mode unattended --enable-components v8_install_deps,ru,client_full,server; \
  rm -rf /tmp/*
ENV PATH="/opt/1cv8/x86_64/8.3.27.1786:$PATH"

# Удаляаем символическую ссылку libstdc++ для запуска клиентов 1С (началось с версии платформы 8.3.24)

RUN set -xe; \
  rm /opt/1cv8/x86_64/8.3.27.1786/libstdc++.so.6; \
  mv $(dirname $(find /opt/1C/1CE -name ring)) /opt/1C/1CE/components/1c-enterprise-ring
ENV PATH="/opt/1C/1CE/components/1c-enterprise-ring:$PATH"

RUN set -xe; \
  curl -o /tmp/oscript.rpm ${NEXUS_REPO}/distr/oscript/onescript-engine-1.9.1-1.fc26.noarch.rpm; \
  rpm -i ./oscript.rpm; \
  for i in cmdline-1.0.0 csv-1.0.2 json-1.1.1 xml-parser-0.1.1 v8metadata-reader-0.3.6 swagger-0.5.0 messenger-2.0.8-mb irac-1.4.0 InternetMail-1.0.6; \
  do \
    curl -o /tmp/$i.ospx ${NEXUS_REPO}/distr/oscript/lib/$i.ospx; \
    opm install -f ./$i.ospx; \
  done; \
  rm -rf /tmp/*

RUN set -xe; \
  curl -o /tmp/coverage41c.zip ${NEXUS_REPO}/distr/coverage41c/Coverage41C-2.7.2.zip; \
  unzip -o -d /opt coverage41c.zip; \
  cp $(find /opt/1C/1CE -name com._1c.g5.v8.dt.debug.core*) /opt/Coverage41C-2.7.2/lib; \
  cp $(find /opt/1C/1CE -name com._1c.g5.v8.dt.debug.model*) /opt/Coverage41C-2.7.2/lib; \
  rm -rf /tmp/*
ENV PATH="/opt/Coverage41C-2.7.2/bin:$PATH"
ENV EDT_LOCATION="/opt/Coverage41C-2.7.2/lib"

COPY config/nethasp.ini /opt/1cv8/conf
COPY config/conf.cfg /opt/1cv8/conf
COPY ./v8ci /usr/local/bin/
COPY ./docker-entrypoint.sh /usr/local/bin/

# Публикую порт для подключения к экрану с использованием протокола VNC
EXPOSE 5900

ENTRYPOINT ["docker-entrypoint.sh"]
  1. Платформа 1С

    Является необходимой частью docker-образов и использует практически все свои компоненты: клиент (тонкий и толстый), конфигуратор, сервер отладки, автономный сервер и сервер удаленного администрирования.

  2. EDT

    Т.к. во многих проектах исходники хранятся в формате EDT, то используем утилиту 1сedtcli (ранее ring) для преобразования конифгурации из формата EDT в формат XML и дальнейшего формирования cf/cfe уже средствами платформы 1С.

  3. Oscript

    Основной инструмент для написания скриптов автоматизации. Он имеет 1С-подобный язык программирования, все необходимые процедуры и функции для автоматизации и богатый набор библиотек для работы с 1С. Используемые на практике библиотеки (не реклама):

    • 1connector - удобная обертка над HTTP-запросами

    • autumn - с интересом смотрю на эту библиотеку, добавляющую Dependency Injection в код oscript

    • cli - работа с командной строкой (парсинг опций, аргументов)

    • irac - работа с сервером администрирования RAS

    • InternetMail - отправка электронной почты

    • json - работа с JSON

    • logos - подсистема логирования

    • messenger - интеграция с различными мессенджерами, тут пришлось допилить код для интеграции с Express

    • swagger - создание описания API в формате swagger на основе комментариев к методам HTTP-сервисов

    • v8metadata-reader - чтение метаданных конфигурации/расширения, используется для получения версии проекта

    • v8runner - запуск всего, что связано с 1С (конфигуратор, клиенты, тестирование)

    • xml-parser - работа с XML

  4. Vanessa Automation

    Дымовое и сценарное тестирование реализовано на данном фреймворке. Тесты пишут автотестировщики и помещают в GitLab.

    Обработку собираем самостоятельно из исходников, т.к. иногда оперативно исправляем найденные ошибки или под запросы автотестировщиков (незначительные доработки).

  5. YaxUnit

    Юнит тестирование и тестирование API реализовано на данном фреймворке. Тесты пишут разработчики в отдельных расширениях, которые так же помещаются в GitLab, собираются в процессе работы конвейера и подключаются к базам тестирования.

  6. Coverage41C

    Инструмент сбора покрытия кода с использованием подключения к серверу отладки 1С.

  7. allurectl

    Единственная цель отправить собранные в процессе тестирования данные (в формате allure) в TestOps.

Этапы конвейера

Этапы конвейера
Этапы конвейера
  1. build

    Сборка артефактов из исходных кодов. На выходе получаем необходимые cf/cfe.

  2. pre-test

    Подготовка информационных баз для тестирования. Здесь есть несколько вариантов:

    • Если есть заранее подготовленная модельная база (выгрузка dt), то разворачивается файловая база, к ней применяются собранные на предыдущем этапе cf/cfe, производится запуск и обновление и выгрузка обратно в dt с сохранением в артефакты. Применяется при небольших модельных базах.

    • Есть заранее подготовленная обезличенная копия информационной базы на сервере 1С, то к ней сразу применяются собранные на предыдущем этапе cf/cfe, производится запуски и обновление.

  3. test

    Все задачи тестирования выполняются на данном этапе. По большей части задачи независимые и выполняются параллельно. Выделяем следующие виды тестирования:

    • Сценарное тестирование - feature-файлы со сценариями на языке Gherkin. Выполняются с помощью инструмента Vanessa Automation.

    • Дымовое тестирование - автоматически генерируемые feature-файлы с помощью Vanessa Automation. В качестве необходимых настроек ведутся файлы исключений определенных действий с определенными метаданными.

    • Юнит тестирование - тесты, написанные с помощью инструмента yaxUnit, реализованное в виде отдельного расширения, собираемого и подключаемого на предыдущих этапах.

    • Тестирование API - отдельный набор тестов, написанных также на yaxUnit, но предназначенные для тестирования API.

  4. check

    На этом этапе идет отправка исходного кода на проверку в SonarQube. Именно после тестирования, т.к. на этапе тестирования собирается информация о покрытии кода.

  5. pre-deploy-api

    Подготовка спецификации в формате openapi 3.0 для HTTP-сервисов проекта.

  6. deploy-api

    Публикация API на портале.

  7. release

    Формирование релиза. Запускается при указании тега на определенный коммит. Подготовленные на предыдущем этапе артефакты (cf/cfe) отправляем в хранилище Nexus, готовим changelog коммитов относительно предыдущего релиза (предыдущего коммита с тегом) и создаем релиз в GitLab с текстом изменений и ссылками на артефакты из Nexus.

Задачи конвейера

  1. Управление переменными и секретами

    В конвейере используется определенный набор переменных, разбитый на несколько групп:

    • Секретные - настраиваются на уровне группы проектов 1С, единые для всех проектов. Это обычно логины, пароли, токены к различным внешним сервисам.

    • GIT-переменные - влияют на процесс клонирования проекта и его подмодулей при запуске GitLab-раннера

    • Доступ к внешним сервисам - хосты, порты, URL и прочее к внешним сервисам: TestOps, Nexus, SonarQube, Express, API-портал

    • Доступ к базам тестирования - хосты и порты сервера 1С, имена баз, адреса публикации баз 1С для работы через web

  2. Структура задачи, модульность и наследование

    Основные критерии при описании задач в конвейере были компактность, понятность и единообразие. Абсолютно не хотелось писать большие портянки скриптов на различных языках программирования. В этом нам помог oscript. Условно вся обертка над логикой работы с переменными среды, файлами, запуском 1С реализованы внутри скрипта oscript. А задача выглядит как последовательный вызов нескольких команд.

    Например:

    cf:
      extends:
      - .client1c-base
      - .build-all-rules
      stage: build
      script:
      # Преобразуем проект из формата EDT в формат XML
      - 1cedtcli -data ${CI_PROJECT_DIR}/build/workspace -command export --project ${CI_PROJECT_DIR}/${MB_PROJECT} --configuration-files ${CI_PROJECT_DIR}/build/xml
      # Создаем пустую файловую базу
      - v8ci createib
      # Загружаем конфигурацию из файлов (xml)
      - v8ci loadconfigfiles
      # Сохраняем конфигурацию в файл (cf)
      - v8ci dumpcfg
      artifacts:
        paths:
        - results/build/*.cf
    

    где v8ci - это cli приложение на oscript вызывающее одну конкретную команду. Каждая команда реализуется в отдельном классе, принимает определенный набор опций и аргументов (большинство из них по умолчанию из переменных среды) и выполняет всю работу.

    Второй важный момент - использование наследования (extends). У нас есть базовые шаблоны gitlab-ci, которые можно наследовать в разных задачах. И тут есть 2 набора шаблонов:

    • Шаблоны действий - содержат используемый образ (image), переменные (variables) и исполняемые скрипты (script). Можно относиться к таким шаблонам как к функциям, которые принимают набор переменных и выполняют определенную работу. Шаблон .cfe-base собирает указанное расширение. В самой задаче достаточно наследоваться от него и указать в переменной имя расширения, которое необходимо собрать.

    Например:

    cfe 1/2:
      extends: .cfe-base
      stage: build
      variables:
        MB_EXTENSION: Расширение1
    
    cfe 2/2:
      extends: .cfe-base
      stage: build
      variables:
        MB_EXTENSION: Расширение2
    
    • Шаблоны правил - содержат правила (rules) для запуска той ли иной задачи. Комбинация двух типов шаблонов дает возможность гибко настраивать задачи без дублирования кода.

  3. Использование inputs

    Достаточно новая возможность GitLab, позиционируется как замена переменных. Можно относится к inputs, как к типизированным переменным. В нашем случае используем их для разделения конвейера на части и возможности выполнения каждой части отдельно.

    spec:
      inputs:
        pipeline-action:
          description: "Действие для запуска конвейера (или его части)"
          options: ["-- Выберите действие --", "Полный запуск", "Полная сборка", "Сборка", "Юнит-тесты", "Дымовые тесты", "Сценарные тесты", "Тесты API", "Публикация API", "Релиз"]
          default: "-- Выберите действие --"
    

    Значение pipeline-action прописано в правилах (rules) запуска той или иной задачи.
    А ручной запуск конвейера выглядит так:

    Ручной запуск конвейера
    Ручной запуск конвейера
  4. Скрипты

    Как уже писал ранее каждая команда - это отдельный класс библиотеки cli. У каждого скрипта есть процедура с описанием команды, включающая опции и аргументы и процедура исполнения команды, реализующая всю логику скрипта.

    Скрипты добавляются по мере необходимости. Общий подход к написанию - делать их максимально переиспользуемыми в разных проектах 1С.

    Скрипты
    Скрипты

    Все скрипты вынесены в отдельный проект GitLab (обзовем его cicd) и подключаются к основному проекту 1С как подмодуль (submodule) средствами Git. Это дает следующие преимущества:

    • За проект отвечает и вносит изменения отдельная роль DevOps.

    • Нет дублирования скриптов в разных проектах (во всех проектах подключается submodule).

    • Есть возможность внести изменения в проект cicd, а в основном проекте перезапустить задачу уже запущенного конвейера без коммитов в основной проект (удобно для отладки и оперативных изменений в конвейере).

  5. Тестирование

    Настройками тестирования так же вынесены в отдельные проекты. Причины похожи:

    • За тестирование отвечает отдельная роль AQA (Automated Quality Assurance).

    • В отличие от проекта cicd для каждой конфигурации свой отдельный проект для дымовых и сценарных тестов.

    Тестирование
    Тестирование

Оптимизация, мониторинг

  1. Стратегия GIT

    Не во всех задачах конвейера требуется получения проекта из Git-репозитория, например:

    • применение изменений к информационной базе - работаем только с артефактами, полученных из предыдущих задач

    • запуск дымовых и сценарных тестов - нужны только настройки тестирования и тексты сценариев

    На крупных проектах, основанных на типовых конфигурациях 1С, объем и время клонирования могут отнимать большое количество ресурсов (времени и места на диске). Для оптимизации используем следующий прием:

    • отключаем клонирование проекта с помощью переменных среды GIT_STRATEGY = none

    • проекты со скриптами oscript и дымовыми и сценарными тестами клонируем в задаче before_script

      before_script:
      # Клонируем проекты, необходимые для запуска дымовых тестов.
      - git clone ${CI_SERVER_URL}/1c/devops/cicd.git ./build
      - git clone ${CI_SERVER_URL}/1c/qa/${MB_SMOKE_PROJECT}.git ./test/smoke
    

    где:

    • MB_SMOKE_PROJECT - имя проекта с настройками запуска дымовых тестов

  2. Параллельность выполнения задач

    Если есть множество однотипных задач и возможность запустить их параллельно, то не упустим возможность это сделать. Например запуск дымовых тестов. В данном случае используем следующий подход:

    • добавляем задачу для динамического создания задач дымовых тестов

    • в зависимости от установленных переменных среды с помощью oscript формируем yml-файл для запуска подчиненного конвейера (downstream pipeline)

    • добавляем задачу trigger, которая запускает подчиненный пайплайн (нml-файл берем из артефактов предыдущей задачи)

    • в итоге будет запущено 31 задача дымовых тестов, которые будут выполняться параллельно и результаты прогона тестов выгружены в ТестОпс.

    Пример задач:

    gen-smoke:
    stage: pre-test
    script:
    # Генерим задачи дымовых тестов для downstrem pipeline
    - v8ci gensmoke results/${CI_JOB_STAGE}
    artifacts:
      paths:
      - results/pre-test/smoke.yml
    
    smoke:
    stage: test
    trigger:
      include:
      - artifact: results/pre-test/smoke.yml
        job: gen-smoke
      strategy: mirror
    variables:
      GIT_STRATEGY: none
      MB_SMOKE_PROJECT: zup3one-smoke
      PARENT_PIPELINE_ID: ${CI_PIPELINE_ID}
    

    Результат запуска дымовых тестов (2500+ тестов стабильно выполняются около 1 часа):

    Запуск дымовых тестов
    Запуск дымовых тестов
  3. Интеграция с мессенджерами

    У многих мессенджеров есть API для интеграции. С помощью oscript (и библиотеки messenger, поддерживает по умолчанию несколько популярных мессенджеров) мы реализовали отправку сообщений о ходе выполнения конвейера в корпоративный мессенджер Express. В сообщении есть ссылки на проект, конвейер и задачу и сам текст сообщения. Отправляем сообщения в специально выделенный канал.

    Мессенджеры
    Мессенджеры
  4. Вопросы лицензирования

    Для запуска клиентов 1С используются клиентские лицензии, а в случае использования серверных баз, ещё и серверная лицензия. На случай больших баз у нас есть данные лицензии для DEV-контура.

    Но для небольших (модельных) информационных баз, для тестирования используем следующий подход:

    • готовим модельную базу к запуску тестов

    • выгружаем базу в *.dt

    • на каждом шаге тестирования создаем файловую базу из *.dt

    • запускаем созданную файловую базу на автономном сервере (не требует лицензий)

    • на автономном сервере так же запущен веб-сервер

    smoke-standalone:
      variables:
        # Стандартный URL публикации базы на автономном сервере
        MB_IB_CONN: /WS"http://localhost:8314/"
      script:
      # Создаем и загружаем информационную базу (из *.dt)
      - ibcmd infobase create --restore=results/pre-test/1cv8-before.dt
      # Запускаем автономный сервер на созданной базе (только http, без отладчика, без регламентных заданий)
      - ibsrv --daemon --disable-direct --schedule-jobs=false
      # Запуск дымовых тестов
      - v8ci runsmoke
    

Идеи

  1. Использование тонких клонов для тестирования

    С помощью инструмента DBLab стром у себя систему создания тонких клонов. Инструмент позволит создавать клоны больших по объему информационных баз за секунды, а тесты запускать изолированно всегда с одного и того же состояния информационной базы (независимо от предыдущих запусков тестов). Идея в следующем:

    • инструмент DBLab держит у себя актуальную реплику (PostgreSQL) основной информационной базы

    • ежедневно с данной реплики делается снимок (snapshot). В данном процессе база обезличивается и обогащается данными и настройками для запуска тестов

    • конвейер перед запуском тестов обращается в DBLab по API с запросом на создание клона со свежего снимка, создает информационную базу на сервере 1С и использует эту базу для запуска тестов

    • после завершения прогона тестов конвейер так же по API удаляет созданный ранее клон и базу на сервере 1С

    • можно создать сразу несколько клонов и запустить тесты параллельно, при этом состояние базы каждого запуска будет одинаковым, а на уровне БД будут храниться только изменения (оценочно 1…5% от размера исходной базы)

  2. Использование ИИ

    Куда же без ИИ. Идея пока полностью не сформировалась. Но общий подход использовать вызовы по API по анализу логов выполнения конвейера, мониторинга и обобщения результатов.

Выводы и результаты

Внедрение описанной выше системы CI/CD позволило достичь значительных результатов в автоматизации процессов разработки и тестирования для экосистемы 1С.

Ключевые особенности:

  • Сокращение времени доставки: Автоматизация сборки, тестирования и развертывания исключила ручной труд на этих этапах

  • Повышение стабильности: Использование модульных скриптов на oscript, наследования шаблонов и единой инфраструктуры (GitLab, Nexus, SonarQube) обеспечило единообразие процессов во всех проектах

  • Эффективное использование ресурсов:

    • Параллельный запуск задач (особенно дымовых тестов) позволил выполнить более 2500 тестов за ~1 час

    • Использование автономных серверов для тестирования модельных баз позволило сэкономить на лицензиях

  • Прозрачность и контроль: Интеграция с TestOps, SonarQube и мессенджерами обеспечивает полную видимость результатов тестирования, покрытия кода и статуса конвейера в реальном времени

  • Гибкость: Возможность ручного запуска отдельных частей конвейера и использование подмодулей позволяет быстро вносить изменения и отлаживать процессы без коммитов в основные проекты

Комментарии (0)