JavaRush /Java блог /Java-проекты /Пишем проект. Добавляем SpringBoot и настраиваем CI проце...
Roman Beekeeper
35 уровень

Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - "Java-проект от А до Я"

Статья из группы Java-проекты
Статья из серии о создании Java-проекта (ссылки на другие материалы — в конце). Ее цель — разбор ключевых технологий, итог — написание телеграм-бота. Приветствую вас, дорогие читатели. Как было описано в предыдущей части, будем идти по плану. Мы уже создали проект и пора его наполнять кодом. Теперь все issue будут добавляться отдельными коммитами. Все, что будет необходимо, я опишу здесь. Если что-то упущу или опишу недостаточно понятно — спрашивайте в комментариях, постараюсь ответить."Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 1

Пишем JRTB-0M

В этой задаче нам нужно добавить пустой SpringBoot каркас для будущей работы. Делать мы это будем так же, как и делали в статье о SpringBoot + Flyway. Качаем проект, открываем его в IDEA и создаем новую ветку с названием JRTB-0. Как это сделать через идею я описывал здесь. Так будет удобнее понятнее для нас в будущем для отслеживания работы. "Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 2Вы уже знали, что теперь нет master ветки? Теперь она называется нейтрально — main. Поэтому привыкаем. Хотя, по правде сказать, мы всегда можем переименовать ее обратно в мастер. Заходим на Spring Initializr и создаем SpringBoot каркас для нашего бота."Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 3На данный момент самая младшая предлагаемая версия спринта бута — 2.3.7, берем ее. Следующие настройки опишу отдельно:
  • Project: Maven Project — мы уже разобрали мавен здесь и здесь. Поэтому дополнительно буду описывать только то, что не раскрыл в предыдущих статьях. Если такие “белые пятна” будут, конечно)
  • Language: Java — здесь все понятно. Будет желание — можем переписать это дело на Kotlin. Я как раз прикупил себе книжонку Kotlin in Action, будем учить котлин вместе))
  • Spring Boot: 2.3.7 — берем самую меньшую из предложенных версий, чтобы исключить какие-либо проблемы. Это и так вполне современная версия бута.
Project Metadata:
  • Group: com.github.javarushcommunity — здесь выбираем домен, на котором хостится наша группа репозиториев.
  • Artifact: javarush-telegrambot — максимальное описание проекта.
  • Name: Javarush TelegramBot — здесь уже полностью напишем.
  • Description: Telegram bot for Javarush from community to community — здесь уже более детальное описание проекта.
  • Package name: com.github.javarushcommunity.jrtb — здесь уже можно использовать аббревиатуру для имени проекта. Теперь с этого пакета будет начинаться проект. Зачем так много? Для того, чтобы когда мы добавляли в classpath другие проекты, они были в разных пакетах. Каждый в своем уникальном. Это важно, чтобы сохранять ООП принципы.
  • Packaging: Jar — это наш стандарт)
  • Java: 11 — будем на шаг впереди. Не думаю, что я буду использовать новшества после восьмой джавы, но пусть уже будет. Есть не просит)... это решение подложит нам небольшую пасхалку в будущем)
Пока что зависимостей никаких добавлять не будем. В рамках этой задачи нам этого не нужно. Заполнив все это, получим (вот ссылка на сгенерированный проект):"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 4Заполнив, нажимаем GENERATE и добавляем в наш проект все внутренности в архиве."Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 5Добавляем файлы в проект. В итоге у нас есть приложение. Чтобы проверить, собирается ли оно вообще, заходим в терминал и пишем: $ mvn clean package"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 6Если у вас так же как из здесь, все ок: проект собрался, и джарник уже готов в target папке. На этом задача в рамках описания готова. Все просто, да? Поэтому делаем коммит и пуш в нашу ветку:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 7Добавляем в начале описания комита имя нашей задачи, чтобы потом было понятно, в рамках какой задачи делалась работа. Нажимаем Commit and Push"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 8Еще раз пересматриваем и проверяем, что именно мы хотим запушить из локального репозитория на удаленный и удостоверившись, что все ок, нажимаем Push. Какой наш следующий шаг? По всем правилам (которые можно почитать в этой статье, в части о GitHub flow) нужно создать пулл-реквест на главную ветку и подождать, чтобы кто-то из команды сделал рецензию кода. Так как я сам, я формально создам пулл-реквест и еще раз все пересмотрю. Захожу на страницу репозитория, а гитхаб уже знает, что у нас прибавление и предлагает создать пулл-реквест:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 9Нет препятствий патриотам (с) — создаем, как и предлагают. Выставляем такие же label, project как и на задаче, в рамках которой работаем, и заполняем описание:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 10Нажимаем Create pull request.

Настраиваем CI процесс

Заходим в созданный пулл-реквест: внизу видим, что у нас не настроен Continuous Integration (здесь и далее — CI). "Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 11Ну не настроен, и что? А зачем нам вообще нужен CI? Что вообще такое CI? Вот примерно тот перечень вопросов, который должен волновать нас в этот момент. В общем и целом CI — это непрерывный процесс сливания кода в общую кодовую базу с запуском сборки проекта перед этим. Так называемый билд (от англ build). Каждый раз, когда мы собираем проект, мы удостовериваемся, что проект прошел компиляцию, все его тесты прошли успешно, плюс к CI после сборки проекта еще можно добавить автотесты от тестировщиков, которые запускаются на эту конкретную сборку. Таким образом получится, что мы становимся более уверенные в том, что новые изменения работают так, как мы ожидаем, и не ломают предыдущий функционал. Также CI хорош тем, что он запускается автоматически после обновления кодовой базы. То есть мы запушили в ветку свои изменения и процесс пошел — сборка, тесты, автотесты и другие шаги. Если какой-то из этих шагов провалился, сборка считается битой и не может быть влита основную ветку. Именно это мы сейчас и сделаем: добавим GitHub Actions, который будет запускать наш код после пуша. GitHub Actions прекрасно ложится на наш GitHub Flow, так что будем использовать его для автоматизации работы. Этот инструмент очень мощный и большой, но пока что мы будем использовать его только для прогонки билда и проверки, что он собирается как нужно. Чтобы включить его, найдем на страничке репозитория кнопку Actions и перейдем по ней:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 12Находим необходимый для нас Continuous Integration workflow:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 13Нажимаем Set up this workflow. Далее нам предлагают использовать их шаблон: полностью соглашаемся, лишь несколько уточним все:

# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: Java CI with Maven

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: Build with Maven
      run: mvn -B package --file pom.xml
Здесь обозначено, что GitHub Action вызывается в двух случаях:
  1. Когда делается пуш в main ветку.
  2. Когда создается пулл-реквест в main ветку.
В секции jobs описаны шаги, которые будут выполняться. У нас всего один шаг — build. В нем видно, что наш проект будет запущен в убунте командой mvn -B package --file pom.xml. Это как раз то, что мы делали локально. Хотите здесь что-то поменять — пожалуйста. Я буду использовать этот шаблон, мне его хватит с головой. Нажимаю Start commit, выбираю create a new branch для настройки процесса и потом Propose new file. Но процесс сборки упал…"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 14Как видно, что Failing after 14s — build. Похоже, что-то произошло: переходим к сборке и смотрим на подробности:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 15Пишет, что не нашел такой помник. Почему? Аааа, точно-точно! Потому что мы создали изменения в главной ветке, а нашей задачи там еще нет. И поэтому он не нашел помник… Поэтому сейчас делаем следующее: таки мерджим в мастер эти данные, потом мерджим main ветку в JRTB-0, и тогда уже все должно пройти отлично. В пулл-реквесте с изменениями github actions нажимаем Merge pull request:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 16И повторяем Confirm merge. Далее гитхаб предлагает нам удалить ветку, в которой мы работали. Мы не отказываемся и удаляем:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 17Далее я не нашел в пулл-реквесте со SpringBoot, как стащить изменения из главной ветки с веб-сайта, поэтому сделаем это ручками через IDEA.

Шаг 1: обновить главную ветку в локальный репозиторий.

В идее переходим на главную ветку, нажимаем ctrl + t и обновляем главную ветку:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 18

Шаг 2: смерджить изменения из главной ветки в ветку JRTB-0.

Переходим на JRTB-0 и мерджим в нее главную."Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 19

Шаг 3: запушить изменения.

Нажимаем ctrl + shift + k и подтверждаем пуш. Теперь ждем, когда пройдет билд и будет зеленый!)) Но он опять красный. Что ж такое? Заходим в логи actions и видим, что у нас рассинхрон в версиях джавы. В GitHubActions стоит 8, а у нас используется 11:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 20Теперь есть два варианта: или actions подправить, или версию опустить до восьмой. Первый вариант, мне кажется, лучше и правильнее. Вносим изменения отдельным коммитом: будем работать не с 8-й, а с 11-й джавой."Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 21И после этого, наконец-то, у нас все получилось, и мы смогли настроить наш CI процесс для проекта. Такие вещи нужно настраивать на начальном этапе, чтобы потом не париться об этом. Теперь уже видно, что билд прошел и можно мерджить без опасений:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 22

Настраиваем работу с ветками в репозитории

Еще можно настроить в репозитории такие вещи, как правила при работе с ветками. Я хочу сделать так, чтобы в main ветку нельзя было пушить напрямую, а только через пулл-реквесты, и сделать так, чтобы нельзя было мержить пулл-реквест, если не прошел билд (то есть, если GitHub Actions упал на каком-то шаге). Для этого находим кнопку Settings и выбираем Branches:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 23На данный момент нет правил для веток, поэтому добавим новое через кнопку Add rule:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 24Здесь много настроек, и каждый может сделать что-то под свои нужды. Чтобы перед мержем в пулл-реквесте успешно прошел билд, добавляем галочку в Require status checks to pass before merging и выбираем статус, который нам нужен — build. Пока что хватит: далее можно будет обновлять этот рул и смотреть, что хочется еще. Нажимаем Create, чтобы создать этот рул."Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 25Далее, если мы снова зайдем в наш пулл-реквест, можно будет увидеть, что теперь у нашей проверки есть маркировка required:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 26Проверим нашу страницу с проектом, на которой отображены все статусы задач:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 27Сразу видно, над какой задачей идет работа. Причем работа уже сделана, и задача находится в code review (рецензия кода) статусе.

Закрываем JRTB-0

Теперь, когда мы подготовили пулл-реквест и сделали к нему CI, нужно завершить последний этап: закрыть задачу, перенести в правильный статус, посмотреть на борде (от англ board) изменения в нашем проекте. Наш пулл-реквест готов к тому, чтобы слить его в мастер. В пулл-реквесте нажимаем кнопку Merge pull request:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 28После успешного мерджа можно удалить, и обычно так и делают. Я этого делать не буду, чтобы вам было легче смотреть изменения между ветками/коммитами. Как только пулл-реквест смерджен, он автоматически переходит в done в нашем борде проекта:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 29Последний шаг — закрыть задачу (issue) со ссылкой на пулл-реквест, в котором это было:"Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 30Эта задача автоматически уходит в done на борде."Java-проект от А до Я": Пишем проект. Добавляем SpringBoot и настраиваем CI процесс - 31Начало положено, первая задача сделана!

Выводы

Казалось бы, мы уже начали работать и писать код, но все еще настройки необходимы. Да, это занимает время, но оно окупится стократ, когда проект станет больше и сложнее и нужны будут гарантии, что просто так не получится все поломать одним коммитом. Пулл-реквест, в котором все это происходит, доступен здесь. Быть может, когда вы будете читать, он будет уже закрыт. Это не страшно: вся нужная информация будет храниться по ссылке. Всем спасибо за чтение, до скорой встречи. Дальше — больше!

Список всех материалов серии в начале этой статьи.

Комментарии (26)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Katsuki Bakugou Уровень 51
27 марта 2023
Всем привет. Застрял на проверки собирается ли проект или нет (после команды mvn clean package). Вообще мне, почему-то, пришлось добавлять кучу зависимостей в pom файл. Тесты не проходят в итоге. Может я что-то делаю не так? Подскажите кто сталкивался.
sumenkov Уровень 36
2 ноября 2022
Не получилось... Приведенной информации оказалось недостаточно для понимания процесса. Рекомендую прочитать статьи, на которые автор ссылается по тексту. :)
Вильсур Уровень 22
1 сентября 2021
помогите мне чайнику это делается через папки или через идею, если да то как?
15 июня 2021

таки мерджим в мастер эти данные, потом мерджим main ветку в JRTB-0, и тогда уже все должно пройти отлично.
зашел в main ветку далее , клик по JRTB-0 и Merge into Current , затем перешёл в JRTB-0 и сделал тоже самое только в неё смерджил main ветку (хотя не понятно зачем , мы же JRTB-0 в main смерджили , а потом тоже самую операцию делаем ...) в итоге так и осталась ошибка подскажите пожалуйста в чём может быть проблема?
Roman Beekeeper Уровень 35
11 марта 2021
⚡️UPDATE⚡️ Друзья, создал телеграм-канал 🤓, в котором освещаю свою писательскую деятельность и свою open-source разработку в целом. Не хотите пропустить новые статьи? Присоединяйтесь ✌️
Руслан Уровень 35
28 февраля 2021
Друзья! Товарищи! Помогите, кто может. Потратил целых два дня, научился за это время многому. Но все же не одолел проблему CI (не видит pom.xml).
Lord Barrington Уровень 8
9 февраля 2021
Спасибо! Когда следующие серии?
Ols Уровень 23
7 февраля 2021
Спасибо, это было интересно и полезно. Вопрос только один, а как удалить случайно созданный не тот workflow? ☺️☺️☺️
Vladimir Уровень 11
5 февраля 2021
Спасибо за проделываемую Вами работу!