You've already forked jenkins-lib
mirror of
https://github.com/firstBitMarksistskaya/jenkins-lib.git
synced 2025-08-25 20:09:25 +02:00
Merge pull request #150 from firstBitMarksistskaya/develop
This commit is contained in:
16
README.md
16
README.md
@@ -46,12 +46,12 @@
|
||||
1. Запуск юнит-тестов с помощью фреймворка YAXUnit с сохранением результатов в формате jUnit и Allure.
|
||||
1. Запуск синтаксического контроля средствами конфигуратора и сохранение результатов в виде отчета jUnit.
|
||||
1. Валидация проекта средствами EDT и трансформация отчета EDT в формат BSL LS с помощью `edt-ripper` или Generic Issue с помощью `stebi`.
|
||||
|
||||
1. Запуск статического анализа для SonarQube.
|
||||
1. Публикация результатов junit и Allure в интерфейс Jenkins.
|
||||
1. Рассылка результатов сборки на почту и в Telegram.
|
||||
1. Конфигурирование логгера запускаемых oscript-приложений.
|
||||
1. Замер покрытия при выполнении тестов.
|
||||
1. Возможность сохранить информационную базу в виде артефакта сборки после выполнения шагов инициализации и\или после выполнения сценарных тестов.
|
||||
|
||||
## Подключение
|
||||
|
||||
@@ -168,6 +168,7 @@ pipeline1C()
|
||||
* Если разработка ведется с использованием подсистемы [БСП "Обновление версии ИБ"](https://its.1c.ru/db/bsp315doc#content:4:1:issogl1_обновление_версии_иб), то в значение параметра `sonar.projectVersion=$configurationVersion` утилиты `sonar-scanner` можно передавать версию из созданного общего модуля. Для этого необходимо заполнить параметр (`sonarqube` -> `infoBaseUpdateModuleName`). Если параметр не заполнен, версия передается из корня конфигурации.
|
||||
* По умолчанию шаг анализа не дожидается окончания фонового задания на сервере SonarQube и не анализирует результат прохождения Порога качества (`sonarqube` -> `waitForQualityGate`).
|
||||
* Если выполнялась валидация EDT, результаты валидации передаются утилите `sonar-scanner` как значение параметра `sonar.externalIssuesReportPaths` при использовании `stebi` или как значение параметра `sonar.bsl.languageserver.reportPaths` при использовании `edt-ripper`.
|
||||
* Информационная база по умолчанию не сохраняется в виде артефакта сборки.
|
||||
* Рассылка уведомлений:
|
||||
* Электронная почта:
|
||||
* Для отправки используется плагин [`email-ext`](https://plugins.jenkins.io/email-ext). Шаблоны сообщений конфигурируются в настройках плагина.
|
||||
@@ -259,8 +260,8 @@ pipeline1C()
|
||||
* [Coverage41C](https://github.com/1c-syntax/Coverage41C), его необходимо установить на агент отдельно
|
||||
* EDT нужной версии или отдельные jar-файлы из его каталога установки, подробнее см. в [Coverage41C/README.md](https://github.com/1c-syntax/Coverage41C)
|
||||
* Если на агенте Coverage41C не включен в PATH, необходимо указать полный путь к нему в параметре `coverage41CPath`
|
||||
* Сбор замеров покрытия активируется для каждого стейджа отдельно с помощью установки параметра `"coverage": true`
|
||||
* поддерживаются `bdd` и `yaxunit`, для использования замеров на стейже `smoke` ожидается исправление vanessa-add в этом [PR](https://github.com/vanessa-opensource/add/pull/1153)
|
||||
* Сбор замеров покрытия активируется для каждого этапа отдельно с помощью установки параметра `"coverage": true`
|
||||
* поддерживаются `bdd` и `yaxunit`, для использования замеров на этапе `smoke` ожидается исправление vanessa-add в этом [PR](https://github.com/vanessa-opensource/add/pull/1153)
|
||||
* Чтобы замеры в `bdd`, `yaxunit`, `smoke` могли выполняться параллельно **на одном агенте**, необходимо указывать для них разные порты отладки в параметре `dbgsPort`.
|
||||
* Не забудьте настроить подключение клиентов тестирования к серверу отладки.
|
||||
|
||||
@@ -312,3 +313,12 @@ jobConfiguration.json
|
||||
|
||||
* При изменении портов отладки в jobConfiguration.json не забывайте менять порты в настройках соответствующих шагов (и наоборот)
|
||||
* Настоятельно рекомендуется использовать не "постоянные" агенты Jenkins, а контейнеры docker. При выполнении билдов в контейнерах можно использовать исключительно стандартный порт 1550.
|
||||
|
||||
## Сохранение ИБ в виде артефакта сборки
|
||||
|
||||
Параметры `initInfobase` -> `archiveInfobase` и `bdd` -> `archiveInfobase` отвечают за сохранение информационной базы в виде артефакта сборки после выполнения соответствующих этапов.
|
||||
Можно управлять тем, при каких статусах сборки ИБ будет сохранена, см. `onAlways`, `onFailure`, `onUnstable`, `onSuccess`.
|
||||
|
||||
Имя файла формируется следующим образом:
|
||||
* для шага `initInfoBase`: '1Cv8.1CD.zip'
|
||||
* для шага `bdd`: '1Cv8.1CD.bdd.zip'
|
||||
|
@@ -36,7 +36,7 @@ val junitVersion = "5.11.0"
|
||||
val spockVersion = "1.3-groovy-2.4"
|
||||
val groovyVersion = "2.4.21"
|
||||
val slf4jVersion = "2.0.16"
|
||||
val jsonschemaVersion = "4.36.0"
|
||||
val jsonschemaVersion = "4.37.0"
|
||||
|
||||
dependencies {
|
||||
implementation("org.codehaus.groovy", "groovy-all", groovyVersion)
|
||||
|
@@ -45,12 +45,24 @@
|
||||
"additionalInitializationSteps": [],
|
||||
"templateDBPath": "",
|
||||
"vrunnerSettings": "./tools/vrunner.json",
|
||||
"archiveInfobase": {
|
||||
"onAlways": false,
|
||||
"onFailure": false,
|
||||
"onUnstable": false,
|
||||
"onSuccess": false
|
||||
},
|
||||
"extensions": []
|
||||
},
|
||||
"bdd": {
|
||||
"vrunnerSteps": [
|
||||
"vanessa --settings ./tools/vrunner.json"
|
||||
],
|
||||
"archiveInfobase": {
|
||||
"onAlways": false,
|
||||
"onFailure": false,
|
||||
"onUnstable": false,
|
||||
"onSuccess": false
|
||||
},
|
||||
"coverage": false,
|
||||
"dbgsPort": 1550
|
||||
},
|
||||
@@ -58,13 +70,12 @@
|
||||
"sonarQubeInstallation": "",
|
||||
"useSonarScannerFromPath": true,
|
||||
"sonarScannerToolName": "sonar-scanner",
|
||||
"infoBaseUpdateModuleName" : "",
|
||||
"infoBaseUpdateModuleName": "",
|
||||
"branchAnalysisConfiguration": "fromEnv",
|
||||
"waitForQualityGate": false
|
||||
},
|
||||
"syntaxCheck": {
|
||||
"groupErrorsByMetadata": true,
|
||||
"pathToJUnitReport": "./build/out/jUnit/syntax.xml",
|
||||
"exceptionFile": "./tools/syntax-check-exception-file.txt",
|
||||
"checkModes": [
|
||||
"-ThinClient",
|
||||
@@ -79,7 +90,9 @@
|
||||
"-CheckUseSynchronousCalls",
|
||||
"-DistributiveModules"
|
||||
],
|
||||
"vrunnerSettings": "./tools/vrunner.json"
|
||||
"vrunnerSettings": "./tools/vrunner.json",
|
||||
"publishToAllureReport": false,
|
||||
"publishToJUnitReport": true
|
||||
},
|
||||
"smoke": {
|
||||
"vrunnerSettings": "./tools/vrunner.json",
|
||||
|
@@ -1,6 +1,27 @@
|
||||
{
|
||||
"$schema" : "http://json-schema.org/draft-07/schema#",
|
||||
"definitions" : {
|
||||
"ArchiveInfobaseOptions" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"onAlways" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Сохранять всегда"
|
||||
},
|
||||
"onFailure" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Сохранять при падении сборки"
|
||||
},
|
||||
"onSuccess" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Сохранять при успешной сборке"
|
||||
},
|
||||
"onUnstable" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Сохранять при нестабильной сборке"
|
||||
}
|
||||
}
|
||||
},
|
||||
"EmailExtConfiguration" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
@@ -28,15 +49,22 @@
|
||||
"bdd" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"archiveInfobase" : {
|
||||
"allOf" : [ {
|
||||
"$ref" : "#/definitions/ArchiveInfobaseOptions"
|
||||
}, {
|
||||
"description" : "Настройки сохранения базы после выполнения всех шагов\n "
|
||||
} ]
|
||||
},
|
||||
"coverage" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять замер покрытия",
|
||||
"default" : "false"
|
||||
"default" : false
|
||||
},
|
||||
"dbgsPort" : {
|
||||
"type" : "integer",
|
||||
"description" : "Порт, на котором будет запущен сервер отладки для замера покрытия",
|
||||
"default" : "1550"
|
||||
"default" : 1550
|
||||
},
|
||||
"vrunnerSteps" : {
|
||||
"description" : "Шаги, запускаемые через vrunner.\n В каждой строке передается отдельная команда \n vrunner и ее аргументы (например, \"vanessa --settings ./tools/vrunner.json\").\n По умолчанию содержит одну команду \"vanessa --settings ./tools/vrunner.json\".\n ",
|
||||
@@ -80,6 +108,13 @@
|
||||
"type" : "string"
|
||||
}
|
||||
},
|
||||
"archiveInfobase" : {
|
||||
"allOf" : [ {
|
||||
"$ref" : "#/definitions/ArchiveInfobaseOptions"
|
||||
}, {
|
||||
"description" : "Настройки сохранения базы после выполнения всех шагов\n "
|
||||
} ]
|
||||
},
|
||||
"extensions" : {
|
||||
"description" : "Массив расширений для загрузки в конфигурацию.",
|
||||
"type" : "array",
|
||||
@@ -250,12 +285,12 @@
|
||||
"coverage" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять замер покрытия",
|
||||
"default" : "false"
|
||||
"default" : false
|
||||
},
|
||||
"dbgsPort" : {
|
||||
"type" : "integer",
|
||||
"description" : "Порт, на котором будет запущен сервер отладки для замера покрытия",
|
||||
"default" : "1550"
|
||||
"default" : 1550
|
||||
},
|
||||
"publishToAllureReport" : {
|
||||
"type" : "boolean",
|
||||
@@ -378,9 +413,15 @@
|
||||
"type" : "boolean",
|
||||
"description" : "Группировать выявленные ошибки по объектам метаданных.\n По умолчанию включено.\n "
|
||||
},
|
||||
"pathToJUnitReport" : {
|
||||
"type" : "string",
|
||||
"description" : "Путь к файлу отчета jUnit\n По умолчанию содержит значение \"./build/out/jUnit/syntax.xml\"\n "
|
||||
"publishToAllureReport" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять публикацию результатов в отчет Allure.\n По умолчанию выключено.\n ",
|
||||
"default" : false
|
||||
},
|
||||
"publishToJUnitReport" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять публикацию результатов в отчет JUnit.\n По умолчанию включено.\n ",
|
||||
"default" : true
|
||||
},
|
||||
"vrunnerSettings" : {
|
||||
"type" : "string",
|
||||
@@ -469,12 +510,12 @@
|
||||
"coverage" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять замер покрытия",
|
||||
"default" : "false"
|
||||
"default" : false
|
||||
},
|
||||
"dbgsPort" : {
|
||||
"type" : "integer",
|
||||
"description" : "Порт, на котором будет запущен сервер отладки для замера покрытия",
|
||||
"default" : "1550"
|
||||
"default" : 1550
|
||||
},
|
||||
"publishToAllureReport" : {
|
||||
"type" : "boolean",
|
||||
|
@@ -33,7 +33,8 @@ public class JobConfigurationSchemaGenerator {
|
||||
writer.write(jsonSchema.toPrettyString());
|
||||
System.out.println(jsonSchema.toPrettyString());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
//noinspection CallToPrintStackTrace
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@ import org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.configuration.StepCoverageOptions
|
||||
import ru.pulsar.jenkins.library.steps.Coverable
|
||||
import sp.sd.fileoperations.FileOperation
|
||||
|
||||
interface IStepExecutor {
|
||||
|
||||
@@ -34,6 +35,10 @@ interface IStepExecutor {
|
||||
|
||||
boolean fileExists(String file)
|
||||
|
||||
void fileOperations(List<FileOperation> fileOperations)
|
||||
|
||||
void fileDeleteOperation(String includes)
|
||||
|
||||
void echo(message)
|
||||
|
||||
def cmd(String script, boolean returnStatus, boolean returnStdout)
|
||||
@@ -89,6 +94,8 @@ interface IStepExecutor {
|
||||
@SuppressWarnings('unused')
|
||||
def zip(String dir, String zipFile, String glob)
|
||||
|
||||
def zip(String dir, String zipFile, String glob, boolean archive)
|
||||
|
||||
def unzip(String dir, String zipFile)
|
||||
|
||||
@SuppressWarnings('unused')
|
||||
@@ -120,4 +127,5 @@ interface IStepExecutor {
|
||||
def brokenTestsSuspects()
|
||||
|
||||
RunWrapper currentBuild()
|
||||
|
||||
}
|
@@ -11,6 +11,7 @@ import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.configuration.StepCoverageOptions
|
||||
import ru.pulsar.jenkins.library.steps.Coverable
|
||||
import ru.yandex.qatools.allure.jenkins.config.ResultsConfig
|
||||
import sp.sd.fileoperations.FileOperation
|
||||
|
||||
class StepExecutor implements IStepExecutor {
|
||||
|
||||
@@ -55,6 +56,16 @@ class StepExecutor implements IStepExecutor {
|
||||
steps.fileExists file
|
||||
}
|
||||
|
||||
@Override
|
||||
void fileOperations(List<FileOperation> fileOperations) {
|
||||
steps.fileOperations fileOperations
|
||||
}
|
||||
|
||||
@Override
|
||||
void fileDeleteOperation(String includes) {
|
||||
steps.fileDeleteOperation includes: includes, excludes: '', useDefaultExcludes: true
|
||||
}
|
||||
|
||||
@Override
|
||||
FileWrapper[] findFiles(String glob, String excludes = '') {
|
||||
steps.findFiles glob: glob, excludes: excludes
|
||||
@@ -196,6 +207,11 @@ class StepExecutor implements IStepExecutor {
|
||||
steps.zip dir: dir, zipFile: zipFile, glob: glob, overwrite: true
|
||||
}
|
||||
|
||||
@Override
|
||||
def zip(String dir, String zipFile, String glob = '', boolean archive) {
|
||||
steps.zip dir: dir, zipFile: zipFile, glob: glob, overwrite: true, archive: archive
|
||||
}
|
||||
|
||||
@Override
|
||||
def unzip(String dir, String zipFile, quiet = true) {
|
||||
steps.unzip dir: dir, zipFile: zipFile, quiet: quiet
|
||||
|
@@ -0,0 +1,31 @@
|
||||
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 ArchiveInfobaseOptions implements Serializable {
|
||||
|
||||
@JsonPropertyDescription("Сохранять всегда")
|
||||
Boolean onAlways = false
|
||||
@JsonPropertyDescription("Сохранять при успешной сборке")
|
||||
Boolean onSuccess = false
|
||||
@JsonPropertyDescription("Сохранять при падении сборки")
|
||||
Boolean onFailure = false
|
||||
@JsonPropertyDescription("Сохранять при нестабильной сборке")
|
||||
Boolean onUnstable = false
|
||||
|
||||
@Override
|
||||
@NonCPS
|
||||
String toString() {
|
||||
return "ArchiveInfobaseOptions{" +
|
||||
"onAlways=" + onAlways +
|
||||
", onSuccess=" + onSuccess +
|
||||
", onFailure=" + onFailure +
|
||||
", onUnstable=" + onUnstable +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,11 +16,16 @@ class BddOptions extends StepCoverageOptions implements Serializable {
|
||||
'vanessa --settings ./tools/vrunner.json'
|
||||
]
|
||||
|
||||
@JsonPropertyDescription("""Настройки сохранения базы после выполнения всех шагов
|
||||
""")
|
||||
ArchiveInfobaseOptions archiveInfobase
|
||||
|
||||
@Override
|
||||
@NonCPS
|
||||
String toString() {
|
||||
return "BddOptions{" +
|
||||
"vrunnerSteps=" + vrunnerSteps +
|
||||
"archiveInfobase=" + archiveInfobase +
|
||||
"coverage=" + coverage +
|
||||
"dbgsPort=" + dbgsPort +
|
||||
'}'
|
||||
|
@@ -69,6 +69,7 @@ class ConfigurationReader implements Serializable {
|
||||
"yaxunitOptions",
|
||||
"syntaxCheckOptions",
|
||||
"resultsTransformOptions",
|
||||
"archiveInfobase",
|
||||
"notificationsOptions",
|
||||
"emailNotificationOptions",
|
||||
"alwaysEmailOptions",
|
||||
|
@@ -40,6 +40,10 @@ class InitInfoBaseOptions implements Serializable {
|
||||
""")
|
||||
String templateDBPath
|
||||
|
||||
@JsonPropertyDescription("""Настройки сохранения базы после выполнения всех шагов
|
||||
""")
|
||||
ArchiveInfobaseOptions archiveInfobase
|
||||
|
||||
@JsonPropertyDescription("Массив расширений для загрузки в конфигурацию.")
|
||||
Extension[] extensions
|
||||
|
||||
@@ -80,6 +84,7 @@ class InitInfoBaseOptions implements Serializable {
|
||||
", vrunnerSettings=" + vrunnerSettings +
|
||||
", templateDBPath=" + templateDBPath +
|
||||
", additionalInitializationSteps=" + additionalInitializationSteps +
|
||||
", archiveInfobase=" + archiveInfobase +
|
||||
", extensions=" + extensions +
|
||||
'}'
|
||||
}
|
||||
|
@@ -2,16 +2,13 @@ package ru.pulsar.jenkins.library.configuration
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
import com.fasterxml.jackson.annotation.JsonInclude
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
class SyntaxCheckOptions implements Serializable {
|
||||
|
||||
@JsonPropertyDescription("""Путь к файлу отчета jUnit
|
||||
По умолчанию содержит значение "./build/out/jUnit/syntax.xml"
|
||||
""")
|
||||
String pathToJUnitReport = "./build/out/jUnit/syntax.xml"
|
||||
|
||||
@JsonPropertyDescription("""Группировать выявленные ошибки по объектам метаданных.
|
||||
По умолчанию включено.
|
||||
""")
|
||||
@@ -31,14 +28,27 @@ class SyntaxCheckOptions implements Serializable {
|
||||
""")
|
||||
String vrunnerSettings = "./tools/vrunner.json"
|
||||
|
||||
@JsonPropertyDescription("""Выполнять публикацию результатов в отчет Allure.
|
||||
По умолчанию выключено.
|
||||
""")
|
||||
@JsonProperty(defaultValue = "false")
|
||||
boolean publishToAllureReport = false
|
||||
|
||||
@JsonPropertyDescription("""Выполнять публикацию результатов в отчет JUnit.
|
||||
По умолчанию включено.
|
||||
""")
|
||||
@JsonProperty(defaultValue = "true")
|
||||
boolean publishToJUnitReport = true
|
||||
|
||||
@Override
|
||||
@NonCPS
|
||||
String toString() {
|
||||
return "SyntaxCheckOptions{" +
|
||||
"pathToJUnitReport='" + pathToJUnitReport + '\'' +
|
||||
", groupErrorsByMetadata=" + groupErrorsByMetadata +
|
||||
", checkModes=" + checkModes +
|
||||
", vrunnerSettings=" + vrunnerSettings +
|
||||
'}';
|
||||
", publishToAllureReport=" + publishToAllureReport +
|
||||
", publishToJUnitReport=" + publishToJUnitReport +
|
||||
'}'
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ class LoadExtensions implements Serializable {
|
||||
|
||||
private Extension[] extensionsFiltered
|
||||
|
||||
LoadExtensions(JobConfiguration config, String stageName = "") {
|
||||
LoadExtensions(JobConfiguration config, String stageName) {
|
||||
this.config = config
|
||||
this.stageName = stageName
|
||||
}
|
||||
@@ -33,13 +33,19 @@ class LoadExtensions implements Serializable {
|
||||
|
||||
def extensions = this.config.initInfoBaseOptions.extensions
|
||||
|
||||
if (this.stageName) {
|
||||
this.extensionsFiltered = extensions.findAll { extension ->
|
||||
extension.stages.contains(this.stageName)
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.extensionsFiltered = extensions.findAll { extension -> extension.stages.length == 0 || extension.stages.contains("initInfoBase") }
|
||||
// NB: расширения, подключаемые на этапе initInfoBase, остаются подключенными на всех остальных этапах
|
||||
if (this.stageName == "initInfoBase") {
|
||||
// подключаются все расширения, у которых явно указано подключение на текущем этапе
|
||||
// и те расширения, в которых этапы подключения не указаны вообще
|
||||
this.extensionsFiltered = extensions.findAll({ extension ->
|
||||
extension.stages.contains(this.stageName) || extension.stages.length == 0
|
||||
})
|
||||
} else {
|
||||
// на остальных этапах подключаются расширения, которые не были подключены на этапе initInfoBase
|
||||
// и у которых явно указано подключение на текущем этапе
|
||||
this.extensionsFiltered = extensions.findAll({ extension ->
|
||||
!extension.stages.contains("initInfoBase") && extension.stages.contains(this.stageName)
|
||||
})
|
||||
}
|
||||
|
||||
def env = steps.env()
|
||||
|
@@ -39,6 +39,9 @@ class PublishAllure implements Serializable {
|
||||
if (config.stageFlags.smoke && config.smokeTestOptions.publishToAllureReport) {
|
||||
safeUnstash(SmokeTest.ALLURE_STASH)
|
||||
}
|
||||
if (config.stageFlags.syntaxCheck && config.syntaxCheckOptions.publishToAllureReport) {
|
||||
safeUnstash(SyntaxCheck.ALLURE_STASH)
|
||||
}
|
||||
|
||||
def env = steps.env()
|
||||
|
||||
|
96
src/ru/pulsar/jenkins/library/steps/SyntaxCheck.groovy
Normal file
96
src/ru/pulsar/jenkins/library/steps/SyntaxCheck.groovy
Normal file
@@ -0,0 +1,96 @@
|
||||
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 SyntaxCheck {
|
||||
|
||||
public static final String ALLURE_STASH = 'syntax-check-allure'
|
||||
|
||||
private final JobConfiguration config
|
||||
|
||||
SyntaxCheck(JobConfiguration config) {
|
||||
this.config = config
|
||||
}
|
||||
|
||||
def run() {
|
||||
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
|
||||
|
||||
Logger.printLocation()
|
||||
|
||||
if (!config.stageFlags.syntaxCheck) {
|
||||
Logger.println("Syntax-check step is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
def env = steps.env()
|
||||
|
||||
def options = config.syntaxCheckOptions
|
||||
|
||||
List<String> logosConfig = ["LOGOS_CONFIG=$config.logosConfig"]
|
||||
steps.withEnv(logosConfig) {
|
||||
steps.installLocalDependencies()
|
||||
|
||||
String junitReport = "build/out/jUnit/syntax-check/syntax-check.xml"
|
||||
FilePath pathToJUnitReport = FileUtils.getFilePath("$env.WORKSPACE/$junitReport")
|
||||
String junitReportDir = FileUtils.getLocalPath(pathToJUnitReport.getParent())
|
||||
|
||||
String allureReport = "build/out/allure/syntax-check/allure.xml"
|
||||
FilePath pathToAllureReport = FileUtils.getFilePath("$env.WORKSPACE/$allureReport")
|
||||
String allureReportDir = FileUtils.getLocalPath(pathToAllureReport.getParent())
|
||||
|
||||
String vrunnerPath = VRunner.getVRunnerPath()
|
||||
String command = "$vrunnerPath syntax-check --ibconnection \"/F./build/ib\""
|
||||
|
||||
// Временно убрал передачу параметра.
|
||||
// См. https://github.com/vanessa-opensource/vanessa-runner/issues/361
|
||||
// command += " --workspace $env.WORKSPACE"
|
||||
|
||||
if (options.groupErrorsByMetadata) {
|
||||
command += ' --groupbymetadata'
|
||||
}
|
||||
|
||||
if (options.publishToJUnitReport) {
|
||||
steps.createDir(junitReportDir)
|
||||
command += " --junitpath $pathToJUnitReport"
|
||||
}
|
||||
|
||||
if (options.publishToAllureReport) {
|
||||
steps.createDir(allureReportDir)
|
||||
command += " --allure-results2 $allureReportDir"
|
||||
}
|
||||
|
||||
FilePath vrunnerSettings = FileUtils.getFilePath("$env.WORKSPACE/$options.vrunnerSettings")
|
||||
if (vrunnerSettings.exists()) {
|
||||
command += " --settings $vrunnerSettings"
|
||||
}
|
||||
|
||||
if (!options.exceptionFile.empty && steps.fileExists(options.exceptionFile)) {
|
||||
command += " --exception-file $options.exceptionFile"
|
||||
}
|
||||
|
||||
if (options.checkModes.length > 0) {
|
||||
def checkModes = options.checkModes.join(" ")
|
||||
command += " --mode $checkModes"
|
||||
}
|
||||
|
||||
// Запуск синтакс-проверки
|
||||
VRunner.exec(command, true)
|
||||
|
||||
if (options.publishToAllureReport) {
|
||||
steps.stash(ALLURE_STASH, "$allureReportDir/**", true)
|
||||
steps.archiveArtifacts("$allureReportDir/**")
|
||||
}
|
||||
|
||||
if (options.publishToJUnitReport) {
|
||||
steps.junit("$junitReportDir/*.xml", true)
|
||||
steps.archiveArtifacts("$junitReportDir/**")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -82,7 +82,7 @@ class Yaxunit implements Serializable, Coverable {
|
||||
}
|
||||
|
||||
if (options.publishToAllureReport) {
|
||||
String allureReport = "./build/out/allure/yaxunit/junit.xml"
|
||||
String allureReport = "./build/out/allure/yaxunit/allure.xml"
|
||||
FilePath pathToAllureReport = FileUtils.getFilePath("$env.WORKSPACE/$allureReport")
|
||||
String allureReportDir = FileUtils.getLocalPath(pathToAllureReport.getParent())
|
||||
|
||||
|
68
src/ru/pulsar/jenkins/library/steps/ZipInfobase.groovy
Normal file
68
src/ru/pulsar/jenkins/library/steps/ZipInfobase.groovy
Normal file
@@ -0,0 +1,68 @@
|
||||
package ru.pulsar.jenkins.library.steps
|
||||
|
||||
import hudson.model.Result
|
||||
import ru.pulsar.jenkins.library.IStepExecutor
|
||||
import ru.pulsar.jenkins.library.configuration.ArchiveInfobaseOptions
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.utils.Logger
|
||||
|
||||
class ZipInfobase implements Serializable {
|
||||
|
||||
private final JobConfiguration config
|
||||
private final String stage
|
||||
|
||||
ZipInfobase(JobConfiguration config, String stage) {
|
||||
this.config = config
|
||||
this.stage = stage
|
||||
}
|
||||
|
||||
def run() {
|
||||
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
|
||||
|
||||
Logger.printLocation()
|
||||
|
||||
def currentBuild = steps.currentBuild()
|
||||
def currentResult = Result.fromString(currentBuild.getCurrentResult())
|
||||
|
||||
def archiveInfobaseOptions = getArchiveInfobaseOptionsForStage(config, stage)
|
||||
|
||||
def archiveName
|
||||
if (stage == 'initInfoBase') {
|
||||
archiveName = "1Cv8.1CD.zip"
|
||||
} else {
|
||||
archiveName = "1Cv8.1CD.${stage}.zip"
|
||||
}
|
||||
|
||||
// опция отвечает только за то, будет ли файл сохранен в виде артефакта
|
||||
def archiveInfobase = false
|
||||
if (archiveInfobaseOptions.onAlways
|
||||
|| (archiveInfobaseOptions.onFailure && (currentResult == Result.FAILURE || currentResult == Result.ABORTED))
|
||||
|| (archiveInfobaseOptions.onUnstable && currentResult == Result.UNSTABLE)
|
||||
|| (archiveInfobaseOptions.onSuccess && currentResult == Result.SUCCESS)) {
|
||||
archiveInfobase = true
|
||||
}
|
||||
|
||||
if (steps.fileExists(archiveName)) {
|
||||
steps.fileOperations([steps.fileDeleteOperation(archiveName)])
|
||||
}
|
||||
steps.zip('build/ib', archiveName, '1Cv8.1CD', archiveInfobase)
|
||||
steps.stash(archiveName, archiveName, false)
|
||||
}
|
||||
|
||||
private static ArchiveInfobaseOptions getArchiveInfobaseOptionsForStage(JobConfiguration config, String stageName) {
|
||||
|
||||
def defaultOptions = new ArchiveInfobaseOptions()
|
||||
if (!stageName) {
|
||||
return defaultOptions
|
||||
}
|
||||
|
||||
try {
|
||||
return config."${stageName}Options".archiveInfobase
|
||||
} catch(MissingPropertyException | NullPointerException e) {
|
||||
Logger.println("Ошибка при получении настроек архивации для этапа ${stageName}: ${e.message}")
|
||||
Logger.println(e.toString())
|
||||
return defaultOptions
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,7 +2,6 @@ package ru.pulsar.jenkins.library.configuration;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import ru.pulsar.jenkins.library.configuration.sonarqube.GenericIssueFormat;
|
||||
import ru.pulsar.jenkins.library.utils.TestUtils;
|
||||
@@ -66,6 +65,7 @@ class ConfigurationReaderTest {
|
||||
assertThat(jobConfiguration.getYaxunitOptions().getDbgsPort()).isEqualTo(1550);
|
||||
|
||||
assertThat(jobConfiguration.getInitInfoBaseOptions().getRunMigration()).isFalse();
|
||||
assertThat(jobConfiguration.getInitInfoBaseOptions().getArchiveInfobase().getOnAlways()).isTrue();
|
||||
assertThat(jobConfiguration.getInitInfoBaseOptions().getAdditionalInitializationSteps()).contains("vanessa --settings ./tools/vrunner.first.json");
|
||||
|
||||
assertThat(jobConfiguration.getBddOptions().getVrunnerSteps()).contains("vanessa --settings ./tools/vrunner.json");
|
||||
|
@@ -35,7 +35,7 @@ class LoadExtensionsTest {
|
||||
.thenReturn(new FilePath(new File("/")));
|
||||
|
||||
// given
|
||||
// файл содержит 4 расширения для разных стейджей
|
||||
// файл содержит 4 расширения для разных этапов
|
||||
String config = IOUtils.resourceToString(
|
||||
"jobConfiguration.json",
|
||||
StandardCharsets.UTF_8,
|
||||
@@ -44,11 +44,11 @@ class LoadExtensionsTest {
|
||||
JobConfiguration jobConfiguration = ConfigurationReader.create(config);
|
||||
|
||||
// when
|
||||
LoadExtensions loadExtensions = new LoadExtensions(jobConfiguration);
|
||||
loadExtensions.run();
|
||||
LoadExtensions loadExtensionsInit = new LoadExtensions(jobConfiguration, "initInfoBase");
|
||||
loadExtensionsInit.run();
|
||||
|
||||
// then
|
||||
InitInfoBaseOptions.Extension[] extensions = loadExtensions.getExtensionsFiltered();
|
||||
InitInfoBaseOptions.Extension[] extensions = loadExtensionsInit.getExtensionsFiltered();
|
||||
assertThat(extensions.length).isEqualTo(2);
|
||||
assertThat(extensions[0].getName()).isEqualTo("mods");
|
||||
assertThat(extensions[1].getName()).isEqualTo("mods2");
|
||||
|
@@ -48,7 +48,10 @@
|
||||
"initInfoBase"
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"archiveInfobase": {
|
||||
"onAlways": true
|
||||
}
|
||||
},
|
||||
"sonarqube": {
|
||||
"sonarQubeInstallation": "qa",
|
||||
|
@@ -144,7 +144,7 @@ void call() {
|
||||
timeout(time: config.timeoutOptions.zipInfoBase, unit: TimeUnit.MINUTES) {
|
||||
printLocation()
|
||||
|
||||
zipInfobase()
|
||||
zipInfobase config, 'initInfoBase'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,6 +237,16 @@ void call() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Архивация ИБ') {
|
||||
steps {
|
||||
timeout(time: config.timeoutOptions.zipInfoBase, unit: TimeUnit.MINUTES) {
|
||||
printLocation()
|
||||
|
||||
zipInfobase config, 'bdd'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,9 +258,19 @@ void call() {
|
||||
beforeAgent true
|
||||
expression { config.stageFlags.syntaxCheck }
|
||||
}
|
||||
steps {
|
||||
timeout(time: config.timeoutOptions.syntaxCheck, unit: TimeUnit.MINUTES) {
|
||||
syntaxCheck config
|
||||
stages {
|
||||
stage('Распаковка ИБ') {
|
||||
steps {
|
||||
unzipInfobase()
|
||||
}
|
||||
}
|
||||
|
||||
stage('Выполнение синтаксического контроля') {
|
||||
steps {
|
||||
timeout(time: config.timeoutOptions.syntaxCheck, unit: TimeUnit.MINUTES) {
|
||||
syntaxCheck config
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,64 +1,12 @@
|
||||
import hudson.FilePath
|
||||
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.VRunner
|
||||
import ru.pulsar.jenkins.library.steps.SyntaxCheck
|
||||
|
||||
def call(JobConfiguration config) {
|
||||
|
||||
ContextRegistry.registerDefaultContext(this)
|
||||
|
||||
// TODO: Вынести в отдельный класс по аналогии с SonarScanner
|
||||
def syntaxCheck = new SyntaxCheck(config)
|
||||
syntaxCheck.run()
|
||||
|
||||
printLocation()
|
||||
|
||||
if (!config.stageFlags.syntaxCheck) {
|
||||
echo("Syntax-check step is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
def options = config.syntaxCheckOptions
|
||||
|
||||
installLocalDependencies()
|
||||
|
||||
unzipInfobase()
|
||||
|
||||
FilePath pathToJUnitReport = FileUtils.getFilePath("$env.WORKSPACE/$options.pathToJUnitReport")
|
||||
|
||||
String outPath = pathToJUnitReport.getParent()
|
||||
createDir(outPath)
|
||||
|
||||
String vrunnerPath = VRunner.getVRunnerPath();
|
||||
String command = "$vrunnerPath syntax-check --ibconnection \"/F./build/ib\""
|
||||
|
||||
// Временно убрал передачу параметра.
|
||||
// См. https://github.com/vanessa-opensource/vanessa-runner/issues/361
|
||||
// command += " --workspace $env.WORKSPACE"
|
||||
|
||||
if (options.groupErrorsByMetadata) {
|
||||
command += ' --groupbymetadata'
|
||||
}
|
||||
|
||||
command += " --junitpath $pathToJUnitReport";
|
||||
|
||||
FilePath vrunnerSettings = FileUtils.getFilePath("$env.WORKSPACE/$options.vrunnerSettings")
|
||||
if (vrunnerSettings.exists()) {
|
||||
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"
|
||||
}
|
||||
|
||||
// Запуск синтакс-проверки
|
||||
VRunner.exec(command, true)
|
||||
|
||||
junit allowEmptyResults: true, testResults: FileUtils.getLocalPath(pathToJUnitReport)
|
||||
|
||||
archiveArtifacts FileUtils.getLocalPath(pathToJUnitReport)
|
||||
}
|
||||
|
@@ -1,7 +1,10 @@
|
||||
def call() {
|
||||
if (fileExists('1Cv8.1CD.zip')) {
|
||||
fileOperations([fileDeleteOperation(includes: '1Cv8.1CD.zip')])
|
||||
}
|
||||
zip dir: 'build/ib', glob: '1Cv8.1CD', zipFile: '1Cv8.1CD.zip'
|
||||
stash name: "1Cv8.1CD.zip", includes: "1Cv8.1CD.zip", allowEmpty: false
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.steps.ZipInfobase
|
||||
|
||||
def call(JobConfiguration config, String stageName) {
|
||||
ContextRegistry.registerDefaultContext(this)
|
||||
|
||||
def zipInfobase = new ZipInfobase(config, stageName)
|
||||
zipInfobase.run()
|
||||
}
|
||||
|
Reference in New Issue
Block a user