mirror of
https://github.com/firstBitMarksistskaya/jenkins-lib.git
synced 2024-12-04 10:34:42 +02:00
Merge branch 'develop'
This commit is contained in:
commit
b65f3f5c4e
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
build/
|
||||
bin/
|
||||
lib/
|
||||
out/
|
||||
|
||||
*.iml
|
||||
.classpath
|
||||
|
16
README.md
16
README.md
@ -112,8 +112,9 @@ pipeline1C()
|
||||
* `STORAGE_USER` - параметры авторизации в хранилище вида "username with password" (для `secrets` -> `storage`).
|
||||
* Все "шаги" по умолчанию выключены (`stages`).
|
||||
* Если в корне репозитория существует файл `packagedef`, то в шагах, работающих с информационной базой, будет выполнена попытка установки локальных зависимостей средствами `opm`.
|
||||
* Если после установки локальных зависимостей в каталоге `oscript_modules/bin` сушествует файл `vrunner`, то для выполнения команд работы с информационной базой будет использоваться он, а не глобально установленный `vrunner` из `PATH`.
|
||||
* Если после установки локальных зависимостей в каталоге `oscript_modules/bin` существует файл `vrunner`, то для выполнения команд работы с информационной базой будет использоваться он, а не глобально установленный `vrunner` из `PATH`.
|
||||
* Результаты в формате `allure` ожидаются в каталоге `build/out/allure` или его подкаталогах.
|
||||
* Каждый шаг имеет свой таймаут в минутах (от 10 до 240 в зависимости от "тяжёлости" шага сборки), но может быть переопределен в секции настроек `timeout`.
|
||||
* Инициализация:
|
||||
* Информационная база инициализируется только в том случае, если в сборочной линии включены шаги, работающие с базой (например, `bdd` или `syntaxCheck`).
|
||||
* Информационная база инициализируется конфигурацией из хранилища конфигурации (`initInfobase` -> `initMethod`).
|
||||
@ -121,14 +122,20 @@ pipeline1C()
|
||||
* Первичный запуск информационной базы:
|
||||
* Если информационная база нужна для запуска в режиме "Предприятие" (например, для шагов `bdd` или `smoke`), то будет запущен шаг "Миграция ИБ".
|
||||
* После загрузки конфигурации в ИБ будет выполняться запуск ИБ с целью запуска обработчиков обновления из БСП (`initInfobase` -> `runMigration`).
|
||||
* Если в настройках шага инициализации не заполнен массив дополнительных шагов миграции (`initInfobase` -> `additionalInitializationSteps`), но в каталоге `tools` присутствуют файлы с именами, удовлетворяющими шаблону `vrunner.init*.json`, то автоматически выполняется запуск `vrunner vanessa` с передачей найденных файлов в качестве значения настроек (параметр `--settings`) в порядке лексиграфической сортировки имен файлов.
|
||||
* Если в настройках шага инициализации не заполнен массив дополнительных шагов миграции (`initInfobase` -> `additionalInitializationSteps`), но в каталоге `tools` присутствуют файлы с именами, удовлетворяющими шаблону `vrunner.init*.json`, то автоматически выполняется запуск `vrunner vanessa` с передачей найденных файлов в качестве значения настроек (параметр `--settings`) в порядке лексикографической сортировки имен файлов.
|
||||
* BDD:
|
||||
* Если в конфигурационном файле проекта не заполнена настройка `bdd` -> `vrunnerSteps`, то автоматически выполняется запуск `vrunner vanessa --settings tools/vrunner.json`.
|
||||
* Дымовые тесты:
|
||||
* Если в репозитории существует файл `tools/vrunner.json`, то запуск дымовых тестов будет выполняться с передачей файла в параметры запуска `vrunner xunit --settings tools/vrunner.json` (`smoke` -> `vrunnerSettings`).
|
||||
* Если установка локальных зависимостей `opm` установит пакет `add`, то будет использоваться обработка `xddTestRunner.epf` из локальных зависимостей.
|
||||
* Если в репозитории существует файл `tools/xUnitParams.json`, то этот путь к файлу будет передан в параметр запуска `vrunner xunit --xddConfig ./tools/xUnitParams.json` (`smoke -> xUnitParams`).
|
||||
* Если используемый конфигурационный файл (`vrunner.json`) не содержит настройку `testsPath`, то запускается полный комплект дымовых тестов, расположенных в `$addRoot/tests/smoke`.
|
||||
* По умолчанию включено формирование отчета в формате `jUnit` (`smoke` -> `publishToJUnitReport`) и выключено формирование отчета в формате Allure (`smoke` -> `publishToAllureReport`).
|
||||
* Синтаксический контроль:
|
||||
* Если в репозитории существует файл `tools/vrunner.json`, то синтаксический контроль конфигурации с помощью конфигуратора будет выполняться с передачей файла в параметры запуска `vrunner syntax-check --settings tools/vrunner.json` (`syntaxCheck` -> `vrunnerSettings`).
|
||||
* Применяется группировка ошибок по метаданным (`syntaxCheck` -> `groupErrorsByMetadata`).
|
||||
* Выгрузка результатов в формат `jUnit` осуществляется в файл `./build/out/jUnit/syntax.xml` (`syntaxCheck` -> `pathToJUnitReport`).
|
||||
* Если в репозитории существует файл `./tools/syntax-check-exception-file.txt`, то команде запука синтаксического контроля конфигурации данный файл будет передаваться как файл с исключениями сообщений об ошибках (параметр `--exception-file`) (`syntaxCheck` -> `exceptionFile`).
|
||||
* Если в репозитории существует файл `./tools/syntax-check-exception-file.txt`, то команде запуска синтаксического контроля конфигурации данный файл будет передаваться как файл с исключениями сообщений об ошибках (параметр `--exception-file`) (`syntaxCheck` -> `exceptionFile`).
|
||||
* Конфигурационный файл по умолчанию уже содержит ряд "режимов проверки" для синтаксического контроля конфигурации (`syntaxCheck` -> `checkModes`).
|
||||
* Трансформация результатов валидации EDT:
|
||||
* По умолчанию из результатов анализа исключаются замечания, сработавшие на модулях с включенным запретом редактирования (желтый куб с замком) (параметры `resultsTransform` -> `removeSupport` и `resultsTransform` -> `supportLevel`).
|
||||
@ -136,5 +143,6 @@ pipeline1C()
|
||||
* Предполагается наличие единственной настройки `SonarQube installation` (`sonarqube` -> `sonarQubeInstallation`).
|
||||
* Используется `sonar-scanner` из переменной окружения `PATH` (`sonarqube` -> `useSonarScannerFromPath`).
|
||||
* Если использование `sonar-scanner` из переменной окружения `PATH` выключено, предполагается наличие настроенного глобального инструмента `SonarQube Scanner` с идентификатором инструмента `sonar-scanner` (`sonarqube` -> `sonarScannerToolName`).
|
||||
* Версия из корня конфигурации передается утилите `sonar-scanner` как значение параметра `sonar.projectVersion=$configurationVersion`.
|
||||
* Если разработка ведется с использованием подсистемы [БСП "Обновление версии ИБ"](https://its.1c.ru/db/bsp315doc#content:4:1:issogl1_обновление_версии_иб), то в значение параметра `sonar.projectVersion=$configurationVersion` утилиты `sonar-scanner` можно передавать версию из созданного общего модуля.
|
||||
Для этого необходимо заполнить параметр (`sonarqube` -> `infoBaseUpdateModuleName`). Если параметр не заполнен, версия передается из корня конфигурации.
|
||||
* Если выполнялась валидация EDT, результаты валидации в формате `generic issues` передаются утилите `sonar-scanner` как значение параметра `sonar.externalIssuesReportPaths`.
|
||||
|
@ -16,6 +16,19 @@
|
||||
"edtValidate": false,
|
||||
"smoke": false
|
||||
},
|
||||
"timeout": {
|
||||
"smoke": 240,
|
||||
"bdd": 120,
|
||||
"createInfoBase": 60,
|
||||
"designerToEdtFormatTransformation": 60,
|
||||
"edtToDesignerFormatTransformation": 60,
|
||||
"edtValidate": 240,
|
||||
"initInfoBase": 60,
|
||||
"resultTransformation": 10,
|
||||
"sonarqube": 90,
|
||||
"syntaxCheck": 240,
|
||||
"zipInfoBase": 60
|
||||
},
|
||||
"initInfobase": {
|
||||
"initMethod": "fromStorage",
|
||||
"runMigration": true,
|
||||
@ -29,7 +42,8 @@
|
||||
"sonarqube": {
|
||||
"sonarQubeInstallation": "",
|
||||
"useSonarScannerFromPath": true,
|
||||
"sonarScannerToolName": "sonar-scanner"
|
||||
"sonarScannerToolName": "sonar-scanner",
|
||||
"infoBaseUpdateModuleName" : ""
|
||||
},
|
||||
"syntaxCheck": {
|
||||
"groupErrorsByMetadata": true,
|
||||
@ -50,6 +64,12 @@
|
||||
],
|
||||
"vrunnerSettings": "./tools/vrunner.json"
|
||||
},
|
||||
"smoke": {
|
||||
"vrunnerSettings": "./tools/vrunner.json",
|
||||
"xddConfigPath": "./tools/xUnitParams.json",
|
||||
"publishToAllureReport": false,
|
||||
"publishToJUnitReport": true
|
||||
},
|
||||
"resultsTransform": {
|
||||
"removeSupport": true,
|
||||
"supportLevel": 0
|
||||
|
@ -65,6 +65,57 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeout" : {
|
||||
"type" : "object",
|
||||
"id" : "urn:jsonschema:ru:pulsar:jenkins:library:configuration:TimeoutOptions",
|
||||
"description" : "Настройка таймаутов для шагов",
|
||||
"properties" : {
|
||||
"edtToDesignerFormatTransformation" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага трансформации исходников из формата EDT в формат Конфигуратора, в минутах.\n По умолчанию содержит значение 60.\n "
|
||||
},
|
||||
"createInfoBase" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага создания информационной базы, в минутах.\n По умолчанию содержит значение 60.\n "
|
||||
},
|
||||
"initInfoBase" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага инициализации информационной базы, в минутах.\n По умолчанию содержит значение 60.\n "
|
||||
},
|
||||
"zipInfoBase" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага архивирования информационной базы, в минутах.\n По умолчанию содержит значение 60.\n "
|
||||
},
|
||||
"designerToEdtFormatTransformation" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага трансформации исходников из формата Конфигуратора в формат EDT, в минутах.\n По умолчанию содержит значение 60.\n "
|
||||
},
|
||||
"edtValidate" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага валидации EDT, в минутах.\n По умолчанию содержит значение 240.\n "
|
||||
},
|
||||
"resultTransformation" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага трансформации результатов EDT, в минутах.\n По умолчанию содержит значение 10.\n "
|
||||
},
|
||||
"bdd" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага проверки сценариев поведения, в минутах.\n По умолчанию содержит значение 120.\n "
|
||||
},
|
||||
"syntaxCheck" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага синтаксического контроля, в минутах.\n По умолчанию содержит значение 240.\n "
|
||||
},
|
||||
"smoke" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага дымовых тестов, в минутах.\n По умолчанию содержит значение 240.\n "
|
||||
},
|
||||
"sonarqube" : {
|
||||
"type" : "integer",
|
||||
"description" : "Таймаут шага статического анализа SonarQube, в минутах.\n По умолчанию содержит значение 90.\n "
|
||||
}
|
||||
}
|
||||
},
|
||||
"initInfobase" : {
|
||||
"type" : "object",
|
||||
"id" : "urn:jsonschema:ru:pulsar:jenkins:library:configuration:InitInfobaseOptions",
|
||||
@ -118,6 +169,10 @@
|
||||
"sonarScannerToolName" : {
|
||||
"type" : "string",
|
||||
"description" : "Имя настроенной утилиты sonar-scanner.\nПрименяется, если useSonarScannerFromPath установлено в false."
|
||||
},
|
||||
"infoBaseUpdateModuleName" : {
|
||||
"type" : "string",
|
||||
"description" : "Имя общего модуля (например, ОбновлениеИнформационнойБазыXXX), в котором указана версия библиотеки.\n Версия должна задаваться в виде присвоения `Описание.Версия = \"ваш номер версии\";`\n "
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -151,6 +206,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"smoke" : {
|
||||
"type" : "object",
|
||||
"id" : "urn:jsonschema:ru:pulsar:jenkins:library:configuration:SmokeTestOptions",
|
||||
"description" : "Настройки дымового тестирования",
|
||||
"properties" : {
|
||||
"vrunnerSettings" : {
|
||||
"type" : "string",
|
||||
"description" : "Путь к конфигурационному файлу vanessa-runner.\n По умолчанию содержит значение \"./tools/vrunner.json\".\n "
|
||||
},
|
||||
"xddConfigPath" : {
|
||||
"type" : "string",
|
||||
"description" : "Путь к конфигурационному файлу для xddTestRunner.\n По умолчанию содержит значение \"./tools/xUnitParams.json\".\n "
|
||||
},
|
||||
"publishToAllureReport" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять публикацию результатов в отчет Allure.\n По умолчанию выключено.\n "
|
||||
},
|
||||
"publishToJUnitReport" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять публикацию результатов в отчет JUnit.\n По умолчанию включено.\n "
|
||||
}
|
||||
}
|
||||
},
|
||||
"resultsTransform" : {
|
||||
"type" : "object",
|
||||
"id" : "urn:jsonschema:ru:pulsar:jenkins:library:configuration:ResultsTransformOptions",
|
||||
|
@ -17,6 +17,8 @@ interface IStepExecutor {
|
||||
|
||||
FileWrapper[] findFiles(String glob, String excludes)
|
||||
|
||||
String readFile(String file)
|
||||
|
||||
String readFile(String file, String encoding)
|
||||
|
||||
boolean fileExists(String file)
|
||||
@ -73,5 +75,7 @@ interface IStepExecutor {
|
||||
|
||||
def allure(List<String> results)
|
||||
|
||||
def junit(String testResults, boolean allowEmptyResults)
|
||||
|
||||
def installLocalDependencies()
|
||||
}
|
@ -33,7 +33,7 @@ class StepExecutor implements IStepExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
String readFile(String file, String encoding) {
|
||||
String readFile(String file, String encoding = 'UTF-8') {
|
||||
steps.readFile encoding: encoding, file: file
|
||||
}
|
||||
|
||||
@ -174,6 +174,11 @@ class StepExecutor implements IStepExecutor {
|
||||
])
|
||||
}
|
||||
|
||||
@Override
|
||||
def junit(String testResults, boolean allowEmptyResults) {
|
||||
steps.junit testResults: testResults, allowEmptyResults: allowEmptyResults
|
||||
}
|
||||
|
||||
@Override
|
||||
def installLocalDependencies() {
|
||||
steps.installLocalDependencies()
|
||||
|
@ -56,15 +56,17 @@ class ConfigurationReader implements Serializable {
|
||||
def nonMergeableSettings = Arrays.asList(
|
||||
"secrets",
|
||||
"stageFlags",
|
||||
"initInfobaseOptions",
|
||||
"timeoutOptions",
|
||||
"initInfoBaseOptions",
|
||||
"bddOptions",
|
||||
"sonarQubeOptions",
|
||||
"smokeTestOptions",
|
||||
"syntaxCheckOptions",
|
||||
"resultsTransformOptions"
|
||||
).toSet()
|
||||
|
||||
mergeObjects(baseConfiguration, configurationToMerge, nonMergeableSettings)
|
||||
mergeInitInfobaseOptions(baseConfiguration.initInfobaseOptions, configurationToMerge.initInfobaseOptions);
|
||||
mergeInitInfoBaseOptions(baseConfiguration.initInfoBaseOptions, configurationToMerge.initInfoBaseOptions);
|
||||
mergeBddOptions(baseConfiguration.bddOptions, configurationToMerge.bddOptions);
|
||||
|
||||
return baseConfiguration;
|
||||
@ -91,7 +93,7 @@ class ConfigurationReader implements Serializable {
|
||||
}
|
||||
|
||||
@NonCPS
|
||||
private static void mergeInitInfobaseOptions(InitInfobaseOptions baseObject, InitInfobaseOptions objectToMerge) {
|
||||
private static void mergeInitInfoBaseOptions(InitInfoBaseOptions baseObject, InitInfoBaseOptions objectToMerge) {
|
||||
if (objectToMerge == null || objectToMerge.additionalInitializationSteps == null) {
|
||||
return
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package ru.pulsar.jenkins.library.configuration
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
|
||||
enum InitInfobaseMethod {
|
||||
enum InitInfoBaseMethod {
|
||||
|
||||
@JsonProperty("fromStorage")
|
||||
FROM_STORAGE,
|
@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
class InitInfobaseOptions implements Serializable {
|
||||
class InitInfoBaseOptions implements Serializable {
|
||||
|
||||
@JsonPropertyDescription("""
|
||||
Способ инициализации информационной базы.
|
||||
@ -14,10 +14,10 @@ class InitInfobaseOptions implements Serializable {
|
||||
* fromSource - инициализация информационной базы из исходников конфигурации;
|
||||
* defaultBranchFromStorage - инициализация основной ветки из хранилища конфигурации, остальных - из исходников конфигурации.
|
||||
По умолчанию содержит значение "fromStorage".""")
|
||||
InitInfobaseMethod initMethod = InitInfobaseMethod.FROM_STORAGE;
|
||||
InitInfoBaseMethod initMethod = InitInfoBaseMethod.FROM_STORAGE;
|
||||
|
||||
@JsonPropertyDescription("Запустить миграцию ИБ")
|
||||
boolean runMigration = true
|
||||
Boolean runMigration = true
|
||||
|
||||
@JsonPropertyDescription("""Дополнительные шаги, запускаемые через vrunner.
|
||||
В каждой строке передается отдельная команда
|
||||
@ -28,7 +28,7 @@ class InitInfobaseOptions implements Serializable {
|
||||
@Override
|
||||
@NonCPS
|
||||
String toString() {
|
||||
return "InitInfobaseOptions{" +
|
||||
return "InitInfoBaseOptions{" +
|
||||
"initMethod=" + initMethod +
|
||||
", runMigration=" + runMigration +
|
||||
", additionalInitializationSteps=" + additionalInitializationSteps +
|
@ -1,7 +1,6 @@
|
||||
package ru.pulsar.jenkins.library.configuration
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
@ -23,6 +22,10 @@ class JobConfiguration implements Serializable {
|
||||
@JsonPropertyDescription("Включение этапов сборок")
|
||||
StageFlags stageFlags;
|
||||
|
||||
@JsonProperty("timeout")
|
||||
@JsonPropertyDescription("Настройка таймаутов для шагов")
|
||||
TimeoutOptions timeoutOptions;
|
||||
|
||||
@JsonPropertyDescription("Имя ветки по умолчанию. Значение по умолчанию - main.")
|
||||
String defaultBranch
|
||||
|
||||
@ -31,7 +34,7 @@ class JobConfiguration implements Serializable {
|
||||
|
||||
@JsonProperty("initInfobase")
|
||||
@JsonPropertyDescription("Настройки шага инициализации ИБ")
|
||||
InitInfobaseOptions initInfobaseOptions;
|
||||
InitInfoBaseOptions initInfoBaseOptions;
|
||||
|
||||
@JsonProperty("bdd")
|
||||
@JsonPropertyDescription("Настройки шага запуска BDD сценариев")
|
||||
@ -45,6 +48,10 @@ class JobConfiguration implements Serializable {
|
||||
@JsonPropertyDescription("Настройки синтаксического контроля")
|
||||
SyntaxCheckOptions syntaxCheckOptions;
|
||||
|
||||
@JsonProperty("smoke")
|
||||
@JsonPropertyDescription("Настройки дымового тестирования")
|
||||
SmokeTestOptions smokeTestOptions;
|
||||
|
||||
@JsonProperty("resultsTransform")
|
||||
@JsonPropertyDescription("Настройки трансформации результатов анализа")
|
||||
ResultsTransformOptions resultsTransformOptions;
|
||||
@ -60,25 +67,27 @@ class JobConfiguration implements Serializable {
|
||||
"v8version='" + v8version + '\'' +
|
||||
", srcDir='" + srcDir + '\'' +
|
||||
", sourceFormat=" + sourceFormat +
|
||||
", defaultBranch=" + defaultBranch +
|
||||
", stageFlags=" + stageFlags +
|
||||
", timeoutOptions=" + timeoutOptions +
|
||||
", defaultBranch='" + defaultBranch + '\'' +
|
||||
", secrets=" + secrets +
|
||||
", initInfobaseOptions=" + initInfobaseOptions +
|
||||
", initInfoBaseOptions=" + initInfoBaseOptions +
|
||||
", bddOptions=" + bddOptions +
|
||||
", sonarQubeOptions=" + sonarQubeOptions +
|
||||
", syntaxCheckOptions=" + syntaxCheckOptions +
|
||||
", smokeTestOptions=" + smokeTestOptions +
|
||||
", resultsTransformOptions=" + resultsTransformOptions +
|
||||
", logosConfig=" + logosConfig +
|
||||
", logosConfig='" + logosConfig + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
boolean infobaseFromFiles(){
|
||||
boolean infoBaseFromFiles() {
|
||||
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
|
||||
def env = steps.env();
|
||||
String branchName = env.BRANCH_NAME;
|
||||
def initMethod = initInfobaseOptions.initMethod
|
||||
def initMethod = initInfoBaseOptions.initMethod
|
||||
|
||||
return (initMethod == InitInfobaseMethod.FROM_SOURCE) ||
|
||||
(initMethod == InitInfobaseMethod.DEFAULT_BRANCH_FROM_STORAGE && branchName != defaultBranch)
|
||||
return (initMethod == InitInfoBaseMethod.FROM_SOURCE) ||
|
||||
(initMethod == InitInfoBaseMethod.DEFAULT_BRANCH_FROM_STORAGE && branchName != defaultBranch)
|
||||
}
|
||||
}
|
@ -8,14 +8,14 @@ import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
class ResultsTransformOptions implements Serializable {
|
||||
|
||||
@JsonPropertyDescription("Фильтровать замечания по уровню поддержки модуля. По умолчанию включено.")
|
||||
boolean removeSupport = true
|
||||
Boolean removeSupport = true
|
||||
|
||||
@JsonPropertyDescription("""Настройка фильтрации замечаний по уровню поддержки.
|
||||
0 - удалить файлы на замке;
|
||||
1 - удалить файлы на замке и на поддержке;
|
||||
2 - удалить файлы на замке, на поддержке и снятые с поддержки.
|
||||
""")
|
||||
int supportLevel
|
||||
Integer supportLevel
|
||||
|
||||
@Override
|
||||
@NonCPS
|
||||
|
@ -0,0 +1,40 @@
|
||||
package ru.pulsar.jenkins.library.configuration
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
class SmokeTestOptions implements Serializable {
|
||||
|
||||
@JsonPropertyDescription("""Путь к конфигурационному файлу vanessa-runner.
|
||||
По умолчанию содержит значение "./tools/vrunner.json".
|
||||
""")
|
||||
String vrunnerSettings
|
||||
|
||||
@JsonPropertyDescription("""Путь к конфигурационному файлу для xddTestRunner.
|
||||
По умолчанию содержит значение "./tools/xUnitParams.json".
|
||||
""")
|
||||
String xddConfigPath;
|
||||
|
||||
@JsonPropertyDescription("""Выполнять публикацию результатов в отчет Allure.
|
||||
По умолчанию выключено.
|
||||
""")
|
||||
boolean publishToAllureReport
|
||||
|
||||
@JsonPropertyDescription("""Выполнять публикацию результатов в отчет JUnit.
|
||||
По умолчанию включено.
|
||||
""")
|
||||
boolean publishToJUnitReport
|
||||
|
||||
@Override
|
||||
@NonCPS
|
||||
String toString() {
|
||||
return "SmokeTestOptions{" +
|
||||
"vrunnerSettings='" + vrunnerSettings + '\'' +
|
||||
", xddConfigPath='" + xddConfigPath + '\'' +
|
||||
", publishToAllureReport=" + publishToAllureReport +
|
||||
", publishToJUnitReport=" + publishToJUnitReport +
|
||||
'}'
|
||||
}
|
||||
}
|
@ -13,13 +13,18 @@ class SonarQubeOptions implements Serializable {
|
||||
String sonarQubeInstallation;
|
||||
|
||||
@JsonPropertyDescription("Использовать sonar-scanner, доступный в PATH")
|
||||
boolean useSonarScannerFromPath
|
||||
Boolean useSonarScannerFromPath
|
||||
|
||||
@JsonPropertyDescription(
|
||||
"Имя настроенной утилиты sonar-scanner.\nПрименяется, если useSonarScannerFromPath установлено в false."
|
||||
)
|
||||
String sonarScannerToolName
|
||||
|
||||
@JsonPropertyDescription("""Имя общего модуля (например, ОбновлениеИнформационнойБазыXXX), в котором указана версия библиотеки.
|
||||
Версия должна задаваться в виде присвоения `Описание.Версия = "ваш номер версии";`
|
||||
""")
|
||||
String infoBaseUpdateModuleName
|
||||
|
||||
@Override
|
||||
@NonCPS
|
||||
String toString() {
|
||||
@ -27,6 +32,7 @@ class SonarQubeOptions implements Serializable {
|
||||
"useSonarScannerFromPath=" + useSonarScannerFromPath +
|
||||
", sonarScannerToolName='" + sonarScannerToolName + '\'' +
|
||||
", sonarQubeInstallation='" + sonarQubeInstallation + '\'' +
|
||||
", infoBaseUpdateModuleName='" + infoBaseUpdateModuleName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -7,22 +7,22 @@ import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
class StageFlags implements Serializable {
|
||||
@JsonPropertyDescription("Анализ SonarQube включен")
|
||||
boolean sonarqube
|
||||
Boolean sonarqube
|
||||
|
||||
@JsonPropertyDescription("Синтаксический контроль включен")
|
||||
boolean syntaxCheck
|
||||
Boolean syntaxCheck
|
||||
|
||||
@JsonPropertyDescription("Валидация EDT включена")
|
||||
boolean edtValidate
|
||||
Boolean edtValidate
|
||||
|
||||
@JsonPropertyDescription("Дымовые тесты включены")
|
||||
boolean smoke
|
||||
Boolean smoke
|
||||
|
||||
@JsonPropertyDescription("Предварительные шаги инициализации включены")
|
||||
boolean initSteps
|
||||
Boolean initSteps
|
||||
|
||||
@JsonPropertyDescription("Запуск BDD сценариев включен")
|
||||
boolean bdd
|
||||
Boolean bdd
|
||||
|
||||
@Override
|
||||
@NonCPS
|
||||
@ -37,7 +37,7 @@ class StageFlags implements Serializable {
|
||||
'}';
|
||||
}
|
||||
|
||||
boolean needInfobase() {
|
||||
boolean needInfoBase() {
|
||||
return smoke || syntaxCheck || initSteps || bdd
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
package ru.pulsar.jenkins.library.configuration
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
class TimeoutOptions implements Serializable {
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага трансформации исходников из формата EDT в формат Конфигуратора, в минутах.
|
||||
По умолчанию содержит значение 60.
|
||||
''')
|
||||
Integer edtToDesignerFormatTransformation
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага создания информационной базы, в минутах.
|
||||
По умолчанию содержит значение 60.
|
||||
''')
|
||||
Integer createInfoBase
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага инициализации информационной базы, в минутах.
|
||||
По умолчанию содержит значение 60.
|
||||
''')
|
||||
Integer initInfoBase
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага архивирования информационной базы, в минутах.
|
||||
По умолчанию содержит значение 60.
|
||||
''')
|
||||
Integer zipInfoBase
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага трансформации исходников из формата Конфигуратора в формат EDT, в минутах.
|
||||
По умолчанию содержит значение 60.
|
||||
''')
|
||||
Integer designerToEdtFormatTransformation
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага валидации EDT, в минутах.
|
||||
По умолчанию содержит значение 240.
|
||||
''')
|
||||
Integer edtValidate
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага трансформации результатов EDT, в минутах.
|
||||
По умолчанию содержит значение 10.
|
||||
''')
|
||||
Integer resultTransformation
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага проверки сценариев поведения, в минутах.
|
||||
По умолчанию содержит значение 120.
|
||||
''')
|
||||
Integer bdd
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага синтаксического контроля, в минутах.
|
||||
По умолчанию содержит значение 240.
|
||||
''')
|
||||
Integer syntaxCheck
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага дымовых тестов, в минутах.
|
||||
По умолчанию содержит значение 240.
|
||||
''')
|
||||
Integer smoke
|
||||
|
||||
@JsonPropertyDescription('''Таймаут шага статического анализа SonarQube, в минутах.
|
||||
По умолчанию содержит значение 90.
|
||||
''')
|
||||
Integer sonarqube
|
||||
}
|
@ -4,6 +4,7 @@ package ru.pulsar.jenkins.library.steps
|
||||
import ru.pulsar.jenkins.library.IStepExecutor
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.utils.Constants
|
||||
import ru.pulsar.jenkins.library.utils.Logger
|
||||
|
||||
class DesignerToEdtFormatTransformation implements Serializable {
|
||||
@ -38,9 +39,9 @@ class DesignerToEdtFormatTransformation implements Serializable {
|
||||
|
||||
Logger.println("Конвертация исходников из формата конфигуратора в формат EDT")
|
||||
|
||||
def ringCommand = "ring edt workspace import --configuration-files '$configurationRoot' --project-name $PROJECT_NAME --workspace-location '$workspaceDir'"
|
||||
def ringCommand = "ring edt workspace import --configuration-files \"$configurationRoot\" --project-name $PROJECT_NAME --workspace-location \"$workspaceDir\""
|
||||
|
||||
def ringOpts = ['RING_OPTS=-Dfile.encoding=UTF-8 -Dosgi.nl=ru -Duser.language=ru']
|
||||
def ringOpts = [Constants.DEFAULT_RING_OPTS]
|
||||
steps.withEnv(ringOpts) {
|
||||
steps.cmd(ringCommand)
|
||||
}
|
||||
|
@ -43,9 +43,9 @@ class EdtToDesignerFormatTransformation implements Serializable {
|
||||
|
||||
Logger.println("Конвертация исходников из формата EDT в формат Конфигуратора")
|
||||
|
||||
def ringCommand = "ring edt workspace export --workspace-location '$workspaceDir' --project '$projectDir' --configuration-files '$configurationRoot'"
|
||||
def ringCommand = "ring edt workspace export --workspace-location \"$workspaceDir\" --project \"$projectDir\" --configuration-files \"$configurationRoot\""
|
||||
|
||||
def ringOpts =[Constants.DEFAULT_RING_OPTS]
|
||||
def ringOpts = [Constants.DEFAULT_RING_OPTS]
|
||||
steps.withEnv(ringOpts) {
|
||||
steps.cmd(ringCommand)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import ru.pulsar.jenkins.library.IStepExecutor
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.configuration.SourceFormat
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.utils.Constants
|
||||
import ru.pulsar.jenkins.library.utils.Logger
|
||||
|
||||
class EdtValidate implements Serializable {
|
||||
@ -46,8 +47,8 @@ class EdtValidate implements Serializable {
|
||||
|
||||
Logger.println("Выполнение валидации EDT")
|
||||
|
||||
def ringCommand = "ring edt workspace validate --workspace-location '$workspaceLocation' --file '$resultFile' $projectList"
|
||||
def ringOpts = ['RING_OPTS=-Dfile.encoding=UTF-8 -Dosgi.nl=ru -Duser.language=ru']
|
||||
def ringCommand = "ring edt workspace validate --workspace-location \"$workspaceLocation\" --file \"$resultFile\" $projectList"
|
||||
def ringOpts = [Constants.DEFAULT_RING_OPTS]
|
||||
steps.withEnv(ringOpts) {
|
||||
steps.catchError {
|
||||
steps.cmd(ringCommand)
|
||||
|
@ -20,7 +20,7 @@ class InitFromFiles implements Serializable {
|
||||
|
||||
Logger.printLocation()
|
||||
|
||||
if (!config.infobaseFromFiles()) {
|
||||
if (!config.infoBaseFromFiles()) {
|
||||
Logger.println("init infoBase from files is disabled")
|
||||
return
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class InitFromStorage implements Serializable {
|
||||
|
||||
Logger.printLocation()
|
||||
|
||||
if (config.infobaseFromFiles()) {
|
||||
if (config.infoBaseFromFiles()) {
|
||||
Logger.println("init infoBase from storage is disabled")
|
||||
return
|
||||
}
|
||||
|
@ -7,11 +7,11 @@ import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.utils.Logger
|
||||
import ru.pulsar.jenkins.library.utils.VRunner
|
||||
|
||||
class InitInfobase implements Serializable {
|
||||
class InitInfoBase implements Serializable {
|
||||
|
||||
private final JobConfiguration config;
|
||||
|
||||
InitInfobase(JobConfiguration config) {
|
||||
InitInfoBase(JobConfiguration config) {
|
||||
this.config = config
|
||||
}
|
||||
|
||||
@ -32,19 +32,27 @@ class InitInfobase implements Serializable {
|
||||
|
||||
String vrunnerPath = VRunner.getVRunnerPath();
|
||||
|
||||
if (config.initInfobaseOptions.runMigration) {
|
||||
if (config.initInfoBaseOptions.runMigration) {
|
||||
Logger.println("Запуск миграции ИБ")
|
||||
|
||||
String command = vrunnerPath + ' run --command "ЗапуститьОбновлениеИнформационнойБазы;ЗавершитьРаботуСистемы;" --execute '
|
||||
String executeParameter = '$runnerRoot/epf/ЗакрытьПредприятие.epf'
|
||||
if (steps.isUnix()) {
|
||||
executeParameter = '\\' + executeParameter
|
||||
}
|
||||
command += executeParameter;
|
||||
command += ' --ibconnection "/F./build/ib"'
|
||||
|
||||
// Запуск миграции
|
||||
steps.catchError {
|
||||
VRunner.exec(vrunnerPath + ' run --command "ЗапуститьОбновлениеИнформационнойБазы;ЗавершитьРаботуСистемы;" --execute \\$runnerRoot/epf/ЗакрытьПредприятие.epf --ibconnection "/F./build/ib"')
|
||||
VRunner.exec(command)
|
||||
}
|
||||
} else {
|
||||
Logger.println("Шаг миграции ИБ выключен")
|
||||
}
|
||||
|
||||
steps.catchError {
|
||||
if (config.initInfobaseOptions.additionalInitializationSteps.length == 0) {
|
||||
if (config.initInfoBaseOptions.additionalInitializationSteps.length == 0) {
|
||||
FileWrapper[] files = steps.findFiles("tools/vrunner.init*.json")
|
||||
files = files.sort new OrderBy( { it.name })
|
||||
files.each {
|
||||
@ -52,7 +60,7 @@ class InitInfobase implements Serializable {
|
||||
VRunner.exec("$vrunnerPath vanessa --settings ${it.path} --ibconnection \"/F./build/ib\"")
|
||||
}
|
||||
} else {
|
||||
config.initInfobaseOptions.additionalInitializationSteps.each {
|
||||
config.initInfoBaseOptions.additionalInitializationSteps.each {
|
||||
Logger.println("Первичная инициализация командой ${it}")
|
||||
VRunner.exec("$vrunnerPath ${it} --ibconnection \"/F./build/ib\"")
|
||||
}
|
@ -23,6 +23,9 @@ class PublishAllure implements Serializable {
|
||||
|
||||
safeUnstash('init-allure')
|
||||
safeUnstash('bdd-allure')
|
||||
if (config.smokeTestOptions.publishToAllureReport) {
|
||||
safeUnstash(SmokeTest.SMOKE_ALLURE_STASH)
|
||||
}
|
||||
|
||||
def env = steps.env();
|
||||
|
||||
@ -47,7 +50,7 @@ class PublishAllure implements Serializable {
|
||||
private void safeUnstash(String stashName) {
|
||||
try {
|
||||
steps.unstash(stashName)
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignored) {
|
||||
Logger.println("Can't unstash $stashName")
|
||||
}
|
||||
}
|
||||
|
120
src/ru/pulsar/jenkins/library/steps/SmokeTest.groovy
Normal file
120
src/ru/pulsar/jenkins/library/steps/SmokeTest.groovy
Normal file
@ -0,0 +1,120 @@
|
||||
package ru.pulsar.jenkins.library.steps
|
||||
|
||||
import hudson.FilePath
|
||||
import ru.pulsar.jenkins.library.IStepExecutor
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.utils.FileUtils
|
||||
import ru.pulsar.jenkins.library.utils.Logger
|
||||
import ru.pulsar.jenkins.library.utils.VRunner
|
||||
|
||||
class SmokeTest implements Serializable {
|
||||
|
||||
public static final String SMOKE_ALLURE_STASH = 'smoke-allure'
|
||||
|
||||
private final JobConfiguration config
|
||||
|
||||
SmokeTest(JobConfiguration config) {
|
||||
this.config = config
|
||||
}
|
||||
|
||||
def run() {
|
||||
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
|
||||
|
||||
Logger.printLocation()
|
||||
|
||||
if (!config.stageFlags.smoke) {
|
||||
Logger.println("Smoke test step is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
List<String> logosConfig = ["LOGOS_CONFIG=$config.logosConfig"]
|
||||
steps.withEnv(logosConfig) {
|
||||
steps.installLocalDependencies()
|
||||
}
|
||||
|
||||
def options = config.smokeTestOptions
|
||||
def env = steps.env()
|
||||
|
||||
String vrunnerPath = VRunner.getVRunnerPath()
|
||||
String command = "$vrunnerPath xunit --ibconnection \"/F./build/ib\""
|
||||
|
||||
String vrunnerSettings = options.vrunnerSettings
|
||||
if (steps.fileExists(vrunnerSettings)) {
|
||||
command += " --settings $vrunnerSettings"
|
||||
}
|
||||
|
||||
String xddTestRunnerPath = "./oscript_modules/add/xddTestRunner.epf"
|
||||
if (steps.fileExists(xddTestRunnerPath)) {
|
||||
command += " --pathxunit $xddTestRunnerPath"
|
||||
}
|
||||
|
||||
if (steps.fileExists(options.xddConfigPath)) {
|
||||
command += " --xddConfig $options.xddConfigPath"
|
||||
}
|
||||
|
||||
String junitReport = "build/out/jUnit/smoke/smoke.xml"
|
||||
FilePath pathToJUnitReport = FileUtils.getFilePath("$env.WORKSPACE/$junitReport")
|
||||
String junitReportDir = FileUtils.getLocalPath(pathToJUnitReport.getParent())
|
||||
|
||||
String allureReport = "build/out/allure/smoke/allure.xml"
|
||||
FilePath pathToAllureReport = FileUtils.getFilePath("$env.WORKSPACE/$allureReport")
|
||||
String allureReportDir = FileUtils.getLocalPath(pathToAllureReport.getParent())
|
||||
|
||||
StringBuilder reportsConfigConstructor = new StringBuilder()
|
||||
|
||||
if (options.publishToJUnitReport) {
|
||||
steps.createDir(junitReportDir)
|
||||
|
||||
String junitReportCommand = "ГенераторОтчетаJUnitXML{$junitReport}"
|
||||
|
||||
reportsConfigConstructor.append(junitReportCommand)
|
||||
}
|
||||
|
||||
if (options.publishToAllureReport) {
|
||||
steps.createDir(allureReportDir)
|
||||
|
||||
String allureReportCommand = "ГенераторОтчетаAllureXMLВерсия2{$allureReport}"
|
||||
|
||||
if (reportsConfigConstructor.length() > 0) {
|
||||
reportsConfigConstructor.append(';')
|
||||
}
|
||||
reportsConfigConstructor.append(allureReportCommand)
|
||||
}
|
||||
|
||||
if (reportsConfigConstructor.length() > 0) {
|
||||
String reportsConfig = reportsConfigConstructor.toString()
|
||||
command += " --reportsxunit \"$reportsConfig\""
|
||||
}
|
||||
|
||||
if (steps.isUnix()) {
|
||||
command = command.replace(';', '\\;')
|
||||
}
|
||||
|
||||
if (!VRunner.configContainsSetting(vrunnerSettings, "testsPath")) {
|
||||
String testsPath = "oscript_modules/add/tests/smoke"
|
||||
if (!steps.fileExists(testsPath)) {
|
||||
testsPath = '$addRoot/tests/smoke'
|
||||
if (steps.isUnix()) {
|
||||
testsPath = '\\' + testsPath
|
||||
}
|
||||
}
|
||||
command += " $testsPath"
|
||||
}
|
||||
|
||||
steps.withEnv(logosConfig) {
|
||||
VRunner.exec(command)
|
||||
}
|
||||
|
||||
if (options.publishToAllureReport) {
|
||||
steps.stash(SMOKE_ALLURE_STASH, "$allureReportDir/**", true)
|
||||
steps.archiveArtifacts("$allureReportDir/**")
|
||||
}
|
||||
|
||||
if (options.publishToJUnitReport) {
|
||||
steps.junit("$junitReportDir/*.xml", true)
|
||||
steps.archiveArtifacts("$junitReportDir/**")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -10,15 +10,9 @@ import ru.pulsar.jenkins.library.utils.VersionParser
|
||||
class SonarScanner implements Serializable {
|
||||
|
||||
private final JobConfiguration config;
|
||||
private final String rootFile
|
||||
|
||||
SonarScanner(JobConfiguration config) {
|
||||
this.config = config
|
||||
if (config.sourceFormat == SourceFormat.EDT){
|
||||
this.rootFile = "$config.srcDir/src/Configuration/Configuration.mdo"
|
||||
} else {
|
||||
this.rootFile = "$config.srcDir/Configuration.xml"
|
||||
}
|
||||
}
|
||||
|
||||
def run() {
|
||||
@ -44,15 +38,9 @@ class SonarScanner implements Serializable {
|
||||
|
||||
String sonarCommand = "$sonarScannerBinary -Dsonar.branch.name=$env.BRANCH_NAME"
|
||||
|
||||
String configurationVersion
|
||||
if (config.sourceFormat == SourceFormat.EDT) {
|
||||
configurationVersion = VersionParser.edt(rootFile)
|
||||
} else {
|
||||
configurationVersion = VersionParser.configuration(rootFile)
|
||||
}
|
||||
|
||||
if (configurationVersion) {
|
||||
sonarCommand += " -Dsonar.projectVersion=$configurationVersion"
|
||||
String projectVersion = computeProjectVersion()
|
||||
if (projectVersion) {
|
||||
sonarCommand += " -Dsonar.projectVersion=$projectVersion"
|
||||
}
|
||||
|
||||
if (config.stageFlags.edtValidate) {
|
||||
@ -69,4 +57,27 @@ class SonarScanner implements Serializable {
|
||||
steps.cmd(sonarCommand)
|
||||
}
|
||||
}
|
||||
|
||||
private String computeProjectVersion() {
|
||||
String projectVersion
|
||||
String nameOfModule = config.sonarQubeOptions.infoBaseUpdateModuleName
|
||||
|
||||
if (!nameOfModule.isEmpty()) {
|
||||
String rootFile
|
||||
if (config.sourceFormat == SourceFormat.EDT) {
|
||||
rootFile = "$config.srcDir/src/CommonModules/$nameOfModule/Module.bsl"
|
||||
} else {
|
||||
rootFile = "$config.srcDir/CommonModules/$nameOfModule/Ext/Module.bsl"
|
||||
}
|
||||
projectVersion = VersionParser.ssl(rootFile)
|
||||
} else if (config.sourceFormat == SourceFormat.EDT) {
|
||||
String rootFile = "$config.srcDir/src/Configuration/Configuration.mdo"
|
||||
projectVersion = VersionParser.edt(rootFile)
|
||||
} else {
|
||||
String rootFile = "$config.srcDir/Configuration.xml"
|
||||
projectVersion = VersionParser.configuration(rootFile)
|
||||
}
|
||||
|
||||
return projectVersion
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ru.pulsar.jenkins.library.utils
|
||||
|
||||
final class Constants {
|
||||
public static final String DEFAULT_RING_OPTS = "RING_OPTS=-Dfile.encoding=UTF-8 -Dosgi.nl=ru -Duser.language=ru"
|
||||
public static final String DEFAULT_RING_OPTS = "RING_OPTS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF8 -Dosgi.nl=ru -Duser.language=ru"
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@ import jenkins.model.Jenkins
|
||||
import ru.pulsar.jenkins.library.IStepExecutor
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
|
||||
import java.nio.file.Path
|
||||
|
||||
class FileUtils {
|
||||
|
||||
static FilePath getFilePath(String path) {
|
||||
@ -18,7 +20,7 @@ class FileUtils {
|
||||
steps.error 'Переменная среды NODE_NAME не задана. Запуск вне node или без agent?'
|
||||
}
|
||||
|
||||
if (nodeName == "master") {
|
||||
if (nodeName == "master" || nodeName == "built-in") {
|
||||
return new FilePath(new File(path));
|
||||
} else {
|
||||
return new FilePath(Jenkins.getInstanceOrNull().getComputer(nodeName).getChannel(), path);
|
||||
@ -30,6 +32,13 @@ class FileUtils {
|
||||
|
||||
def env = steps.env();
|
||||
|
||||
return filePath.getRemote().replaceAll("^$env.WORKSPACE/", "").toString()
|
||||
Path workspacePath = new File(env.WORKSPACE).toPath()
|
||||
Path rawFilePath = new File(filePath.getRemote()).toPath()
|
||||
|
||||
return workspacePath.relativize(rawFilePath)
|
||||
.toString()
|
||||
.replaceAll('\\\\\\\\', '/')
|
||||
.replaceAll('\\\\', '/')
|
||||
.toString()
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,15 @@ class VRunner {
|
||||
return steps.cmd(command, returnStatus)
|
||||
} as int
|
||||
}
|
||||
|
||||
static boolean configContainsSetting(String configPath, String settingName) {
|
||||
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
|
||||
|
||||
if (!steps.fileExists(configPath)) {
|
||||
return false
|
||||
}
|
||||
|
||||
String fileContent = steps.readFile(configPath)
|
||||
return fileContent.contains("\"$settingName\"")
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import java.util.regex.Pattern
|
||||
|
||||
class VersionParser implements Serializable {
|
||||
final static VERSION_REGEXP = ~/(?i)<version>(.*)<\/version>/
|
||||
final static VERSION_REGEXP_SSL = ~/(?i)Описание.Версия = "(.*)";/
|
||||
|
||||
static String configuration(rootFile = 'src/cf/Configuration.xml') {
|
||||
return extractVersionFromFile(rootFile, VERSION_REGEXP)
|
||||
@ -21,6 +22,10 @@ class VersionParser implements Serializable {
|
||||
return extractVersionFromFile(versionFile, VERSION_REGEXP)
|
||||
}
|
||||
|
||||
static String ssl(versionFile) {
|
||||
return extractVersionFromFile(versionFile, VERSION_REGEXP_SSL)
|
||||
}
|
||||
|
||||
private static String extractVersionFromFile(String filePath, Pattern regexp) {
|
||||
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
|
||||
|
||||
@ -28,7 +33,7 @@ class VersionParser implements Serializable {
|
||||
return ""
|
||||
}
|
||||
|
||||
def configurationText = steps.readFile(filePath, 'UTF-8');
|
||||
def configurationText = steps.readFile(filePath)
|
||||
return version(configurationText, regexp)
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,8 @@ class ConfigurationReaderTest {
|
||||
assertThat(jobConfiguration.getV8version()).isEqualTo("8.3.14.1944");
|
||||
|
||||
assertThat(jobConfiguration.getSonarQubeOptions().getSonarScannerToolName()).isEqualTo("sonar-scanner");
|
||||
assertThat(jobConfiguration.getSonarQubeOptions().getSonarQubeInstallation()).isEqualTo("qa");
|
||||
assertThat(jobConfiguration.getSonarQubeOptions().getUseSonarScannerFromPath()).isTrue();
|
||||
|
||||
assertThat(jobConfiguration.getSecrets())
|
||||
.hasFieldOrPropertyWithValue("storage", "1234")
|
||||
@ -41,15 +43,22 @@ class ConfigurationReaderTest {
|
||||
|
||||
assertThat(jobConfiguration.getSyntaxCheckOptions().getCheckModes()).hasSize(1);
|
||||
|
||||
assertThat(jobConfiguration.getResultsTransformOptions().isRemoveSupport()).isFalse();
|
||||
assertThat(jobConfiguration.getResultsTransformOptions().getRemoveSupport()).isFalse();
|
||||
assertThat(jobConfiguration.getResultsTransformOptions().getSupportLevel()).isZero();
|
||||
|
||||
assertThat(jobConfiguration.getInitInfobaseOptions().getRunMigration()).isFalse();
|
||||
assertThat(jobConfiguration.getInitInfobaseOptions().getAdditionalInitializationSteps()).contains("vanessa --settings ./tools/vrunner.first.json");
|
||||
assertThat(jobConfiguration.getSmokeTestOptions().getVrunnerSettings()).contains("./tools/vrunner-smoke.json");
|
||||
assertThat(jobConfiguration.getSmokeTestOptions().isPublishToAllureReport()).isFalse();
|
||||
assertThat(jobConfiguration.getSmokeTestOptions().isPublishToJUnitReport()).isTrue();
|
||||
|
||||
assertThat(jobConfiguration.getInitInfoBaseOptions().getRunMigration()).isFalse();
|
||||
assertThat(jobConfiguration.getInitInfoBaseOptions().getAdditionalInitializationSteps()).contains("vanessa --settings ./tools/vrunner.first.json");
|
||||
|
||||
assertThat(jobConfiguration.getBddOptions().getVrunnerSteps()).contains("vanessa --settings ./tools/vrunner.json");
|
||||
|
||||
assertThat(jobConfiguration.getLogosConfig()).isEqualTo("logger.rootLogger=DEBUG");
|
||||
|
||||
assertThat(jobConfiguration.getTimeoutOptions().getBdd()).isEqualTo(120);
|
||||
assertThat(jobConfiguration.getTimeoutOptions().getZipInfoBase()).isEqualTo(123);
|
||||
}
|
||||
|
||||
}
|
@ -34,6 +34,11 @@ public class TestUtils {
|
||||
return FileUtils.readFileToString(new File(file), encoding);
|
||||
});
|
||||
|
||||
when(steps.readFile(anyString())).thenAnswer(invocation -> {
|
||||
String file = invocation.getArgument(0);
|
||||
return FileUtils.readFileToString(new File(file), StandardCharsets.UTF_8);
|
||||
});
|
||||
|
||||
when(steps.fileExists(anyString())).thenAnswer(invocation -> {
|
||||
String file = invocation.getArgument(0);
|
||||
return new File(file).exists();
|
||||
|
@ -6,17 +6,28 @@
|
||||
"stages": {
|
||||
"syntaxCheck": true
|
||||
},
|
||||
"timeout": {
|
||||
"zipInfoBase": 123
|
||||
},
|
||||
"initInfobase": {
|
||||
"runMigration": false,
|
||||
"additionalInitializationSteps": [
|
||||
"vanessa --settings ./tools/vrunner.first.json"
|
||||
]
|
||||
},
|
||||
"sonarqube": {
|
||||
"sonarQubeInstallation": "qa"
|
||||
},
|
||||
"syntaxCheck": {
|
||||
"checkModes": ["-ThinClient"]
|
||||
},
|
||||
"resultsTransform": {
|
||||
"removeSupport": false
|
||||
},
|
||||
"smoke": {
|
||||
"vrunnerSettings": "./tools/vrunner-smoke.json",
|
||||
"publishToAllureReport": false,
|
||||
"publishToJUnitReport": true
|
||||
},
|
||||
"logosConfig": "logger.rootLogger=DEBUG"
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.steps.InitInfobase
|
||||
import ru.pulsar.jenkins.library.steps.InitInfoBase
|
||||
|
||||
def call(JobConfiguration config) {
|
||||
ContextRegistry.registerDefaultContext(this)
|
||||
|
||||
def initInfobase = new InitInfobase(config)
|
||||
def initInfobase = new InitInfoBase(config)
|
||||
initInfobase.run()
|
||||
}
|
@ -19,7 +19,6 @@ void call() {
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '30'))
|
||||
timeout(time: 2, unit: TimeUnit.HOURS)
|
||||
timestamps()
|
||||
}
|
||||
|
||||
@ -29,6 +28,9 @@ void call() {
|
||||
agent {
|
||||
label 'agent'
|
||||
}
|
||||
options {
|
||||
timeout(time: 1, unit: TimeUnit.HOURS)
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
@ -46,7 +48,7 @@ void call() {
|
||||
}
|
||||
when {
|
||||
beforeAgent true
|
||||
expression { config.stageFlags.needInfobase() }
|
||||
expression { config.stageFlags.needInfoBase() }
|
||||
}
|
||||
|
||||
stages {
|
||||
@ -56,25 +58,28 @@ void call() {
|
||||
}
|
||||
when {
|
||||
beforeAgent true
|
||||
expression { config.stageFlags.needInfobase() && config.infobaseFromFiles() && config.sourceFormat == SourceFormat.EDT }
|
||||
expression { config.stageFlags.needInfoBase() && config.infoBaseFromFiles() && config.sourceFormat == SourceFormat.EDT }
|
||||
}
|
||||
steps {
|
||||
edtToDesignerFormatTransformation config
|
||||
timeout(time: config.timeoutOptions.edtToDesignerFormatTransformation, unit: TimeUnit.MINUTES) {
|
||||
edtToDesignerFormatTransformation config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Создание ИБ') {
|
||||
steps {
|
||||
createDir('build/out')
|
||||
timeout(time: config.timeoutOptions.createInfoBase, unit: TimeUnit.MINUTES) {
|
||||
createDir('build/out')
|
||||
|
||||
script {
|
||||
if (config.infobaseFromFiles()){
|
||||
// Создание базы загрузкой из файлов
|
||||
initFromFiles config
|
||||
}
|
||||
else{
|
||||
// Создание базы загрузкой конфигурации из хранилища
|
||||
initFromStorage config
|
||||
script {
|
||||
if (config.infoBaseFromFiles()) {
|
||||
// Создание базы загрузкой из файлов
|
||||
initFromFiles config
|
||||
} else {
|
||||
// Создание базы загрузкой конфигурации из хранилища
|
||||
initFromStorage config
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,16 +91,20 @@ void call() {
|
||||
expression { config.stageFlags.initSteps }
|
||||
}
|
||||
steps {
|
||||
// Инициализация и первичная миграция
|
||||
initInfobase config
|
||||
timeout(time: config.timeoutOptions.initInfoBase, unit: TimeUnit.MINUTES) {
|
||||
// Инициализация и первичная миграция
|
||||
initInfobase config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Архивация ИБ') {
|
||||
steps {
|
||||
printLocation()
|
||||
timeout(time: config.timeoutOptions.zipInfoBase, unit: TimeUnit.MINUTES) {
|
||||
printLocation()
|
||||
|
||||
zipInfobase()
|
||||
zipInfobase()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -109,10 +118,12 @@ void call() {
|
||||
}
|
||||
when {
|
||||
beforeAgent true
|
||||
expression { config.sourceFormat == SourceFormat.DESIGNER && config.stageFlags.edtValidate}
|
||||
expression { config.sourceFormat == SourceFormat.DESIGNER && config.stageFlags.edtValidate }
|
||||
}
|
||||
steps {
|
||||
designerToEdtFormatTransformation config
|
||||
timeout(time: config.timeoutOptions.designerToEdtFormatTransformation, unit: TimeUnit.MINUTES) {
|
||||
designerToEdtFormatTransformation config
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -131,7 +142,9 @@ void call() {
|
||||
label 'edt'
|
||||
}
|
||||
steps {
|
||||
edtValidate config
|
||||
timeout(time: config.timeoutOptions.edtValidate, unit: TimeUnit.MINUTES) {
|
||||
edtValidate config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +153,9 @@ void call() {
|
||||
label 'oscript'
|
||||
}
|
||||
steps {
|
||||
transform config
|
||||
timeout(time: config.timeoutOptions.resultTransformation, unit: TimeUnit.MINUTES) {
|
||||
transform config
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -155,9 +170,11 @@ void call() {
|
||||
expression { config.stageFlags.bdd }
|
||||
}
|
||||
steps {
|
||||
unzipInfobase()
|
||||
|
||||
bdd config
|
||||
timeout(time: config.timeoutOptions.bdd, unit: TimeUnit.MINUTES) {
|
||||
unzipInfobase()
|
||||
|
||||
bdd config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,7 +187,9 @@ void call() {
|
||||
expression { config.stageFlags.syntaxCheck }
|
||||
}
|
||||
steps {
|
||||
syntaxCheck config
|
||||
timeout(time: config.timeoutOptions.syntaxCheck, unit: TimeUnit.MINUTES) {
|
||||
syntaxCheck config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,7 +202,11 @@ void call() {
|
||||
expression { config.stageFlags.smoke }
|
||||
}
|
||||
steps {
|
||||
smoke config
|
||||
timeout(time: config.timeoutOptions.smoke, unit: TimeUnit.MINUTES) {
|
||||
unzipInfobase()
|
||||
|
||||
smoke config
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -198,7 +221,9 @@ void call() {
|
||||
expression { config.stageFlags.sonarqube }
|
||||
}
|
||||
steps {
|
||||
sonarScanner config
|
||||
timeout(time: config.timeoutOptions.sonarqube, unit: TimeUnit.MINUTES) {
|
||||
sonarScanner config
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,12 @@
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.steps.SmokeTest
|
||||
|
||||
def call(JobConfiguration config) {
|
||||
|
||||
ContextRegistry.registerDefaultContext(this)
|
||||
|
||||
// TODO: Вынести в отдельный класс по аналогии с SonarScanner
|
||||
|
||||
printLocation()
|
||||
|
||||
if (!config.stageFlags.smoke) {
|
||||
echo("Smoke tests step is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
def options = config.syntaxCheckOptions
|
||||
|
||||
installLocalDependencies()
|
||||
|
||||
unzipInfobase()
|
||||
def smokeTest = new SmokeTest(config)
|
||||
smokeTest.run()
|
||||
|
||||
}
|
||||
|
@ -46,15 +46,15 @@ def call(JobConfiguration config) {
|
||||
command += " --settings $vrunnerSettings";
|
||||
}
|
||||
|
||||
if (!options.exceptionFile.empty && fileExists(options.exceptionFile)) {
|
||||
command += " --exception-file $options.exceptionFile"
|
||||
}
|
||||
|
||||
if (options.checkModes.length > 0) {
|
||||
def checkModes = options.checkModes.join(" ")
|
||||
command += " --mode $checkModes"
|
||||
}
|
||||
|
||||
if (!options.exceptionFile.empty && fileExists(options.exceptionFile)) {
|
||||
command += " --exception-file $options.exceptionFile"
|
||||
}
|
||||
|
||||
// Запуск синтакс-проверки
|
||||
VRunner.exec(command, true)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user