Перейти к основному содержимому

Job DSL Playground — jobs Jenkins как код

Разработчику Архитектору

Job DSL Playground — jobs Jenkins как код

В Jenkins Pipeline вы описываете одну сборку — checkout, test, deploy — в файле Jenkinsfile. Но сам job (имя, привязка к Git, расписание, тип Pipeline или Freestyle) часто создают вручную в UI Jenkins. Когда jobs десятки и сотни, это ломает воспроизводимость:

  • нет pull request на изменение конфигурации;
  • staging и production расходятся;
  • новый controller поднимают неделями.

Job DSL Plugin (jenkinsci/job-dsl-plugin) решает задачу Infrastructure as Code для jobs: Groovy-скрипт описывает jobs, папки и views; seed job применяет скрипт к controller.

Playground в этой статье — два уровня:

  1. интерактив ниже — пресеты DSL и схема seed-потока;
  2. API Viewer на живом Jenkins — /plugin/job-dsl/api-viewer/index.html — справочник всех методов с примерами вложенности.

База Groovy для DSL: делегирование замыканий (блоки pipelineJob('x') { ... } — те же closure, что dependencies { } в Gradle). Общий код pipeline — Shared Library. Теория CI — DevOps CI/CD, Jenkins в DevOps.

Job DSL Playground

Пройдите пресеты Pipeline job, Freestyle + Gradle и Папка и view, затем читайте разделы ниже — там те же паттерны в контексте Git-репозитория и seed job.


Что получится

  • понимание разницы между Job DSL (создание jobs) и Pipeline (шаги сборки);
  • минимальный seed job и структура репозитория jenkins-jobs/;
  • умение читать pipelineJob и job в Groovy;
  • навык пользоваться API Viewer как playground на controller.

Определения

ТерминОпределение
JobНастроенная задача Jenkins (Freestyle, Pipeline, Multibranch)
Job DSLGroovy-API плагина для декларативного описания jobs
Seed jobОбычный Freestyle job, который выполняет DSL-скрипт и создаёт/обновляет другие jobs
DSL scriptФайл .groovy с вызовами job(...), pipelineJob(...), folder(...)
ControllerГлавный узел Jenkins, хранит конфигурацию jobs
API ViewerВстроенный справочник методов Job DSL
FolderПапка для группировки jobs (backend/api, backend/web)
ViewПредставление на главной — список jobs по regex или именам
Dynamic DSLОбходной путь для плагинов без нативной поддержки в DSL

Job DSL и Jenkinsfile — разные уровни

Job DSLPipeline (Jenkinsfile)
Объект описанияJob на controllerСценарий одной сборки
Файлjobs/*.groovy в infra-репоJenkinsfile в app-репо
Когда выполняетсяSeed job / JCasC при изменении infraКаждый build
СинтаксисpipelineJob('x') { definition { ... } }pipeline { stages { ... } }
Кто правитDevOps / platform teamКоманда продукта

Типичная связка

  1. Job DSL создаёт Multibranch Pipeline или pipelineJob с cpsScm.
  2. При сборке Jenkins читает Jenkinsfile из Git приложения.
  3. В Jenkinsfile подключают @Library для общих шагов.

Установка и API Viewer

  1. Manage Jenkins → Plugins — установите Job DSL (перезапуск controller при необходимости).
  2. Manage Jenkins → Job DSL API Viewer или URL /plugin/job-dsl/api-viewer/index.html.
  3. В поиске viewer введите pipelineJob, multibranchPipelineJob, folder, listView.
  4. Скопируйте каркас блоков scm, triggers, definition в свой .groovy.

Зачем viewer. DSL огромен — сотни методов под комбинации плагинов. Viewer показывает обязательные и опциональные closure, как документация Gradle API для build.gradle. Это и есть "playground" на production controller — безопаснее экспериментировать на копии job, чем в UI вслепую.


Seed job — поток от Git до jobs

Структура репозитория

jenkins-jobs/
├── README.md
├── jobs/
│ ├── shop-build.groovy
│ ├── hello-nightly.groovy
│ └── folder-backend.groovy
└── views/
└── team-dashboard.groovy

Соглашения

  • один файл — одна логическая группа jobs (или один job);
  • views/ — только listView, buildPipelineView и т.д.;
  • изменения через PR + code review — как для application code.

Настройка seed job в UI

ШагЗначение
ТипFreestyle project
Имяseed-jobs (или job-dsl-seed)
SCMGit → URL репозитория jenkins-jobs
Build stepProcess Job DSLs
DSL sourceLook on Filesystem
Globjobs/**/*.groovy и отдельно views/**/*.groovy (или один шаг на каталог)

Альтернатива — build step Execute Groovy DSL с текстом скрипта inline (удобно для эксперимента, плохо для версионирования).

После Build Now:

  • jobs создаются, если не существуют;
  • jobs обновляются по имени при повторном запуске;
  • jobs не дублируются (в отличие от ручного клонирования в UI).

Webhook. Настройте push в jenkins-jobs → POST на seed job, иначе после merge в main seed нужно запускать вручную.


pipelineJob — Pipeline from SCM

Тот же сценарий, что минимальный Jenkinsfile в 22.md, но определение job — код:

pipelineJob('shop-build') {
description('Сборка shop — ветка main')
definition {
cpsScm {
scm {
git {
remote { url('https://github.com/example/shop.git') }
branch('main')
}
}
scriptPath('Jenkinsfile')
}
}
triggers {
scm('H/15 * * * *')
}
}

Разбор pipelineJob

Строка / блокСмысл
pipelineJob('shop-build')Имя job на controller; строка — идентификатор в DSL
description(...)Текст в UI job
definition { cpsScm { ... } }Тип Pipeline — скрипт из SCM, не inline
scm { git { remote { url(...) } branch(...) } }Откуда клонировать (аналог настройки Git в UI)
scriptPath('Jenkinsfile')Путь к pipeline-файлу внутри репозитория
triggers { scm('H/15 * * * *') }Poll SCM каждые ~15 мин (H — hash для разнесения нагрузки)

cpsScm vs cps { script }. cpsScm — pipeline в Git рядом с кодом приложения; изменения pipeline проходят review в app-репо. Inline script(''' pipeline { ... } ''') держит логику в infra-репо — годится для учебных jobs, редко для долгоживущих production pipeline.


job — Freestyle и shell

Для простых nightly-сборок без Declarative Pipeline:

job('hello-groovy-nightly') {
description('Ночной прогон тестов hello-groovy')
scm {
git {
remote { url('https://github.com/example/hello-groovy.git') }
branch('main')
}
}
triggers {
cron('H 2 * * *')
}
steps {
shell('./gradlew test --no-daemon')
}
publishers {
junit('**/build/test-results/test/*.xml')
}
}

Разбор Freestyle job

  • job('...') — классический Freestyle (не Pipeline).
  • triggers { cron('H 2 * * *') } — запуск около 02:00 (H — случайная минута).
  • steps { shell(...) } — эквивалент "Execute shell" в UI; на Windows — batchFile или agent с Linux.
  • publishers { junit(...) } — тот же glob, что в 22.md post { junit ... }.

Связь с Gradle Groovy DSL: команда ./gradlew test идентична stage Build & Test в Jenkinsfile.


Папки и views

folder('backend') {
description('Сервисы backend-команды')
}

pipelineJob('backend/api-gateway') {
definition {
cpsScm {
scm {
git { remote { url('https://github.com/example/gateway.git') } }
}
scriptPath('Jenkinsfile')
}
}
}

listView('backend/all') {
description('Все jobs backend')
jobs { regex('backend/.*') }
columns {
status()
weather()
name()
lastSuccess()
lastFailure()
}
}

Разбор folder и view

  • folder('backend') — создаёт папку; job с именем backend/api-gateway попадает внутрь неё.
  • Слэш / в имени job — не URL, а иерархия Jenkins Folders (нужен плагин Folders).
  • listView('backend/all') — dashboard; regex('backend/.*') подхватывает все jobs в папке.
  • columns { status(); weather(); ... } — колонки таблицы на главной.

Для Multibranch (авто-ветки) смотрите в API Viewer multibranchPipelineJob — типичный паттерн для GitFlow (22.md § Multibranch).


Inline Pipeline и SCM — когда что

КритерийcpsScm + Jenkinsfilecps { script('''...''') }
Владелец pipelineКоманда приложенияPlatform / DevOps
ReviewВ app PRВ infra PR
ПереиспользованиеShared LibraryCopy-paste между DSL-файлами
РекомендацияProductionПрототип, sandbox

Безопасность и sandbox

Job DSL выполняется на controller с правами Script Security:

  • неподписанные методы Groovy требуют одобрения admin (In-process Script Approval);
  • в seed job включайте Use Groovy Sandbox, где доступно;
  • секреты не храните в DSL — credentials в Jenkins + withCredentials в Jenkinsfile (22.md);
  • Dynamic DSL и configure { } могут записать секрет в XML job — избегайте в Git.

Wiki плагина: Script Security.


Configuration as Code (JCasC)

Seed Freestyle можно заменить фрагментом JCasC при старте controller:

jobs:
- script: >
pipelineJob('shop-build') {
definition {
cpsScm {
scm { git { remote { url('https://github.com/example/shop.git') } } }
scriptPath('Jenkinsfile')
}
}
}

Плюсы — воспроизводимый Docker-образ Jenkins, jobs на чистом controller без ручного клика. Минусы — ошибка в YAML ломает старт; тестируйте на staging.


Job DSL и Shared Library

Job DSLShared Library
УровеньJobs, folders, viewsФункции и классы внутри pipeline
ПримерpipelineJob('shop') { ... }standardPipeline(deploy: true)
ЗапускSeed job@Library в Jenkinsfile

Вместе — platform team держит DSL-репо (какие repos вообще собираются), product team — короткий Jenkinsfile с @Library.


Частые ошибки

СимптомВероятная причинаДействие
Job не появилсяНеверный glob в seedПроверьте jobs/**/*.groovy, лог seed build
No such DSL method 'pipelineJob'Плагин Job DSL не установленPlugins → Job DSL
No such DSL method 'git'Нет Git pluginУстановить Git + перезапуск
Два одинаковых jobДва seed управляют одним именемfailOnSeedCollision / один seed
Pipeline пустой / NPEscriptPath не тотПуть в репо vs scriptPath('ci/Jenkinsfile')
DSL изменился, jobs старыеSeed не запускалсяWebhook на seed после push
Sandbox approval loopНовый метод в DSLApprove или упростить скрипт

Что попробовать

  1. Docker Jenkins + один pipelineJob на свой учебный репозиторий (первая программа Groovy).
  2. В API Viewer собрать multibranchPipelineJob для feature-веток.
  3. Вынести listView в views/team.groovy.
  4. Добавить Shared Library — DSL создаёт job, library сокращает Jenkinsfile.

Дальше

Jenkins Shared Library · Jenkins Pipeline · Gradle Groovy DSL · DevOps CI/CD