Разработка первого приложения с использованием программного компонента#

Оглавление#

Настройка конфигурационных файлов в Jenkins#

Создание конфигурационного файла производится с помощью функции Jenkins, которая называется Config Files:

  1. В созданной области (папке) Jenkins перейти в Config Files → нажать на Add a new Config.

  2. Выбрать Type конфигурационного файла.

  3. В ID записать идентификатор, который затем будет указываться в файле *pipeline.yml. После чего нажать Submit.

  4. Заполнить content для определнного типа конфигурационного файла.

Пример создания settings.xml#

Чтобы создать settings.xml, необходимо:

  1. В качестве Type для создания нового конфигурационного файла выбрать Maven settings.xml.

  2. Указать ID конфигурационного файла, например - maven-settings.

  3. В поле **content необходимо добавить содержимое settings.xml (того, что используется для сборки артефактов), но без раздела servers (об этом далее).

  4. Раздел servers в settings.xml заполняется в Jenkins с использованием credentials. Для их добавления необходимо воспользоваться кнопкой Add - следует указать корректные serverId, чтобы они совпадали с ID подключаемых репозиториев.

Для загрузки дистрибутива во внешний репозиторий, определенный разделом distribution в pipeline.yml, необходимо заполнить соответствующие serverId в settings.xml (см. п.4) с правами на запись

Пример заполнения settings.xml:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">    
  <mirrors>
    <mirror>
      <id>central</id>
      <name>Mirror of public repositories</name>
      <url>https://nexus.mycompany.com/nexus/content/repositories/mirror-central</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>

    <profiles>
        <profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <repositories>
                <repository>
                    <id>cdp</id>
                    <name>distribution repo</name>
                    <url>https://nexus.mycompany.com/nexus/content/repositories/distribution</url>
                </repository>
            </repositories>
        </profile>
    </profiles>
            
</settings>

Пример создания .npmrc#

Чтобы создать .npmrc, необходимо:

  1. В качестве Type для создания нового конфигурационного файла выбрать Npm config file.

  2. Указать ID конфигурационного файла, например - npmrc.

  3. В поле **content необходимо добавить содержимое .npmrc вашего проекта.

Пример заполнения .npmrc:

//registry.host/path/to/repo/npm/:_authToken=<authToken> ; BASE64_STRING это строка из профиля пользователя. Инструкция по получению ниже
registry=https://registry.host/path/to/repo/npm/
audit=false
always-auth=true
fetch-retries=5
cafile=/local path/ca_root.pem ; Необходимо для проверки отношений доверия ресурсам, если сертификата нет, можно отключить проверку. Инструкция по получению находится ниже
strict-ssl=false ; Отключение проверки сертификата при ошибках доверия
save-exact=true ; Опционально для сохранения в package.json версии скачанного пакета (до максимально доступной патч версии(без ^))

Создание Jenkins job#

Перед созданием Jenkins job должны быть выполнены шаги из раздела Системные требования, а также сформирован файл pipeline.yml.
Для создания Jenkins job сборки необходимо в используемом пространстве (папке) Jenkins выбрать → New Item → указать имя Jenkins job и указать тип Pipeline.
После чего откроется страница настроек.

Ниже описаны необходимые настройки:

  • Раздел Pipeline → Definition : Pipeline script from SCM.

  • Pipeline → SCM : Git.

  • Pipeline → SCM → Repositories → Repository URL : ssh://git@<...>/ufs-pipeline.git (ssh-адрес репозитория ufs-pipeline).

  • Pipeline → SCM → Repositories → Credentials : Используйте SSH credentials используемой ТУЗ.

  • Pipeline → SCM → Branches to build → Branch Specifier (blank for „any“) : master.

если требуется использование какой-либо конкретной версии библиотеки, можно использотовать соответствующий тег, например: tags/1.4.1-*

  • Pipeline → Script Path → pipeline.groovy.

  • Lightweight checkout → true.

    Создание Jenkins job сборки

После сохранения Jenkins job появится возможность его запуска.

Первичная настройка Jenkins job#

В большинстве случаев какая-либо специальная настройка параметров Jenkins job не требуется. Все необходимые параметры будут добавлены в Jenkins job при первом запуске:

  • PLAYBOOKS - сценарии запуска. Более подробно описано ниже.

  • CONFIG_REPO - репозиторий с конфигурацией - тот, в котором хранится pipeline.yml, а также остальные конфигурационные файлы.

  • CONFIG_BRANCH - ветка репозитория с конфигурацией.

  • EMAIL_LIST - список рассылки, для уведомлений о сборках.

В разделе Настройка Jenkins job приведен список настроек, которые могут быть использованы при настройке Jenkins job.

Подключение библиотеки без DPMPipelineUtils#

Существует также и другой вариант подключения библиотеки.

Для этого необходимо выбрать для Pipeline definition вариант Pipeline script.

После чего, в окне кода ввести следующие строки:

def creds = 'ssh-tuz' // Используйте ssh credentials вашего ТУЗа
def gitUrl = 'ssh://<...>/ufs-pipeline.git'
def branch = 'master'

def scm = [
    $class: 'GitSCM', 
    branches: [[name: branch]], 
    userRemoteConfigs: [[
        credentialsId: creds, 
        url: gitUrl
        ]]
    ]

library identifier: "ufs-pipeline@$branch", retriever: legacySCM(scm)

ansiColor('xterm') {
    runPipeline(scm)
}

Детали настройки статического анализа кода#

Настройка SonarQube для проектов Development Pipeline#

Подготовка к работе#

Для подготовки SonarQube к работе необходимо выполнить следующие действия:

  1. Получить доступ к SonarQube.

  2. Создать проектную область с помощью Jenkins:

    • Область в SonarQube (PROJECT_KEY) для maven проектов рекомендуется создавать по GroupId:ArtifactId.

  3. Организовать доступ участников к проектной области.

  4. Осуществить настройку анализа.

  5. Осуществить настройку в файлах settings.xml, pom.xml.

  6. Настроить SonarQube для PR.

Для получения доступа необходимо выполнить вход в SonarQube. В таком случае используемая для входа учетная запись будет добавлена в SonarQube, после чего ее можно будет добавить в администраторы проекта при создании посредством Jenkins job

Настройка анализа при сборке дистрибутива#

При подготовке к сканированию следует также добавить в свой проект Jenkins credential c типом (Kind) - Secret text. Его идентификатор нужно указать в pipeline.yml в разделе Настройка инструментов сборки SonarQube

Для анализа в SonarQube используемые параметры в файле pipeline.yml: sonarSkip, sonarPomConfigured.

  • sonarSkip – необязательный параметр, по-умолчанию: false. Значение true указывается для модулей, не попадающих в пром и не требующих прохождения QG (например envelope ear для развертывания jar на тестовые стенды).

  • sonarPomConfigured – необязательный параметр, по-умолчанию: false. Значение true указывается для запуска проверки SonarQube QG, достаточно выполнить sonar:sonar.

Внимание

Если не указаны параметры sonarPomConfigured: true, либо sonar.projectKey в properties в файле pom.xml, то в качестве sonar.projectKey прописывается название репозитория. Таким образом подключение к SonarQube будет выполнено с названием репозитория. Если проект в сонаре был создан с GroupId:ArtifactId, то Jenkins job не увидит проект в SonarQube без параметров sonarPomConfigured: true, либо sonar.projectKey.

В файле pipeline.yml в разделе bh можно указать следующую настройку - sonar: {mainBranch: 'master'}. По умолчанию defaultbranch - develop. Эта настройка необходима, если defaultBranch отличается.

bh:
- name: "bh-app-1"
  repo: "project/bh-app-1.git"
  branch: "release/pir1024"
  sonar: {mainBranch: 'master'}
  cmd: "clean test"
  outputs: 
  - "./bh-app-1-ear/target/*.ear"
    

В параметрах Jenkins job можно указать SONAR_DISABLED.

  • Если глобально необходимо пропустить SonarQube, то можно указать параметр SONAR_DISABLED, также данный параметр выключает ожидание ответа от сонара.

    Внимание

    В случае с параметром SONAR_DISABLED у сборки не появится флаг ci_ok, а следовательно, она не попадет на ПСИ.

Также существует возможность установить собственную настройку SonarQube с помощью параметра sonar_cmd в файле pipeline.yml в блоке bh.

Например: sonar_cmd: "sonar:sonar -Dsonar.login=token -Dsonar.branch.name=ufs-pipieline-test". Данная строка полностью будет воспроизведена при запуске Pipeline, как есть. Другие параметры будут взяты из файла pom.xml/settings.xml. В параметре Jenkins job можно указать версию JDK для анализа в сонаре через строковый параметр SONAR_JDK. По умолчанию используется версия JDK_1.8_121_Linux.

Настройки в settings.xml, pom.xml#

В файле settings.xml можно указать:

<settings>
    <profile>
        <id>sonar</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
            <sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
    </profile>
</settings>

Для первоначального анализа проекта необходимо выполнить запуск на master ветке. Для этих целей можно создать тестовый Jenkins job с типом Pipeline, либо запустить из командной строки с указанием своих данных. В случае если была проведена настройка в файлах pom.xml, settings.xml, то в Jenkins job достаточно mvn sonar:sonar:

mvn sonar:sonar -Dsonar.host.url=https://sonar.example/sonar -Dsonar.login=SONAR_TOKEN -Dsonar.projectName=ProjectName

В файле pom.xml указываются следующие данные:

  • sonar.projectKey

Мультимодульные проекты – это проекты, выделяемые в том случае, когда в головном файле pom.xml указывается несколько модулей в разделе modules, например:

    <modules>
        <module>name-exchange-bh</module>
        <module>name-exchange-war</module>
        <module>name-exchange-ear</module>
    </modules>

Для мультимодульных проектов лучшее решение – использовать проект с ключом groupId:artifactId.

  <properties>
  <sonar.java.source>1.8</sonar.java.source>
  <sonar.projectKey>${project.artifactId}</sonar.projectKey>
  <sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
  <sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
</properties>

В случае с многомодульными проектами Maven возможно возникновение рекурсии и переполнение стека с ошибкой StackOverflowError. Причиной ошибки может быть установленное в корневом POM свойство <sonar.projectKey>projectKey</sonar.projectKey>.
При WorkDirectoriesInitializer.cleanAllWorkingDirs рекурсии по проекту вычисляется ключ для каждого модуля, однако это происходит путем чтения свойства sonar.projectKey. Поскольку это одинаковое значение для каждого модуля, рекурсия никогда не завершается и стек переполняется.

Исправление заключается в добавлении <sonar.moduleKey>${project.artifactId}</sonar.moduleKey> к корневому POM, который оценивает разные значения для каждого подмодуля и, таким образом, позволяет завершить рекурсию.
В этом случае можно указать sonar.projectKey в виде ${project.groupId}:${project.artifactId}:

   <properties>
   <sonar.java.source>1.8</sonar.java.source>
   <sonar.projectKey>${project.groupId}:${project.artifactId}</sonar.projectKey>
   <sonar.moduleKey>${project.artifactId}</sonar.moduleKey>
   <sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
   <sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
   </properties>

Для не мультимодульных проектов запись осуществляется в виде – <sonar.projectKey>${project.groupId}:${project.artifactId}</sonar.projectKey>, либо можно указать sonarPomConfigured: true в файле pipeline.yml для каждого репозитория bh.

<properties>
  <sonar.java.source>1.8</sonar.java.source>
  <sonar.projectKey>${project.artifactId}</sonar.projectKey>
  <sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
  <sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
</properties>

Область в сонаре (PROJECT_KEY) необходимо создавать по GroupId:ArtifactId.

Если данные для проекта явно не указаны в файле settings.xml, то они берутся из корневого файла pom.xml. Ключ проекта будет сформирован как groupId:artefactId. В случае не указывания данных в pom.xml ключ по умолчанию будет формироваться с названием репозитория, т.е. область в SonarQube ищется по названию репозитория в bh.
Ключ проекта может быть указан непосредственно в файле settings.xml с помощью параметра sonar.projectKey (однако это не работает для многомодульных проектов, поскольку будет собран только первый POM).

Также Maven можно вызывать с параметрами, добавив при этом собственные данные в sonar-project.properties:

sonar.projectKey=
sonar.projectName=
sonar.projectVersion=${project.version}
sonar.sources=*/src
sonar.language=java
sonar.sourceEncoding=UTF-8
sonar.java.binaries=*/target/classes
sonar.locale=ru_RU

Настройка SonarQube для PR#

Maven может также быть вызван с параметрами при добавлении собственных данных в Properties:

sonar.projectKey=
maven.compiler.sources=
maven.compiler.target=
sonar.branch.name=${PULL_REQUEST_FROM_BRANCH}
sonar.branch.target=${PULL_REQUEST_TO_BRANCH}
sonar.login=$SONAR_TOKEN
sonar.host.url=https://<domain>-sonarqube.example.ru

Настройки, которые при этом необходимо указать в файле settings.xml:

<profile>
    <id>sonar</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <sonar.host.url>${env.SONAR_HOST_URL}</sonar.host.url>
        <sonar.login>${env.SONAR_AUTH_TOKEN}</sonar.login>
    </properties>
</profile>

Настройка SonarQube в общем случае#

Пример настройки SonarQube. Подробнее о том, как задать значение tool name, можно прочитать в разделе Поиск инструментов сборки.

def onDistrib(app, distr) {
  nodejs(configId: 'test.app.npmrc', nodeJSInstallationName: 'v7.5.0-linux-x64') {
    sh 'npm ci'
    sh 'npm run build'
    withEnv(["PATH+SCANNER=${tool name: 'SonarQube_Scanner'}"]) {
      sh "sonar-scanner -Dsonar.host.url=${env.SONAR_HOST_URL} -Dsonar.login=${env.SONAR_AUTH_TOKEN} -Dsonar.projectKey=my-app"
    }
  }
}

return wrapJenkinsfile(this)