Перейти к основному содержанию
`Ctrl`+`K`

# Релизы

Релиз представляет из себя снимок файлов определенной версии.

## Решение

Релиз решения содержит перечень модулей и их версий.

## Конфигурация

Релиз конфигурации содержит данные и скрипты обновления конфигурации решения. База выпуска релизов выбирается по согласованию с заказчиком.

## Сервер приложения

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

## Комплект сборки

Содержит скомпилированные прикладные модули. Версия формируется по следующему правилу:

- `GENERATION` - модули должны содержать одно поколение.

- `MAJOR` - перещелкивается при любом изменении мажорной версии модуля в составе комплекта.

- `MINOR` - перещелкивается при любом изменении минорной версии модуля в составе комплекта.

- `BUILD` - перещелкивается при любом изменении билда версии модуля в составе комплекта.

- `PATCH` - перещелкивается при любом изменении патч версии модуля в составе комплекта.

## Snapshot версия

Используется для распространения артефактов из ночной сборки или внеплановой сборки. Разработчики могут повторно загружать артефакты snapshot-версий в репозиторий.

Для обновления Snapshot версий разработчику необходимо выполнить следующие команды sbt:

    sbt clean
    sbt update
    sbt updateClassifiers
    sbt publishDevDependencies

## Релиз прикладного модуля

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

### Версия модуля

Укажите версию модуля в формате: Поколение.МажорнаяВерсия.МинорнаяВерсия.Билд.Патч

### Типы релиза

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

- `Мажор` – крупные изменения, которые могут ломать обратную совместимость. К примеру переключение сервера приложений или обновление SBT плагина.

- `Минор` – плановые изменения в рамках развития модуля, а так же изменение конфигурации модулей проекта (добавление, удаление модулей).

- `Билд` – сквозная нумерация. Увеличивается при выпуске любой из версий, не считая патчей.

- `Патч` – изменения критических ошибок на уже выпущенных версиях. От патчей нельзя создавать другие версии, кроме последующих патчей.

#### Состав релиза

Релиз состоит из:

- исходного кода;

- первичных данных, указанных в `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`. Могут содержать секцию, которая будет выполнена, если задача уже выполнялась на целевой базе. А также могут быть анонимными и не содержать тело.

###### Простая задача

Содержит только тело. Пример объявления задачи:

    upTask("taskWOElse", 1){
      //Код задачи
    }

###### Задача с секцией orElse

Если задача выполняет установку каких-то данных, например, типа объекта, то можно указать ей секцию `orElse`, которая будет вызвана, если тело задачи уже было выполнено, например, в этой секции можно вызвать метод поиска типа объекта по его системному имени.
Пример объявления такой задачи:

    upTask("installType", 1){
      Btk_AuditActionApi().register("someName", "someCaption", "SomeDesc")
    }.orElse{
      Btk_AuditActionApi().findByMnemoCode("someName")
    }

###### Анонимная задача

Задача без тела, выполняется для группировки зависимостей.
Пример объявления:

    upTask("dependencyGroup")
      .dependsOnDbData("Wf_Doc", "dataInstall", 25)
      .dependsOn(installStkTypeTask())

###### Зависимости

Для каждой задачи можно указать зависимость как от другой задачи, так и от данных, устанавливаемых секцией `dbData`.

Пример объявления зависимостей:

    val someOtherTask = upTask("someOtherTask", 1){
      //Код задачи
    }

    upTask("taskWOElse", 1){
      //Код задачи
    }
      .dependsOnDbData("Wf_Doc", "dataInstall", 25) //зависимость от dbData
      .dependsOn(someOtherTask) // зависимость от другой задачи

###### Зависимости между модулями.

Для того чтобы сделать зависимость задачи одного модуля (`module1`) от задачи другого (`module2`) требуется:

1. В `Module1_MigratePkg` задачу вынести в отдельный метод и вызывать его из `upMigrate.`:

       def someTask(): UpTask[NLong] = {
         upTask("someTask", 1){
           1.nl
         }
       }

       override def onUpMigrate(): Unit = {
         someTask()
       }

2. В `Module2_MigratePkg` для задачи указать зависимость от задачи из `module1`:

       override def onUpMigrate(): Unit = {
         val someTask = Module1_MigratePkg().someTask()
         upTask("someDepTask", 1){
           //Получаем значение, которое вернула задача, от которой зависим
           val someTaskValue = someTask.get()
         }
           .dependsOn(someTask)
       }

##### DownTask

Задачи метода `downMigrate`. Содержат только тело задачи.
Пример объявления задачи:

    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.

2. В нужном модуле в `scala`-ветки найдите или создайте пакет с именем `<Имя модуля>_MigratePkg`.

3. Создайте задачу миграции, используя методы `upTask` или `downTask`.

### Создание sql-скрипта миграции

1. Зайдите в IDE.

2. В нужном модуле в ветке `resource/migration` найдите или создайте файл `trunk.script.jexl`.

3. Добавьте в него скрипт используя методе `before` или `after`.

### Выпуск новой версии

Выпуск с помощью плагина для IDEA Выпуск с помощью GSF-CLI.

### Установка релиза

1. Сервер приложений Global должен быть запущен.

2. Подключитесь к серверу `SSH`-клиентом. И выполните скрипт.

       attach db {dbAlias} as sys
       upgrade
       detach
       exit

   `dbAlias` – алиас базы данных. Если не указан, будет использоваться значение по умолчанию из `global3.config.xml`

Обновление будет выполняться под суперпользователем `SYS`

#### Алгоритм работы

1. `Shh`-команда `attach db as sys` переключает консоль в режим работы с обновлениями.

2. Команда `upgrade` запустит процесс обновления, состоящий из следующих действий:

   1. Формирование очереди выполнения `sql`-скриптов миграции.

   2. Последовательное обновление схемы с промежуточными выполнениями скриптов.

   3. Установка первичных данных (`dbData`).

   4. Выполнение задач миграции.

3. Отключение от базы.

4. Выход из SSH.

#### Сброс состояния обновления

Если требуется откатить информацию об установленных первичных данных или миграционных задачах, то используется `ssh`-команда: `reset upgrade`.

Если в нее не передан идентификатор обновления, то будет сброшено последнее выполненное обновление.

    attach db {dbAlias} as sys
    reset upgrade
    detach
    exit

или

    attach db {dbAlias} as sys
    reset upgrade 10202
    detach
    exit

### Создание нового тега

1. Выбираем проект, заходим в коммиты этого проекта.

2. Выбираем коммит, от которого хотим создать тег, нажимаем на вкладку «Options» в правом верхнем углу, выбираем «Tag».

3. В поле «Tag name» вводим номер следующего тега. В поле «Message» то же, только перед этим слово «Release».

4. Выбираем «Create tag».