1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/beijing-guangyu-online-jenkins-json-build

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 56 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 24.11.2024 07:24 849efb3

Jenkins Json Build

В моей организации много проектов, и мы используем множество языков и фреймворков, таких как Java, ReactNative, C# .NET, Android, iOS и другие. У нас также есть различные среды развёртывания, такие как Tomcat, K8S, IIS, а клиентские приложения устанавливаются с использованием корпоративных сертификатов в локальной сети.

У нас нет специального администратора по настройке или специалиста по развёртыванию. Разработчики самостоятельно пишут сценарии сборки в Jenkins для каждого проекта. Однако сценарии сборки для похожих проектов (например, все проекты на Java или все проекты .NET) очень похожи друг на друга. Они основаны на нескольких существующих сценариях сборки, которые были адаптированы под конкретные нужды.

Разработчики не обладают глубокими знаниями о написании сценариев сборки Jenkins. Кроме того, из-за отсутствия правил и ограничений, а также механизмов повторного использования кода, работа по сборке и развёртыванию становится хаотичной и трудно управляемой.

Для решения этой проблемы мы разработали проект Jenkins-Json-Build. Он подходит для разработчиков с некоторым опытом программирования, которым не нужно разбираться в том, как писать сценарии сборки Jenkins. С помощью простого файла конфигурации JSON можно легко выполнить следующие шаги для одного проекта: получить исходный код, провести модульное тестирование, проверить код, скомпилировать и собрать, развернуть. Это позволяет реализовать типичный процесс непрерывной интеграции (CI).

Кроме того, поскольку этот проект использует механизм Shared Libraries в Jenkins, коэффициент повторного использования сценариев сборки значительно повышается. Разработчики могут легко расширять функциональность и удовлетворять потребности различных сценариев сборки и развёртывания. Этот проект идеально подходит для команд разработчиков, которые самостоятельно управляют сборкой и развёртыванием. Проект Jenkins-Json-Build помогает организовать и контролировать процессы сборки и развёртывания в этих командах, обеспечивая при этом достаточную гибкость и автономию для удовлетворения специфических потребностей каждого проекта.

Содержание:

  1. Подготовка к работе.
  2. Создание задачи конвейера Jenkins.
  3. Формат и способ выполнения документов JSON.
  4. Переменные в JSON.
  5. Унифицированный сценарий сборки.
  6. Сборка проекта Java.
  7. Сборка проекта JS.
  8. Сборка проекта ReactNative.
  9. Сборка проекта Android.
  10. Сборка проекта iOS.
  11. Сборка проекта .NET.
  12. Сборка нескольких подпроектов.
  13. Обработка успешной сборки и сбоя.
  14. Создание Pod для сборки внутри K8S.
  15. Минимальный сценарий сборки.
  16. Другие настройки.
  • Подготовка к работе:

    • Установите Jenkins.
    • Ознакомьтесь с Shared Libraries в Jenkins.
    • Установите Gitlab.
    • Установите клиент Git.
    • (Необязательно) Ознакомьтесь со структурой проекта Shared Library.
  • Создание задачи конвейера Jenkins:

    • Зависимые плагины: Pipeline Utility Steps.

    • Создайте новый конвейер в системе Jenkins.

      • После создания измените определение задачи на pipeline script from SCM.
      • Измените SCM на Git и URL репозитория на адрес репозитория проекта.
      • Отмените выбор лёгкого извлечения в Additional Behaviours, так как это может конфликтовать с плагином Git Parameter позже.
      • В Additional Behaviours выберите Advanced Clone Behavior и установите время ожидания для операций клонирования и извлечения на 10 минут, чтобы учесть медленное первоначальное клонирование больших проектов.
    • Сохраните и выйдите.

  • Файлы, необходимые в каталоге проекта:

    • В каталоге проекта должны быть два файла: Jenkinsfile и jenkins-project.json. Их можно получить из примера файлов. Jenkinsfile — это сценарий сборки, который автоматически выполняется после получения исходного кода проекта, а jenkins-project.json — это файл конфигурации сборки, необходимый для этого проекта (имя файла по умолчанию — jenkins-project.json, но его можно изменить в сценарии).
  • Настройка Shared Libraries:

    • Настройте Shared Libraries в системе. Shared Library — это имя библиотеки, которое будет использоваться позже в сценариях сборки. Адрес репозитория — это адрес репозитория Shared Library.
    • Скопируйте ресурсы, src и vars каталоги из shared-library в каталог Shared Library репозитория.
  • Запуск задачи конвейера:

    • После завершения настройки запустите задачу конвейера немедленно.
  • Формат документа JSON и способ его выполнения:

    • Пример сценария сборки состоит из пяти этапов: инициализация, проверка кода, модульное тестирование, компиляция и сборка, развёртывание.
@Library('shared-library') _

pipeline {
    agent any
    stages {
        stage('初始化') {
            steps {
                script{
                    runWrapper.loadJSON('/jenkins-project.json')
                    runWrapper.runSteps('初始化')
                }
            }
        }
        stage('代码检查') {
            steps {
                script{
                    runWrapper.runSteps('代码检查')
                }
            }
        }
        stage('单元测试') {
            steps {
                script{
                    runWrapper.runSteps('单元测试')
                }
            }
        }
        stage('编译构建') {
            steps {
                script{
                    runWrapper.runSteps('编译构建')
                }
            }
        }
        stage('部署') {
            steps {
                script{
                    runWrapper.runSteps('部署')
                }
            }
        }
    }
}

Конкретные шаги сборки определяются в файле jenkins-project.json в корневом каталоге репозитория:

{
  "初始化": {
    "执行脚本": {
      "Type": "COMMAND_STDOUT",
      "Script": {
        "脚本-1": "echo 初始化脚本-1",
        "脚本-2": "echo 初始化脚本-2"
      }
    }
  },
``` ```
"代码检查": {
    "Выполнение скрипта": {
      "Тип": "COMMAND_STATUS",
      "Скрипт": {
        "Сценарий-1": "echo сценарий проверки кода 1",
        "Сценарий-2": "echo сценарий проверки кода 2"
      }
    }
  },
  "Юнит-тестирование": {
    "Выполнение скрипта": {
      "Тип": "COMMAND_STATUS",
      "Скрипт": {
        "Сценарий-1": "echo юнит-тест сценария 1",
        "Сценарий-2": "echo юнит-тест сценария 2"
      }
    }
  },
  "Компиляция и сборка": {
    "Выполнение скрипта": {
      "Тип": "COMMAND_STATUS",
      "Скрипт": {
        "Сценарий-1": "echo компиляция и сборка сценария 1",
        "Сценарий-2": "echo компиляция и сборка сценария 2"
      }
    }
  },
  "Развёртывание": {
    "Выполнение скрипта": {
      "Тип": "COMMAND_STATUS_FOR",
      "Для": "1,2,3",
      "Шаблон скрипта": "echo компиляция и сборка сценария-${цикл-команда-для}"
    }
  }
}

В запросе представлен фрагмент JSON-файла с описанием этапов сборки программного обеспечения. В файле определены этапы «код проверка», «юнит-тестирование», «компиляция и сборка» и «развёртывание». Для каждого этапа заданы параметры выполнения скрипта, включая тип операции и сами скрипты.

Текст запроса содержит также описание процесса выполнения этих этапов. Этапы выполняются последовательно, начиная с инициализации. Каждый этап включает в себя выполнение скриптов, которые могут содержать несколько команд.

В тексте запроса также представлены примеры вывода информации о выполнении этапов, включая сообщения об успешном завершении. ``` { script { runWrapper.loadJSON('/jenkins-project.json') runWrapper.runSteps('测试变量') } }


**Содержание файла /jenkins-project.json:**

```json
{
  "RuntimeVariable": {
    // Deploy_Choice — это параметр сборки
    "JENKINS_PARAMS_DEPLOY": "echo ${deploy-choice}",
    // BUILD_URL — глобальная переменная Jenkins
    "JENKINS_BUILD_URL": "echo ${BUILD_URL}",
    // выполнит команду pwd для получения текущего каталога
    "SCRIPT_PWD": "pwd",
    // выполняет скрипт для получения информации о git commit
    "SCM_CHANGE_TITLE": "git --no-pager show -s --format=\"%s\" -n 1"
  },
  "GlobalVariable": {
    // использует значение переменной JENKINS_PARAMS_DEPLOY из RuntimeVariable
    "GV_PARAMS_DEPLOY": "${JENKINS_PARAMS_DEPLOY}",
    // использует значение переменной JENKINS_BUILD_URL из RuntimeVariable
    "GV_BUILD_URL": "${JENKINS_BUILD_URL}",
    // определяет глобальную переменную
    "GV_VAR": "gv_var_value",
    // определяет другую глобальную переменную
    "TEMP_VAR": "temp_var_value"
  },
  "测试变量": {
    "Вывод переменных RuntimeVariable": {
      "Тип": "COMMAND_STATUS",
      "Скрипт": {
        "Вывод JENKINS_PARAMS_DEPLOY": "echo ${JENKINS_PARAMS_DEPLOY}",
        "Вывод JENKINS_BUILD_URL": "echo ${JENKINS_BUILD_URL}",
        "Вывод SCRIPT_PWD": "echo ${SCRIPT_PWD}",
        "Вывод SCM_CHANGE_TITLE": "echo ${SCM_CHANGE_TITLE}"
      }
    },
    "Вывод переменных GlobalVariable": {
      "Тип": "COMMAND_STATUS",
      "Переменная": {
        // перезаписывает значение переменной TEMP_VAR в GlobalVariable
        "TEMP_VAR": "variable_value",
        // определяет локальную переменную
        "Local_Variable": "Local_Variable"
      },
      "Скрипт": {
        "Вывод GV_PARAMS_DEPLOY": "echo ${GV_PARAMS_DEPLOY}",
        "Вывод GV_BUILD_URL": "echo ${GV_BUILD_URL}",
        "Вывод GV_VAR": "echo ${GV_VAR}",
        "Вывод TEMP_VAR": "echo ${TEMP_VAR}",
        "Вывод Local_Variable": "echo ${Local_Variable}"
      }
    }
  }
}

Журнал сборки:

Начало выполнения [测试变量] и [Вывод переменных RuntimeVariable].
Начало выполнения команды [echo 部署全部] из [Вывод JENKINS_PARAMS_DEPLOY].
bash: no job control in this shell
部署全部
Выполнение завершено [0].
Начало выполнения команды [echo http://192.168.0.15:8081/job/Test-Jenkins-Json-Build/11/] из [Вывод JENKINS_BUILD_URL].
bash: no job control in this shell
http://192.168.0.15:8081/job/Test-Jenkins-Json-Build/11/
Выполнение завершено [0].
Начало выполнения команды [echo /root/.jenkins/workspace/Test-Jenkins-Json-Build] из [Вывод SCRIPT_PWD].
bash: no job control in this shell
/root/.jenkins/workspace/Test-Jenkins-Jenkins-Json-Build
Выполнение завершено [0].
Начало выполнения команды [echo test] из [Вывод SCM_CHANGE_TITLE].
bash: no job control in this shell
test
Выполнение завершено [0].
Завершение выполнения [Вывод переменных RuntimeVariable].

Начало выполнения [Вывод переменных GlobalVariable].
Начало выполнения команды [echo 部署全部] из [Вывод GV_PARAMS_DEPLOY].
bash: no job control in this shell
部署全部
Выполнение завершено [0].
Начало выполнения команды [echo http://192.168.0.15:8081/job/Test-Jenkins-Json-Build/11/] из [Вывод GV_BUILD_URL].
bash: no job control in this shell
http://192.168.0.15:8081/job/Test-Jenkins-Json-Build/11/
Выполнение завершено [0].
Начало выполнения команды [echo gv_var_value] из [Вывод GV_VAR].
bash: no job control in this shell
gv_var_value
Выполнение завершено [0].
Начало выполнения команды [echo variable_value] из [Вывод TEMP_VAR].
bash: no job control in this shell
variable_value
Выполнение завершено [0].
Начало выполнения команды [echo Local_Variable] из [Вывод Local_Variable].
bash: no job control in this shell
Local_Variable
Выполнение завершено [0].
Завершение выполнения [Вывод переменных GlobalVariable].
Завершение выполнения [тестирование переменной].
Finished: SUCCESS

Значение переменной JENKINS_PARAMS_DEPLOY можно получить только при втором выполнении сборки, так как скрипт добавления параметров сборки находится в файле Jenkinsfile, и при первом выполнении задачи эти параметры ещё не определены. Кроме того, в определении переменных в узле RuntimeVariable нельзя использовать простые присваивания, как в случае с GlobalVariable. Вместо этого необходимо использовать команду echo для присвоения значений.

Если в узле RuntimeVariable определяется переменная через HTTP или чтение файла, то можно установить путь к файлу или URL после @path[\имя узла\имя узла], чтобы получить значение узла и присвоить его переменной. Например:

В узле RuntimeVariable переменная задаётся через чтение файла:

"JAVA_VERSION_SCRIPT": "./src/main/jenkins/com/bluersw/jenkins/libraries/json/java-build.json@path[\\инициализация\\проверка Java среды\\Script\\вывод версии Java]"

Здесь значение переменной JAVA_VERSION_SCRIPT — «java -version 2>&1».

Также в узле RuntimeVariable можно задать переменную через HTTP:

"HTTP_JAVA_VERSION_SCRIPT": "https://raw.githubusercontent.com/sunweisheng/jenkins-json-build/master/unit-tests/src/main/jenkins/com/bluersw/jenkins/libraries/json/java-build.json@path[\\инициализация\\проверка Java среды\\Script\\вывод версии Java]"

Здесь также значение переменной HTTP_JAVA_VERSION_SCRIPT — «java -version 2>&1». BUILD_URL: http://ops.gydev.cn:8080/job/Test-Jenkins-Json-Build/28/ CLASSPATH: deploy-choice: 模拟部署脚本-1 HUDSON_HOME: /root/.jenkins HUDSON_SERVER_COOKIE: 04f54204dabc2b46 HUDSON_URL: http://ops.gydev.cn:8080/ JENKINS_HOME: /root/.jenkins JENKINS_SERVER_COOKIE: 04f54204dabc2b46 JENKINS_URL: http://ops.gydev.cn:8080/ JOB_BASE_NAME: Test-Jenkins-Json-Build JOB_DISPLAY_URL: http://ops.gydev.cn:8080/job/Test-Jenkins-Json-Build/display/redirect JOB_NAME: Test-Jenkins-Json-Build JOB_URL: http://ops.gydev.cn:8080/job/Test-Jenkins-Json-Build/ library.shared-library.version: V2 RUN_ARTIFACTS_DISPLAY_URL: http://ops.gydev.cn:8080/job/Test-Jenkins-Json-Build/28/display/redirect?page=artifacts RUN_CHANGES_DISPLAY_URL: http://ops.gydev.cn:8080/job/Test-Jenkins-Json-Build/28/display/redirect?page=changes RUN_DISPLAY_URL: http://ops.gydev.cn:8080/job/Test-Jenkins-Json-Build/28/display/redirect RUN_TESTS_DISPLAY_URL: http://ops.gydev.cn:8080/job/Test-Jenkins-Json-Build/28/display/redirect?page=tests

REAL_USER_NAME: (выполнение сборки учётной записи пользователя) WORKSPACE: /root/.jenkins/workspace/Test-Jenkins-Json-Build PROJECT_PATH: /root/.jenkins/workspace/Test-Jenkins-Json-Build/ PROJECT_DIR:

  • json конфигурация файла находится в корневом каталоге проекта.
  • PROJECT_PATH — это путь к каталогу, ближайший к загруженному файлу конфигурации json.
  • PROJECT_DIR — это путь первого уровня между корнем репозитория и каталогом файлов конфигурации json, поэтому, если корень репозитория является корнем проекта, то PROJECT_DIR пуст.
  • WORKSPACE — это корневой каталог репозитория.

Переменная PROJECT_PATH часто используется, и перед выполнением командного сценария обычно необходимо добавить cd ${PROJECT_PATH}, чтобы определить путь выполнения командного сценария. Эти неявные объявления переменных можно использовать в любом месте документа.

Унифицированный сценарий сборки

Можно написать один или несколько унифицированных сценариев сборки для использования во всех проектах, что упрощает использование и обслуживание разработчиками. Например, типичный сценарий сборки (Jenkinsfile) выглядит следующим образом:

@Library('shared-library') _

pipeline {
    agent { label params['agent-name'] }
    parameters { //определение параметров сборки
        choice choices: ['-'], description: 'Выберите способ развёртывания', name: 'deploy-choice'
        agentParameter name:'agent-name'
        checkboxParameter name:'project-list', format:'YAML', uri:'https://raw.githubusercontent.com/sunweisheng/jenkins-json-build/master/example/microservice-build/project-list.yaml'
    }
    stages {
        stage('Инициализация') {
            steps {
                script{
                    runWrapper.loadJSON(params['project-list'])
                    runWrapper.runSteps('Инициализация')
                }
            }
        }
        stage('Юнит-тестирование') {
            steps {
                script{
                    runWrapper.runSteps('Юнит-тестирование')
                }
            }
        }
        stage('Проверка кода') {
            steps {
                script{
                    runWrapper.runSteps('Проверка кода')
                }
            }
        }
        stage('Компиляция и сборка') {
            steps {
                script{
                    runWrapper.runSteps('Компиляция и сборка')
                }
            }
        }
        stage('Развёртывание') {
            steps {
                script{
                    runWrapper.runStepForEnv('Развёртывание','deploy-choice')
                }
            }
        }
    }
}

Вышеупомянутый процесс сборки состоит из пяти основных этапов: инициализация (обычно включает загрузку конфигурации сборки, проверку среды сборки и привязку значений параметров сборки), юнит-тестирование, проверка кода (проверка соответствия кода стандартам), компиляция и сборка, развёртывание. Он подходит для большинства проектов и использует два связанных плагина Jenkins:

Плагин Agent Server Parameter используется для выбора сервера сборки (узел агента Jenkins), а плагин Custom Checkbox Parameter используется для выборочного построения подпроектов в корне репозитория (если нет подпроектов, этот плагин можно не использовать). В большинстве случаев также используется плагин Git Parameter, который используется для выбора ветки для получения исходного кода.

Определение параметра сборки с раскрывающимся списком:

//Выберите один из способов развёртывания вместо выполнения всех способов развёртывания
choice choices: ['-'], description: 'Пожалуйста, выберите способ развёртывания', name: 'deploy-choice'

Привязка значения параметра сборки к раскрывающемуся списку:

"Привязка параметров сборки": {
      "Type": "BUILD_PARAMETER_DROP_DOWN_MENU",
      "StepsName": "Развёртывание",
      "ParamName": "deploy-choice"
    }

Выполните этап сборки в соответствии со значением выбора:

runWrapper.runStepForEnv('Развёртывание','deploy-choice')

Метод runWrapper.runStepForEnv() выполняет этап сборки с указанным именем в соответствии со значением глобальной переменной. В сценарии Jenkinsfile определён раскрывающийся список для выбора способа развёртывания, а в файле конфигурации json он связан со списком этапов сборки. Таким образом, метод runStepForEnv() может достичь цели выбора этапа сборки для выполнения.

В последующих примерах проектов все они используют унифицированный сценарий сборки Jenkinsfile, но содержимое файла конфигурации json отличается, поэтому результаты сборки также различаются.

Сборка Java-проекта

Пример проекта

Необходимое программное обеспечение

На сервере сборки необходимо установить Java, Maven и Sonar-Scanner. Конфигурация сборки Java-проекта: плагины и зависимости

  • JUnit — это среда тестирования, которая используется для проверки правильности работы кода.
  • JaCoCo — инструмент для измерения покрытия кода тестами.

Конфигурация сборки проекта на Java

Конфигурационный файл сборки содержит информацию о том, как должен быть построен проект. В нём описаны шаги, которые необходимо выполнить, а также параметры, которые нужно передать этим шагам.

Файл конфигурации написан на языке JSON и содержит следующие разделы:

  1. «Инициализация» — проверка наличия необходимых компонентов (Java, Maven, SonarScanner).
  2. «Юнит-тестирование» — выполнение юнит-тестов с помощью Maven и плагинов JUnit и JaCoCo.
  3. «Проверка кода» — запуск анализа кода с использованием SonarQube.
  4. «Компиляция и сборка» — сборка проекта с помощью Maven.
  5. «Развёртывание» — имитация развёртывания приложения с использованием двух сценариев.

В разделе «Инициализация» содержатся проверки наличия необходимых компонентов. Если компонент отсутствует, то сборка завершается ошибкой.

Раздел «Юнит-тестирование» описывает выполнение юнит-тестов. Сначала выполняется команда Maven для запуска тестов, затем плагин JUnit генерирует отчёт о тестах, а плагин JaCoCo собирает информацию о покрытии кода тестами.

Раздел «Проверка кода» запускает анализ кода с использованием инструмента SonarQube, который проверяет качество кода и выявляет возможные проблемы.

Раздел «Компиляция и сборка» выполняет сборку проекта с помощью команды Maven.

Раздел «Развёртывание» имитирует развёртывание приложения. Здесь описаны два сценария развёртывания.

Данный конфигурационный файл описывает процесс сборки проекта на Java. Он содержит подробную информацию о каждом шаге сборки и параметрах, которые должны быть переданы этим шагам. Инициализация:

  • Проверка Node.js окружения: вывод версии Node.js при выполнении команды «node -v».
  • Проверка SonarScanner окружения: вывод версии SonarQube Scanner при выполнении команды «sonar-scanner -v».
  • Проверка react-native-cli окружения: вывод версии react-native-cli при выполнении команды «react-native -version».

Привязка параметров сборки: BUILD_PARAMETER_DROP_DOWN_MENU, StepsName — «Развёртывание», ParamName — deploy-choice.

Глобальная установка компонентов:

  • jest: выполнение команды «npm install -g jest».

Выполнение юнит-тестов:

  • обновление библиотек: «cd ${PROJECT_PATH}; npm install»;
  • запуск юнит-теста: «cd ${PROJECT_PATH}; npm test».

Анализ покрытия кода юнит-тестами: JEST_COVERAGE_ANALYSIS, Statements — 100%, Branches — 100%, Functions — 100%, Lines — 100%.

Проверка кода: SONAR_QUBE.

Компиляция и сборка: RN-Android сборка.

В запросе не удалось перевести часть текста. В результате перевода могут быть неточности. ### RN构建 iOS версии конфигурации файла

{
  "初始化": {
    "Проверка Nodejs среды": {
      "Тип": "COMMAND_STDOUT",
      "Success-IndexOf": "v11.6.0",
      "Скрипт": {
        "Вывод Node версии": "node -v"
      }
    },
    "Проверка SonarScanner среды": {
      "Тип": "COMMAND_STDOUT",
      "Success-IndexOf": "SonarQube Scanner 4.0.0.1744",
      "Скрипт": {
        "Вывод SonarScanner версии": "sonar-scanner -v"
      }
    },
    "Проверка ruby среды": {
      "Тип": "COMMAND_STDOUT",
      "Success-IndexOf": "ruby 2.6",
      "Скрипт": {
        "Вывод ruby версии": "ruby -v"
      }
    },
    "Проверка react-native-cli среды": {
      "Тип": "COMMAND_STDOUT",
      "Success-IndexOf": "react-native-cli: 2.0.1",
      "Скрипт": {
        "Вывод react-native-cli версии": "react-native -version"
      }
    },
    "Проверка Xcode среды": {
      "Тип": "COMMAND_STDOUT",
      "Success-IndexOf": "Xcode 11.1",
      "Скрипт": {
        "Вывод Xcode версии": "xcodebuild -version"
      }
    },
    "Привязка параметров сборки": {
      "Тип": "BUILD_PARAMETER_DROP_DOWN_MENU",
      "StepsName": "Развёртывание",
      "ParamName": "deploy-choice"
    },
    "Установка jest глобально": {
      "Тип": "COMMAND_STATUS_IF",
      "TestScript": "jest -v",
      "NotExpect": "0",
      "Скрипт": {
        "Установка jest": "npm install -g jest"
      }
    },
    "Получение прав доступа к связке ключей": {
      "Тип": "COMMAND_STATUS_WITH_CREDENTIALS",
      "CredentialsId": "iOS_admin_passwd",
      "Скрипт": {
        "Получение прав": "cd ${PROJECT_PATH};security set-key-partition-list -S apple-tool:,apple: -s -k $password login.keychain"
      }
    }
  },
  "Модульное тестирование": {
    "Выполнение модульного тестирования": {
      "Тип": "COMMAND_STATUS",
      "Скрипт": {
        "Обновление библиотеки": "cd ${PROJECT_PATH};npm install",
        "Запуск модульного тестирования": "cd ${PROJECT_PATH};npm test"
      }
    },
    "Анализ покрытия модульных тестов": {
      "Тип": "JEST_COVERAGE_ANALYSIS",
      "Statements": "100",
      "Branches": "100",
      "Functions": "100",
      "Lines": "100"
    }
  },
  "Код проверка": {
    "Запуск сканирования SQ кода": {
      "Тип": "SONAR_QUBE"
    }
  },
  "Компиляция и сборка": {
    "Выполнение RN-iOS сборки": {
      "Тип": "COMMAND_STATUS",
      "Variable": {
        "ProjectName": "TestRnBuild",
        "PlistPath": "${PROJECT_PATH}/ios/test-rn-build.plist"
      },
      "Скрипт": {
        "Установка CocoaPods зависимостей": "cd ${PROJECT_PATH}/ios;pod install --verbose --no-repo-update",
        "Очистка каталога build": "cd ${PROJECT_PATH}/ios;rm -rf build",
        "Упаковка": "export LC_ALL=en_US.UTF-8;cd ${PROJECT_PATH}/ios/;xcodebuild -workspace ${ProjectName}.xcworkspace -scheme ${ProjectName} -configuration Release -archivePath build/${ProjectName}.xcarchive -UseModernBuildSystem=YES -allowProvisioningUpdates archive; xcodebuild -exportArchive -archivePath build/${ProjectName}.xcarchive -exportPath build -exportOptionsPlist ${PlistPath}"
      }
    }
  },
  "Развёртывание": {
    "Эмуляция развёртывания сценария 1": {
      "Тип": "COMMAND_STATUS",
      "Скрипт": {
        "Копирование файла": "echo Эмуляция копирования файла"
      }
    },
    "Эмуляция развёртывания сценария 2": {
      "Тип": "COMMAND_STATUS",
      "Скрипт": {
        "Передача файла по HTTP": "echo Эмуляция передачи файла по HTTP"
      }
    }
  }
}

Описание:

"Получение прав доступа к связке ключей": {
  "Тип": "COMMAND_STATUS_WITH_CREDENTIALS",
  "CredentialsId": "iOS_admin_passwd",
  "Скрипт": {
    "Получение прав": "cd ${PROJECT_PATH};security set-key-partition-list -S apple-tool:,apple: -s -k $password login.keychain"
  }
}

Этот узел используется для выполнения командных сценариев с использованием имени пользователя и пароля. CredentialsId — это имя учётных данных в Jenkins, которое в настоящее время может использовать только тип учётных данных usernamePassword. В сценарии команды $password представляет пароль, а $username представляет имя пользователя. Скрипт может содержать несколько операторов. Конфигурация сборки iOS-приложения

Проверка среды SonarScanner:

Тип: COMMAND_STDOUT.

Успешный индекс: SonarQube Scanner 4.0.0.1744.

Скрипт: вывод версии SonarScanner: sonar-scanner -v.

Проверка среды Xcode:

Тип: COMMAND_STDOUT.

Успешный индекс: Xcode 11.

Скрипт: вывод версии Xcode: xcodebuild -version.

Проверка среды OCLint:

Тип: COMMAND_STDOUT.

Успешный индекс: OCLint version 0.13.

Скрипт: вывод версии OCLint: oclint -version.

Проверка среды xcpretty:

Тип: COMMAND_STDOUT.

Успешный индекс: 0.3.0.

Скрипт: вывод версии xcpretty: xcpretty -v.

Привязка параметров сборки:

Тип: BUILD_PARAMETER_DROP_DOWN_MENU.

Имя шага: развёртывание.

Параметр имени: deploy-choice.

Получение прав доступа к связке ключей:

Тип: COMMAND_STATUS_WITH_CREDENTIALS.

Идентификатор учётных данных: iOS_admin_passwd.

Сценарий: получение прав доступа: cd ${PROJECT_PATH};security set-key-partition-list -S apple-tool:,apple: -s -k $password login.keychain. Выполнение JUnit плагина:

Тип: JUNIT_PLUG_IN.

JunitReportPath: «/${PROJECT_DIR}//build/reports/.xml*».**

Анализ юнит-тестов покрытия:

Тип: LLVM_COV_COVERAGE_ANALYSIS.

XcodePathScript: «Xcode-select --print-path».

llvm-covCommand: «/Toolchains/XcodeDefault.xctoolchain/usr/bin/llvm-cov export -format=text --summary-only -instr-profile».

XcodeBuildLogPath: «${PROJECT_PATH}/xcodebuild.log».

TestDeviceID: «${TestDeviceID}».

APPName: «${ProjectName}».

FileNameContains: «Presenter».

Functions: 100.

Instantiations: 0.

Lines: 95.

Regions: 95.

Код проверки:

Очистка и подготовка данных:

Тип: COMMAND_STATUS.

Скрипт: * Очистка build каталога: «cd ${PROJECT_PATH};rm -rf build». * Xcode сборка очистки: «cd ${PROJECT_PATH}; xcodebuild clean». * Удаление файлов: «cd ${PROJECT_PATH};rm -rf compile_commands.json;rm -rf xcodebuild.log;rm -rf compile_commands.json;rm -rf sonar-reports». * Создание каталога: «cd ${PROJECT_PATH};mkdir sonar-reports». * Сбор и форматирование xcodebuild журнала: «export LC_ALL=en_US.UTF-8;cd ${PROJECT_PATH}; xcodebuild -scheme ${ProjectName} -workspace ${ProjectName}.xcworkspace -configuration Release clean build | tee xcodebuild.log | xcpretty -r json-compilation-database --output compile_commands.json». * Обработка OLint: «cd ${PROJECT_PATH}; oclint-json-compilation-database -- -max-priority-1 10000 -max-priority-2 10000 -max-priority-3 10000 -rc LONG_LINE=150 -report-type pmd -o ./sonar-reports/oclint.xml».

Выполнение SQ кода сканирования:

Тип: SONAR_QUBE.

Компиляция сборки:

Выполнение iOS сборки:

Тип: COMMAND_STATUS.

Переменная: * PlistPath: «${PROJECT_PATH}CICDTestApp.plist».

Скрипт: * Очистка сборки среды: «xcodebuild -workspace ${ProjectName}.xcworkspace -scheme CICD-ObjectC-Test clean». * Выполнение сборки: «cd ${PROJECT_PATH};xcodebuild -workspace ${ProjectName}.xcworkspace -scheme ${ProjectName} -configuration Debug -archivePath build/${ProjectName}.xcarchive archive». * Экспорт IPA: «cd ${PROJECT_PATH};xcodebuild -exportArchive -archivePath build/${ProjectName}.xcarchive -exportPath build -exportOptionsPlist ${PlistPath}».

Развёртывание:

Имитация развёртывания сценария — 1:

Тип: COMMAND_STATUS.

Сценарий: * Копирование файла: «echo имитация копирования файла».

Имитация развёртывания сценария — 2:

Тип: COMMAND_STATUS.

Сценарий: * HTTP передача файла: «echo HTTP передача файла». ``` "Script": { "Запуск юнит-тестов": "cd ${PROJECT_PATH}\\ && MSBuild My.msbuild /t:GenerateCoverageHtmlReport", }, "Анализ покрытия юнит-теста": { "Type": "MSBUILD_COVERAGE_ANALYSIS", "ReportDir": "${PROJECT_PATH}\Cover\", "Lines": "0" }, }, "Код-чек": { "Выполнение SQ-кода сканирования": { "Type": "SONAR_QUBE", "Variable": { "project_key": "Jenkins:WinBuild", "project_name": "Jenkins:WinBuild", "project_version": "1.0" }, "ReportTaskPath": "${PROJECT_PATH}\\.sonarqube\out\\.sonar\report-task.txt", "?ScannerScript": "SonarScanner с журнальными параметрами /d:sonar.verbose=true", "ScannerScript": "cd ${PROJECT_PATH}\ && SonarScanner.MSBuild.exe begin /k:"${project_key}" /n:"${project_name}" /v:"${project_version}" && "${MSBuildBinDir}\MSBuild.exe" /t:Rebuild /p:VisualStudioVersion=12.0 && SonarScanner.MSBuild.exe end", "Gate": "NONE" }, }, "Развёртывание": { "Имитация сценария развёртывания - 1": { "Type": "COMMAND_STATUS", "Script": { "Копирование файлов": "echo имитация копирования файлов" } }, "Имитация сценария развёртывания - 2": { "Type": "COMMAND_STATUS", "Script": { "HTTP-передача файлов": "echo HTTP-передача файлов" } } }


Сначала строится проект .NET, используя инструмент MSBuild, который имеет собственную конфигурацию сборки. Пример конфигурации инструмента MSBuild можно найти в файле My.msbuild на GitHub. Этот файл определяет большую часть процесса сборки.

Тип узла MSBUILD_COVERAGE_ANALYSIS используется для создания отчётов о покрытии юнит-тестами на основе результатов сборки с помощью MSBuild. В настоящее время он может рассчитывать только покрытие кода по строкам. Также необходимо настроить свойства узла SonarQube сканирования кода в соответствии с операционной системой, так как команды для Windows и Linux различаются.

## Сборка нескольких подпроектов

Пример проекта для сборки нескольких подпроектов можно найти на GitHub.

Сборка нескольких подпроектов может быть полезна для проектов типа микросервисов, где один репозиторий содержит несколько независимых подпроектов, или для проектов с передним и задним концами в одном репозитории, например, серверный проект на Java и клиентский проект на JavaScript.

Файлы Jenkinsfile и json для конфигурации сборки не отличаются друг от друга, разница лишь в уровне каталогов, в которых они хранятся:

!

Плагин Custom Checkbox Parameter Plugin позволяет удобно выбирать подпроекты для сборки.

## Обработка успешных и неудачных сборок

В декларативном синтаксисе Jenkinsfile можно обрабатывать успешные и неудачные сборки в разделе post. Пример проекта можно найти на GitHub.

### Необходимые плагины Jenkins

* Email Extension Template
* Rich Text Publisher

### Пример обработки сбоя сборки

Вот пример решения для обработки сбоя сборки:

```groovy
@Library('shared-library') _

pipeline {
  agent any
  stages {
    stage('Обработка процесса 1') {
      steps {
        script{
          Exception ex
          runWrapper.loadJSON('/jenkins-project.json')
          }
        }
      }
    stage('Обработка процесса 2') {
      steps {
        script{
          println('Обработка процесса 2')
          try{
              throw new Exception('имитация исключения')
          }catch(Exception e){
              ex = e
              throw e
          }
        }
      }
    }
    stage('Обработка процесса 3') {
      steps {
        script{
          println('Обработка процесса 3')
          }
        }
      }
    }
  post {
    failure {
      script{
        runWrapper.postFailure(ex)
      }
    }
    success{
      script{
        runWrapper.postSuccess()
      }
    }
  }
}

Объяснение:

Метод runWrapper.postFailure (ex) обрабатывает сбой сборки, а метод runWrapper.postSuccess () обрабатывает успешную сборку. Оба метода отправляют электронные письма, адреса получателей и копии которых задаются в файле конфигурации json:

{
  "GlobalVariable": {
    "Email-TO": "sunweisheng@live.cn",
    "Email-CC": "sunweisheng@live.cn"
  }
}

Определённые в GlobalVariable адреса Email-TO (получатель) и Email-CC (копия) используются при отправке электронных писем. Если есть несколько получателей или копий, они разделяются знаком «,».

Создание Pod в K8S для сборки

Пример проекта можно найти на GitHub.

Этот подход заключается в создании временного Pod внутри кластера Kubernetes, который становится агентом Jenkins для сборки. После завершения сборки и развёртывания Pod удаляется Kubernetes. Для этого требуется настроить среду использования Jenkins в Kubernetes:

  • Использование плагина Jenkins для Kubernetes
  • Реализация Docker in Docker в Pod и использование kubectl для развёртывания
  • Пример файла конфигурации Kubernetes

Плагины Jenkins, необходимые для использования

Kubernetes plugin for Jenkins

Шаблоны Pod и Jenkinsfile

Это перевод исходного текста. Он может содержать неточности или ошибки. В запросе используется язык Groovy.

Текст запроса в переводе на русский язык:

В корневом каталоге репозитория необходимо создать файл KubernetesPod.yaml (шаблон Pod), где образ Docker должен соответствовать требованиям к сборке проекта, например, установлена Java, Maven и т. д. Пример:

apiVersion: "v1"
kind: "Pod"
metadata:
spec:
  containers:
    - name: "docker-build"
      image: "repo.bluersw.com:8083/bluersw/centos-7-docker-kubectl:2.0"
      command:
        - "cat"
      tty: true
      volumeMounts:
        - mountPath: "/etc/docker/daemon.json"
          name: "volume-0"
          readOnly: false
        - mountPath: "/root/.docker/config.json"
          name: "volume-1"
          readOnly: false
        - mountPath: "/var/lib/kubelet/pki"
          name: "volume-2"
          readOnly: false
        - mountPath: "/var/run/docker.sock"
          name: "volume-3"
          readOnly: false
        - mountPath: "/root/.kube"
          name: "volume-4"
          readOnly: false
      workingDir: "/home/jenkins/agent"
  securityContext:
    runAsGroup: 0
    runAsUser: 0
  volumes:
    - hostPath:
        path: "/etc/docker/daemon.json"
      name: "volume-0"
    - hostPath:
        path: "/root/.docker/config.json"
      name: "volume-1"
    - hostPath:
        path: "/var/lib/kubelet/pki"
      name: "volume-2"
    - hostPath:
        path: "/var/run/docker.sock"
      name: "volume-3"
    - hostPath:
        path: "/root/.kube"
      name: "volume-4"

Для реализации Docker In Docker и использования команды kubectl для развёртывания ресурсов K8S в Pod, было смонтировано множество каталогов.

Файл yaml будет загружен из Jenkinsfile для создания временного Pod в процессе сборки проекта:
```groovy
@Library('shared-library') _

pipeline {
  agent {
    kubernetes {
      yamlFile 'KubernetesPod.yaml'
    }
  }
  stages {
    stage('初始化') {
      steps {
        container('jnlp') {
          println('jnlp:' + pwd())
        }
        container('docker-build'){
          script{
            runWrapper.loadJSON('/jenkins-project.json')
            runWrapper.runSteps('初始化')
            runWrapper.printEnvVars()
          }
        }
      }
    }
    stage('单元测试') {
      steps {
        container('docker-build'){
          script{
            runWrapper.runSteps('单元测试')
          }
        }
      }
    }
    stage('代码检查') {
      steps {
        container('docker-build'){
          script{
            runWrapper.runSteps('代码检查')
          }
        }
      }
    }
    stage('编译构建') {
      steps {
        container('docker-build'){
          script{
            runWrapper.runSteps('编译构建')
          }
        }
      }
    }
    stage('部署') {
      steps {
        container('docker-build'){
          script{
            runWrapper.runSteps('部署')
          }
        }
      }
    }
  }
}

Примечание:

  • container используется для переключения между различными средами контейнеров (в одном Pod может быть несколько контейнеров, как и в Docker), но рабочий каталог остаётся неизменным;
  • container('jnlp') — это контейнер, который Jenkins использует для выполнения программы Agent и программы Git, он автоматически создаётся Jenkins;
  • container('docker-build') — это пользовательский контейнер, определённый в KubernetesPod.yaml.

Минимальный скрипт сборки

Если шаги сборки в файле конфигурации json проекта организованы следующим образом: инициализация, юнит-тестирование, проверка кода, компиляция и сборка, развёртывание, то можно максимально упростить скрипт сборки Jenkinsfile:

  • Для выполнения однопроектной сборки с использованием сервера агента Jenkins:
@Library('shared-library') _

agentServer()
  • Для многопроектной сборки с использованием сервера агента Jenkins:
@Library('shared-library') _

agentServer(projectURL: 'URL-адрес списка дочерних проектов в формате yaml или json')
  • Для однопроектной сборки с использованием Pod в кластере Kubernetes (при наличии файла KubernetesPod.yaml в корневом каталоге):
@Library('shared-library') _

k8sCluster()
  • Для многопроектной сборки с использованием Pod в кластере Kubernetes (при наличии файла KubernetesPod.yaml в корневом каталоге):
@Library('shared-library') _

k8sCluster(projectURL: 'URL-адрес списка дочерних проектов в формате yaml или json')

Все эти методы скрывают один параметр замыкания, который представляет собой процесс обработки после успешного завершения. Можно настроить некоторые действия после успешной сборки, такие как использование git для добавления тегов. Например:

@Library('shared-library') _

k8sCluster(projectURL: 'http://xyz.com/project-list.yaml',{
    it.runSteps('Добавить тег')
})

Из-за проблемы https://issues.jenkins-ci.org/browse/JENKINS-56943 в проекте используется плагин Git Parameter, и при использовании кластера K8S для сборки нельзя использовать метод File для загрузки шаблона Pod. Необходимо напрямую загрузить содержимое шаблона Pod, например:

@Library('shared-library') _

k8sCluster(podTemplate: 
"""
apiVersion: "v1"
kind: "Pod"
metadata:
spec:
  containers:
    - name: "docker-build"
      image: "repo.bluersw.com:8083/bluersw/centos-7-docker-kubectl:2.0"
      command:
        - "cat"
      tty: true
      volumeMounts:
        - mountPath: "/etc/docker/daemon.json"
          name: "volume-0"
          readOnly: false
        - mountPath: "/root/.docker/config.json"
          name:
``` Эти методы все определены в каталоге vars общей библиотеки, и их можно модифицировать по мере необходимости.

## Другие настройки

### Отображение переменных среды Jenkins

В Jenkinsfile можно выполнить `runWrapper.printEnvVars()`, чтобы вывести распознаваемые переменные среды Jenkins:

```groovy
runWrapper.printEnvVars()

Вывод информации журнала при загрузке файла конфигурации JSON

Добавьте узел LogLevel в узел GlobalVariable, где содержимое узла LogLevel может быть DEBUG, INFO, WARNING или ERROR, причём DEBUG обеспечивает наиболее полное ведение журнала.

"GlobalVariable": {
  "LogLevel": "DEBUG"
}

Чтобы вывести журнал загрузки файла JSON, в Jenkinsfile выполните метод runWrapper.printLoadFactoryLog():

runWrapper.printLoadFactoryLog()

Кодировка файла конфигурации JSON

Используйте кодировку UTF-8 для файлов конфигурации JSON.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/beijing-guangyu-online-jenkins-json-build.git
git@api.gitlife.ru:oschina-mirror/beijing-guangyu-online-jenkins-json-build.git
oschina-mirror
beijing-guangyu-online-jenkins-json-build
beijing-guangyu-online-jenkins-json-build
master