1
0
mirror of https://github.com/silverbulleters/vanessa-usher.git synced 2026-06-21 01:29:42 +02:00

feat: прототип usher2

This commit is contained in:
Tymko Oleg
2021-08-03 20:45:49 +07:00
parent 4b9c1bea2c
commit 539d2d0e06
51 changed files with 6849 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf
+6
View File
@@ -0,0 +1,6 @@
.settings
.idea
.gradle
build
.vscode
+24
View File
@@ -0,0 +1,24 @@
## ПОЛЬЗОВАТЕЛЬСКОЕ ЛИЦЕНЗИОННОЕ СОГЛАШЕНИЕ
=======================================
## Программный продукт «Vanessa-Usher»
Настоящее Пользовательское лицензионное соглашение является документом, регулирующим правила использования Программного продукта, обозначенного выше, физическим или юридическим лицом, обладающим правомерно изготовленным и введенным в гражданский оборот экземпляром данного Программного продукта - «Лицензиатом». Программный продукт (утилита) является библиотекой универсальной сборочной линии Vanessa-Usher для подключения к серверу сборок Jenkins*, и выполняет следующую функцию: расширение для платформы Jenkins* для автоматизации операций сборки и развертывания ИТ-решений на платформе 1С. Все исключительные имущественные права на обозначенный Программный продукт принадлежат ООО «СЕРЕБРЯНАЯ ПУЛЯ» (ОГРН 1147746395158), зарегистрированному в г.Москве (далее - «Правообладатель»). Устанавливая (используя) Программный продукт, Лицензиат признает себя связанным условиями настоящего Пользовательского лицензионного соглашения. По настоящему Пользовательскому лицензионному соглашению Правообладатель предоставляет Лицензиату отдельные неисключительные права, описанные ниже. Лицензиат обязан сохранять настоящее Пользовательское лицензионное соглашение в качестве документа (электронного документа), подтверждающего наличие у него прав на использование Программного продукта, предоставленных Правообладателем.
**ОПИСАНИЕ ПРАВ И ОГРАНИЧЕНИЙ:**
1. Лицензиат имеет право использовать Программный продукт на принадлежащем Лицензиату персональном компьютере/ сервере (в т.ч. «облачный сервер» Лицензиата) в соответствии с сопроводительной документацией, самостоятельно либо силами Пользователей (сотрудников Лицензиата, нанятых им по трудовому договору, действующему на момент использования Программного продукта). Лицензиат отвечает за действия своих сотрудников как за свои собственные и не вправе ссылаться на их неосведомленность в лицензионных правилах использования Программного продукта – ответственность за такое ознакомление и неправомерные действия своих сотрудников полностью лежит на Лицензиате.
2. Передача прав по настоящему Пользовательскому лицензионному соглашению третьим лицам (например, в случае реорганизации юридического лица-Лицензиата) допускается исключительно с письменного согласия Правообладателя, при условии передачи Лицензиатом третьему лицу полного комплекта поставки Программного продукта, включая настоящее Пользовательское лицензионное соглашение. При этом первоначальный Лицензиат обязан удалить со всех носителей все имеющиеся копии Программного продукта и/или не использовать Программный продукт.
3. Лицензиат обязуется не допускать нарушений исключительных прав Правообладателя на Программный продукт, в частности, не совершать и не допускать совершение третьими лицами неправомерных действий, а именно:
• Не распространять, не передавать Программный продукт или отдельные его компоненты, включая распространение путем предоставления доступа третьим лицам к воспроизведенному в любой форме Программному продукту, в том числе сетевым и иными способами, на возмездной либо безвозмездной основе, в том числе - не размещать публично Программный продукт в сети Интернет, не пересылать по электронной почте, а также с помощью иных программ и средств, и не совершать иных аналогичных действий направленных на распространение, тиражирование, передачу Программного продукта третьим лицам, прямо не указанных в настоящем пункте. Коммерческое использование Лицензиатом Комплекта и его составляющих частей запрещено. Под коммерческим использованием понимается, в частности, оказание услуг третьим лицам с использованием Программного продукта, либо предоставление доступа к Программному продукту третьим лицам, с целью извлечения прибыли. К коммерческому использованию не относится использование Программного продукта в профессиональной деятельности Лицензиата (сотрудниками Лицензиата). Лицензиат признает коммерческую ценность Программного продукта, обязуется не оспаривать (присваивать) авторство, а также исключительные права Правообладателя на Программный продукт, а также не совершать действий, наносящих вред деловой репутации, деловому имиджу и благосостоянию Правообладателя.
• Не вносить какие-либо изменения в код Программного продукта, за исключением тех, которые вносятся штатными средствами, входящими в состав Программного продукта и описанными в сопроводительной документации. Не вносить в Программный продукт изменения (модификации), не восстанавливать исходный код, не декомпилировать или (и) деассемблировать программную часть системы.
4. В случае нарушения Лицензиатом правил использования и ограничения Программного продукта, о которых стало известно Правообладателю, Правообладатель вправе отозвать лицензию без ее восстановления, без права ее восстановления, в одностороннем письменном порядке уведомив Лицензиата за 1 (один) календарный день до дня отзыва. Уведомление может быть направлено посредством электронной почты. Со дня отзыва лицензии (расторжения лицензионного соглашения) Лицензиат теряет все права использования Программного продукта.
5. Данная неисключительная лицензия считается бессрочной (на весь срок действия исключительного права) и не имеющей территориальных ограничений использования. Настоящее Пользовательское лицензионное соглашение действует в течение всего срока эксплуатации Лицензиатом Программного продукта и/или нахождения у него экземпляров Программного продукта
6. Лицензиат обязуется соблюдать авторские и исключительные права Правообладателя, не превышать пределы использования исключительных прав, установленных настоящим Пользовательским лицензионным соглашением.
7. При установлении недействительности какого-либо пункта или положения настоящего Пользовательского лицензионного соглашения, остальные его пункты признаются действующими.
8. Об изменениях в Лицензионных правилах, если таковые будут Правообладатель уведомляет Лицензиата посредством размещения информации на своем сайте.
______________________________
* - «open source»-продукт (https://jenkins.io/)
+64
View File
@@ -0,0 +1,64 @@
val junitVersion = "5.6.1"
plugins {
java
groovy
id("com.mkobit.jenkins.pipelines.shared-library") version "0.10.1"
id("com.github.ben-manes.versions") version "0.21.0"
}
dependencies {
implementation("org.codehaus.groovy", "groovy-all", "2.4.19")
// unit-tests
testImplementation("org.junit.jupiter", "junit-jupiter-api", "5.6.1")
testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", "5.6.1")
testImplementation("org.assertj", "assertj-core", "3.15.0")
// integration-tests
integrationTestImplementation("org.spockframework", "spock-core", "1.3-groovy-2.4")
integrationTestImplementation("org.codehaus.groovy", "groovy-all", "2.4.19")
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8;
}
tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
reports {
html.isEnabled = true
}
}
tasks.check {
dependsOn(tasks.integrationTest)
}
// https://github.com/mkobit/jenkins-pipeline-shared-library-example/blob/master/build.gradle.kts
jenkinsIntegration {
baseUrl.set(uri("http://localhost:5050").toURL())
authentication.set(providers.provider { com.mkobit.jenkins.pipelines.http.AnonymousAuthentication })
downloadDirectory.set(layout.projectDirectory.dir("jenkinsResources"))
}
// https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin
sharedLibrary {
coreVersion.set(jenkinsIntegration.downloadDirectory.file("core-version.txt").map { it.asFile.readText().trim() })
pluginDependencies {
dependency("org.jenkins-ci.plugins", "pipeline-build-step", "2.9")
dependency("org.6wind.jenkins", "lockable-resources", "2.5")
val declarativePluginsVersion = "1.3.9"
dependency("org.jenkinsci.plugins", "pipeline-model-api", declarativePluginsVersion)
dependency("org.jenkinsci.plugins", "pipeline-model-declarative-agent", "1.1.1")
dependency("org.jenkinsci.plugins", "pipeline-model-definition", declarativePluginsVersion)
dependency("org.jenkinsci.plugins", "pipeline-model-extensions", declarativePluginsVersion)
}
}
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+185
View File
@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"
Vendored
+104
View File
@@ -0,0 +1,104 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+1
View File
@@ -0,0 +1 @@
2.164.3
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/6.5.1/userguide/multi_project_builds.html
*/
pluginManagement {
repositories {
gradlePluginPortal()
}
}
rootProject.name = "vanessa-usher"
+125
View File
@@ -0,0 +1,125 @@
//The global script scope
def ctx = context(scope: scriptScope())
contributor(ctx) {
method(name: 'parallel', type: 'Object', params: ['closures': 'java.util.Map'], doc: 'Execute in parallel')
method(name: 'parallel', type: 'Object', namedParams: [parameter(name: 'closures', type: 'java.util.Map'), parameter(name: 'failFast', type: 'boolean'),], doc: 'Execute in parallel')
method(name: 'build', type: 'Object', params: [job: 'java.lang.String'], doc: 'Build a job')
method(name: 'build', type: 'Object', namedParams: [parameter(name: 'job', type: 'java.lang.String'), parameter(name: 'parameters', type: 'java.util.List'), parameter(name: 'propagate', type: 'boolean'), parameter(name: 'quietPeriod', type: 'java.lang.Integer'), parameter(name: 'wait', type: 'boolean'),], doc: 'Build a job')
method(name: 'catchError', type: 'Object', params: [body: 'Closure'], doc: 'Catch error and set build result to failure')
method(name: 'catchError', type: 'Object', params: [body: Closure], namedParams: [parameter(name: 'buildResult', type: 'java.lang.String'), parameter(name: 'catchInterruptions', type: 'boolean'), parameter(name: 'message', type: 'java.lang.String'), parameter(name: 'stageResult', type: 'java.lang.String'),], doc: 'Catch error and set build result to failure')
method(name: 'echo', type: 'Object', params: [message: 'java.lang.String'], doc: 'Print Message')
method(name: 'emailext', type: 'Object', namedParams: [parameter(name: 'subject', type: 'java.lang.String'), parameter(name: 'body', type: 'java.lang.String'), parameter(name: 'attachLog', type: 'boolean'), parameter(name: 'attachmentsPattern', type: 'java.lang.String'), parameter(name: 'compressLog', type: 'boolean'), parameter(name: 'from', type: 'java.lang.String'), parameter(name: 'mimeType', type: 'java.lang.String'), parameter(name: 'postsendScript', type: 'java.lang.String'), parameter(name: 'presendScript', type: 'java.lang.String'), parameter(name: 'recipientProviders', type: 'java.util.List'), parameter(name: 'replyTo', type: 'java.lang.String'), parameter(name: 'saveOutput', type: 'boolean'), parameter(name: 'to', type: 'java.lang.String'),], doc: 'Extended Email')
method(name: 'emailextrecipients', type: 'Object', params: [recipientProviders: 'java.util.List'], doc: 'Extended Email Recipients')
method(name: 'error', type: 'Object', params: [message: 'java.lang.String'], doc: 'Error signal')
method(name: 'findBuildScans', type: 'Object', params: [:], doc: 'Find published build scans')
method(name: 'input', type: 'Object', params: [message: 'java.lang.String'], doc: 'Wait for interactive input')
method(name: 'input', type: 'Object', namedParams: [parameter(name: 'message', type: 'java.lang.String'), parameter(name: 'id', type: 'java.lang.String'), parameter(name: 'ok', type: 'java.lang.String'), parameter(name: 'parameters', type: 'java.util.List'), parameter(name: 'submitter', type: 'java.lang.String'), parameter(name: 'submitterParameter', type: 'java.lang.String'),], doc: 'Wait for interactive input')
method(name: 'isUnix', type: 'Object', params: [:], doc: 'Checks if running on a Unix-like node')
method(name: 'library', type: 'Object', params: [identifier: 'java.lang.String'], doc: 'Load a shared library on the fly')
method(name: 'library', type: 'Object', namedParams: [parameter(name: 'identifier', type: 'java.lang.String'), parameter(name: 'changelog', type: 'java.lang.Boolean'), parameter(name: 'retriever', type: 'Map'),], doc: 'Load a shared library on the fly')
method(name: 'libraryResource', type: 'Object', params: [resource: 'java.lang.String'], doc: 'Load a resource file from a shared library')
method(name: 'libraryResource', type: 'Object', namedParams: [parameter(name: 'resource', type: 'java.lang.String'), parameter(name: 'encoding', type: 'java.lang.String'),], doc: 'Load a resource file from a shared library')
method(name: 'lock', type: 'Object', params: [resource: java.lang.String, body: 'Closure'], doc: 'Lock shared resource')
method(name: 'lock', type: 'Object', params: [body: Closure], namedParams: [parameter(name: 'resource', type: 'java.lang.String'), parameter(name: 'extra', type: 'java.util.List'), parameter(name: 'inversePrecedence', type: 'boolean'), parameter(name: 'label', type: 'java.lang.String'), parameter(name: 'quantity', type: 'int'), parameter(name: 'skipIfLocked', type: 'boolean'), parameter(name: 'variable', type: 'java.lang.String'),], doc: 'Lock shared resource')
method(name: 'mail', type: 'Object', namedParams: [parameter(name: 'subject', type: 'java.lang.String'), parameter(name: 'body', type: 'java.lang.String'), parameter(name: 'bcc', type: 'java.lang.String'), parameter(name: 'cc', type: 'java.lang.String'), parameter(name: 'charset', type: 'java.lang.String'), parameter(name: 'from', type: 'java.lang.String'), parameter(name: 'mimeType', type: 'java.lang.String'), parameter(name: 'replyTo', type: 'java.lang.String'), parameter(name: 'to', type: 'java.lang.String'),], doc: 'Mail')
method(name: 'milestone', type: 'Object', params: [ordinal: 'java.lang.Integer'], doc: 'The milestone step forces all builds to go through in order')
method(name: 'milestone', type: 'Object', namedParams: [parameter(name: 'ordinal', type: 'java.lang.Integer'), parameter(name: 'label', type: 'java.lang.String'),], doc: 'The milestone step forces all builds to go through in order')
method(name: 'node', type: 'Object', params: [label: java.lang.String, body: 'Closure'], doc: 'Allocate node')
method(name: 'properties', type: 'Object', params: [properties: 'java.util.List'], doc: 'Set job properties')
method(name: 'publishChecks', type: 'Object', params: [:], doc: 'Publish customized checks to SCM platforms')
method(name: 'publishChecks', type: 'Object', namedParams: [parameter(name: 'actions', type: 'java.util.List'), parameter(name: 'annotations', type: 'java.util.List'), parameter(name: 'conclusion', type: 'Map'), parameter(name: 'detailsURL', type: 'java.lang.String'), parameter(name: 'name', type: 'java.lang.String'), parameter(name: 'status', type: 'Map'), parameter(name: 'summary', type: 'java.lang.String'), parameter(name: 'text', type: 'java.lang.String'), parameter(name: 'title', type: 'java.lang.String'),], doc: 'Publish customized checks to SCM platforms')
method(name: 'readTrusted', type: 'Object', params: [path: 'java.lang.String'], doc: 'Read trusted file from SCM')
method(name: 'resolveScm', type: 'Object', namedParams: [parameter(name: 'source', type: 'Map'), parameter(name: 'targets', type: 'java.util.List'), parameter(name: 'ignoreErrors', type: 'boolean'),], doc: 'Resolves an SCM from an SCM Source and a list of candidate target branch names')
method(name: 'retry', type: 'Object', params: [count: int, body: 'Closure'], doc: 'Retry the body up to N times')
method(name: 'script', type: 'Object', params: [body: 'Closure'], doc: 'Run arbitrary Pipeline script')
method(name: 'sleep', type: 'Object', params: [time: 'int'], doc: 'Sleep')
method(name: 'sleep', type: 'Object', namedParams: [parameter(name: 'time', type: 'int'), parameter(name: 'unit', type: 'java.util.concurrent.TimeUnit'),], doc: 'Sleep')
method(name: 'stage', type: 'Object', params: [name: java.lang.String, body: 'Closure'], doc: 'Stage')
method(name: 'stage', type: 'Object', params: [body: Closure], namedParams: [parameter(name: 'name', type: 'java.lang.String'), parameter(name: 'concurrency', type: 'java.lang.Integer'),], doc: 'Stage')
method(name: 'step', type: 'Object', params: [delegate: 'Map'], doc: 'General Build Step')
method(name: 'timeout', type: 'Object', params: [time: int, body: 'Closure'], doc: 'Enforce time limit')
method(name: 'timeout', type: 'Object', params: [body: Closure], namedParams: [parameter(name: 'time', type: 'int'), parameter(name: 'activity', type: 'boolean'), parameter(name: 'unit', type: 'java.util.concurrent.TimeUnit'),], doc: 'Enforce time limit')
method(name: 'timestamps', type: 'Object', params: [body: 'Closure'], doc: 'Timestamps')
method(name: 'tool', type: 'Object', params: [name: 'java.lang.String'], doc: 'Use a tool from a predefined Tool Installation')
method(name: 'tool', type: 'Object', namedParams: [parameter(name: 'name', type: 'java.lang.String'), parameter(name: 'type', type: 'java.lang.String'),], doc: 'Use a tool from a predefined Tool Installation')
method(name: 'unstable', type: 'Object', params: [message: 'java.lang.String'], doc: 'Set stage result to unstable')
method(name: 'waitForQualityGate', type: 'Object', params: [abortPipeline: 'boolean'], doc: 'Wait for SonarQube analysis to be completed and return quality gate status')
method(name: 'waitForQualityGate', type: 'Object', namedParams: [parameter(name: 'abortPipeline', type: 'boolean'), parameter(name: 'credentialsId', type: 'java.lang.String'), parameter(name: 'webhookSecretId', type: 'java.lang.String'),], doc: 'Wait for SonarQube analysis to be completed and return quality gate status')
method(name: 'waitUntil', type: 'Object', params: [body: 'Closure'], doc: 'Wait for condition')
method(name: 'waitUntil', type: 'Object', params: [body: Closure], namedParams: [parameter(name: 'initialRecurrencePeriod', type: 'long'), parameter(name: 'quiet', type: 'boolean'),], doc: 'Wait for condition')
method(name: 'warnError', type: 'Object', params: [message: java.lang.String, body: 'Closure'], doc: 'Catch error and set build and stage result to unstable')
method(name: 'warnError', type: 'Object', params: [body: Closure], namedParams: [parameter(name: 'message', type: 'java.lang.String'), parameter(name: 'catchInterruptions', type: 'boolean'),], doc: 'Catch error and set build and stage result to unstable')
method(name: 'withChecks', type: 'Object', params: [name: java.lang.String, body: 'Closure'], doc: 'Inject checks properties into its closure')
method(name: 'withCredentials', type: 'Object', params: [bindings: java.util.List, body: 'Closure'], doc: 'Bind credentials to variables')
method(name: 'withEnv', type: 'Object', params: [overrides: java.util.List, body: 'Closure'], doc: 'Set environment variables')
method(name: 'wrap', type: 'Object', params: [delegate: Map, body: 'Closure'], doc: 'General Build Wrapper')
method(name: 'ws', type: 'Object', params: [dir: java.lang.String, body: 'Closure'], doc: 'Allocate workspace')
method(name: 'dockerFingerprintRun', type: 'Object', params: [containerId: 'java.lang.String'], doc: 'Advanced/Deprecated Record trace of a Docker image run in a container')
method(name: 'dockerFingerprintRun', type: 'Object', namedParams: [parameter(name: 'containerId', type: 'java.lang.String'), parameter(name: 'toolName', type: 'java.lang.String'),], doc: 'Record trace of a Docker image run in a container')
method(name: 'envVarsForTool', type: 'Object', namedParams: [parameter(name: 'toolId', type: 'java.lang.String'), parameter(name: 'toolVersion', type: 'java.lang.String'),], doc: 'Fetches the environment variables for a given tool in a list of \'FOO=bar\' strings suitable for the withEnv step.')
method(name: 'getContext', type: 'Object', params: [type: 'Map'], doc: 'Advanced/Deprecated Get contextual object from internal APIs')
method(name: 'withContext', type: 'Object', params: [context: java.lang.Object, body: 'Closure'], doc: 'Advanced/Deprecated Use contextual object from internal APIs within a block')
property(name: 'docker', type: 'org.jenkinsci.plugins.docker.workflow.DockerDSL')
property(name: 'pipeline', type: 'org.jenkinsci.plugins.pipeline.modeldefinition.ModelStepLoader')
property(name: 'env', type: 'org.jenkinsci.plugins.workflow.cps.EnvActionImpl.Binder')
property(name: 'params', type: 'org.jenkinsci.plugins.workflow.cps.ParamsVariable')
property(name: 'currentBuild', type: 'org.jenkinsci.plugins.workflow.cps.RunWrapperBinder')
property(name: 'scm', type: 'org.jenkinsci.plugins.workflow.multibranch.SCMVar')
// new
method(name: 'pipeline', type: 'Object', params: [body:'Closure'], doc: 'Pipeline root element')
method(name: 'scm', type: 'Object', params: [body:'Closure'], doc: 'SCM root element')
method(name: 'stages', type: 'Object', params: [body:'Closure'], doc: 'Stages root element')
method(name: 'steps', type: 'Object', params: [body:'Closure'], doc: 'Stages root element')
}
//Steps that require a node context
def nodeCtx = context(scope: closureScope())
contributor(nodeCtx) {
def call = enclosingCall('node')
if (call) {
method(name: 'bat', type: 'Object', params: [script: 'java.lang.String'], doc: 'Windows Batch Script')
method(name: 'bat', type: 'Object', namedParams: [parameter(name: 'script', type: 'java.lang.String'), parameter(name: 'encoding', type: 'java.lang.String'), parameter(name: 'label', type: 'java.lang.String'), parameter(name: 'returnStatus', type: 'boolean'), parameter(name: 'returnStdout', type: 'boolean'),], doc: 'Windows Batch Script')
method(name: 'checkout', type: 'Object', params: [scm: 'Map'], doc: 'Check out from version control')
method(name: 'checkout', type: 'Object', namedParams: [parameter(name: 'scm', type: 'Map'), parameter(name: 'changelog', type: 'boolean'), parameter(name: 'poll', type: 'boolean'),], doc: 'Check out from version control')
method(name: 'deleteDir', type: 'Object', params: [:], doc: 'Recursively delete the current directory from the workspace')
method(name: 'dir', type: 'Object', params: [path: java.lang.String, body: 'Closure'], doc: 'Change current directory')
method(name: 'fileExists', type: 'Object', params: [file: 'java.lang.String'], doc: 'Verify if file exists in workspace')
method(name: 'git', type: 'Object', params: [url: 'java.lang.String'], doc: 'Git')
method(name: 'git', type: 'Object', namedParams: [parameter(name: 'url', type: 'java.lang.String'), parameter(name: 'branch', type: 'java.lang.String'), parameter(name: 'changelog', type: 'boolean'), parameter(name: 'credentialsId', type: 'java.lang.String'), parameter(name: 'poll', type: 'boolean'),], doc: 'Git')
method(name: 'junit', type: 'Object', params: [testResults: 'java.lang.String'], doc: 'Archive JUnit-formatted test results')
method(name: 'junit', type: 'Object', namedParams: [parameter(name: 'testResults', type: 'java.lang.String'), parameter(name: 'allowEmptyResults', type: 'boolean'), parameter(name: 'checksName', type: 'java.lang.String'), parameter(name: 'healthScaleFactor', type: 'double'), parameter(name: 'keepLongStdio', type: 'boolean'), parameter(name: 'skipPublishingChecks', type: 'boolean'), parameter(name: 'testDataPublishers', type: 'java.util.List'),], doc: 'Archive JUnit-formatted test results')
method(name: 'load', type: 'Object', params: [path: 'java.lang.String'], doc: 'Evaluate a Groovy source file into the Pipeline script')
method(name: 'powershell', type: 'Object', params: [script: 'java.lang.String'], doc: 'PowerShell Script')
method(name: 'powershell', type: 'Object', namedParams: [parameter(name: 'script', type: 'java.lang.String'), parameter(name: 'encoding', type: 'java.lang.String'), parameter(name: 'label', type: 'java.lang.String'), parameter(name: 'returnStatus', type: 'boolean'), parameter(name: 'returnStdout', type: 'boolean'),], doc: 'PowerShell Script')
method(name: 'publishHTML', type: 'Object', params: [target: 'Map'], doc: 'Publish HTML reports')
method(name: 'pwd', type: 'Object', params: [:], doc: 'Determine current directory')
method(name: 'pwd', type: 'Object', namedParams: [parameter(name: 'tmp', type: 'boolean'),], doc: 'Determine current directory')
method(name: 'pwsh', type: 'Object', params: [script: 'java.lang.String'], doc: 'PowerShell Core Script')
method(name: 'pwsh', type: 'Object', namedParams: [parameter(name: 'script', type: 'java.lang.String'), parameter(name: 'encoding', type: 'java.lang.String'), parameter(name: 'label', type: 'java.lang.String'), parameter(name: 'returnStatus', type: 'boolean'), parameter(name: 'returnStdout', type: 'boolean'),], doc: 'PowerShell Core Script')
method(name: 'readFile', type: 'Object', params: [file: 'java.lang.String'], doc: 'Read file from workspace')
method(name: 'readFile', type: 'Object', namedParams: [parameter(name: 'file', type: 'java.lang.String'), parameter(name: 'encoding', type: 'java.lang.String'),], doc: 'Read file from workspace')
method(name: 'sh', type: 'Object', params: [script: 'java.lang.String'], doc: 'Shell Script')
method(name: 'sh', type: 'Object', namedParams: [parameter(name: 'script', type: 'java.lang.String'), parameter(name: 'encoding', type: 'java.lang.String'), parameter(name: 'label', type: 'java.lang.String'), parameter(name: 'returnStatus', type: 'boolean'), parameter(name: 'returnStdout', type: 'boolean'),], doc: 'Shell Script')
method(name: 'stash', type: 'Object', params: [name: 'java.lang.String'], doc: 'Stash some files to be used later in the build')
method(name: 'stash', type: 'Object', namedParams: [parameter(name: 'name', type: 'java.lang.String'), parameter(name: 'allowEmpty', type: 'boolean'), parameter(name: 'excludes', type: 'java.lang.String'), parameter(name: 'includes', type: 'java.lang.String'), parameter(name: 'useDefaultExcludes', type: 'boolean'),], doc: 'Stash some files to be used later in the build')
method(name: 'svn', type: 'Object', params: [url: 'java.lang.String'], doc: 'Subversion')
method(name: 'svn', type: 'Object', namedParams: [parameter(name: 'url', type: 'java.lang.String'), parameter(name: 'changelog', type: 'boolean'), parameter(name: 'poll', type: 'boolean'),], doc: 'Subversion')
method(name: 'tm', type: 'Object', params: [stringWithMacro: 'java.lang.String'], doc: 'Expand a string containing macros')
method(name: 'unstash', type: 'Object', params: [name: 'java.lang.String'], doc: 'Restore files previously stashed')
method(name: 'validateDeclarativePipeline', type: 'Object', params: [path: 'java.lang.String'], doc: 'Validate a file containing a Declarative Pipeline')
method(name: 'withGradle', type: 'Object', params: [body: 'Closure'], doc: 'WithGradle')
method(name: 'writeFile', type: 'Object', namedParams: [parameter(name: 'file', type: 'java.lang.String'), parameter(name: 'text', type: 'java.lang.String'), parameter(name: 'encoding', type: 'java.lang.String'),], doc: 'Write file to workspace')
method(name: 'archive', type: 'Object', params: [includes: 'java.lang.String'], doc: 'Advanced/Deprecated Archive artifacts')
method(name: 'archive', type: 'Object', namedParams: [parameter(name: 'includes', type: 'java.lang.String'), parameter(name: 'excludes', type: 'java.lang.String'),], doc: 'Archive artifacts')
method(name: 'dockerFingerprintFrom', type: 'Object', namedParams: [parameter(name: 'dockerfile', type: 'java.lang.String'), parameter(name: 'image', type: 'java.lang.String'), parameter(name: 'commandLine', type: 'java.lang.String'), parameter(name: 'toolName', type: 'java.lang.String'),], doc: 'Record trace of a Docker image used in FROM')
method(name: 'unarchive', type: 'Object', params: [:], doc: 'Advanced/Deprecated Copy archived artifacts into the workspace')
method(name: 'unarchive', type: 'Object', namedParams: [parameter(name: 'mapping', type: 'java.util.Map'),], doc: 'Copy archived artifacts into the workspace')
method(name: 'withDockerContainer', type: 'Object', params: [image: java.lang.String, body: 'Closure'], doc: 'Advanced/Deprecated Run build steps inside a Docker container')
method(name: 'withDockerContainer', type: 'Object', params: [body: Closure], namedParams: [parameter(name: 'image', type: 'java.lang.String'), parameter(name: 'args', type: 'java.lang.String'), parameter(name: 'toolName', type: 'java.lang.String'),], doc: 'Run build steps inside a Docker container')
method(name: 'withDockerRegistry', type: 'Object', params: [registry: Map, body: 'Closure'], doc: 'Advanced/Deprecated Sets up Docker registry endpoint')
method(name: 'withDockerRegistry', type: 'Object', params: [body: Closure], namedParams: [parameter(name: 'registry', type: 'Map'), parameter(name: 'toolName', type: 'java.lang.String'),], doc: 'Sets up Docker registry endpoint')
method(name: 'withDockerServer', type: 'Object', params: [server: Map, body: 'Closure'], doc: 'Advanced/Deprecated Sets up Docker server endpoint')
}
}
// Errors on:
@@ -0,0 +1,25 @@
package org.silverbulleters.usher.config
import com.cloudbees.groovy.cps.NonCPS
import com.fasterxml.jackson.databind.MapperFeature
import com.fasterxml.jackson.databind.ObjectMapper
import org.silverbulleters.usher.config.JobConfiguration
class ConfigurationReader {
private static ObjectMapper mapper
static {
mapper = new ObjectMapper()
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
}
@NonCPS
static JobConfiguration create(String config) {
return mapper.readValue(config, JobConfiguration.class)
}
static JobConfiguration create() {
return new JobConfiguration()
}
}
@@ -0,0 +1,78 @@
package org.silverbulleters.usher.config
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
import org.silverbulleters.usher.config.additional.InfoBase
import org.silverbulleters.usher.config.stage.*
@JsonIgnoreProperties(ignoreUnknown = true)
class JobConfiguration implements Serializable {
/**
* Режим запуска: ci, gitsync, cd
*/
String mode = "ci"
/**
* Версия платформы 1С
*/
String v8Version = "8.3"
/**
* Агент по умолчанию
*/
String agent = "any"
/**
* Режим отладки
*/
boolean debug = false
/**
* E-mail для уведомлений
*/
String emailForNotification = "NO_USE"
/**
* Путь к общему конфигу vrunner
*/
String vrunnerConfig = "./tools/JSON/vRunner.json"
/**
* Общий таймаут на задание
*/
int timeout = 100
/**
* Информационная база по умолчанию
*/
InfoBase defaultInfobase = InfoBase.EMPTY
/**
* Шаги задания
*/
Stages stages = Stages.EMPTY
@JsonProperty("gitsync")
GitsyncOptional gitsyncOptional = GitsyncOptional.EMPTY
@JsonProperty("preparebase")
PrepareBaseOptional prepareBaseOptional = PrepareBaseOptional.EMPTY
@JsonProperty("syntaxCheck")
SyntaxCheckOptional syntaxCheckOptional = SyntaxCheckOptional.EMPTY
@JsonProperty("smoke")
SmokeOptional smokeOptional = SmokeOptional.EMPTY
@JsonProperty("tdd")
TddOptional tddOptional = TddOptional.EMPTY
@JsonProperty("bdd")
BddOptional bddOptional = BddOptional.EMPTY
@JsonProperty("sonarqube")
SonarQubeOptional sonarQubeOptional = SonarQubeOptional.EMPTY
@JsonProperty("build")
BuildOptional buildOptional = BuildOptional.EMPTY
}
@@ -0,0 +1,25 @@
package org.silverbulleters.usher.config
import com.cloudbees.groovy.cps.NonCPS
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
class Stages {
static final EMPTY = createEmptyStages()
boolean gitsync = false
boolean prepareBase = false
boolean syntaxCheck = false
boolean smoke = false
boolean tdd = false
boolean bdd = false
boolean sonarqube = false
boolean build = false
boolean deploy = false
@NonCPS
private static Stages createEmptyStages() {
return new Stages()
}
}
@@ -0,0 +1,17 @@
package org.silverbulleters.usher.config.additional
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
class InfoBase {
static final EMPTY = new InfoBase()
/**
* Строка подключения к информационной базе
*/
String connectionString = ""
/**
* Идентификатор секрета авторизации в информационной базе
*/
String auth = ""
}
@@ -0,0 +1,11 @@
package org.silverbulleters.usher.config.additional
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)
class Repo {
static final Repo EMPTY = new Repo()
String path = ""
String auth = ""
}
@@ -0,0 +1,14 @@
package org.silverbulleters.usher.config.stage
import com.fasterxml.jackson.annotation.JsonIgnore
class BaseOptional {
@JsonIgnore
String name = "Base stage"
/**
* Таймаут работы stage
*/
int timeout = 0
}
@@ -0,0 +1,13 @@
package org.silverbulleters.usher.config.stage
class BddOptional extends BaseOptional {
static final EMPTY = new BddOptional()
String allurePath = "./out/bddallure"
BddOptional() {
name = "BDD"
timeout = 100
}
}
@@ -0,0 +1,13 @@
package org.silverbulleters.usher.config.stage
class BuildOptional extends BaseOptional {
static final EMPTY = new BuildOptional()
String distPath = '.packman/1cv8.cf'
BuildOptional() {
name = "Build"
timeout = 100
}
}
@@ -0,0 +1,17 @@
package org.silverbulleters.usher.config.stage
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import org.silverbulleters.usher.config.additional.Repo
@JsonIgnoreProperties(ignoreUnknown = true)
class GitsyncOptional extends BaseOptional {
static final EMPTY = new GitsyncOptional()
Repo repo = Repo.EMPTY
String configPath = "./tools/JSON/gitsync_conf.JSON"
GitsyncOptional() {
name = "Gitsync"
timeout = 40
}
}
@@ -0,0 +1,18 @@
package org.silverbulleters.usher.config.stage
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import org.silverbulleters.usher.config.additional.Repo
@JsonIgnoreProperties(ignoreUnknown = true)
class PrepareBaseOptional extends BaseOptional {
static final EMPTY = new PrepareBaseOptional()
String sourcePath = "./src/cf"
String template = ""
Repo repo = Repo.EMPTY
PrepareBaseOptional() {
name = "Prepare base"
timeout = 100
}
}
@@ -0,0 +1,15 @@
package org.silverbulleters.usher.config.stage
class SmokeOptional extends BaseOptional {
static final EMPTY = new SmokeOptional()
String xddConfig = "./tools/JSON/smokeTestRunnerConf.json"
String testPath = '$addroot/tests/smoke'
String allurePath = "./out/smoke/allure"
SmokeOptional() {
name = "Smoke"
timeout = 100
}
}
@@ -0,0 +1,34 @@
package org.silverbulleters.usher.config.stage
/**
* Опции этапа SonarQube
*/
class SonarQubeOptional extends BaseOptional {
static final EMPTY = new SonarQubeOptional()
/**
* Агент, на котором будет выполняться задача
*/
String agent = "any"
/**
* Идентификатор sonar-scanner
*/
String toolId = "sonar-scanner"
/**
* Идентификатор сервера SonarQube
*/
String serverId = "SonarQube"
/**
* Режим дебага sonar-scanner
*/
boolean debug = false
SonarQubeOptional() {
name = "SonarQube static analysis"
timeout = 100
}
}
@@ -0,0 +1,13 @@
package org.silverbulleters.usher.config.stage
class SyntaxCheckOptional extends BaseOptional {
static final EMPTY = new SyntaxCheckOptional()
String allurePath = "./out/syntaxCheck/allure"
SyntaxCheckOptional() {
name = "Syntax check"
timeout = 100
}
}
@@ -0,0 +1,15 @@
package org.silverbulleters.usher.config.stage
class TddOptional extends BaseOptional {
static final EMPTY = new TddOptional()
String xddConfig = "./tools/JSON/xddTestRunnerConf.json"
String testPath = './tests/unit'
String allurePath = "./out/tdd/allure"
TddOptional() {
name = "TDD"
timeout = 100
}
}
@@ -0,0 +1,20 @@
package org.silverbulleters.usher.ioc
/**
* https://jjba.dev/posts/jenkins-shared-library/
*/
class ContextRegistry implements Serializable {
private static IContext context
static void registerContext(IContext context) {
ContextRegistry.context = context
}
static void registerDefaultContext(Object steps) {
ContextRegistry.context = new DefaultContext(steps)
}
static IContext getContext() {
return ContextRegistry.context
}
}
@@ -0,0 +1,14 @@
package org.silverbulleters.usher.ioc
class DefaultContext implements IContext, Serializable {
private steps
DefaultContext(steps) {
this.steps = steps
}
@Override
IStepExecutor getStepExecutor() {
return new StepExecutor(this.steps)
}
}
@@ -0,0 +1,5 @@
package org.silverbulleters.usher.ioc
interface IContext {
IStepExecutor getStepExecutor()
}
@@ -0,0 +1,6 @@
package org.silverbulleters.usher.ioc
interface IStepExecutor {
int sh(String command)
void error(String message)
}
@@ -0,0 +1,30 @@
package org.silverbulleters.usher.ioc
import org.jenkinsci.plugins.workflow.cps.EnvActionImpl
import org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper
class StepExecutor implements IStepExecutor {
private steps
public EnvActionImpl env
public RunWrapper currentBuild
public Map params
StepExecutor(steps) {
this.steps = steps
this.env = this.steps.env
this.currentBuild = this.steps.currentBuild
this.params = Collections.unmodifiableMap(this.steps.params)
}
@Override
int sh(String command) {
this.steps.sh returnStatus: true, script: "${command}"
}
@Override
void error(String message) {
this.steps.currentBuild.setResult(JobStatus.Failure)
this.steps.error(message)
}
}
+51
View File
@@ -0,0 +1,51 @@
import com.mkobit.jenkins.pipelines.codegen.LocalLibraryRetriever
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition
import org.jenkinsci.plugins.workflow.job.WorkflowJob
import org.jenkinsci.plugins.workflow.libs.GlobalLibraries
import org.jenkinsci.plugins.workflow.libs.LibraryConfiguration
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.jvnet.hudson.test.JenkinsRule
class cmdRunTest {
@Rule
public JenkinsRule jenkinsRule = new JenkinsRule()
@Before
void configureGlobalLibraries() {
jenkinsRule.timeout = 30
def retriever = new LocalLibraryRetriever()
def localLibrary = new LibraryConfiguration('vanessa-usher', retriever)
localLibrary.implicit = true
localLibrary.defaultVersion = 'unused'
localLibrary.allowVersionOverride = false
GlobalLibraries.get().libraries = [localLibrary]
}
@Test
void "cmdRun echo message"() {
def script = getPipelineScript()
def flowDefinition = new CpsFlowDefinition(script, true)
def workflowJob = jenkinsRule.createProject(WorkflowJob, 'project')
workflowJob.definition = flowDefinition
jenkinsRule.assertLogContains('Проверка', jenkinsRule.buildAndAssertSuccess(workflowJob))
}
static String getPipelineScript() {
return '''
pipeline {
agent any
stages {
stage('test') {
steps {
cmdRun("echo Проверка")
}
}
}
}
'''.stripIndent()
}
}
@@ -0,0 +1,57 @@
import org.junit.jupiter.api.Test
import org.silverbulleters.usher.config.ConfigurationReader
import org.silverbulleters.usher.config.additional.InfoBase
import org.silverbulleters.usher.config.Stages
import org.silverbulleters.usher.config.stage.*
import static org.assertj.core.api.Assertions.assertThat
class ConfigurationReaderTest {
@Test
void "Check default configuration"() {
def config = ConfigurationReader.create()
assertThat(config.getMode()).isEqualTo("ci")
assertThat(config.getAgent()).isEqualTo("any")
assertThat(config.getV8Version()).isEqualTo("8.3")
assertThat(config.isDebug()).isFalse()
assertThat(config.getTimeout()).isEqualTo(100)
assertThat(config.getDefaultInfobase()).isEqualTo(InfoBase.EMPTY)
checkStages(config.getStages());
assertThat(config.getGitsyncOptional()).isEqualTo(GitsyncOptional.EMPTY)
assertThat(config.getPrepareBaseOptional()).isEqualTo(PrepareBaseOptional.EMPTY)
assertThat(config.getSyntaxCheckOptional()).isEqualTo(SyntaxCheckOptional.EMPTY)
assertThat(config.getSmokeOptional()).isEqualTo(SmokeOptional.EMPTY)
assertThat(config.getTddOptional()).isEqualTo(TddOptional.EMPTY)
assertThat(config.getBddOptional()).isEqualTo(BddOptional.EMPTY)
assertThat(config.getSonarQubeOptional()).isEqualTo(SonarQubeOptional.EMPTY)
assertThat(config.getBuildOptional()).isEqualTo(BuildOptional.EMPTY)
}
// @Test
// void "Check"() {
// def configData = IOUtils.resourceToString(
// "example-conf-full.json",
// StandardCharsets.UTF_8,
// this.getClass().getClassLoader()
// )
// def config = ConfigurationReader.create(configData)
// assertThat(config.getV8Version()).isEqualTo("8.3")
// }
private static void checkStages(Stages stages) {
assertThat(stages).isNotNull()
assertThat(stages.isGitsync()).isFalse()
assertThat(stages.isPrepareBase()).isFalse()
assertThat(stages.isSyntaxCheck()).isFalse()
assertThat(stages.isSmoke()).isFalse()
assertThat(stages.isTdd()).isFalse()
assertThat(stages.isBdd()).isFalse()
assertThat(stages.isSonarqube()).isFalse()
assertThat(stages.isBuild()).isFalse()
}
}
@@ -0,0 +1,64 @@
{
"mode": "ci",
"agent": "any",
"v8Version": "8.3",
"debug": true,
"emailForNotification": "main@localhost",
"vrunnerConfig": "./tools/JSON/vRunner.json",
"timeout": 100,
"defaultInfobase": {
"connectionString": "/SLocalhost/infobase",
"auth": "auth-db-mybase"
},
"stages": {
"gitsync": true,
"prepareBase": false,
"syntaxCheck": false,
"smoke": false,
"tdd": false,
"bdd": false,
"sonarqube": false,
"build": false,
"deploy": false
},
"gitsync": {
"timeout": 40,
"repoPath": "//share/repo1c",
"repoAuth": "auth-repo-repo1c",
"configPath": "./tools/JSON/gitsync_conf.JSON"
},
"prepareBase": {
"timeout": 40,
"sourcePath": "./src/cf",
"template": "./example/demo.dt"
},
"syntaxCheck": {
"timeout": 40
},
"smoke": {
"timeout": 40
},
"tdd": {
"timeout": 60
},
"bdd": {
"timeout": 40
},
"sonarqube": {
"timeout": 60,
"agent": "all",
"toolId": "SonarQube",
"debug": true
},
"build": {
"timeout": 20,
"projectName": "PIPELINE_NAME",
"buildDir": ".",
"distPath": "./dist/.packman/1cv8.cf"
},
"deploy": {
"ras": "localhost:1545",
"unCode": "locked",
"lockedMessage": "Регламентные работы"
}
}
+5
View File
@@ -0,0 +1,5 @@
public void createAllureCategories(String title, String allurePath) {
// нужен плагин https://plugins.jenkins.io/pipeline-utility-steps/
def categories = [['name': title]]
writeJSON file: "${allurePath}/categories.json", json: categories
}
+57
View File
@@ -0,0 +1,57 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
@Field
JobConfiguration config
void call(JobConfiguration config) {
boolean needPublish = config.getStages().isSyntaxCheck() || config.getStages().isSmoke() || config.getStages().isTdd() || config.getStages().isBdd()
if (!needPublish) {
return
}
this.config = config
stage("Allure publish") {
node(config.getAgent()) {
checkout scm
publish()
}
}
}
private def publish() {
reports = []
if (config.getStages().isSyntaxCheck()) {
def path = getPrettyPath(config.getSyntaxCheckOptional().getAllurePath())
reports.add([path: path])
}
if (config.getStages().isSmoke()) {
def path = getPrettyPath(config.getSmokeOptional().getAllurePath())
reports.add([path: path])
}
if (config.getStages().isTdd()) {
def path = getPrettyPath(config.getTddOptional().getAllurePath())
reports.add([path: path])
}
if (config.getStages().isBdd()) {
def path = getPrettyPath(config.getBddOptional().getAllurePath())
reports.add([path: path])
}
junit allowEmptyResults: true, testResults: '**/out/junit/*.xml '
allure includeProperties: false, jdk: '', results: reports
}
private String getPrettyPath(String path) {
if (path.startsWith("./")) {
return path.substring(2)
}
return path
}
+51
View File
@@ -0,0 +1,51 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.stage.BddOptional
import org.silverbulleters.usher.config.stage.SmokeOptional
@Field
JobConfiguration config
@Field
BddOptional stageOptional
void call(JobConfiguration config) {
if (!config.getStages().isBdd()) {
return
}
this.config = config
this.stageOptional = config.getBddOptional()
timeout(unit: 'MINUTES', time: stageOptional.getTimeout()) {
stage(stageOptional.getName()) {
node(config.getAgent()) {
checkout scm
catchError(message: 'Ошибка во время выполнения bdd тестирования', buildResult: 'FAILURE', stageResult: 'FAILURE') {
testing()
}
if (fileExists(stageOptional.getAllurePath())) {
allureHelper.createAllureCategories(stageOptional.getName(), stageOptional.getAllurePath())
}
}
}
}
}
private def testing() {
def auth = config.getDefaultInfobase().getAuth()
if (!auth.isEmpty() && credentional.exist(auth)) {
withCredentials([usernamePassword(credentialsId: auth, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
def credentional = credentional.getAuthString()
bddTesting(credentional)
}
} else {
bddTesting('')
}
}
private bddTesting(String credentional) {
command = vrunner.vanessa(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
}
+52
View File
@@ -0,0 +1,52 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.stage.BuildOptional
import org.silverbulleters.usher.config.additional.InfoBase
@Field
JobConfiguration config
@Field
BuildOptional stageOptional
void call(JobConfiguration config) {
if (!config.getStages().isBuild()) {
return
}
this.config = config
this.stageOptional = config.getBuildOptional()
timeout(unit: 'MINUTES', time: stageOptional.getTimeout()) {
stage(stageOptional.getName()) {
node(config.getAgent()) {
checkout scm
catchError(message: 'Ошибка во время сборки поставки', buildResult: 'FAILURE', stageResult: 'FAILURE') {
runBuild()
archiving()
}
}
}
}
}
private void runBuild() {
def auth = config.getDefaultInfobase().getAuth()
if (!auth.isEmpty() && credentional.exist(auth)) {
withCredentials([usernamePassword(credentialsId: auth, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
def credentional = credentional.getCustomAuth("-db-user", "-db-pwd")
packman.setDatabase(config, credentional)
packman.makeCf(config)
}
} else {
packman.setDatabase(config, '')
packman.makeCf(config)
}
}
private void archiving() {
if (fileExists(stageOptional.getDistPath())) {
archiveArtifacts stageOptional.getDistPath()
}
}
+16
View File
@@ -0,0 +1,16 @@
/**
* Функция исполнения команд. Установка локализации при использовании MS Windows
* Пример вызова: cmdRun.Выполнить("dir /w")
*/
def call(String command, Map buildEnv) {
call(command)
}
def call(String command) {
if (isUnix()) {
sh "${command}"
} else {
def logCmd = ""
bat " chcp 65001\n${logCmd}${command}"
}
}
+41
View File
@@ -0,0 +1,41 @@
String getAuthString() {
def credentional = "--db-user ${USERNAME}"
try {
credentional = credentional + " --db-pwd ${PASSWORD} "
} catch (e) {
}
return credentional
}
String getAuthRepoString() {
def credentional = "--storage-user ${USERNAME}"
try {
credentional = credentional + " --storage-pwd ${PASSWORD} "
} catch (e) {
}
return credentional
}
String getCustomAuth(String userName, String passName) {
def credentional = "${userName} ${USERNAME}"
try {
credentional = credentional + " ${passName} ${PASSWORD} "
} catch (e) {
}
return credentional
}
boolean exist(String id) {
boolean result = false
try {
withCredentials([usernamePassword(credentialsId: id, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
result = true;
}
} catch (e) {
println(e.getMessage())
result = false
}
println("Credentional " + id + " exist? " + result)
return result
}
+15
View File
@@ -0,0 +1,15 @@
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.ConfigurationReader
import org.silverbulleters.usher.ioc.ContextRegistry
JobConfiguration call(String pathToConfig) {
ContextRegistry.registerDefaultContext(this)
if (fileExists(pathToConfig)) {
def content = readFile(pathToConfig)
return ConfigurationReader.create(content)
} else {
println("Конфигурационный файл не найден")
}
return ConfigurationReader.create()
}
+57
View File
@@ -0,0 +1,57 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.stage.GitsyncOptional
import org.silverbulleters.usher.config.additional.InfoBase
@Field
JobConfiguration config
@Field
GitsyncOptional stageOptional
void call(JobConfiguration config) {
if (!config.getStages().isGitsync()) {
return
}
this.config = config
this.stageOptional = config.getGitsyncOptional()
timeout(unit: 'MINUTES', time: config.getTimeout()) {
stage(stageOptional.getName()) {
node(config.getAgent()) {
checkout scm
syncInternal()
}
}
}
}
private def syncInternal() {
def auth = config.getDefaultInfobase().getAuth()
if (!auth.isEmpty() && credentional.exist(auth)) {
withCredentials([usernamePassword(credentialsId: auth, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
def credentional = credentional.getAuthString()
runSync(credentional)
}
} else {
runSync('')
}
}
private def runSync(String credentional) {
def connectionString = getConnectionString()
def command = "gitsync %credentionalID% --v8version ${config.getV8Version()} --ibconnection ${connectionString} all ${stageOptional.getConfigPath()}"
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
// TODO: ищем ошибку "КРИТИЧНАЯОШИБКА" в логах, если есть - фейлим сборку этой ошибкой
}
// FIXME: ДУБЛЬ!
private def getConnectionString() {
def connectionString = ""
if (config.getDefaultInfobase() != InfoBase.EMPTY) {
connectionString = config.getDefaultInfobase().getConnectionString()
}
return connectionString;
}
+10
View File
@@ -0,0 +1,10 @@
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.additional.InfoBase
String getConnectionString(JobConfiguration config) {
def connectionString = ""
if (config.getDefaultInfobase() != InfoBase.EMPTY) {
connectionString = config.getDefaultInfobase().getConnectionString()
}
return connectionString;
}
+21
View File
@@ -0,0 +1,21 @@
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.additional.InfoBase
public void setDatabase(JobConfiguration config, String credentional) {
def command = [
"packman",
"set-database", infobaseHelper.getConnectionString(config),
"%credentionalID%"
].join(" ")
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
}
public void makeCf(JobConfiguration config) {
def command = [
"packman",
"make-cf",
"-v8version", config.getV8Version()
].join(" ")
cmdRun(command)
}
+100
View File
@@ -0,0 +1,100 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.stage.PrepareBaseOptional
@Field
JobConfiguration config
@Field
PrepareBaseOptional stageOptional
/**
* Подготовка и обновление базы
*
* @param config
*/
void call(JobConfiguration config) {
if (!config.getStages().isPrepareBase()) {
return
}
this.config = config
this.stageOptional = config.getPrepareBaseOptional()
timeout(unit: 'MINUTES', time: stageOptional.getTimeout()) {
stage('Prepare base') {
node(config.getAgent()) {
checkout scm
prepare()
}
}
}
}
private def prepare() {
def auth = config.getDefaultInfobase().getAuth()
if (!auth.isEmpty() && credentional.exist(auth)) {
withCredentials([usernamePassword(credentialsId: auth, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
def credentional = credentional.getAuthString()
prepareInternal(credentional)
}
} else {
prepareInternal('')
}
}
private def prepareInternal(String credentional) {
if (stageOptional.getTemplate().isEmpty()) {
if (stageOptional.getRepo() != Repo.EMPTY) {
loadRepo(credentional)
updateDB(credentional)
} else {
initDevFromSource(credentional)
}
} else {
initDevWithTemplate(credentional)
compile(credentional)
}
migrate(credentional)
}
private def loadRepo(credentional) {
command = vrunner.loadRepo(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
auth = stageOptional.getRepo().getAuth()
withCredentials([usernamePassword(credentialsId: auth, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
def credentionalRepo = credentional.getAuthRepoString()
command = command.replace("%credentionalStorageID%", credentionalRepo)
cmdRun(command)
}
}
private def updateDB(credentional) {
command = vrunner.updateDB(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
}
private def initDevWithTemplate(credentional) {
command = vrunner.initDevWithTemplate(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
}
private def initDevFromSource(credentional) {
command = vrunner.initDevFromSource(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
}
private def compile(credentional) {
command = vrunner.initDevWithTemplate(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
}
private def migrate(credentional) {
command = vrunner.migrate(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
}
+60
View File
@@ -0,0 +1,60 @@
import com.cloudbees.groovy.cps.NonCPS
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.additional.InfoBase
import org.silverbulleters.usher.config.additional.Repo
import org.silverbulleters.usher.config.ConfigurationReader
@Field
JobConfiguration config
void call() {
call('gitsync_config.json')
}
void call(String pathToConnfig) {
catchError(buildResult: 'FAILURE') {
start(pathToConnfig);
}
if (currentBuild.result == 'FAILURE') {
sendNotification()
} else {
// success
}
}
void start(String pathToConnfig) {
node {
checkout scm
init(pathToConnfig)
// gitsync
gitsync(config) // скрипт
// ci
prepareBase(config) // скрипт
syntaxCheck(config) // скрипт
sonarAnalyze(config) // скрипт
smoke(config) // скрипт
tdd(config) // скрипт
bdd(config) // скрипт
allurePublish(config) // скрипт
build(config) // скрипт
}
}
void init(String pathToConnfig) {
stage('Initializing') {
config = getJobConfiguration(pathToConnfig)
}
}
def sendNotification() {
emailext(
body: "Подробности по ссылке ${env.BUILD_URL}.",
subject: "Ошибка. Задача '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
to: config.getEmailForNotification()
)
}
+65
View File
@@ -0,0 +1,65 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.stage.SmokeOptional
@Field
JobConfiguration config
@Field
SmokeOptional stageOptional
void call(JobConfiguration config) {
if (!config.getStages().isSmoke()) {
return
}
this.config = config
this.stageOptional = config.getSmokeOptional()
timeout(unit: 'MINUTES', time: stageOptional.getTimeout()) {
stage(stageOptional.getName()) {
node(config.getAgent()) {
checkout scm
catchError(message: 'Ошибка во время выполнения дымового тестирования', buildResult: 'FAILURE', stageResult: 'FAILURE') {
testing()
}
if (fileExists(stageOptional.getAllurePath())) {
allureHelper.createAllureCategories(stageOptional.getName(), stageOptional.getAllurePath())
}
}
}
}
}
private def testing() {
def auth = config.getDefaultInfobase().getAuth()
if (!auth.isEmpty() && credentional.exist(auth)) {
withCredentials([usernamePassword(credentialsId: auth, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
def credentional = credentional.getAuthString()
def credentionalTestClient = getTestClient()
smokeTesting(credentional, credentionalTestClient)
}
} else {
smokeTesting('', '')
}
}
private smokeTesting(String credentional, String credentionalTestClient) {
command = vrunner.smoke(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
command = command.replace("%credentionalTestClientID%", credentionalTestClient)
cmdRun(command)
}
// FIXME: ДУБЛЬ
private String getTestClient() {
def baseValue = '%s:%s:1538'
login = "${USERNAME}"
pass = ""
try {
pass = "${PASSWORD}"
} catch (e) {
}
def credentionalTestClient = String.format('%s:%s:1538', login, pass)
return credentionalTestClient
}
+47
View File
@@ -0,0 +1,47 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.stage.SonarQubeOptional
@Field
JobConfiguration config
@Field
SonarQubeOptional stageOptional
void call(JobConfiguration config) {
if (!config.getStages().isSonarqube()) {
return
}
this.config = config
this.stageOptional = config.getSonarQubeOptional()
timeout(unit: 'MINUTES', time: stageOptional.getTimeout()) {
stage('Sonarqube static analysis') {
node(stageOptional.getAgent()) {
checkout scm
catchError(message: 'Ошибка во время выполнения sonar-scanner', buildResult: 'FAILURE', stageResult: 'FAILURE') {
analyze()
}
}
}
}
}
private def analyze() {
def projectVersion = getProjectVersion()
def scannerHome = tool stageOptional.getToolId()
def sonarDebugKey = ''
if (stageOptional.isDebug()) {
sonarDebugKey = '-X'
}
sonarCommand = "${scannerHome}/bin/sonar-scanner ${sonarDebugKey} ${projectVersion}"
withSonarQubeEnv("${stageOptional.getServerId()}") {
cmdRun(sonarCommand)
}
}
private String getProjectVersion() {
return ''
}
+51
View File
@@ -0,0 +1,51 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.additional.InfoBase
import org.silverbulleters.usher.config.stage.SyntaxCheckOptional
@Field
JobConfiguration config
@Field
SyntaxCheckOptional stageOptional
def call(JobConfiguration config) {
if (!config.getStages().isSyntaxCheck()) {
return
}
this.config = config
this.stageOptional = config.getSyntaxCheckOptional()
timeout(unit: 'MINUTES', time: stageOptional.getTimeout()) {
stage(stageOptional.getName()) {
node(config.getAgent()) {
checkout scm
catchError(message: 'Ошибка во время выполнения синтаксической проверки', buildResult: 'FAILURE', stageResult: 'FAILURE') {
check()
}
if (fileExists(stageOptional.getAllurePath())) {
allureHelper.createAllureCategories(stageOptional.getName(), stageOptional.getAllurePath())
}
}
}
}
}
private def check() {
def auth = config.getDefaultInfobase().getAuth()
if (!auth.isEmpty() && credentional.exist(auth)) {
withCredentials([usernamePassword(credentialsId: auth, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
def credentional = credentional.getAuthString()
runSyntaxCheck(credentional)
}
} else {
runSyntaxCheck('')
}
}
private def runSyntaxCheck(credentional) {
command = vrunner.syntaxCheck(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
cmdRun(command)
}
+66
View File
@@ -0,0 +1,66 @@
import groovy.transform.Field
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.stage.SmokeOptional
import org.silverbulleters.usher.config.stage.TddOptional
@Field
JobConfiguration config
@Field
TddOptional stageOptional
void call(JobConfiguration config) {
if (!config.getStages().isTdd()) {
return
}
this.config = config
this.stageOptional = config.getTddOptional()
timeout(unit: 'MINUTES', time: stageOptional.getTimeout()) {
stage(stageOptional.getName()) {
node(config.getAgent()) {
checkout scm
catchError(message: 'Ошибка во время выполнения модульного тестирования', buildResult: 'FAILURE', stageResult: 'FAILURE') {
testing()
}
if (fileExists(stageOptional.getAllurePath())) {
allureHelper.createAllureCategories(stageOptional.getName(), stageOptional.getAllurePath())
}
}
}
}
}
private def testing() {
def auth = config.getDefaultInfobase().getAuth()
if (!auth.isEmpty() && credentional.exist(auth)) {
withCredentials([usernamePassword(credentialsId: auth, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
def credentional = credentional.getAuthString()
def credentionalTestClient = getTestClient()
xddTesting(credentional, credentionalTestClient)
}
} else {
xddTesting('')
}
}
private xddTesting(String credentional, String credentionalTestClient) {
command = vrunner.xunit(config, stageOptional)
command = command.replace("%credentionalID%", credentional)
command = command.replace("%credentionalTestClientID%", credentionalTestClient)
cmdRun(command)
}
// FIXME: ДУБЛЬ
private String getTestClient() {
def baseValue = '%s:%s:1538'
login = "${USERNAME}"
pass = ""
try {
pass = "${PASSWORD}"
} catch (e) {
}
def credentionalTestClient = String.format('%s:%s:1538', login, pass)
return credentionalTestClient
}
+155
View File
@@ -0,0 +1,155 @@
import org.silverbulleters.usher.config.JobConfiguration
import org.silverbulleters.usher.config.stage.BddOptional
import org.silverbulleters.usher.config.stage.PrepareBaseOptional
import org.silverbulleters.usher.config.additional.InfoBase
import org.silverbulleters.usher.config.stage.SmokeOptional
import org.silverbulleters.usher.config.stage.SyntaxCheckOptional
import org.silverbulleters.usher.config.stage.TddOptional
def initDevFromSource(JobConfiguration config, PrepareBaseOptional optional) {
def command = [
"vrunner",
"init-dev",
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--ibconnection", infobaseHelper.getConnectionString(config),
"--src=${optional.getSourcePath()}",
"--v8version", config.getV8Version(),
"--nocacheuse"
]
return command.join(" ")
}
def initDevWithTemplate(JobConfiguration config, PrepareBaseOptional optional) {
// TODO: проверить существование `optional.getTemplate()`
def command = [
"vrunner",
"init-dev",
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--ibconnection", infobaseHelper.getConnectionString(config),
"--dt", optional.getTemplate(),
"--v8version", config.getV8Version(),
"--nocacheuse"
]
return command.join(" ")
}
def compile(JobConfiguration config, PrepareBaseOptional optional) {
def command = [
"vrunner",
"compile",
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--ibconnection", infobaseHelper.getConnectionString(config),
"--src=${optional.getSourcePath()}",
"-c",
"--noupdate",
"--v8version", config.getV8Version(),
"--nocacheuse"
]
return command.join(" ")
}
def loadRepo(JobConfiguration config, PrepareBaseOptional optional) {
def command = [
"vrunner",
"loadrepo",
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--ibconnection", infobaseHelper.getConnectionString(config),
"%credentionalStorageID%",
"--v8version", config.getV8Version(),
"--storage-name", optional.getRepo().getPath(),
"--nocacheuse"
]
return command.join(" ")
}
def updateDB(JobConfiguration config, PrepareBaseOptional optional) {
def command = [
"vrunner",
"updatedb",
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--ibconnection", infobaseHelper.getConnectionString(config),
"--v8version", config.getV8Version(),
"--nocacheuse"
]
return command.join(" ")
}
def migrate(JobConfiguration config, PrepareBaseOptional optional) {
def command = [
"vrunner",
"run",
"%credentionalID%",
"--ibconnection", infobaseHelper.getConnectionString(config),
"--settings", config.getVrunnerConfig(),
"--command", "'ЗапуститьОбновлениеИнформационнойБазы;ЗавершитьРаботуСистемы;'",
"--execute", '$runnerRoot/epf/ЗакрытьПредприятие.epf'
]
return command.join(" ")
}
def syntaxCheck(JobConfiguration config, SyntaxCheckOptional optional) {
def command = [
"vrunner",
"syntax-check",
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--allure-results2", optional.getAllurePath(),
"--junitpath", "./out/junit/syntaxCheck.xml",
"--ibconnection", infobaseHelper.getConnectionString(config),
"--v8version", config.getV8Version()
]
return command.join(" ")
}
def smoke(JobConfiguration config, SmokeOptional optional) {
def pathToAllure = "${optional.getAllurePath()}/allure-smoke.xml"
def command = [
"vrunner",
"xunit",
optional.getTestPath(),
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--ibconnection", infobaseHelper.getConnectionString(config),
"--v8version", config.getV8Version(),
"--testclient", "%credentionalTestClientID%",
"--reportsxunit", "ГенераторОтчетаJUnitXML{out/junit/smoke.xml};ГенераторОтчетаAllureXMLВерсия2{${pathToAllure}}",
"--xddExitCodePath", "./xddExitCodePath.txt",
"--xddConfig", optional.getXddConfig()
]
return command.join(" ")
}
def xunit(JobConfiguration config, TddOptional optional) {
def pathToAllure = "${optional.getAllurePath()}/allure-xdd.xml"
def command = [
"vrunner",
"xunit",
optional.getTestPath(),
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--ibconnection", infobaseHelper.getConnectionString(config),
"--v8version", config.getV8Version(),
"--testclient", "%credentionalTestClientID%",
"--reportsxunit", "ГенераторОтчетаJUnitXML{out/junit/xdd.xml};ГенераторОтчетаAllureXMLВерсия2{${pathToAllure}}",
"--xddExitCodePath", "./xddExitCodePath.txt",
"--xddConfig", optional.getXddConfig()
]
return command.join(" ")
}
def vanessa(JobConfiguration config, BddOptional optional) {
def command = [
"vrunner",
"vanessa",
"%credentionalID%",
"--settings", config.getVrunnerConfig(),
"--ibconnection", infobaseHelper.getConnectionString(config),
"--v8version", config.getV8Version()
]
return command.join(" ")
}