Опенсорс на 1С без боли: Git worktrees, XML вместо EDT и сборка расширения в одну кнопку

11.02.26

Разработка - DevOps и автоматизация разработки

Один репозиторий GitHub и одно расширение, которое нужно выпускать сразу для нескольких конфигураций 1С — звучит как «будут конфликты». В статье показываю рабочую схему: main как ядро, ветки; сборки под конфигурации, `git worktree`, чистая XML;выгрузка (без EDT артефактов) и автоматизация сборки `.cfe` через PowerShell + 1cv8 DESIGNER.

Опенсорс-расширение 1С на GitHub без боли: ветки под конфигурации, XML вместо EDT и сборка .cfe в одну кнопку

Если вы хоть раз пытались вести «одно расширение на несколько конфигураций» (УНФ/Розница/УТ/КА/ERP) в Git, то знаете три чувства: diff, merge и «почему опять конфликт в Configuration.xml». Мы прошли этот квест на проекте 1C AI Autofill и собрали рабочую схему, которую можно забрать себе.

Дисклеймер: если я говорю «мы», это значит я и мои агенты в Cursor IDE. Они тоже участвуют в мерже — и тоже нервничают, когда конфликтов в Configuration.xml больше, чем изменений в коде.

Что это за проект (в двух строках): расширение для 1С:Предприятие 8.3, которое помогает генерировать продающие описания номенклатуры и (по настройкам) заполнять доп. реквизиты/характеристики с помощью AI. Исходники открыты, релизы лежат на GitHub, а логика разработки — внятная и повторяемая.

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

 

Коротко (TL;DR)

  • main — ядро (вся логика и «истина»), а ветки конфигураций — тонкие адаптеры (в основном отличаются xml/Configuration.xml).
  • git worktree — чтобы держать одновременно несколько веток рядом и не переключаться туда-сюда.
  • Только XML-выгрузка — чтобы diff был читаемым, а merge — предсказуемым.
  • Сборка автоматизирована (PowerShell + 1cv8 DESIGNER): из XML → .cfe → загрузка → обновление БД (опционально).

Мем-пауза, чтобы пережить merge

 

Голлум: «Мой precious — merge без конфликтов»

 

Содержание: Git-схема · Почему XML · Фрагменты кода · Сборка .cfe · Чек-лист · Планы · Как контрибьютить · Что сделать прямо сейчас · Ссылки

 

0. Для кого статья

  • Разработчики 1С, которым нужно поддерживать расширение сразу для нескольких конфигураций.
  • Те, кто хочет «как в нормальном мире»: GitHub, релизы, воспроизводимая сборка, минимум ручных действий.
  • Те, кто устал от EDT-артефактов и конфликтов, когда «вроде ничего не менял, а изменилось всё».

 

1. Git «по-взрослому»: одно ядро и несколько веток конфигураций

Фраза «main — это состояние души» смешная ровно до первого релиза. Потом она становится правилом: в main живёт ядро, а ветки конфигураций периодически подтягивают изменения и собирают свои .cfe.

Структура веток

В репозитории держим несколько веток/сборок:

  • main — ядро расширения: полная XML-выгрузка (включая Configuration.xml и ConfigDumpInfo.xml).
  • UNF_Rozn — сборка для УНФ и Розницы.
  • UNF_Rozn_Fresh — сборка для 1cfresh (отличается, в том числе, именем расширения).
  • UT_KA_ERP — сборка для УТ, КА и ERP.

Где обычно отличия: в xml/Configuration.xml — имя конфигурации (<Name>) и иногда версия (<Version>). Всё остальное — как в main (если не было осознанного точечного отличия под конкретную конфигурацию).

Worktrees: «хочу видеть всё сразу»

Вместо вечного git checkout — отдельный worktree на каждую ветку. Это резко снижает количество «ой, я правил не там».

git worktree add ../worktrees/UNF_Rozn UNF_Rozn
git worktree add ../worktrees/UT_KA_ERP UT_KA_ERP

Поток разработки (как живём каждый день)

  • Фичи и общая логика — делаем в main.
  • Ветки конфигураций — периодически делают git merge main, разрешают конфликты по правилам и выпускают свой релиз.
  • Редкие исключения: если правка нужна только одной конфигурации — она живёт в её ветке (и вы заранее понимаете, что на следующем merge это может дать конфликт).

Merge main → ветка конфигурации

Команды максимально скучные (а это хорошо):

cd worktrees/UNF_Rozn
git merge main

Конфликты: быстрые правила, чтобы не «вспоминать проект по ходу мержа»

Если Git не знает, кого любить — пусть любит ваши правила:

  • xml/Configuration.xml: оставляем своё значение <Name> (и при необходимости <Version>) для ветки конфигурации.
  • xml/ConfigDumpInfo.xml: оставляем свою версию/идентификаторы (или разрешаем по смыслу, если менялись осознанно).
  • Модули, формы, общая логика: почти всегда берём из main (main — источник правды).

Подробно (и тем же смыслом, но в формате «инструкции») это уже оформлено в репозитории: MERGE.md.

 

2. Почему «чистая XML-выгрузка» выигрывает у EDT в таких репозиториях

EDT мы пробовали. Оно умеет многое, но для сценария «одно ядро → несколько веток конфигураций → частые мержи» цена оказывается слишком высокой.

Что обычно ломает кайф

  • Лишние артефакты в репозитории (служебные файлы, метаданные).
  • Тяжёлый diff: «как понять, что реально изменилось?»
  • Merge как квест: конфликтов больше, чем изменений.

Что делаем вместо

Храним расширение в чистой XML-выгрузке (каталог xml/). В результате:

  • diff читается глазами разработчика 1С;
  • merge становится процедурой, а не приключением;
  • репозиторий остаётся прозрачным (без «а это что за файл?»).

Следы эпохи EDT обычно выглядят так (и да, их лучше игнорировать):

# EDT/Eclipse служебные файлы
.metadata/
.project
.classpath
.settings/
*.launch

 

3. Как выглядит код: два фрагмента, чтобы было «осязаемо»

Ниже — пара кусочков из расширения: серверный вызов к API и клиентская часть с длительной операцией. Это не «идеальный эталон», а понятный скелет, который работает и хорошо мержится.

Сервер: HTTP + JSON, получение ответа и нормальная ошибка

Функция ОтправитьЗапрос(Промт) Экспорт
	
	СтрокаJSON = СериализоватьЗапросВJSON(Промт);
	Соединение = ПолучитьHTTPСоединение();   
	Запрос = Новый HTTPЗапрос(ПолучитьПутьChatCompletions(), ПолучитьHTTPЗаголовки());  
	
	Запрос.УстановитьТелоИзСтроки(СтрокаJSON);
	Результат = Соединение.ОтправитьДляОбработки(Запрос); //POST
		
	Если Результат.КодСостояния=200 Тогда 
		ЧтениеJson = Новый ЧтениеJson;
		ЧтениеJson.УстановитьСтроку(Результат.ПолучитьТелоКакСтроку());
		РезСтруктура = ПрочитатьJSON(ЧтениеJson);
		
		МассивРезультатов = РезСтруктура["choices"];			
		Если МассивРезультатов <> Неопределено 
			И МассивРезультатов.Количество() 
			И ТипЗнч(МассивРезультатов[0]) = Тип("Структура")
			И МассивРезультатов[0]["message"] <> Неопределено
			И ТипЗнч(МассивРезультатов[0]["message"]) = Тип("Структура") Тогда
			Ответ = СокрЛП(МассивРезультатов[0]["message"]["content"]);	
		Конецесли;
	Иначе 
		СообщениеобОшибке = "Не удалось получить ответ. Код ошибки: "+Результат.КодСостояния +" "+ Результат.ПолучитьТелоКакСтроку();  
		ВызватьИсключение СообщениеобОшибке;
	КонецЕсли; 
	
	Возврат Ответ;
	
КонецФункции  

Функция СериализоватьЗапросВJSON(ТекстЗапроса)	
	Настройки = НастройкаПоУмолчанию();
	Сообщения = Новый Массив;
	Сообщение = Новый Структура;
	Сообщение.Вставить("role", "user"); 
	Сообщение.Вставить("content", ТекстЗапроса); 
	Сообщения.Добавить(Сообщение); 
	
	Структура = Новый Структура;
	Модель = Настройки.МодельИИ;
	Если НЕ ЗначениеЗаполнено(Модель) Тогда
		Модель = "auto";
	КонецЕсли;
	Структура.Вставить("model", Модель);
	Структура.Вставить("messages", Сообщения);
	
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON,Структура);
	
	Возврат ЗаписьJSON.Закрыть();
	
КонецФункции

Клиент: длительная операция, чтобы форма не зависала

Когда пользователь нажимает «Заполнить ИИ», запрос может выполняться заметно долго. Поэтому — длительная операция: запускаем на сервере и ждём с окном ожидания.

&НаКлиенте
Процедура GPT_ЗаполнитьОписание(Команда)  
	
	СостояниеНастроек = GPT_ОбщийВызовСервера.GPT_СостояниеНастроек();
	Если НЕ СостояниеНастроек.Готово Тогда
		ОткрытьФорму("ОбщаяФорма.GPT_Регистрация", , ЭтотОбъект, , , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
		Возврат;
	КонецЕсли;
	
	GPT_ОтправитьЗапросНаСервере();
	
	ОписаниеОповещения = Новый ОписаниеОповещения("ПолучениеОтветаChatGPT", ЭтотОбъект);
	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	ПараметрыОжидания.ВыводитьОкноОжидания = Истина;
	ДлительныеОперацииКлиент.ОжидатьЗавершение(ЭтаФорма.GPT_ДлительнаяОперация, ОписаниеОповещения, ПараметрыОжидания);	

КонецПроцедуры

&НаСервере
Функция GPT_ОтправитьЗапросНаСервере()
	
	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(Новый УникальныйИдентификатор);
	ПараметрыВыполнения.ОжидатьЗавершение = Ложь; 

	ЭтаФорма.GPT_ДлительнаяОперация = ДлительныеОперации.ВыполнитьФункцию(
		ПараметрыВыполнения,
		"GPT_ОбщийМодульСервер.СгенерироватьОписаниеИДопСвойстваНоменклатуры",
		Объект.Ссылка
	); 
		
КонецФункции

 

4. Автоматизация сборки: .cfe без рутины «LoadCfg / UpdateDBCfg вручную»

Ручная сборка .cfe — это десятки одинаковых действий, умноженные на количество веток. Автоматизация убирает человеческий фактор: скрипт делает всё одинаково каждый раз.

Типовая схема: main → merge в ветки → скрипт собирает .cfe для каждой ветки → (опционально) можно повесить на CI.

Пример скрипта (PowerShell): параметры

Смысл простой: путь к платформе, строка подключения, путь к XML, куда положить .cfe, имя расширения и флаги.

param(
    [string]$PlatformExe = 'C:\Program Files\1cv8\8.5.1.1150\bin\1cv8.exe',
    [string]$ConnectionString = '',
    [string]$XmlPath = (Join-Path (Split-Path $PSScriptRoot -Parent) 'xml'),
    [string]$ExtensionCfePath = (Join-Path (Split-Path $PSScriptRoot -Parent) 'bin\Расширение.cfe'),
    [string]$ExtensionName = 'GPT_ОписаниеНоменклатуры',
    [switch]$BuildFromXml,
    [switch]$SkipLoadExtension,
    [switch]$SkipDbUpdate,
    [switch]$SkipRunClient,
    [switch]$Wait
)

Сборка .cfe из XML: два вызова DESIGNER

# Сборка .cfe из xml (если -BuildFromXml)
if ($BuildFromXml) {
    $xmlFullPath = [System.IO.Path]::GetFullPath($XmlPath)
    $loadXmlArgs = $baseArgs + @('/LoadConfigFromFiles', $xmlFullPath, '-Extension', $ExtensionName)
    Invoke-Platform -Arguments $loadXmlArgs -OperationName 'Сборка: загрузка расширения из XML в конфигурацию'

    $dumpArgs = $baseArgs + @('/DumpCfg', $cfeFullPath, '-Extension', $ExtensionName)
    Invoke-Platform -Arguments $dumpArgs -OperationName 'Сборка: выгрузка расширения в .cfe'
}

Загрузка .cfe и обновление БД (если нужно)

$loadArgs = $baseArgs + @('/LoadCfg', $cfeFullPath, '-Extension', $ExtensionName)
Invoke-Platform -Arguments $loadArgs -OperationName 'Загрузка расширения из .cfe в конфигурацию'

$updateArgs = $baseArgs + @('/UpdateDBCfg', '-Extension', $ExtensionName)
Invoke-Platform -Arguments $updateArgs -OperationName 'Обновление конфигурации БД'

Полный цикл одной командой обычно выглядит так: .\update-extension-and-run-db.ps1 -BuildFromXml. Скрипт соберёт, загрузит, обновит (если не отключено) и может запустить клиент (если предусмотрено вашей обвязкой).

 

5. Мини-чек-лист релиза (чтобы не держать всё в голове)

  • В main: влитые фичи/фиксы, при необходимости обновлён <Version> в xml/Configuration.xml.
  • В ветке конфигурации: git merge main + конфликты по правилам (имя/версия свои, логика из main).
  • Сборка: скрипт → получаем .cfe (и при необходимости прогоняем установку в тестовой базе).
  • Публикация: релиз в GitHub (отдельно на каждую ветку/сборку).

 

6. Планы по развитию

Самое очевидное следующее улучшение — автоматизированное тестирование, чтобы релизы не держались на «проверил руками и вроде ок».

  • Автотест сборки: воспроизводимая сборка .cfe из xml/ (скриптом) в CI.
  • Smoke-тест установки: установка/обновление расширения в тестовой базе и проверка, что оно подключилось без ошибок.
  • Проверка базовых сценариев: «кнопка есть», «запрос ушёл», «ошибка показывается понятно» (минимум, который ловит регрессии).

 

7. Как контрибьютить (быстро и без боли)

  • Нашли баг / есть идея: создайте issue в репозитории — Issues. Если хочется обсудить до реализации — Discussions.
  • Хотите сделать PR: начните с CONTRIBUTING.md и посмотрите правила мержа веток в MERGE.md.
  • Локальный запуск/сборка: готовый скрипт — automation/update-extension-and-run-db.ps1 (и короткая инструкция — automation/README.md).

Мини-онбординг: форк → ветка/изменения → PR. Если вы делаете правки общей логики — целимся в main; ветки конфигураций подтягивают изменения мерджем.

 

8. Что можно сделать прямо сейчас (идеи для первого вклада)

  • Документация: улучшить разделы «быстрый старт», «частые ошибки», «как собрать .cfe» и «как добавить поддержку новой конфигурации».
  • Автотесты/CI: добавить workflow, который собирает .cfe из xml/, а также smoke-проверки установки/обновления в тестовой базе.
  • Улучшение DX: сделать понятнее сообщения об ошибках (HTTP/JSON/настройки), добавить диагностический режим/логирование (без лишнего шума).
  • UI/UX в формах: мелкие улучшения размещения команд/кнопок/подсказок, чтобы пользователю было проще начать.
  • Быстрые задачи: берите подборку good first issue и help wanted.

 

 

Заключение

Опенсорс на 1С — это не «страшно и больно», если у вас предсказуемая структура: main как ядро, ветки как сборки, чистая XML-выгрузка и скрипт сборки. Остальное — дисциплина и пару раз пережить первый merge.

Вступайте в нашу телеграмм-группу Инфостарт

1С расширение cfe Git GitHub worktree XML‑выгрузка EDT DevOps CI/CD автоматизация сборки УНФ Розница УТ11 КА ERP

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Системный администратор Разработчик 1С 8.3 1С 8.5 Бесплатно (free)

В прошлой статье у ERP оставалось 89 отказов загрузки, у ЗУП — 19. Теперь обе конфигурации совпали с эталонами, а собранные файлы прошли круг через платформу. Развертка выделена в открытый репозиторий cf-unwrapper: библиотека на Rust и консольная утилита. Показываю результаты, объясняю границы «100%» и приглашаю к проверкам и развитию проекта.

02.11.2026    234    oyti    1    

1

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Разработчик 1С:Предприятие 8 Россия Бесплатно (free)

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

02.11.2026    467    vanya_gonchar    2    

5

Файловый обмен (TXT, XML, DBF), FTP DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Системный администратор Разработчик 1С 8.5 Бесплатно (free)

В прошлой статье я выгрузил Бухгалтерию в XML байт в байт и спросил, на чем проверить дальше. Вы ответили: ERP, старые релизы, зарплата. Прогнал пять конфигураций, от клиента ЭДО до ERP на 120 тысяч файлов. Рассказываю, что сломалось после Бухгалтерии, почему эталону платформы нельзя верить на слово, как выгрузить одну конфигурацию в формат трех версий платформы - и почему cf-конвертер становится отдельным продуктом, Разверткой.

02.11.2026    311    oyti    2    

3

Инструментарий разработчика DevOps и автоматизация разработки Разработчик 1С 8.3 Абонемент ($m)

Как отличить срочное исправление от обычного вечернего коммита? Проверила расчёт показателей поставок по отчёту хранилища 1С и истории двух открытых проектов. На стенде счётчики совпали со сценарием, а в выборке открытого проекта правило «те же объекты» ошиблось во всех шести случаях. Показываю границы такого замера и отличие от метрик DORA. Прилагаются инструмент и материалы опыта.

1 стартмани

29.10.2026    305    Ninel_S    0    

0

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Файловый обмен (TXT, XML, DBF), FTP Системный администратор Разработчик 1С 8.5 Бесплатно (free)

Выгрузка типовой Бухгалтерии в XML через базу занимает больше четырёх минут. Я написал движок, который читает файл конфигурации напрямую и выгружает его за 35 секунд, совпадая с выгрузкой платформы байт в байт во всех 90 385 файлах. Загрузка обратно тоже работает: круг через платформу совпадает полностью. Рассказываю, как ускоряли, как проверяем и что при загрузке XML теряет сама платформа. А в конце спрашиваю, нужно ли это кому-то, кроме меня, и на какой конфигурации проверить следующей.

27.10.2026    883    oyti    20    

16

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Разработчик 1С 8.3 Абонемент ($m)

Хук pre-commit проверяет полный снимок индекса Git в отдельной базе 1С. На «Нано-УТ» и платформе 8.3.27 повторила 12 попыток коммита: восемь прошли, четыре остановлены. Чистый коммит занял 31,8 с. Вызов несуществующего метода общего модуля хук останавливает только с ключом -ExtendedModulesCheck. В архиве версия 2, тесты, инструкция и журналы.

1 стартмани

26.10.2026    343    Ninel_S    2    

-1

Нейросети DevOps и автоматизация разработки Разработчик 1С 8.3 Абонемент ($m)

Я дала агенту Claude Code задачу словами: добавить в учебную конфигурацию документ «Внутреннее потребление товаров», который списывает товар по средней стоимости и не даёт уйти в минус. Три запуска с нуля, каждый принят проверкой на платформе 1С: 1 мин 49 с, 2 мин 33 с и 2 мин 56 с. Показываю, что агент поменял, где ошибался и почему на типовой УТ так быстро не будет.

1 стартмани

26.10.2026    603    Ninel_S    0    

-1

Нейросети DevOps и автоматизация разработки Разработчик 1С 8.3 Бесплатно (free)

ИИ пишет код на 1С все быстрее, а разработчик по-прежнему носит вопросы, ответы и статусы между чатом с агентом, аналитиком и архитектором. Показываю другой подход и демо-стенд: задача из Яндекс Трекера сама идет по этапам, ИИ-агент работает в GitLab CI, а люди только утверждают спецификацию, архитектуру, план и код. Живой пример задачи от заявки до merge, честный отказ агента, права агента, время и стоимость: вся задача обошлась в 68 центов.

22.10.2026    717    maxrubtsoff    1    

3
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. dhurricane 11.02.26 13:21 Сейчас в теме
А можно немного подробнее про проблемы при работе с EDT?
1. Почему считаете, что перечисленные Вами файлы лишние? Да, с каталогом metadata действительно так, воркспейс и репозиторий действительно должны быть в разных папках. Правда не понимаю, как у Вас так получилось, что воркспейс оказался внутри репозитория, EDT препятствует этому. А с остальными то файлами что не так, почему они не должны быть в репозитории?
2. Чем diff у EDT тяжелее платформенного? Напротив, формат EDT более "плоский", более предсказуемый, нежели у платформы, т.к. изначально заточен под работу в git. Не говоря уже о том, что EDT хорошо умеет решать конфликты, так как оперирует объектами, а не строками текстовых файлов. Можете пример привести тяжелого diff?
yukon; MaCCapAkIII; +2 – Ответить
2. yukon 158 15.02.26 11:30 Сейчас в теме
И в целом непонятно, откуда в EDT непонятные артефакты - там вроде как всегда ясно какой именно файл редактировался. А вот конфигуратор, вполне может добавить артефактов при выгрузке - она всегда пакетная.

И еще минус платформенной выгрузки это смена версии платформы. Вот уж где изменений полно, и миграция активного проекта с двумя десятками веток весьма нетривиальная задача.
Для отправки сообщения требуется регистрация/авторизация