JenkinsActiveChoice: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
(не показано 16 промежуточных версий этого же участника) | |||
Строка 5: | Строка 5: | ||
= В чем сложность ?= |
= В чем сложность ?= |
||
− | В целом решается задача достаточно несложно - особенно когда есть одно приложение и один репозиторий, но ситуация другая когда приложений и репозиториев (а |
+ | В целом решается задача достаточно несложно - особенно когда есть одно приложение и один репозиторий, но ситуация другая когда приложений и репозиториев (а соответственно и ключей к ним) становится много |
+ | <BR> |
||
+ | Это тоже не кажется сложным, просто использовать для каждого приложения свой скрипт где будет "зашит" свой адрес и ключ. |
||
+ | <BR> |
||
+ | НО в этом случае получаем множество скриптов которые нужно будет синхронно обновлять и правильно вызывать |
||
+ | <BR> |
||
+ | Хочется использовать ОДИН скрипт который '''единственный''' модифицировать при добавлении приложения. |
||
+ | |||
<BR> |
<BR> |
||
− | == |
+ | == Постановка задачи == |
* Деплоймент приложения состоящего из множества сервисов: app1, app2, app3 ... appN. Число сервисов может увеличиваться. |
* Деплоймент приложения состоящего из множества сервисов: app1, app2, app3 ... appN. Число сервисов может увеличиваться. |
||
* Сервисы могут деплоится в любых сочетаниях - один, два, все сразу, первый и третий, только номер N ... |
* Сервисы могут деплоится в любых сочетаниях - один, два, все сразу, первый и третий, только номер N ... |
||
Строка 14: | Строка 21: | ||
+ | == Пример интерфейса == |
||
− | [[Изображение:Файл:Screenshot 2022-07-12 at 11.53.46.png|600px]] |
||
+ | * Слева - выбран один сервис и бранча для него, второй сервис не выбран и соответвенно выбор бранчи для него недоступен. |
||
− | |||
+ | * Справа - выбрано два сервиса и бранчи для обоих сервисов |
||
+ | [[File:Screenshot_2022-07-12_at_11.53.46.png|400px]] |
||
+ | [[File:Screenshot_2022-07-12_at_11.54.06.png|400px]] |
||
+ | == Как решается задача== |
||
+ | Собственно задача сводится к тому что бы определить изменение какого параметра вызвало запуск скрипта |
||
<BR> |
<BR> |
||
+ | Так как значение того параметра что вызвало запуск скрипта передается в скрипт (имя переменной совпадает с именем параметра и в примере это будет app1 или app2 или ... appN) |
||
− | Это тоже не кажется сложным, просто использовать для кажого приложения свой скрипт где будет "зашит" свой адрес и ключ. НО в этом случае получаем множество скриптов которые нужно будет синхронно обновлять и правильно вызывать |
||
<BR> |
<BR> |
||
+ | то этим можно воспользоваться - создать список сервисов с информацией о них и их именами |
||
− | Хочется использовать ОДИН скрипт который единственный модифицировать при добавлении приложения. |
||
+ | <PRE> |
||
+ | List reposAndKeys = [ |
||
+ | [ |
||
+ | "name": "app1", |
||
+ | "repo": "git@github.com:app2.git", |
||
+ | "repoKeyId": "key1", |
||
+ | ], |
||
+ | [ |
||
+ | "name": "app2", |
||
+ | "repo": "git@github.com:app2.git", |
||
+ | "repoKeyId": "key2", |
||
+ | ], |
||
+ | ... |
||
+ | </PRE> |
||
+ | Составить список какие имена могут быть доступны? |
||
+ | <PRE> |
||
+ | List applications = [] |
||
+ | reposAndKeys.each { repoAndKey -> |
||
+ | applications.add(repoAndKey["name"]) |
||
+ | } |
||
+ | </PRE> |
||
+ | Проверить существование переменной (и ее значение) можно вот таким способом: если скрипт вызван изменением значения параметра app1 то переменная app1 будет доступна внутри кода а переменная app2 нет (это верно для любого appN) |
||
+ | <PRE> |
||
+ | applications.each { it -> |
||
+ | try { |
||
+ | // если it указывает на несуществующее значение то тут будет исключение |
||
+ | println("${it} = ${this[ it ]}") |
||
+ | |||
+ | // Если чекбокс не выбран - то в значении переменной (имя переменной это имя параметра) будет пустая строка |
||
+ | // тут нужно добаить другие проверки если планируется использовать другиме типы параметов |
||
+ | if ("${this[ it ]}" == "") { |
||
+ | isDisabled = true |
||
+ | } |
||
+ | triggeredByParameterNames.add("${it}") |
||
+ | } catch(Exception Ex) { |
||
+ | println("${it}") |
||
+ | println(Ex) |
||
+ | } |
||
+ | } |
||
+ | </PRE> |
||
+ | Некоторые дополнительные вещи вроде обработки ситуаций когда не выбран не один appN но скрипт запущен или ошибочно сконфигурировано более чем 1 appN как параметр вызывающей пересчет сиска бранчей |
||
= Пример кода = |
= Пример кода = |
||
+ | |||
− | {{#spoiler:show=show version| |
||
+ | ==Описаниа в Jenkins Job Builder== |
||
+ | {{#spoiler:show=Jenkins job builder definition| |
||
+ | <PRE> |
||
+ | - job: |
||
+ | name: 'common/frontend/build/build-all-frontend-applications' |
||
+ | project-type: pipeline |
||
+ | dsl: |
||
+ | !include-raw: 'pipelines/common/frontend/build/build-all-frontend-applications.groovy' |
||
+ | concurrent: true |
||
+ | build-discarder: |
||
+ | artifactDaysToKeep: '30' |
||
+ | artifactNumToKeep: '-1' |
||
+ | daysToKeep: '30' |
||
+ | numToKeep: '30' |
||
+ | properties: |
||
+ | - copyartifact: |
||
+ | projects: "*" |
||
+ | parameters: |
||
+ | - active-choices: |
||
+ | name: "app1" |
||
+ | description: "Deploy app1" |
||
+ | script: |
||
+ | groovy: "return ['app1:selected']" |
||
+ | use-groovy-sandbox: false |
||
+ | choice-type: "checkboxes" |
||
+ | - active-choices-reactive: |
||
+ | name: "app1_git_branch" |
||
+ | description: "Git Branch For App1" |
||
+ | script: |
||
+ | groovy: |
||
+ | !include-raw: 'pipelines/common/frontend/build/active-choice-scripts/branch-selector.groovy' |
||
+ | use-groovy-sandbox: false |
||
+ | choice-type: single-select |
||
+ | enable-filters: true |
||
+ | filter-starts-at: 1 |
||
+ | referenced-parameters: "app1" |
||
+ | |||
+ | - active-choices: |
||
+ | name: "app2" |
||
+ | description: "Deploy app2" |
||
+ | script: |
||
+ | groovy: "return ['app2:selected']" |
||
+ | use-groovy-sandbox: false |
||
+ | choice-type: "checkboxes" |
||
+ | - active-choices-reactive: |
||
+ | name: "app2_git_branch" |
||
+ | description: "Git Branch For App2" |
||
+ | script: |
||
+ | groovy: |
||
+ | !include-raw: 'pipelines/common/frontend/build/active-choice-scripts/branch-selector.groovy' |
||
+ | use-groovy-sandbox: false |
||
+ | choice-type: single-select |
||
+ | enable-filters: true |
||
+ | filter-starts-at: 1 |
||
+ | referenced-parameters: "app2" |
||
+ | |||
+ | </PRE> |
||
+ | }} |
||
+ | |||
+ | ==Код branch selector == |
||
+ | {{#spoiler:show=pipelines/common/frontend/build/active-choice-scripts/branch-selector.groovy| |
||
<PRE> |
<PRE> |
||
import com.cloudbees.plugins.credentials.CredentialsProvider; |
import com.cloudbees.plugins.credentials.CredentialsProvider; |
Текущая версия на 11:57, 12 июля 2022
Jenkins Active Choice
Есть плагин который позволяет динамически формировать значения параметров, например динамически подтягивать список веток в git (НО нельзя динамически создать параметры, и у меня не вышло сделать скрытыми параметры в зависимости от того что выбрано в другом параметре)
В чем сложность ?
В целом решается задача достаточно несложно - особенно когда есть одно приложение и один репозиторий, но ситуация другая когда приложений и репозиториев (а соответственно и ключей к ним) становится много
Это тоже не кажется сложным, просто использовать для каждого приложения свой скрипт где будет "зашит" свой адрес и ключ.
НО в этом случае получаем множество скриптов которые нужно будет синхронно обновлять и правильно вызывать
Хочется использовать ОДИН скрипт который единственный модифицировать при добавлении приложения.
Постановка задачи
- Деплоймент приложения состоящего из множества сервисов: app1, app2, app3 ... appN. Число сервисов может увеличиваться.
- Сервисы могут деплоится в любых сочетаниях - один, два, все сразу, первый и третий, только номер N ...
- Для сервиса который выбран для деплоймента предоставлять выбор бранчи, для сервиса который не выбран - не предоставлять
Пример интерфейса
- Слева - выбран один сервис и бранча для него, второй сервис не выбран и соответвенно выбор бранчи для него недоступен.
- Справа - выбрано два сервиса и бранчи для обоих сервисов
Как решается задача
Собственно задача сводится к тому что бы определить изменение какого параметра вызвало запуск скрипта
Так как значение того параметра что вызвало запуск скрипта передается в скрипт (имя переменной совпадает с именем параметра и в примере это будет app1 или app2 или ... appN)
то этим можно воспользоваться - создать список сервисов с информацией о них и их именами
List reposAndKeys = [ [ "name": "app1", "repo": "git@github.com:app2.git", "repoKeyId": "key1", ], [ "name": "app2", "repo": "git@github.com:app2.git", "repoKeyId": "key2", ], ...
Составить список какие имена могут быть доступны?
List applications = [] reposAndKeys.each { repoAndKey -> applications.add(repoAndKey["name"]) }
Проверить существование переменной (и ее значение) можно вот таким способом: если скрипт вызван изменением значения параметра app1 то переменная app1 будет доступна внутри кода а переменная app2 нет (это верно для любого appN)
applications.each { it -> try { // если it указывает на несуществующее значение то тут будет исключение println("${it} = ${this[ it ]}") // Если чекбокс не выбран - то в значении переменной (имя переменной это имя параметра) будет пустая строка // тут нужно добаить другие проверки если планируется использовать другиме типы параметов if ("${this[ it ]}" == "") { isDisabled = true } triggeredByParameterNames.add("${it}") } catch(Exception Ex) { println("${it}") println(Ex) } }
Некоторые дополнительные вещи вроде обработки ситуаций когда не выбран не один appN но скрипт запущен или ошибочно сконфигурировано более чем 1 appN как параметр вызывающей пересчет сиска бранчей