Обновление – это, наверное, одна из самых частых задач, которая стоит практически перед каждым из тех, кто связан с разработкой на 1С.
Главная особенность этой задачи состоит в том, что нам не позволено никакого творчества – нужно просто сделать все как следует.
После выполнения этой абсолютно рутинной и скучной работы (выполняется она обычно руками), раздаются звонки, приходят письма: «После вашего обновления, у нас, у нас есть проблемы» – «Я не хочу есть проблемы!»
За долгое время существования 1С появилось много интересных инструментов, которые позволяют сделать этот процесс чуть менее рутинным, чуть более быстрым. Об этом мы и поговорим.
Обновление неизбежно
Я вставил на слайд одно из самых частых возражений наших клиентов: «У нас уникальные бизнес-процессы, сделайте нам все, как мы хотим, обновляться мы не будем никогда – нам это не нужно».
1С-ники делятся на три категории:
-
на тех, кто обновляет;
-
на тех, кто будет обновлять;
-
и тающая категория «счастливчиков», от которых не требуют обновлений.
Эта третья категория с каждым годом становится все малочисленнее, потому что рано или поздно «счастливчики» перестают быть таковыми. Например, до недавних пор самым кастомизируемым и необновляемым решением была Управление торговлей. Но появились кассы, появились маркировки, появились ЭДО. И внезапно выяснилось, что решение от вендора обходится клиенту существенно дешевле, чем содержание штата своих программистов, которые всю эту красоту внедрят в систему.
Что затронем в докладе
Какие темы затронем?
-
Как дорабатывать, чтобы испытывать меньше боли.
-
Как обновлять.
-
Какие инструменты использовать.
-
Как проверять результаты.
-
Немного коснемся того, о чем зачастую забывают.
Не будем затрагивать темы про:
-
Расширения – тема обширная, но пока, на мой взгляд, мало изучена, мало практики накоплено. В своей практике пользуюсь исключительно по необходимости, когда клиенты на поддержку приходят с такими волшебными вещами.
-
EDT также не будем обсуждать, хотя оно, конечно, близко к нашей теме и обладает дополнительным набором инструментов, которые тоже облегчают процесс обновления.
-
Распределенные информационные базы – зло абсолютное!
-
Обычные формы – пора выкидывать!
Подходы к внесению доработок
Краткая памятка по доработке конфигураций:
-
Не «ломаем» – избегаем изменения типовых механизмов.
-
Все доработки максимально отражаем через код.
-
По возможности, минимально затрагиваем объекты поставщика.
-
Формы дорабатываем кодом.
-
Весь внесенный наш код или измененный код вендора обрамляем комментариями.
По ссылке https://github.com/arkuznetsov/some1cdocs/blob/master/docs/changing-1c-conf.md я собрал свой концентрированный опыт за многолетнюю работу с 1С, там описаны те приемы и подходы к доработкам, которые позволяют уменьшить в дальнейшем боль от обновлений.
Ранее мы использовали классический «хардкорный» способ обновления – с тремя конфигураторами.
-
В первом конфигураторе мы сравниваем нашу доработанную конфигурацию со старой конфигурацией поставщика.
-
Во втором – выявляем типовые изменения старой и новой конфигурации поставщика.
-
И в третьем – выполняем обновление вручную штатными средствами. Автообновлению я лично не доверяю, еще с тех старых пор, когда оно давало не очень вменяемые результаты.
Первые два конфигуратора в этом способе нужны для контроля изменений, особенно в случаях, когда поставщик, как это часто бывает, существенно изменил расположение своих процедур и функций, а то и полностью переписал функциональность. Чтобы корректно все перенести, информация о типовых изменениях может быть полезна.
Чтобы повысить качество обновления, может пригодиться еще один один простой, но не самый дешевый способ – это посадить рядом двух человек обновлять одну и ту же конфигурацию. И так как вероятность того, что оба ошибутся в одних и тех же местах достаточно мала, то сравниваем получившиеся CF-ники, правим ошибки и получаем обновленную конфигурацию.
По ссылке https://github.com/arkuznetsov/some1cdocs/blob/master/docs/deploing-1c-conf.md приведена небольшая памятка про «дедовский» способ обновления с тремя конфигураторами.
Как организовать контур разработки и процесс внесения изменений с использованием Git
В последнее время для обновлений можно использовать Git. Он уже для многих любимый, но для некоторых еще не знакомый. Почему Git?
-
Потому что так быстрее. И автоматически. Почти.
-
Git нам позволяет хранить всю историю изменений – как наши доработки, так и историю выполняемых обновлений.
-
Также в Git мы храним информацию об авторстве. Это полезно как минимум для того, чтобы видеть, кто менял конкретный кусок кода.
Самый простой подход к обновлению с использованием Git выглядит следующим образом.
-
Мы берем старую конфигурацию поставщика, выгружаем ее путем выгрузки файлов в Git и сохраняем (коммитим) в ветку master.
-
И из этого же коммита создаем новую ветку – называем ее base1C (потому что чаще всего поставщик типовой конфигурации – фирма 1С)
-
Следующим шагом мы выгружаем в ветку base1C новую конфигурацию поставщика поверх старой, тоже сохраняем.
-
Точно так же мы выгружаем нашу доработанную конфигурацию и сохраняем ее в ветку master.
-
И далее командой git merge выполняем слияние нашей доработанной конфигурации с новой конфигурацией поставщика.
-
После этого мы получаем некий результат, но он не всегда полностью автоматический, т.к. обычно остаются какие-то конфликты, например, когда и мы, и поставщик изменили один и тот же объект (в терминах Git – один и тот же файл). Соответственно, мы решаем эти конфликты.
-
И в конце загружаем получившийся результат через загрузку файлов обратно в конфигуратор – получаем наш обновленный cf-ник.
Если вы уже используете Git в своей повседневной работе, но еще не имеете в этом репозитарии ветку поставщика, ситуация усложняется.
Большая красная надпись на слайде связана с тем, что добавить ветку поставщика в существующий репозитарий – задача не тривиальная. И, в зависимости от способа, ее результат гарантирует не все возможности. В частности, может возникнуть проблема с авторством коммитов.
-
Самый простой вариант – это начать с «чистого листа».
-
Еще есть вариант – собрать ветку поставщика из двух репозитариев. Отдельно выгрузить в репозитарий конфигурации поставщика все те версии, которые мы ранее дорабатывали. И слить эти два репозитария в один.
-
Также у Git есть достаточно глубокие возможности под названием rebase и filter-branch. Я много раз пробовал их использовать, но почему-то ни разу положительного результата получить не удавалось, видимо моих познаний в GIT пока недостаточно, и я каждый раз все ломал. Но я верю, что это возможно, и буду изучать тему дальше.
-
И еще один достаточно «топорный» вариант – это на основании ветки master с текущим состоянием нашей конфигурации создать ветку base1C, почистить ее, туда залить старую конфигурацию поставщика, от нее сделать ветку update для обновления, и уже с этим работать.
Наша задача – получить ситуацию, когда у нас есть общий предок для трехстороннего сравнения-объединения.
И далее идем по тому процессу, который был описан ранее (на предыдущем слайде):
-
в ветке update выполняем слияние текущего состояния master с выгрузкой новой конфигурации поставщика из base1C;
-
решаем конфликты;
-
загружаем конфигурацию в базу и проверяем, что там все в порядке;
-
после этого имеет смысл еще раз дополнительно выгрузить конфигурацию обратно в файлы, потому что иногда, к сожалению, при повторной выгрузке появляются некоторые дополнительные артефакты от 1С;
-
и заливаем в ветку master наш результат обновления в качестве нашей новой, обновленной версии.
Идеальный вариант – когда у нас уже есть красивый репозитарий с веткой master и отдельной веткой поставщика base1C.
Тогда все достаточно просто.
-
мы просто подливаем регулярно из ветки master в нашу ветку update для выполнения обновлений те изменения, которые выполняем в процессе разработки;
-
в момент выхода новой версии поставщика кладем ее файлы в ветку поставщика base1C;
-
выполняем слияние base1C и update;
-
и дальше по той же схеме – решаем конфликты, заливаем в базу, проверяем, что все залилось;
-
и загружаем файлы из ветки update в наш master.
Какие у нас есть ключевые точки?
-
Получение конфигурации поставщика.
-
Подготовка – выгрузка в файлы нашей конфигурации.
-
Выполнение слияния и разрешение конфликтов.
-
Загрузка результирующей конфигурации.
Давайте далее посмотрим, какие инструменты и подходы мы можем применить для каждого из этих моментов.
Инструменты, повышающие скорость и качество обновлений
Где взять конфигурацию поставщика?
-
Понятно, что текущая конфигурация поставщика есть в нашей базе – надеюсь, вы уже перестали снимать свои конфигурации с поддержки.
-
Новую конфигурацию поставщика мы качаем с сайта releases.1c.ru.
-
Но процесс скачивания файла с сайта релизов хочется как-то автоматизировать. Для этого существует уже достаточно большое количество средств загрузки конфигураций с сайта – они написаны на абсолютно разных языках. Многие из них находятся на GitHub.
-
Как обычно, для искоренения этого «фатального недостатка» мы напилили свое средство и назвали его Yet another release downloader (YARD).
Разумеется, мы реализовали его на OneScript и выложили на GitHub в репозитарий https://github.com/ArKuznetsov/yard.
YARD выполняет:
-
Загрузку релизов – это многие умеют
-
Далее идет функция, которую мне не удалось найти в других инструментах – это распаковка архивов конфигурации. У 1С есть две проблемы. Во-первых, файл setup в silent-режиме не запускается, и во-вторых, дистрибутив обновления использует свой собственный формат архива – файл efd. По сути, это просто zip без заголовка. В одной из публикаций на Инфостарте добрый человек с этим разобрался, а я всего лишь адаптировал его разработки под OneScript и немного причесал.
-
Следующий момент – к сожалению, до сих пор часть конфигураций на сайте релизов 1С выкладываются не в полном виде, а в виде только файлов обновлений – CFU. А для Бухгалтерии хотя и выложен cf-файл в полном виде, но он сейчас требует номера телефона. Т.е. скачивание таких файлов плохо автоматизируется. Инструмент YARD решает и эту задачу – мы скачиваем нужную нам последовательность релизов, натравливаем YARD, и он нам последовательно собирает все полные cf-файлы и раскладывает по тем же папкам.
-
И еще одна функция – это выгрузка скачанных конфигураций в репозитарий GIT. YARD может точно так же по всем этим папкам пройтись и создать нам, по сути, отдельный репозитарий с конфигурацией поставщика, который мы потом можем использовать для целей обновления. Он все файлики последовательно выложит и пометит их датами выхода релизов.
Что касается выгрузки в файлы, то этот процесс требует постоянного внимания разработчика, т.к. состоит из последовательных нажатий на кнопки в конфигураторе, очистки каталогов, переключения веток в GIT и т.п. Например, если вы запустили обновление в пятницу вечером и случайно забыли о нем, то процесс затянется на все выходные.
Для решения этого вопроса сделали еще один инструмент – назвали его Rector.
Из репозитария https://github.com/silverbulleters/rector вы также можете скачать его исходники.
Одной из функций Rector является последовательная выгрузка хранилища конфигурации в файлы.
Все знают, что для этой цели уже есть инструмент Gitsync. Но Rector, в отличие от Gitsync, умеет еще и последовательно вытащить конфигурацию поставщика и положить ее в отдельную ветку.
Одна проблема – Rector был не совсем удачным экспериментом, т.к. работает он не быстро.
Так как у нас отсутствует информация о версии конфигурации поставщика, нам приходится для каждого коммита ее выгружать и проверять, что файл не изменился. Мы этот файл не распаковываем каждый раз, а проверяем его просто через хэш, но, тем не менее, это требуется делать. Если файл изменился, то мы распаковываем, вытаскиваем конфигурацию поставщика, кладем в ветку поставщика.
Долго, но работает. Если у вас маленький репозитарий и вам интересно, можете поэкспериментировать.
У Rector есть нереализованная функциональность – задумывалось, что он сможет корректно слить два репозитария – узнает, какая версия поставщика была правильной, и из двух репозитариев соберет третий.
Но основная функция Rector, которой я пользуюсь – это решение задачи подготовки репозитария для обновления по той схеме, которую я до этого показывал.
Как подготовить обновление с использованием Rector:
-
На входе библиотека принимает cf-файлы. Ей можно подать на вход две или три конфигурации – если подать две, она из первой конфигурации сама достанет старую конфигурацию поставщика (если, конечно, она там есть). Также можно подать на вход хранилище или готовые распакованные репозитарии.
-
На выходе мы получаем репозитарий с практически готовыми результатами слияния, и нам остается только разрешить конфликты.
Соответственно, к этому результату мы применяем инструмент для разрешения конфликтов объединения. Таких инструментов достаточно много (kdiff3, p4merge и пр.). Я в практике привык использовать kdiff3. Он нам показывает общего предка, показывает изменение каждого из потомков относительно него, т.е. изменения нашей доработанной конфигурации и новой конфигурации поставщика.
Часть задач по решению конфликтов этот инструмент берет на себя – он автоматически распознает, с какой стороны взять правильный код.
Часть задач он предлагает нам решить самостоятельно.
И результат записывает в наш файлик.
Проблемы слияния
Но не все так радужно. При слиянии могут возникнуть некоторые проблемы:
-
На первом месте стоит забавная проблема – иногда инструменты объединения считают себя довольно умными и принимают решение об объединении там, где его принимать не нужно. Чаще всего это случается в том случае, если поставщик сильно изменил структуру модуля – переставил местами процедуры и функции. В 90% случаев это очень просто ловится на этапе проверки модулей, потому что код попадает между функциями – модуль считается некорректным, 1С нам об этом скажет.
-
Следующая проблема – это управляемые формы, измененные путем добавления реквизитов в редакторе форм. Проблема очень простая – у реквизитов формы существуют цифровые идентификаторы, которые должны быть уникальны. Соответственно, если мы независимо от поставщика изменили форму путем добавления реквизита, а потом поставщик тоже добавил новый реквизит на форму, то у этих двух разных реквизитов будет один и тот же идентификатор. За этим нужно смотреть. Поэтому, как я уже раньше сказал, лучше дорабатывать существующие формы кодом. Это позволяет избегать проблем. Код объединяется очень хорошо.
-
XML-файлы. Инструменты сравнения-объединения работают со всем, как с текстом. Они не различают тегов. И здесь может оказаться, что это серьезная проблема. Но на самом деле я считаю, что это – возможность. Это позволяет в процессе выполнения обновлений качественно изучить структуру этих XML-файлов для лучшего понимания того, как это все хранится в 1С.
-
Бинарные файлы – их редко меняют, поэтому обычно конфликты бинарных файлов решаются путем замены на файлы, полученные из конфигурации поставщика.
-
Есть проблема со сменой авторства кода – в большинстве случаев это, опять же, связано с изменением структуры модуля, который сделал поставщик. Мы доработали процедуру «При открытии», которая раньше была вверху. В следующем релизе она уехала куда-то далеко вниз. Мы честно это заметили при слиянии, честно перенесли наши доработки в эту процедуру. Но с этого момента авторами этой процедуры будем считаться мы, а не тот, кто ранее вносил эти изменения.
-
И, к сожалению, все еще существуют небольшие проблемы с выгрузкой/загрузкой – при повторной выгрузке конфигурации появляются некоторые артефакты. Конфигурация, выгруженная в файлы и потом загруженная обратно, иногда изменяется. Это проявляется в мелочах и не влияет ни на какую функциональность – чаще всего это какие-нибудь файлы справки. Но это вносит некий дополнительный шум и добавляет чуть-чуть работы.
Контроль результатов обновления
Как нам проверить те результаты, которые мы получили?
-
Первым этапом проверки выступает момент загрузки конфигурации из файлов. После чего мы иногда получаем картинку со многими красными восклицательными знаками. Есть хорошая новость – в платформе 8.3.17 оказалось, что если по этим строчкам кликнуть, то во многих случаях откроется конкретный файлик с указанием проблемного места. Раньше такого не было. Это приятно, это значит, что платформа развивается. Надеюсь, что дальше будет еще лучше, еще проще искать такие проблемы.
-
Следующим заградительным постом от ошибок является синтаксический контроль и проверка модулей. Как я выше уже упоминал, иногда бывает, что модули слились некорректно. Эти ошибки синтаксический контроль отлавливает очень хорошо. Запустили проверку, подождали, посмотрели ошибки и исправили их. После чего все загрузилось.
-
Еще – очень хорошо результат загрузки помогают проверить дымовые тесты. С тестами так всегда – чем больше тестов, тем лучше. Здесь показана картинка из многим знакомого Jenkins как раз по результатам выполнения обновлений.
-
И также, как я уже упоминал, полезно взять и загруженный cf-ник тут же выгрузить обратно – это позволяет еще раз себя проверить, увидеть, какие там появились артефакты, и закоммитить. Поэтому обычно после коммита слияния у меня еще следует коммит с исправлениями артефактов. И в этот же момент мы еще выгружаем правильный файл поставки. Слить его мы его не можем, так как он имеет не совсем текстовый формат, поэтому мы его просто в момент обновления забираем из новой конфигурации поставщика как он есть, а после загрузки cf-ника мы выгружаем результат и получаем правильный файл поставки.
Про что мы обычно забываем в этом процессе?
-
Дополнительные отчеты и обработки, которые лежат в соответствующем справочнике. Мы вроде все обновили, накатили, но потом нам прилетает, что ничего не работает. Здесь рекомендация – храните их и дорабатывайте в Git. Это позволяет, как минимум, о них помнить.
-
Опять же, в Git имеет смысл хранить тесты.
-
Также забываем о правилах обмена. Рекомендация та же – храните в Git. Здесь вам может помочь разработка GitRules от Олега Тымко. Она позволяет огромный XML-файл правил «Конвертации данных 2» разложить по папкам на отдельные куски кода и комфортно смотреть, что там изменилось, удобно дорабатывать и пр.
-
Я уже говорил, что про расширения мы говорить не будем. Тем не менее, их, как минимум, нужно проверить на применимость. Хорошо, что платформа предоставляет нам инструменты для этого, а также мы можем использовать тесты.
-
Часто забываем загрузить конфигурацию поставщика. Прежде чем собирать файл поставки для продуктива, не забудьте выполнить стандартное обновление конфигурации поставщика – просто чтобы она попала в базу. Никаких флажков тут уже изменять не нужно – просто запускаем обновление, нажимаем ОК, после чего уже накатываем нашу подготовленную обновленную конфигурацию.
Бонусы и итоги
Бонусом за использование Git мы получаем быстрое произвольное сравнение версий – это решает ту боль, которая у нас есть в хранилище, где практически нереально дождаться сравнения и найти, кто менял конкретный объект. Здесь сравнение производится просто в редакторе. Выделяем две любые версии из двух любых веток, получаем все различия, которые у нас имеются.
Также мы быстро видим авторов кода. Это нам помогает, например, при использовании статического анализа с помощью SonarQube, т.к. мы можем отфильтровать ошибки в коде по автору 1c@1c.ru и увидеть только те ошибки, которые касаются нашего кода.
В итоге – что мы получили?
-
Мы умеем быстро готовить обновления – как минимум, так обновлять интереснее.
-
Мы знаем, как проверить результаты обновления.
-
И умеем готовить красивый репозитарий, который, в частности, помогает нам исключить те ошибки, которые вносит вендор, и отделить их от наших.
Лишний раз напомню, что ссылки на все упомянутые инструменты добавлены не просто так, а чтобы ими пользовались, присылали свои идеи и замечания, ну и, разумеется, pull request’ы.
-
https://github.com/arkuznetsov/some1cdocs/blob/master/docs/changing-1c-conf.md – рекомендации по внесению изменений в конфигурацию;
-
https://github.com/arkuznetsov/some1cdocs/blob/master/docs/deploing-1c-conf.md – рекомендации по выполнению обновлений;
-
https://github.com/ArKuznetsov/yard – инструмент для загрузки релизов с сайта 1С;
-
https://github.com/silverbulleters/rector – инструмент для подготовки обновлений с использованием GIT
*************
Данная статья написана по итогам доклада (видео), прочитанного на конференции Infostart Event 2021 Post-Apocalypse.
Также Артем провел мастер-класс: Обновляем доработанную конфигурацию "без боли".