Публикация Android библиотеки

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Недавно у меня появилось желание попробовать создать свою собственную Android библиотеку и выложить ее на Maven Central репозиторий.

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

Я решил поделиться процессом публикации моей библиотеки Awesome-Buttons.

Ну что ж, приступим.

Регистрация на Sonatype JIRA и создание Issue

Перейдите на сайт Sonatype JIRA и создайте себе аккаунт.

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

Заполните всю необходимую информацию.

Обратите внимание на Group Id .Обычно в качестве его указывается доменное имя в обратном порядке.

Если у вас есть свой сайт или сайт библиотеки, то вы можете использовать его доменное имя (например: ru.freeit256), но для этого нужно будет дополнительно прописать запись в вашем регистраторе домена (после создания Issue вы увидите информацию как это сделать).

Я использовал другой подход: указал свой Github в качестве Group Id

Также для того, чтобы использовать Github в качестве Group Id вам нужно создать пустой репозиторий с именем OSSRH-74088

Не забудьте отправить ваше Issue на проверку и дождаться статуса CLOSED

Создаем Android библиотеку в Android Studio

Сначала создайте любое пустое приложение с app модулем.

Затем вы можете либо добавить модуль Android библиотеки, либо изменить текущий модуль на библиотечный. Читайте об этом на официальном сайте

Генерации GPG ключа

Перед публикацией необходимо сгенерировать пару GPG ключей.

Для генерации ключей выполните следующую команду:

 gpg --full-gen-key

Основные параметры при создании ключей:

  • формат шифрования: RSA and RSA

  • размер: 4096 бит

  • срок годности ключа можно указать 0 (никогда не истечет)

  • имя, email и комментарий укажите свои

Чтобы посмотреть все сгенерированные ключи выполните команду:

gpg --list-keys

Обратите внимание, последние 8 символов это ID ключа:

Для подписи библиотеки мы будем использовать приватный ключ, а чтобы пользователи смогли удостовериться, что библиотека принадлежит нам, мы должны выложить публичный ключ на общедоступный сервер, например keyserver.ubuntu.com:

// укажите свой ID ключа
gpg --keyserver keyserver.ubuntu.com --send-keys 0F11924A

Чтобы получить приватный ключ для подписи нужно выполнить:

// вы указываете свой email, который юзали, когда создавали ключ
gpg --armor --export-secret-keys dmitry.tehnicov@gmail.com | awk 'NR == 1 { print "GPG_SIGNING_KEY=" } 1' ORS='\\n'

Вуаля! Позже он нам понадобится.

Настройка библиотеки для публикации:

Добавляем плагин io.github.gradle-nexus в корневой файл build.gradle:

buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20"
    }
}

plugins {
  	// плагин для автоматизации публикации нашей либы
    id "io.github.gradle-nexus.publish-plugin" version "1.1.0"
}

// позже мы добавим скрипты для публикации
apply from: "${rootDir}/scripts/publish-root.gradle"

task clean(type: Delete) {
    delete rootProject.buildDir
}

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

Создадим в корне проекта папку scripts, и добавим новый скрипт publish-module.gradle:

apply plugin: 'maven-publish'
apply plugin: 'signing'

task androidSourcesJar(type: Jar) {
    archiveClassifier.set('sources')
    if (project.plugins.findPlugin("com.android.library")) {
        // For Android libraries
        from android.sourceSets.main.java.srcDirs
        from android.sourceSets.main.kotlin.srcDirs
    } else {
        // For pure Kotlin libraries, in case you have them
        from sourceSets.main.java.srcDirs
        from sourceSets.main.kotlin.srcDirs
    }
}

artifacts {
    archives androidSourcesJar
}

afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {
                // мы позже добавимм эти константы в другом файле
                groupId PUBLISH_GROUP_ID
                artifactId PUBLISH_ARTIFACT_ID
                version PUBLISH_VERSION

                // Two artifacts, the `aar` (or `jar`) and the sources
                if (project.plugins.findPlugin("com.android.library")) {
                    from components.release
                } else {
                    from components.java
                }

                artifact androidSourcesJar

                // Mostly self-explanatory metadata
                pom {
                    name = PUBLISH_ARTIFACT_ID
                    // описание нашей библиотеки
                    description = 'Different animated buttons for android applications'
                    // ссылка на сайт либы или на Github
                    url = 'https://github.com/KiberneticWorm/Awesome-Buttons'
                    licenses {
                        license {
                            name = 'Apache License 2.0'
                            // также вам нужно создать лицензию для своей либы
                            // я скопировал ее из Open Source проекта
                            url = 'https://github.com/KiberneticWorm/Awesome-Buttons/blob/master/LICENSE.txt'
                        }
                    }
                    developers {
                        developer {
                        		// далее указывает id, имя и почту разработчика
                            id = 'Twilly'
                            name = 'Dmitry Tsyvtsyn'
                            email = 'dmitry.tehnicov@gmail.com'
                        }
                        
                    }

                    scm {
                    		// информация о библиотеки на Github'е
                        connection = 'scm:github.com/KiberneticWorm/Awesome-Buttons.git'
                        developerConnection = 'scm:git:ssh://github.com/KiberneticWorm/Awesome-Buttons.git'
                        url = 'https://github.com/KiberneticWorm/Awesome-Buttons/tree/main'
                    }
                }
            }
        }
    }
}

signing {
    useInMemoryPgpKeys(
            rootProject.ext["signing.keyId"],
            rootProject.ext["signing.key"],
            rootProject.ext["signing.password"],
    )
    sign publishing.publications
}

Также нам нужно добавить скрипт publish-root.gradle:

// мы укажем все эти переменные в файле local.properties
ext["signing.keyId"] = ''
ext["signing.password"] = ''
ext["signing.key"] = ''
ext["ossrhUsername"] = ''
ext["ossrhPassword"] = ''
ext["sonatypeStagingProfileId"] = ''

File secretPropsFile = project.rootProject.file('local.properties')
if (secretPropsFile.exists()) {
    // Read local.properties file first if it exists
    Properties p = new Properties()
    new FileInputStream(secretPropsFile).withCloseable { is -> p.load(is) }
    p.each { name, value -> ext[name] = value }
} else {
    // Use system environment variables
    ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME')
    ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD')
    ext["sonatypeStagingProfileId"] = System.getenv('SONATYPE_STAGING_PROFILE_ID')
    ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID')
    ext["signing.password"] = System.getenv('SIGNING_PASSWORD')
    ext["signing.key"] = System.getenv('SIGNING_KEY')
}

nexusPublishing {
    repositories {
        sonatype {
            stagingProfileId = sonatypeStagingProfileId
            username = ossrhUsername
            password = ossrhPassword
            nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
            snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
        }
    }
}

Теперь нам нужно добавить maven-publish плагин и некоторые константы в начало build.gradle файла нашего модуля:


plugins {
    id 'com.android.library'
    id 'kotlin-android'
    id 'maven-publish'
}

// чтобы пользователь смог добавить нашу библиотеку 
// мы должны указать group id, artifact id и ее версию
ext {
		// group id
    PUBLISH_GROUP_ID = 'io.github.kiberneticworm'
    // текущая версия библиотеки
    PUBLISH_VERSION = '1.0.1'
    // artifact id библиотеки
    PUBLISH_ARTIFACT_ID = 'awesome-buttons'
}

apply from: "${rootProject.projectDir}/scripts/publish-module.gradle"

// ...

И самый важный момент, файл local.properties:

// добавьте следующие константы

// ID ключа, последние 8 символов
signing.keyId=
// пароль, который вы задали при создании ключа
signing.password=
// имя пользователя JIRA Sonatype
ossrhUsername=Twilly
// пароль
ossrhPassword=
// вернемся чуть позже
sonatypeStagingProfileId=
// приватный ключ, который вы получили ранее
signing.key=

Публикация

После основных настроек, зайдите на Nexus Repository Manager и войдите под учетными данными JIRA Sonatype.

Далее переходим во вкладку Staging Profiles и выбираем необходимый профиль.

Копируем sonatypeStagingProfileId из адреса сайта и указываем его в local.properties файле:

Переходим к публикации.

// укажите свой модуль библиотеки
./gradlew awesome-buttons:publishReleasePublicationToSonatypeRepository

Далее у вас есть два варианта зарелизить либу: вручную через графический интерфейс или с помощью gradle задачи.

Первый

Зайдите на сайт Nexus Repository Manager , перейдите во вкладку Staging Repositories и выберите необходимый репозиторий.

Чтобы выпустить релиз библиотеки нужно воспользоваться двумя командами close и release.

Для отмены релиза юзайте drop

Второй

Выполните команду, которая сама закроет и зарелизит вашу либу:

./gradlew closeAndReleaseSonatypeStagingRepository

Заключение

Вы уже убедились, что процесс публикации Andorid либы весьма затратный и рутинный.

Я постарался изложить только основные моменты. Возможно у вас возникнут какие-либо ошибки, которые вам придется самим решать ну и конечно же гуглить!

Такова жизнь прогера: постоянно гуглить. :)

Надеюсь, что статья оказалась вам полезной.

Желаю всем хорошего кода и побольше успешных релизов! :)

Источник: https://habr.com/ru/post/585472/


Интересные статьи

Интересные статьи

Поскольку это моя первая публикация на Хабр, давайте для начала представлюсь: меня зовут Федор, я из Нижнего Новгорода и работаю в компании Orion Innovation техническим м...
Привет! Меня зовут Виталий Сулимов, я Android-разработчик в компании Wheely, и сегодня я бы хотел поговорить с вами об архитектуре мобильных приложений. А именно о том, к...
Последние 6 лет я работаю экспертом по информационной безопасности в Одноклассниках и отвечаю за безопасность приложений. Мой доклад сегодня — о механизмах межпроцессного взаимодействия...
VUE.JS - это javascript фрэймворк, с версии 18.5 его добавили в ядро битрикса, поэтому можно его использовать из коробки.
Google предложил разработчикам обновить приложения для совместимости с архитектурой ARM64 в срок до 1 августа 2019 года, если они не соответствуют этим требованиям Найдем и включим поддержку ...