Предисловие
Данная статья основана на статье с Baeldung – Hosting a Maven Repository on GitHub.
Если интересно сразу перейти к делу, то пожалуйста)
Уже как три года я работаю над проектом со стеком Kotlin, Spring Boot, Maven. Все начиналось как небольшая учебная практика в вузе на коленке за пару недель и разрослось в приличную систему, которая уже использовалась по всей России.
В связи с ростом проекта, монорепозитория стало мало и появилась необходимость часть логики выделять в отдельные репозитории. Вот здесь и возникает вопрос: как управлять этими зависимостями?
Разбор решений
Для управления несколькими репозиториями был сделан небольшой обзор имеющихся решений
Использование Git Submodules
Изначально при появлении новых репозиториев они добавлялись как подмодули и собирались вместе со всем проектом, на тот момент это было оптимальным решением.
Плюсы
-
Простая настройка.
-
Простое обновление модулей (если берется всегда последний коммит мастер-ветки).
Минусы
-
Если у модуля сложное версионирование (с минорами и патчами), появляются сложности с обновлением (по крайней мере не отображается информация о версии модуля).
-
В случае нескольких модулей первый пункт становится еще сложнее.
Когда стоит использовать
-
Если зависимость не имеет версионирования с патчами и минорами (то есть всегда используется версия последнего коммита в мастер).
-
Если зависимость не меняется вообще (по сути первый пункт, только модули не нужно обновлять вообще).
-
Если подмодулей не больше двух.
Публикация артефактов в maven-репозиторий
Этот вариант выглядит более взрослым и сложным, по этой причине изначально я даже не стал смотреть в его сторону (на тот момент это и не было нужно).
Плюсы
-
Более удобное управление зависимостями: просто меняем версию в pom’нике.
-
Можно разделять версии на нестабильные (*-SNAPSHOT) и стабильные/релизные (.RELEASE): первые использовать во время активной разработки для обкатки фичей, вторые при релизе.
-
Зависимости собираются отдельно от основного репозитория, что ускоряет сборку (иногда значительно). Особенно это полезно при частой переборке всего проекта.
Минусы
-
Более сложная настройка.
-
Для использования зависимостей нужно публиковать новые версии артефактов. Это минус в случае ручной публикации и в случае автоматизации (в сравнении с подмодулями): в первом случае просто неприлично в ручную публиковать зависимость, когда можно сделать автоматизацию, во втором случае нужно написать автоматизацию.
Когда стоит использовать
-
Есть время разобраться в настройке публикации и в ее автоматизации.
-
В проекте используется больше двух зависимостей.
-
В версионировании зависимостей используются миноры и патчи.
По итогу во время роста числа зависимостей выбор был сделан в пользу публикации артефактов в maven-репозиторий.
Как можно публиковать в maven-репозиторий
Когда было принято решение публиковать зависимости как отдельные артефакты, я начал искать, как можно осуществить мою задумку. В итоге нашлось два варианта.
Публикация в Maven Central Portal
Для публикации в Maven Central Portal существует целая инструкция, здесь я не буду подробно описывать как это сделать. Опишу лишь причины, по которым я отказался от этого варианта:
-
Инструкция показалась достаточно сложной, для не самой приоритетной задачи.
-
Необходимо иметь собственный домен, если не нравится использовать
io.<github/gitlab/gitee/bitbucket>.usernameкак группу проекта. -
Необходимо соблюсти много стандартов, не соблюдая которые могут удалить артефакты (если артефакты нужны лишь для собственных проектов, то эти стандарты ни к чему).
Публикация в кастомный репозиторий
Для кастомных репозиториев есть несколько вариантов, но мне пригляделась инструкция по публикации артефактов в репозитории на GitHub. Почему же?
-
Простая инструкция.
-
Можно использовать любое имя группы проекта.
-
Стандарты можно не соблюдать, никто не удалит артефакты (чтобы ими пользоваться, разработчик должен сам осознанно добавить ваш репозиторий как maven-репозиторий).
В общем все вело к тому, чтобы публиковать артефакты в GitHub репозиторий.
Инструкция
Приступим!
-
Создадим проект (я использую IntelliJ IDEA в качестве среды разработки)
Создание проекта в IntelliJ IDEA По итогу получим вот такой pom-файл (с точностью до вынесения версий в блок
properties):<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.publish</groupId> <artifactId>publish-test</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <kotlin.code.style>official</kotlin.code.style> <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget> <kotlin.version>2.1.20</kotlin.version> <junit.version>5.10.0</junit.version> <maven.plugin.surfire.version>2.22.2</maven.plugin.surfire.version> </properties> <repositories> <repository> <id>mavenCentral</id> <url>https://repo1.maven.org/maven2/</url> </repository> </repositories> <build> <sourceDirectory>src/main/kotlin</sourceDirectory> <testSourceDirectory>src/test/kotlin</testSourceDirectory> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>test-compile</id> <phase>test-compile</phase> <goals> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>${maven.plugin.surfire.version}</version> </plugin> <plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>${maven.plugin.surfire.version}</version> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-test-junit5</artifactId> <version>${kotlin.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> </project> -
Создадим репозиторий на GitHub для хранения в нем текущего и будущих артефактов.
Создание репозитория на GitHub для хранения в нем артефактов -
Добавим временное локальное хранилище артефактов.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.publish</groupId> <artifactId>publish-test</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> ... <!-- Путь к временному хранилищу артефактов --> <deploy.temporaryArtifactDir>${project.build.outputDirectory}/mvn-artifact</deploy.temporaryArtifactDir> </properties> ... <distributionManagement> <!-- Репозиторий для временного хранилища артефактов --> <repository> <id>internal.repo</id> <name>Temporary Staging Repository</name> <url>file://${deploy.temporaryArtifactDir</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </distributionManagement> ... </project> -
Добавим все необходимые плагины.
-
maven-deploy-plugin– для включения после сборки артефактов в локальный репозиторий:<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.publish</groupId> <artifactId>publish-test</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> ... <!-- Версия для Maven Deploy PLugin --> <maven.plugin.deploy.version>2.8.2</maven.plugin.deploy.version> ... </properties> ... <build> ... <!-- Maven Deploy Plugin --> <plugins> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>${maven.plugin.deploy.version}</version> <configuration> <altDeploymentRepository> internal.repo::default::file://${deploy.temporaryArtifactDir} </altDeploymentRepository> </configuration> </plugin> ... </plugins> </build> ... </project>
-
maven-source-plugin(опционально) – для публикации вместе с артефактами самих исходников:<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.publish</groupId> <artifactId>publish-test</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> ... <!-- Версия Maven Source Plugin --> <maven.plugin.source.version>3.1.0</maven.plugin.source.version> </properties> ... <build> ... <plugins> ... <!-- Maven Source Plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>${maven.plugin.source.version}</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> ... </plugins> </build> ... </project> -
site-maven-plugin– для публикации артефактов в GitHub репозиторий:<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.publish</groupId> <artifactId>publish-test</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> ... <!-- Ветка, куда будут пушиться коммиты с артефактами --> <deploy.branch.name>master</deploy.branch.name> <!-- Название репозиторий, куда будут публиковаться артефакты --> <deploy.repository.name>maven-test-repo</deploy.repository.name> <!-- Имя пользователя или название организации GitHub (TODO: заменить на свое) --> <deploy.repository.owner>your-username/your-oraganization-name</deploy.repository.owner> </properties> ... <build> ... <plugins> ... <plugin> <groupId>com.github.github</groupId> <artifactId>site-maven-plugin</artifactId> <version>${maven.plugin.site.version}</version> <configuration> <!-- Коммит-месседж при пуше коммитов (TODO: опционально измененить) --> <message>${project.groupId}:${project.artifactId}:${project.version}</message> <noJekyll>true</noJekyll> <outputDirectory>${deploy.temporaryArtifactDir}</outputDirectory> <branch>refs/heads/${deploy.branch.name}</branch> <includes> <include>*/**</include> </includes> <merge>true</merge> <repositoryName>${deploy.repository.name}</repositoryName> <repositoryOwner>${deploy.repository.owner}</repositoryOwner> <server>github</server> </configuration> <executions> <execution> <goals> <goal>site</goal> </goals> <phase>deploy</phase> </execution> </executions> </plugin> ... </plugins> </build> ... </project>Также обязательно добавить данные для аутентификации на GitHub в
~/.m2/settings.xml. Для этого необходимо сгенерировать GitHub PAT с правамиrepoиuserи добавить его в файл.<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"> ... <servers> <server> <id>github</id> <!-- GitHub PAT (TODO: обновить на свой) --> <password>your-personal-access-token</password> </server> </servers> ... </settings>
По итогу получим следующий pom-файл:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.publish</groupId> <artifactId>publish-test</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> ... <maven.plugin.surfire.version>2.22.2</maven.plugin.surfire.version> <maven.plugin.deploy.version>2.8.2</maven.plugin.deploy.version> <maven.plugin.source.version>3.1.0</maven.plugin.source.version> <maven.plugin.site.version>0.12</maven.plugin.site.version> <!-- Deployment --> <deploy.temporaryArtifactDir>${project.build.outputDirectory}/mvn-artifact</deploy.temporaryArtifactDir> <deploy.branch.name>master</deploy.branch.name> <deploy.repository.name>maven-test-repo</deploy.repository.name> <deploy.repository.owner>your-username/organization-name</deploy.repository.owner> </properties> <repositories> <repository> <id>mavenCentral</id> <url>https://repo1.maven.org/maven2/</url> </repository> </repositories> <distributionManagement> <repository> <id>internal.repo</id> <name>Temporary Staging Repository</name> <url>file://${deploy.temporaryArtifactDir}</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </distributionManagement> <build> ... <plugins> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>${maven.plugin.deploy.version}</version> <configuration> <altDeploymentRepository> internal.repo::default::file://${deploy.temporaryArtifactDir} </altDeploymentRepository> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>${maven.plugin.source.version}</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.github.github</groupId> <artifactId>site-maven-plugin</artifactId> <version>${maven.plugin.site.version}</version> <configuration> <message>${project.groupId}:${project.artifactId}:${project.version}</message> <noJekyll>true</noJekyll> <outputDirectory>${deploy.temporaryArtifactDir}</outputDirectory> <branch>refs/heads/${deploy.branch.name}</branch> <includes> <include>*/**</include> </includes> <excludes> <exclude>demo-app/**</exclude> <exclude>**/demo-app/**</exclude> </excludes> <merge>true</merge> <repositoryName>${deploy.repository.name}</repositoryName> <repositoryOwner>${deploy.repository.owner}</repositoryOwner> <server>github</server> </configuration> <executions> <execution> <goals> <goal>site</goal> </goals> <phase>deploy</phase> </execution> </executions> </plugin> ... </plugins> </build> ... </project> -
-
Опубликуем артефакты.
Достаточно запустить команду
mvn clean deploy. В итоге будет следующая картина:
Репозиторий после запуска команды
Файлы включенные в коммит Проект собрался и все артефакты теперь лежат в нашем репозитории на GitHub.
Для возможности использовать созданные артефакты необходимо добавить свой репозиторий в проект:
<repositories> ... <repository> <id>github-maven-repo</id> <name>GitHub Maven Repository</name> <url>https://raw.githubusercontent.com/*username*/*repo-name*/master/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>
Заключение
Прочитав эту статью вы научились публиковать артефакты в собственный GitHub репозиторий и использовать их в своих проектах.
Если данная статья будет интересна, напишу статью об автоматизации процесса публикации с использованием GitHub Actions.
ссылка на оригинал статьи https://habr.com/ru/articles/938008/
Добавить комментарий