Jenkins Groovy Modify Params Map
Частный случай - требуется модифицировать params
Суть проблемы
У дженкинса есть переменная params которая представляет
мапу параметров которые переданы на вход билду и которые не модифицируемым простым способом
println(params.getClass().getName()
java.util.Collections$UnmodifiableMap
Доступ к ним можно получить по именами параметров
params.PARAMETER_1 params.PARAMETER_2 ... params.PARAMETER_N
Такая организация параметров приносит 2 проблемы
- Если есть сторонний код который требует наличие параметров и подключается из библиотеки и который нельзя по какой-то причине модифицировать
- Параметры попадают в переменные окружения всего исполняемого кода что накладывает ограничение на размер параметров
Другими словами - параметры доступны в коде везде и всегда
sh "env"
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin ... PARAMETER_1=MY_APP ...
Зачем использовать параметры большого размера?
- Это удобно - можно не иметь в описании кучу параметров а иметь один, и через него передавать все что нужно
myJobConfiguration = readJSON text: params.SUPER_LARGE_PARAMETER_FOR_JOB_CONFIGURATION
Размер памяти отведенный под переменные окружения ограничен
- не помню точное значение для Linux но оно достаточно маленькое что бы в него можно было упереться
Проблема преобретает остроту когда параметр оказывается большим - например тектовое поле в несколько килобайт,
и в этом случае ломается практически все
любой вызов конструкции
sh " ... "
завершается с ошибкой
Caused by: java.io.IOException: Cannot run program "/usr/bin/git" (in directory): error=7, Argument list too long
Если для исполнения простых скриптов можно придумать
withEnv(['LARGE_SIZE_PARAMETER=']) { sh "env" }
То для конструкций ниже например scm решение не работает. При этом плагин не стесняется вызывать под-капотом бинарник гита (и нахуя тогда нужен такой плагин? Вопрос открыт но имеем то что имеем)
withEnv(['LARGE_SIZE_PARAMETER=']) { dir(applicationName) { checkout scm: [ $class:'GitSCM', branches : [[name: branch]], userRemoteConfigs: [[url: gitUrl, credentialsId: gitCredentialsId]] ] } }
Решение
@NonCPS def addOrReplaceParamValue(name, value) { def build = currentBuild.getRawBuild(); def npl = new ArrayList<StringParameterValue>() def pv = new hudson.model.StringParameterValue(name,value); npl.add(pv); def newPa = null def oldPa = build.getAction(hudson.model.ParametersAction.class) if (oldPa != null) { build.actions.remove(oldPa) newPa = oldPa.createUpdated(npl) } else { newPa = new hudson.model.ParametersAction(npl) } return build.actions.add(newPa); }