«1. Обзор

В этом руководстве мы рассмотрим процесс непрерывной интеграции/непрерывного развертывания (CI/CD) и реализуем его основные части.

Мы создадим простое приложение Spring Boot, а затем отправим его в общий репозиторий Git. После этого мы создадим его с помощью службы интеграции зданий, создадим образ Docker и отправим его в репозиторий Docker.

В конце мы автоматически развернем наше приложение в сервисе PaaS (Heroku).

2. Контроль версий

Важнейшей частью CI/CD является система контроля версий для управления нашим кодом. Кроме того, нам нужна служба хостинга репозитория, с которой будут связаны наши этапы сборки и развертывания.

Давайте выберем Git в качестве VCS и GitHub в качестве нашего поставщика репозитория, поскольку они наиболее популярны на данный момент и бесплатны для использования.

Во-первых, нам нужно создать учетную запись на GitHub.

Кроме того, мы должны создать репозиторий Git. Назовем его baeldung-ci-cd-process. Кроме того, давайте выберем общедоступный репозиторий, так как он позволит нам получить доступ к другим сервисам бесплатно. Наконец, давайте инициализируем наш репозиторий файлом README.md.

Теперь, когда наш репозиторий создан, мы должны локально клонировать наш проект. Для этого давайте выполним эту команду на нашем локальном компьютере:

git clone https://github.com/$USERNAME/baeldung-ci-cd-process.git

Это инициализирует наш проект в каталоге, где мы выполнили команду. На данный момент он должен содержать только файл README.md.

3. Создание приложения

В этом разделе мы создадим простое приложение Spring Boot, которое будет участвовать в процессе. Мы также будем использовать Maven в качестве инструмента сборки.

Во-первых, давайте инициализируем наш проект в каталоге, где мы клонировали репозиторий контроля версий.

Например, мы можем сделать это с помощью Spring Initializer, добавив веб-модули и модули привода.

3.1. Создание приложения вручную

Или мы можем вручную добавить зависимости spring-boot-starter-web и spring-boot-starter-actuator:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Первый — ввести конечную точку REST, а второй — конечная точка проверки работоспособности.

Кроме того, давайте добавим плагин, который позволит нам запускать наше приложение:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

И, наконец, добавим основной класс Spring Boot:

@SpringBootApplication
public class CiCdApplication {

    public static void main(String[] args) {
        SpringApplication.run(CiCdApplication.class, args);
    }
}

3.2. Отправка

Будь то использование Spring Initializr или создание проекта вручную, теперь мы готовы зафиксировать и отправить наши изменения в наш репозиторий.

Давайте сделаем это с помощью следующих команд:

git add .
git commit -m 'Initialize application'
git push

Теперь мы можем проверить, существуют ли наши изменения в репозитории.

4. Автоматизация сборки

Другая часть процесса CI/CD — это сервис, который будет собирать и тестировать наш проталкиваемый код.

Здесь мы будем использовать Travis CI, но подойдет и любой строительный сервис.

4.1. Maven Wrapper

Давайте начнем с добавления Maven Wrapper в наше приложение. Если мы использовали Spring Initializr, мы можем пропустить эту часть, так как она включена по умолчанию.

В каталоге приложения выполните:

mvn -N io.takari:maven:0.7.7:wrapper

Это добавит файлы-оболочки Maven, включая файлы mvnw и mvnw.cmd, которые можно использовать вместо Maven.

Хотя у Travis CI есть собственный Maven, у других строительных служб может и не быть. Эта Maven Wrapper поможет нам быть готовыми к любой ситуации. Кроме того, разработчикам не нужно будет устанавливать Maven на свои машины.

4.2. Building Service

После этого давайте создадим учетную запись на Travis CI, выполнив вход с помощью нашей учетной записи GitHub. В дальнейшем мы должны разрешить доступ к нашему проекту в GitHub.

Далее нам нужно создать файл .travis.yml, который будет описывать процесс сборки в Travis CI. Большинство сервисов сборки позволяют нам создать такой файл, который находится в корне нашего репозитория.

В нашем случае давайте скажем Трэвису использовать Java 11 и Maven Wrapper для сборки нашего приложения:

language: java
jdk:
  - openjdk11
script:
  - ./mvnw clean install

Свойство языка указывает, что мы хотим использовать Java.

Свойство jdk указывает, какой образ Docker нужно загрузить с DockerHub, в данном случае openjdk11.

Свойство сценария говорит, какую команду запускать — мы хотим использовать нашу оболочку Maven.

Наконец, мы должны отправить наши изменения в репозиторий. Travis CI должен автоматически запускать сборку.

«5. Докеризация

В этом разделе мы создадим образ Docker с нашим приложением и разместим его на DockerHub как часть процесса компакт-диска. Это позволит нам с легкостью запускать его на любой машине.

5.1. Репозиторий для образов Docker

Во-первых, мы должны создать репозиторий Docker для наших образов.

Давайте создадим учетную запись на DockerHub. Также создадим репозиторий для нашего проекта, заполнив соответствующие поля:

    имя: baeldung-ci-cd-process visibility: Public Настройка сборки: GitHub

5.2. Образ Docker

Теперь мы готовы создать образ Docker и отправить его на DockerHub.

Во-первых, давайте добавим jib-maven-plugin, который будет создавать и отправлять наш образ с приложением в репозиторий Docker (замените DockerHubUsername на правильное имя пользователя):

<profile>
    <id>deploy-docker</id>
    <properties>
        <maven.deploy.skip>true</maven.deploy.skip>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>2.2.0</version>
                <configuration>
                    <to>
                        <image>${DockerHubUsername}/baeldung-ci-cd-process</image>
                        <tags>
                            <tag>${project.version}</tag>
                            <tag>latest</tag>
                        </tags>
                    </to>
                </configuration>
            </plugin>
        </plugins>
    </build>
</profile>

Мы добавили его как часть Профиль Maven, чтобы не запускать его со сборкой по умолчанию.

Кроме того, мы указали два тега для изображения. Чтобы узнать больше о плагине, посетите нашу статью о Jib.

Забегая вперед, давайте изменим наш файл сборки (.travis.yml):

before_install:
  - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
  - docker pull openjdk:11-jre-slim-sid

script:
  - ./mvnw clean install
  - ./mvnw deploy jib:build -P deploy-docker

С этими изменениями служба сборки будет входить в DockerHub перед сборкой приложения. Кроме того, он выполнит фазу развертывания с нашим профилем. На этом этапе наше приложение будет отправлено в виде образа в репозиторий Docker.

Наконец, мы должны определить переменные DOCKER_PASSWORD и DOCKER_USERNAME в нашей службе сборки. В Travis CI эти переменные можно определить как часть настроек сборки.

Теперь давайте отправим наши изменения в VCS. Служба сборки должна автоматически запускать сборку с нашими изменениями.

Мы можем проверить, был ли образ Docker отправлен в репозиторий, запустив локально:

docker run -p 8080:8080 -t $DOCKER_USERNAME/baeldung-ci-cd-process

Теперь мы должны получить доступ к нашей проверке работоспособности, зайдя на http://localhost:8080/actuator/health. .

6. Анализ кода

Следующее, что мы включим в процесс CI/CD, — это статический анализ кода. Основная цель такого процесса — обеспечить максимальное качество кода. Например, он может обнаружить, что у нас недостаточно тестовых случаев или что у нас есть проблемы с безопасностью.

Давайте интегрируемся с CodeCov, который будет информировать нас о нашем тестовом покрытии.

Во-первых, мы должны войти в CodeCov с нашим профилем GitHub, чтобы установить интеграцию.

Во-вторых, мы должны внести изменения в наш код. Начнем с добавления плагина jacoco:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.5</version>
    <executions>
        <execution>
            <id>default-prepare-agent</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Плагин отвечает за создание тестовых отчетов, которые будут использоваться CodeCov.

Затем мы должны настроить раздел script в нашем файле службы сборки (.travis.yml):

script:
  - ./mvnw clean org.jacoco:jacoco-maven-plugin:prepare-agent install
  - ./mvnw deploy jib:build -P deploy-docker

after_success:
  - bash <(curl -s https://codecov.io/bash)

Мы проинструктировали подключаемый модуль jacoco срабатывать на этапе чистой установки. Кроме того, мы включили раздел after_success, который отправит отчет в CodeCov после успешной сборки.

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

@SpringBootTest
class CiCdApplicationIntegrationTest {

    @Test
    public void contextLoads() {

    }
}

Наконец, мы должны отправить наши изменения. Сборка должна быть запущена, и отчет должен быть сгенерирован в нашем профиле CodeCov, связанном с репозиторием.

7. Развертывание приложения

В качестве последней части нашего процесса мы развернем наше приложение. Имея образ Docker, доступный для использования, мы можем развернуть его на любом сервисе. Например, мы могли бы развернуть его на облачной платформе PaaS или IaaS.

Давайте развернем наше приложение на Heroku, который представляет собой PaaS, требующий минимальной настройки.

Сначала мы должны создать учетную запись, а затем войти в нее.

Далее давайте создадим пространство приложения в Heroku и назовем его baeldung-ci-cd-process. Имя приложения должно быть уникальным, поэтому нам может понадобиться использовать другое.

Мы развернем его, интегрировав Heroku с GitHub, так как это самое простое решение. Однако мы могли бы также написать конвейер, который будет использовать наш образ Docker.

В будущем мы должны включить плагин heroku в наш pom:

<profile>
    <id>deploy-heroku</id>
    <properties>
        <maven.deploy.skip>true</maven.deploy.skip>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>com.heroku.sdk</groupId>
                <artifactId>heroku-maven-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <appName>spring-boot-ci-cd</appName>
                    <processTypes>
                        <web>java $JAVA_OPTS -jar -Dserver.port=$PORT target/${project.build.finalName}.jar</web>
                    </processTypes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</profile>

Как и в случае с Docker, мы добавили его как часть профиля Maven. Кроме того, мы включили команду запуска в веб-раздел.

«Затем мы должны настроить наш файл службы сборки (.travis.yml), чтобы также развернуть приложение на Heroku:

script:
  - ./mvnw clean install
  - ./mvnw heroku:deploy jib:build -P deploy-heroku,deploy-docker

Кроме того, давайте добавим API-KEY Heroku в переменную HEROKU_API_KEY в нашей службе сборки.

Наконец, давайте зафиксируем наши изменения. Приложение должно быть развернуто в Heroku после завершения сборки.

Мы можем проверить это, зайдя на https://baeldung-ci-cd-process.herokuapp.com/actuator/health

8. Заключение

В этой статье мы узнали, какие основные части процессы CI/CD и как их подготовить.

Сначала мы подготовили Git-репозиторий на GitHub и отправили туда наше приложение. Затем мы использовали Travis CI в качестве инструмента сборки для сборки нашего приложения из этого репозитория.

После этого мы создали образ Docker и отправили его на DockerHub.

Далее мы добавили сервис, отвечающий за статический анализ кода.

Наконец, мы развернули наше приложение в PaaS и получили к нему доступ.

Как всегда, код этих примеров доступен на GitHub.