# Релизы Релиз представляет из себя снимок файлов определенной версии. ## Решение Релиз решения содержит перечень модулей и их версии. ## Конфигурация Релиз конфигурации содержит данные и скрипты обновления `конфигурации решения`. База выпуска релизов выбирается по согласованию с заказчиком. ## Сервер приложения Содержит в себе ядровой функционал необходимый для запуска решения. Использует [семантическое версионирование](https://semver.org/). ## Комплект сборки Содержит скомпилированные прикладные модули. Версия формируется по следующему правилу: - `MAJOR` \ Модули должны содержать одну мажор версию. - `MINOR` \ Перещелкивается при любом изменении минорной версии модуля в составе комплекта. - `PATCH` \ Перещелкивается при любом изменении патч версии модуля в составе комплекта. ## Snapshot версия Используется для распространения артефактов из ночной сборки или внеплановой сборки. Артефакты snapshot версии могут повторно закачиваться в репозиторий. Для обновления Snapshot версий разработчику необходимо выполнить следующие команды sbt ```text sbt clean sbt update sbt updateClassifiers sbt publishDevDependencies ``` ## Релиз прикладного модуля Исходный код, согласованный на момент выпуска релиза, а также скрипты необходимые для установки обновления модуля в базе даннхы. ### Версия модуля Версия модуля задается в формате: МажорнаяВерсия.МинорнаяВерсия.Релиз.Билд ### Типы релиза - `Мажорный` – Крупные изменения, которые могут ломать обратную совместимость. Так же в этом типе релиза происходит очистка миграционных скриптов предыдущей версии. Устанавливается только на предыдущую мажорную версию. - `Минорный` – Крупные изменения, которые могут ломать обратную совместимость. - `Релиз` – изменения, требующие выполнения sql-скриптов миграции. - `Билд` – сборка, не требующая выполнения sql-скриптов миграции. Разрешается выпускать, если нет невыпущенных sql-скриптов миграции. #### Состав релиза Релиз состоит из: - Исходного кода - Первичных данных, указанных в `odm.xml` и `pkg.xml` - Первичных и миграционных данных, указанных в пакетах миграции (`<Имя модуля>_MigratePkg`) - `Sql`-скриптов миграции ##### Схема базы данных модуля Схема базы данных, прикладного модуля создается в базе данных при установке модуля. Объекты схемы, которые были сформированы ранее, и были удалены из исходного кода приложения, не удаляются из БД автоматически. Этим занимается администратор используя инструмент "Корзина удаленных объектов схемы". ##### Доменная схема Доменная схема, представляет из себя таблицы, индексы и последовательности создаваемые по описанию классов в `odm`-файлах. ##### Расширенная схема Расширенная схема, может быть описана в `odm`-, `pkg`-файлах, в тэге `dbSchema`. #### Поставочные данные модуля Поставочные данные прикладного модуля устанавливаются в базу данных при установки модуля. #### Миграционные данные Миграционные данные делятся на 2 типа: - `Sql-скрипты` - используются для работы с изменением схемы напрямую в БД, без `eclipse-link`. Хранятся в структуре модуля в ветке `resource/migration/dbSchema` - `Миграционные задачи` – скрипты, которые написаны с использованием `Api` и `Pkg`. Хранятся в миграционных пакетах модуля. ### Миграционные пакеты #### Общие сведения В каждом модуле возможно создание миграционного пакета, который должен иметь имя `<Имя модуля>_MigratePkg`, и находится в рутовом `scala`-каталоге модуля. Например, полное имя пакета модуля `btk` будет иметь вид: `ru.bitec.app.btk.Btk_MigratePkg` Этот пакет используется для написания кода по установке первичных данных или выполнения миграции данных, которое можно выполнить с помощью `scala`-кода. Миграционные пакеты требуется наследовать от `MigratePkg`, переопределяя в них методы `onUpMigrate` и `onDownMigrate`, в этих методах требуется создавать соответствующие задачи миграции через методы `upTask` и `downTask`. Вызов миграционных пакетов осуществляется после выполнения команды установки первичных данных (`init data`). #### Порядок вызова Вызов миграционных пакетов осуществляется в 2 прохода: - первый раз осуществляется вызов метода `upMigrate`, при обходе модулей от низкоуровниевых (например, `gtk`), к высокоуровниевым (например, `stk`). В этом методе можно писать логику по созданию новых данных - при втором проходе вызывается метод `downMigrate`, при проходе модулей от высокоуровниевых к низкоуровниевым. В этом методе можно удалять данные. #### Миграционные задачи Задачи имеют имя и версию. Задача выполняется только один раз, для того чтобы выполнить задачу повторно, требуется изменить ее версию или имя. Задачи делятся на 2 вида: - `upTask` - используется в `upMigrate` - `downTask` – используется в `downMigrate` ##### UpTask Задачи метода `upMigrate`. Позволяют указывать зависимости от других задач, от скриптов `dbData` из `odm.xml` и `pkg.xml`. Могут содержать секцию, которая будет выполнена, если задача уже выполнялась на целевой базе. А также могут быть анонимными и не содержать тело. ###### Простая задача Содержит только тело. Пример объявления задачи: ```scala upTask("taskWOElse", 1){ //Код задачи } ``` ###### Задача с секцией orElse Если задача выполняет установку каких-то данных, например, типа объекта, то можно указать ей секцию `orElse`, которая будет вызвана, если тело задачи уже было выполнено, например, в этой секции можно вызвать метод поиска типа объекта по его системному имени. Пример объявления такой задачи: ```scala upTask("installType", 1){ Btk_AuditActionApi().register("someName", "someCaption", "SomeDesc") }.orElse{ Btk_AuditActionApi().findByMnemoCode("someName") } ``` ###### Анонимная задача Задача без тела, выполняется для группировки зависимостей. Пример объявления: ```scala upTask("dependencyGroup") .dependsOnDbData("Wf_Doc", "dataInstall", 25) .dependsOn(installStkTypeTask()) ``` ###### Зависимости Для каждой задачи можно указать зависимость как от другой задачи, так и от данных, устанавливаемых секцией `dbData`. Пример объявления зависимостей. ```scala val someOtherTask = upTask("someOtherTask", 1){ //Код задачи } upTask("taskWOElse", 1){ //Код задачи } .dependsOnDbData("Wf_Doc", "dataInstall", 25) //зависимость от dbData .dependsOn(someOtherTask) // зависимость от другой задачи ``` ###### Зависимости между модулями. Для того, чтобы сделать зависимость задачи одного модуля (`module1`) от задачи другого (`module2`) требуется: 1. В `Module1_MigratePkg` задачу вынести в отдельный метод и вызывать его из `upMigrate.` ```scala def someTask(): UpTask[NLong] = { upTask("someTask", 1){ 1.nl } } override def onUpMigrate(): Unit = { someTask() } ```` 2. В `Module2_MigratePkg` для задачи указать зависимость от задачи из `module1`. ```scala override def onUpMigrate(): Unit = { val someTask = Module1_MigratePkg().someTask() upTask("someDepTask", 1){ //Получаем значение, которое вернула задача, от которой зависим val someTaskValue = someTask.get() } .dependsOn(someTask) } ``` ##### DownTask Задачи метода `downMigrate`. Содержат только тело задачи. Пример объявления задачи: ```scala downTask("Task_Down", 1) { //код задачи } ``` ### Sql-скрипты миграции #### Общие сведения Используются для внесения изменений в схему БД, до инициализации `eclipse-link`. Позволяют гарантированно выполняться в схеме, идентичной той, что была на момент выпуска релиза. #### Описание файла скриптов Миграционные скрипты размещаются внутри файла `resource/migration/trunk.script.jexl`. А при выпуске релиза копируются в подкаталог `resource/migration/dbSchema`. Скрипты пишутся в формате `jexl`-скрипта, и могут быть выполнены до обновления схемы или после. Исполняются внутри специального `jexl`-контекста, который обладает функциями: - `before` – скрипт будет выполнен до обновления схемы - `after` – скрипт будет выполнен после обновления схемы. Если при выполнении скрипта миграции будет получена ошибка, то процесс установки релиза и обновления базы будет прерван. Для того, чтобы выполнить какой-либо скрипт с игнорированием ошибок нужно добавить к нему директиву `force()`. #### Пример файла скриптов ``` //выполнение скрипта после обновления схемы after("scriptName1", ` delete from btk_class where 1=2 asd `); //выполнение скрипта перед обновлением схемы before("scriptName2", ` delete from btk_class where 1=2 `); //выполнение скрипта с игнорированием ошибок. //Если в таком скрипте произойдет ошибка, то обновление не будет остановлено after("scriptName3", ` delete from btk_class where 1=2 `).force(); ``` ## Инструкции ### Создание задачи миграции 1. Зайдите в IDE 1. В нужном модуле в `scala`-ветки найдите или создайте пакет с именем `<Имя модуля>_MigratePkg` 1. Создайте задачу миграции, используя методы `upTask` или `downTask` ### Создание sql-скрипта миграции 1. Зайдите в IDE 1. В нужном модуле в ветке `resource/migration` найдите или создайте файл `trunk.script.jexl` 1. Добавьте в него скрипт используя методе `before` или `after` ### Выпуск новой версии #### Выпуск билда 1. Запустите конфигуратор для базы разработки 1. Зайдите в модули 1. Выполните операцию `Выпустить билд` #### Выпуск релиза 1. Отправьте изменения в систему контроля версий 1. Запустите конфигуратор для базы разработки 1. Зайдите в модули 1. Выполните операцию `Выпустить релиз` #### Выпуск минорной версии 1. Отправьте изменения в систему контроля версий 1. Запустите конфигуратор для базы разработки 1. Зайдите в модули 1. Выполните операцию `Выпустить минорную версию` #### Выпуск мажорной версии 1. Отправьте изменения в систему контроля версий 1. Запустите конфигуратор для базы разработки 1. Зайдите в модули 1. Выполните операцию `Выпустить мажорную версию` ### Установка релиза 1. Сервер приложений Global должен быть запущен. 1. Подключитесь к серверу `SSH`-клиентом. И выполните скрипт. ``` attach db {dbAlias} as sys upgrade detach exit ``` `dbAlias` – алиас базы данных. Если не указан, будет использоваться значение по умолчанию из `global3.config.xml` Обновление будет выполняться под суперпользователем `SYS` #### Алгоритм работы 1. `Shh`-команда `attach db as sys` переключает консоль в режим работы с обновлениями. 1. Команда `upgrade` запустит процесс обновления, состоящий из следующих действий: 1. Формирование очереди выполнения `sql`-скриптов миграции. 1. Последовательное обновление схемы с промежуточными выполнениями скриптов 1. Установка первичных данных (`dbData`) 1. Выполнение задач миграции 1. Отключение от базы 1. Выход из SSH #### Сброс состояния обновления Если требуется откатить информацию об установленных первичных данных или миграционных задачах, то используется `ssh`-команда `reset upgrade` Если в нее не передан идентификатор обновления, то будет сброшено последнее выполненное обновление. ``` attach db {dbAlias} as sys reset upgrade detach exit ``` или ``` attach db {dbAlias} as sys reset upgrade 10202 detach exit ```