Введение
В 1С для хранения кода, его истории и ведения совместной работы используется хранилище конфигурации. Для других языков программирования тоже используются системы управления версиями кода. На данный момент одной из наиболее распространенных систем управления версиями является git. Историю git можно также узнать в сети, но, думаю, достаточно будет сказать, что на данный момент разработка ядра Linux ведётся при помощи этой системы, чтобы убедить: git - это серьёзно.
Если сравнить возможности git и хранилища конфигурации 1С, то для git можно выделить ряд полезных особенностей:
- git -- распределённая система управления версиями. В отличие от хранилища конфигурации, для работы с git не требуется иметь доступ к серверу, хранящему код. Всё, что нужно для работы, хранится локально, достаточно время от времени (желательно регулярно) проводить синхронизацию локальных изменений и изменений других разработчиков. Обратной стороной этого достоинства является то, что при синхронизации могут возникнуть конфликты, которые нужно разрешать вручную. В случае с 1С здесь имеются сложности, так как значительную часть кода конфигурации представляют формы, макеты и другие типы данных, хранящиеся в виде xml документов. Ручное объединение таких документов представляет достаточно трудоёмкий процесс.
- git blame. Очень часто требуется выяснить, кто, когда и зачем добавил или изменил ту или иную строку кода. Можно потратить не один час, решая эту задачу средствами хранилища конфигурации 1С, а средствами git это делается моментально.
- Ветки. В репозитории git можно организовать ветки кода, в которых хранить альтернативные версии продукта или вести параллельную разработку с последующим их слиянием. Особую ценность представляет возможность управления разработкой посредством веток, называемая "git flow".
- Хранение любой информации. В отличие от хранилища 1С, в git можно хранить любую информацию (желательно текстовую, но это не обязательно). Поэтому при использовании git возникает возможность хранить не только конфигурацию, но и все внешние отчеты, обработки и другую сопутствующую информацию.
Возникает вопрос, а можно ли при текущем варианте разработки, без использования EDT, использовать git? Ответ на этот вопрос: "да".
В этой статье я не буду касаться вопросов установки git, его использования и других широко освещенных в сети тем. Будем считать, что базовые знания по работе с git у вас уже есть и вы умеете пользоваться github'ом, а также умеете устанавливать программы на компьютер, создавать службы и выполнять другие административные операции.
Git & 1С
Для начала зафиксируем стандартный процесс разработки решений для платформы 1С:Предприятие:
- Разработка ведётся коллективом разработчиков при помощи конфигуратора;
- В качестве системы управления версиями используется хранилище конфигурации;
- При доработке кода, в коде, как правило, оставляются комментарии с информацией, кто, когда и почему изменил код. При этом прокомментировать таким образом изменения в формах или макетах вообще не представляется возможным.
- Управление внешними обработками осуществляется вручную, а сами обработки хранятся в файловой системе. Получить предыдущие версии обработок, скажем для старых версий продукта, зачастую, если такая возможность заранее не была предусмотрена процессом, невозможно.
Разумеется, таким образом процесс разработки организован не у всех, но это наиболее распространённая схема совместной работы.
С выходом EDT становится возможным работать без использования конфигуратора и хранилища конфигурации, но этот вариант я не буду рассматривать в данной статье: сейчас немногие энтузиасты готовы перевести процесс разработки в EDT, да и классический процесс разработки будет применяться ещё довольно долго. В случае же использования EDT, работа с git не только упрощается, но и отпадает необходимость обоснования использования git, т. к. git становится единственным (пока?) средством управления версиями кода.
Итак, что мы можем получить от использования git в проекте разработки продукта на основе 1С:Предприятие?
На первое место я бы поставил возможность получать информацию об источнике изменений (git blame). Теперь разработчик не обязан помещать в код метки, указывающие причину изменения кода, git всё это делает сам. Код становится чище, разработчику нужно делать меньше непродуктивной работы. Помимо этого, также становится доступной история изменений в макетах и формах.
Во-вторых, в git-репозитории, наряду с конфигурацией можно хранить внешние отчёты и обработки, что позволит не только получать информацию об истории изменений, но и версии этих обработок на любой момент времени, что до того достигалось при помощи определённых усилий со стороны разработчиков.
В-третьих, в git-репозитории можно хранить не только код, но и документацию к продукту, что также решает массу проблем с организацией процесса документирования и получения истории изменения документации.
Давайте определим, каким должен быть процесс разработки, исключим из существующего процесса лишние элементы, а какие-то элементы изменим и, возможно, введём новые.
- Разработка должна вестись в конфигураторе, как и раньше.
- Если возможно, вести разработку без хранилища конфигурации, ведь ему на замену мы решаем ввести git. Забегая вперёд скажу: это, к сожалению, сделать будет нельзя, по крайней мере, без существенного усложнения процесса разработки, но ведь мы добиваемся обратного -- его упрощения!
- Отсутствие необходимости комментировать изменения кода в самом коде. Описание изменений хранить отдельно от кода. По правде сказать, это можно делать и сейчас, заполняя комментарий версии при помещении объектов в хранилище конфигурации, однако в текущем виде комментарии могут дать ответ на вопрос, что было изменено в текущей версии, но нет инструмента, позволившего бы ответить на вопрос, в какой версии был изменён конкретный кусок кода.
- Внешние отчеты и обработки должны храниться вместе с кодом разрабатываемого продукта. При этом они также должны версионироваться по общим правилам версионирования кода git.
- Документация к продукту (пользовательская и разработческая) также должна располагаться в хранилище продукта. В конечном итоге, история изменения документации также представляет интерес, как и история изменения кода продукта.
Что можно сделать уже сейчас?
"Превращение" конфигурации в исходный код. Это делается при помощи меню конфигуратора "Конфигурация/Выгрузить конфигурацию в файлы" или использования ключа запуска конфигуратора "/DumpConfigToFiles". Однако следует помнить, что при работе без хранилища конфигурации возможны одновременные изменения одних и тех же объектов несколькими разработчиками, поэтому перед выгрузкой своих изменений нужно сначала произвести их слияние с изменениями других разработчиков.
Другими словами, при изменении конфигурации необходимо:
- выгрузить свою текущую конфигурацию в файлы;
- собрать из текущего состояния кода продукта конфигурацию (делается также через меню конфигуратора "Конфигурация/Загрузить конфигурацию из файлов" или ключа запуска конфигуратора "/LoadConfigFromFiles");
- выполнить получение изменений в локальный репозиторий продукта (pull);
- произвести сравнение/объединение текущей конфигурации продукта со своими изменениями;
- выполнить сохранение конфигурации в файлы, расположенные в локальном репозитории продукта;
- произвести commit изменений с указанием комментария изменений;
- выполнить push изменений в центральный репозиторий. При этом нужно быть готовым к тому, что с момента начала помещения Ваших изменений в git-репозиторий кто-то мог сделать это быстрее и при помещении изменений могут возникнуть конфликты, требующие ручного их разрешения. Для этого описанный здесь алгоритм нужно будет выполнять повторно.
Согласитесь, не самый простой способ до того так просто выполняющейся операции. Причём основную массу проблем вызывает именно асинхронные изменения кода, если их исключить, можно существенно упростить описанный процесс публикации изменений. Таким образом мы вынуждены вернуться к идее использования хранилища при разработке, к тому же у нас возникает единая точка возникновения изменений: не отдельная база разработчика, а само хранилище конфигурации. Каждое помещение изменений в хранилище и является отдельным коммитом в git-репозиторий. В результате, процесс помещения изменений в git-репозиторий существенно не изменяется:
- разработчик помещает изменения в хранилище конфигурации;
- производится выгрузка помещенных изменений в git.
Последний пункт не обязательно выполнять разработчику, его можно автоматизировать при помощи того же jenkins, в результате чего процесс разработки вообще останется без изменений.
Правда теперь выгрузку конфигурации придётся производить немного по-другому. Для выгрузки версии хранилища нужно сначала получить базу данных с нужной версией хранилища и затем уже выполнять её выгрузку в файлы. Для загрузки нужной версии конфигурации из хранилища используется ключ запуска конфигуратора "/ConfigurationRepositoryUpdateCfg". Выгрузку можно производить периодически или по факту изменения хранилища. При этом нужно "помнить" номер последней выгруженной версии хранилища и последовательно выгружать только те версии, которые появились после последней выгруженной.
Алгоритм выгрузки конфигурации получается следующим (я рассматриваю вариант с использованием git-сервера):
- клонируем репозиторий продукта в пустой каталог. Это необходимо, чтобы исключить влияние локальных изменений и выгружать конфигурацию в репозиторий, содержащий все изменения;
- определяем номер последней выгруженной версии хранилища;
- создаём пустую базу (команда запуска "CREATEINFOBASE") и подключаем её к хранилищу (ключ запуска конфигуратора "/ConfigurationRepositoryBindCfg")
- для каждой версии, большей, чем определённая на втором шаге, последовательно производим:
- обновление конфигурации на следующую версию хранилища;
- выгрузку конфигурации в каталог исходников в локальном git-репозитории;
- выполняем commit изменений с комментарием, указанном в хранилище конфигурации;
- устанавливаем номер последней выгруженной версии;
- выполняем push произведённых изменений в центральный репозиторий.
Таким образом в git-репозитории продукта у нас окажутся все версии хранилища со всей историей. Однако в процессе выгрузки изменений нужно будет решить вопрос с авторством коммитов, т. к. исходя из целей, в git-репозитории нам важно знать, кто произвёл те или иные изменения. Коммиты необходимо выполнять от имени их авторов с указанием их e-mail'ов.
gitsync
Безусловно, подобный функционал может реализовать почти каждый разработчик, и было бы странно, если бы эту функцию реализовывала каждая команда разработчиков и ни одна не поделилась бы результатами: готовым решением для синхронизации хранилища конфигурации и git-репозитория.
Такое решение существует, называется оно gitsync и реализовано на языке OneScript. Благодаря привычному синтаксису языка 1С:Предприятие, программы на OneScript будут понятны любому 1С-разработчику. Более того, на этом языке уже реализована масса инструментов предназначенных для автоматизации разработки на платформе 1С:Предприятие. В этой статье описаны существующие библиотеки для данного языка.
Здесь я продемонстрирую, как выполнить синхронизацию хранилища с git-репозиторием.
Для начала надо установить сам OneScript. Отсюда берём сам интерпретатор (в удобном для Вас виде и под Вашу платформу) и устанавливаем его в систему. Я буду демонстрировать использование на примере платформы Windows. По умолчанию OneScript устанавливается в каталог "C:\Program Files (x86)\OneScript" и в переменную "PATH" прописывается путь к каталогу исполняемых файлов OneScript "C:\Program Files (x86)\OneScript\bin". Если ы устанавливали OneScript не при помощи установщика, то вам придётся прописать путь к этому каталогу самостоятельно.
Далее нужно установить gitsync (возможно он уже установлен вместе с OneScript, но в будущих версиях OneScript gitsync может быть убран из стандартной поставки). Установка библиотек и приложений OneScript, производится специальной утилитой "opm" (OneScript Package Manager, поставляется вместе с интерпретатором) из специально созданного хаба, куда разработчики помещают эти библиотеки и приложения. Разумеется, это не единственный способ устанавливать библиотеки и приложения. Их можно разработать самому или скачать из сети и сохранить в любой каталог, предварительно "сообщив" интерпретатору, что библиотеки и приложения нужно искать ещё и в нём.
На всякий случай выполним обновление библиотек оскрипта (данный шаг выполнять не обязательно, если у вас уже установлены последние версии библиотек):
REM Обновим только opm
> opm update opm
REM Обновим все установленные библиотеки
> opm update -all
REM Установим gitsync
> opm install gitsync
Нужно помнить, что в большинстве случаев данные команды надо выполнять с правами администратора, т. к. обновляемые библиотеки располагаются в иерархии каталога установки OneScript, в который запрещена запись простым пользователям.
После установки, gitsync доступен для запуска, т. к. скрипт запуска создаётся в каталоге исполняемых файлов OneScript. Ознакомиться с параметрами запуска gitsync можно при помощи команды
> gitsync help
Теперь нужно настроить git-репозиторий для работы с gitsync. Для этого надо создать в репозитории каталог, в котором будут храниться исходники конфигурации (примем, что это будет каталог "cf" в корне репозитория), инициализировать gitsync в данном репозитории, настроить пользователей хранилища и указать версию хранилища, начиная с которой нужно выполнять синхронизацию.
REM Здесь я создам сам git-репозиторий. Это делать не надо, если у вас уже есть git-репозиторий
> git init myProduct
> cd myProduct
REM Создадим каталог исходников
> md cf
REM Инициализируем gitsync. Здесь нужно указать путь к хранилищу конфигурации,
REM пока сетевой, но в будущем появится возможность указывать хранилище, расположенное
REM на сервере хранилища конфигурации и предоставляемое по протоколам tcp или http
REM
REM указание домена e-mail адресов не обязательно, но тогда вам потребуется указать его
REM вручную для каждого пользователя хранилища конфигурации
> gitsync init d:/path/to/storage/product cf -email my.domain.com
В результате выполнения этой команды в каталоге "cf" создались два файла: "AUTHORS" и "VERSION". В файле "AUTHORS" указаны все пользователи хранилища, здесь надо проверить правильность указания e-mail адресов этих пользователей. Все коммиты в git-репозиторий будут производиться от имени пользователей с этими e-mail'ами. Файл "VERSION" имеет формат xml и содержит единственный узел "VERSION", в который нужно записать номер версии хранилища, начиная с которой необходимо выполнять синхронизацию. Делать это вручную не обязательно, для этого у gitsync есть команда "set-version". Выполняем
> gitsync set-version cf 0
где "cf": -- каталог, в котором расположен файл "VERSION", а 0: -- номер версии, начиная с которой нужно выполнять синхронизацию.
К этому моменту к синхронизации всё готово. Выполняем команду
> gitsync export d:/path/to/storage/product cf
и ждём. Если у вас большая конфигурация или в хранилище достаточно много версий, ждать придётся ощутимо долго, будьте к этому готовы. Однако можно разбить синхронизацию хранилища с git-репозиторием на несколько этапов, выгружая за один запуск gitsync по небольшому количеству версий, указав ему параметры "-minversion" и "-maxversion". Также при запуске gitsync следите за версией платформы 1С:Предприятие (по умолчанию будет запускаться последняя версия), указать конкретную версию можно при помощи ключа "-v8version".
Всё. На данный момент в локальном git-репозитории мы имеем всю историю хранилища конфигурации и можно выполнить push в центральный репозиторий продукта на сервер, если у вас такой есть.
Для упрощения коллективной работы с репозиторием продукта я настоятельно рекомендую держать этот репозиторий на каком-либо git-сервере, но помните, что не всякий продукт можно выкладывать в общедоступные репозитории, например на github, из-за лицензионных ограничений. При этом есть возможность "поднять" свой собственный git-сервер внутри локальной сети. Есть разные git-серверы с разными возможностями, лицензиями и стоимостью, я использую простой и бесплатный gogs, но, наверное, сейчас остановил бы свой выбор на gitlab.
precommit1c
Теперь вернёмся к вопросу версионирования внешних отчётов и обработок. В последних версиях платформы есть возможность редактирования внешних отчётов и обработок в "иерархическом XML формате". В этом случае никаких особых действий производить не требуется. Правка отчетов и обработок, находящихся в репозитории продукта производится, как обычно, в конфигураторе, после чего осуществляется коммит изменений. При этом может возникнуть конфликт изменений, когда в репозитории на сервере находится более новая версия отчета/обработки, чем та, которая была изменена разработчиком. Здесь от разработчика потребуется произвести слияние изменения или внести свои изменения повторно, после получения свежей версии отчета/обработки. Впрочем, данный подход для git является штатным и к нему нужно привыкнуть, нужно только не забывать перед началом правки чего-либо получить свежие изменения в репозитории, а после изменений осуществлять коммит этих изменений и push на сервер.
Если же ваша платформа не поддерживает редактирование отчетов/обработок в "иерархическом XML формате", то можно воспользоваться специальной "утилитой" "precommit1c", которая является, по сути, набором git-"перехватчиков" (git hooks), выполняемых при какой-либо операции с репозиторием. В данном случае действия выполняются при коммите изменений в репозиторий. Для использования precommit1c необходимо его установить и настроить локальный репозиторий для работы с ним.
Установка самого precommit1c на компьютер производится через opm командой
> opm install precommit1c
Эту операцию, как уже говорилось выше, нужно выполнять с правами администратора системы. Настройка локального репозитория для работы с percommit1c выполняется командой
> precommit1c --install
запущенной в каталоге локального репозитория. Важно помнить, что данную операцию нужно выполнять в локальном репозитории каждого разработчика, в противном случае изменения обработки не отразятся в исходном коде этой обработки.
При коммите изменённой обработки в репозитории, precommit1c производит её разбор на файлы и помещает эти файлы в каталог "src" репозитория. Например, если обработка располагалась по пути "./epf/Внешние обработки/Моя обработка.epf", то исходники будут выгружены в каталог "./src/epf/Внешние обработки/Моя обработка". Также следует иметь ввиду, что формат выгрузки precommit1c не совместим с форматом хранения обработок в "иерархическом XML формате".
Собрать обработку обратно в epf файл можно при помощи того же precommit1c, используя команду "--compile", Например команда
> precommit1c --compile "/path/to/repository/src/epf/Внешние обработки/Моя обработка" "D:/epf"
создаст в каталоге "D:/epf" файл "Моя обработка.epf". Рекомендую при указании путей использовать прямые слеши ("/"), а не принятые в windows обратные. Это сэкономит вам массу времени и нервов при дальнейшей автоматизации процессов.
Структура репозитория
В процессе работы с продуктом у вас выработаются свои стандарты хранения информации внутри репозитория продукта. Вы для себя определите, где хранить файлы конфигурации, где хранить файлы внешних отчетов и обработок, где хранить документацию и прочие правила. Однако можно воспользоваться готовым шаблоном структуры репозитория продукта. В частности здесь можно "подсмотреть" рекомендуемую командой Silverbulleters иерархию каталогов. Возможно, изучение данной структуры поможет вам разработать подход к построению своей структуры, возможно, вы возьмёте данный шаблон за основу. Этот шаблон не догма и не руководство к действию, а только лишь пример.
Однако есть одна практическая рекомендация, которая может облегчить жизнь при дальнейшей эксплуатации различных инструментов: каталог исходников конфигурации нужно располагать как можно ближе к корню файловой системы. Причиной этому служит ограничение максимальной длины пути в операционной системе, особенно, когда в Вашей конфигурации присутствуют объекты с достаточно длинными наименованиями, что часто встречается в типовых конфигурациях и в БСП в частности. Эта рекомендация в большей степени касается windows, но 1С слабо отделим от windows, поэтому, даже если у вас вся разработка ведётся на Linux, всё равно не пренебрегайте этим правилом.
Итоги
В данной статье я попытался рассказать о способе включения git в процесс разработки решений на базе платформы 1С:Предприятие. Использование git позволяет расширить возможности хранения истории кода, проектной информации и документации. В дальнейшем, я постараюсь рассказать, как использование git позволит упростить построение инфраструктуры CI и, возможно, расскажу об основах ведения разветвлённой разработки 1С-конфигураций.
Ссылки
Первая часть: Введение в CI для 1С
Вторая часть: Использование git при разработке на 1С