More Related Content
Similar to Jenkins 2.0: Организуем тестирование в составе Continuous Delivery (20)
Jenkins 2.0: Организуем тестирование в составе Continuous Delivery
- 2. ©2016CloudBees,Inc.AllRightsReserved
• ~10 лет в R&D и автоматизации
• Фокус: электроника и встраиваемое
ПО
– Intel, Sitronics, Synopsys
• Развертывание и поддержка
больших систем автоматизации
• Автоматизация тестирования и QA
2
О себе. Бэкграунд
@oleg_nenashev
oleg-nenashev
onenashev
- 4. ©2016CloudBees,Inc.AllRightsReserved
Кто такой Jenkins?
4
• Сервер автоматизации
• Continuous Integration
• Continuous Delivery
• DevOps
• …
• Веб-интерфейс
• Распределенная система
• Open-source (MIT)
https://jenkins.io
Сборка
Тестиро-
вание
Создание
пакетов
Установка,
развер-
тывание
Построе-
ние
отчетов,
аналитика
и другое
- 7. ©2016CloudBees,Inc.AllRightsReserved
Jenkins 2.0. А зачем?
• Смена фокуса с CI в разработке софта
– Continuous Delivery/Deployment
– DevOps
– Everything as Code
• Проблемы User Experience в Jenkins
– Сложность настройки системы и задач
– Неполная документация
– Интеграционные проблемы
7
- 20. ©2016CloudBees,Inc.AllRightsReserved
Что нам нужно для CD?
•Параллелизация (что можно)
•Версионирование кода и процедур сборки
•Воспроизводимость тестов и сборок
– Чистое окружение для каждого прогона
– Тесты сами подготавливают окружение
•Тестирование на реальном релизе
– Staging-репозитории релизов
20
- 24. ©2016CloudBees,Inc.AllRightsReserved
Строим Delivery Pipeline. “Классический”
подход
• Failover
– Naginator-плагин
• Воспроизводимость
– Чистое окружение
– Одноразовые
виртуальные
машины
24
• Параллелизация
– Matrix Project
– Parameterized
Trigger
• Цепочки задач:
– MultiJob plugin
– Build Pipeline Plugin
• Шаблонизация:
– Template project
– Inheritance plugin
- 36. ©2016CloudBees,Inc.AllRightsReserved
• Pipeline не привязан к конкретной ноде
• Параллелизация
– Команда parallel() – не нужны связки
джобов
• Множественные node() в одной задаче
– => + parallel() – запуск тестов на разных
машинах тестов на машинах
• Множественные scm() в одной задаче
• Интерактивные шаги
36
Специфика Pipeline
- 37. ©2016CloudBees,Inc.AllRightsReserved
37
Пример. Параллельные тесты
…
stage ‘test'
parallel 'unit' : {
node {
unstash 'source'
sh "./gradlew :test"
stash includes: 'build/jacoco/*.exec', name: 'unitCodeCoverage'
step([$class:'JUnitResultArchiver',
testResults:'**/build/test-results/*.xml'])
}
}, 'integration': {
node {
unstash 'source'
sh "./gradlew -PhappyPath :integration-test:test"
step([$class:'JUnitResultArchiver',
testResults:'**/build/test-results/*.xml'])
}
}
- 38. ©2016CloudBees,Inc.AllRightsReserved
• Устойчивость к рестарту мастера
– Pipeline хранит контекст и продолжает задачу
после рестарта
• Шаг sh() – Durable Task Plugin
– Устойчивость к разрывам сети
• Failover в случае инфраструктурных проблем
38
Pipeline. Надежность инфраструктуры
- 39. ©2016CloudBees,Inc.AllRightsReserved
Pipeline. Надежность инфраструктуры
• Почти любая ошибка может быть
перехвачена и отработана
Переход на другую ноду
Node #1 Node #2. . .
. . .
for (def board : boards) {
echo "trying board " + board;
try {
node(board) {
checkout scm
sh ‘./bin/run.sh’
// Call passed => DONE
break;
}
} catch (Exception ex) {
if (ex.message.contains
("exit code 255")) {
// Fatal error
fail("Test run failed")
} } }
Пример кода
- 40. ©2016CloudBees,Inc.AllRightsReserved
• Команда load() –загрузка Pipeline из файла
• Pipeline Global Library Plugin
– Входит в состав ядра Pipeline plugin
– Создает Git-репозиторий в Jenkins
– Предоставляет глобальные классы и
переменные
• Pipeline Remote Loader Plugin
– Загрузка кода Pipeline из Git/GitHub
40
Фичи. Шаблонизация
- 41. ©2016CloudBees,Inc.AllRightsReserved
Pipeline. Воспроизводимость
• Staging-репозитории
– Плагины/CLI для Nexus, Artifactory, TFS, …
• «Чистые» окружения
– Нативная поддержка виртуальных машин
– Поддержка Cloud API Jenkins
o AWS, EC2, Azure, Mesos, vSphere, Docker, …
– Docker Pipeline Plugin
41
- 43. ©2016CloudBees,Inc.AllRightsReserved
43
Пример. CD Jenkins-бота
#!groovy
def imageName = 'jenkinsciinfra/ircbot’
node('docker') {
checkout scm
// Немного магии для получения тэга Docker-образа
sh 'git rev-parse HEAD > GIT_COMMIT'
shortCommit = readFile('GIT_COMMIT').take(6)
def imageTag = "build${shortCommit}"
stage 'Build ircbot'
withMavenEnv
(["BUILD_NUMBER=${env.BUILD_NUMBER}:${shortCommit}"]) {
sh 'make bot' // Make вызывает Maven
}
stage 'Build container'
def whale = docker.build("${imageName}:${imageTag}”)
stage 'Deploy container'
whale.push()
}
https://github.com/jenkins-infra/ircbot
- 46. ©2016CloudBees,Inc.AllRightsReserved
46
Пример. Интерактивные шаги
// Сборка проекта из репозитория
// Инициализация тестового прогона в TestRail для QA
// Автотесты, репортинг, деплой на staging-сервер
// Отправить уведомления ручным тестировщикам
echo ’Automatic tests passed’
hipchatSend('@QATeam The build ' + buildVersion + ' has been staged: ' + stagingURL
+ '. Please Test it and report back to ' + build.url
+ '. TestRail run is here: ' + testRailRunURL)
// Подождать, пока QA подтвердят релиз
input message: 'Have manual spot-checks passed? Ready to release?'
// Релиз и нотификации
mail to: "dream_team@cloudbees.com",
subject: "Dream Product - build is released",
body: "Hi there, The new build of the product has been released. Link:» + artifactoryLink
~~~~~~Много кода~~~~~~
~~~~~~Много кода~~~~~~
- 47. ©2016CloudBees,Inc.AllRightsReserved
Pipeline в CloudBees Jenkins Platform
• Частичный Continuous Delivery
• Около 100 внутренних модулей + open-source
• Тысячи сборок в день
• У нас нет тестировщиков (только SDET)
• Что мы автоматизируем?
– Проверка pull-request’ов, validated Merge
– Релизы (компоненты, инсталляторы)
– CD документации на сайты
– Интеграция компонентов (ночные сборки)
– Деплой на staging
47
- 48. ©2016CloudBees,Inc.AllRightsReserved
Pipeline в CloudBees Jenkins Platform
• Что сделали?
– Весь код в SCM, минимальные настройки проектов
– Внутренняя библиотека Pipeline
– Pipeline Utility Steps
• Чего добились?
– Релиз и staging одной кнопкой
– Легко тестируем изменения в Build Flow
– Более эффективная параллелизация UI-тестов
oUI-тесты: 8 часов (на N машинах) => 1 час
oРелиз основного модуля– 3 часа
48
- 49. ©2016CloudBees,Inc.AllRightsReserved
• Jenkins 2.0
– … частично решает проблемы с UI/UX
– … будет развиваться дальше
• Pipeline as Code
– … снижает затраты на поддержку
автоматизации
– … может быть применен для CD
– … может быть применен для задач QA
49
Заключение
- 50. ©2016CloudBees,Inc.AllRightsReserved
• Twitter: @jenkins_ru
• Gitter: http://gitter.im/jenkinsci-ru
– QA: использование и разработка
Jenkins
• Митапы:
– Санкт-Петербург
o http://www.meetup.com/St-Petersburg-Jenkins-
Meetup/
– Москва – in progress
o http://www.meetup.com/Moscow-Jenkins-
Meetup/
– Минск (@KostyaSha, привет!)
– CloudBees спонсирует митапы
50
Русскоязычное комьюнити
Здесь может
быть Ваше лого
- 51. ©2016CloudBees,Inc.AllRightsReserved
• Jenkins:
– Вебсайт: http://jenkins.io
– Jenkins 2.0: https://jenkins-ci.org/2.0/
– Jenkins и CD: https://jenkins.io/solutions/pipeline/
• Pipeline-as-Code:
– Документация: https://jenkins.io/doc/pipeline/
– Примеры: https://github.com/jenkinsci/pipeline-examples
• CloudBees:
– Вебсайт: https://www.cloudbees.com/
– CloudBees Jenkins Platform:
https://www.cloudbees.com/products/cloudbees-jenkins-platform
51
Ссылки
- 56. ©2016CloudBees,Inc.AllRightsReserved
• Multibranch Pipeline – тип задачи
– В конфигурации – ссылка на репозиторий
o Git/GitHub, BitBucket, …
– Описание проекта - Jenkinsfile
– Для всех веток – ОТДЕЛЬНЫЕ задачи в Jenkins
o Сборки при коммитах
o Независимые отчеты и Build History
– [СКОРО] – Сборка pull-request’ов
• (+) Multi-branch работает на уровне организаций в GitHub и
BitBucket
56
Фичи Pipeline. Multibranch
- 59. ©2016CloudBees,Inc.AllRightsReserved
59
Pipeline Remote Loader. Пример
stage 'Load files from GitHub'
def environment, helloworld
fileLoader.withGit ('https://github.com/jenkinsci/workflow-
remote-loader-plugin.git', 'master', null, '')
{
helloworld = fileLoader.load('examples/fileLoader/helloworld');
environment = fileLoader.load('examples/fileLoader/environment');
}
stage 'Run methods from the loaded content'
helloworld.printHello()
environment.dumpEnvVars()