ProHoster > بلوق > إدارة > استخدام إجراءات Gradle و Github لنشر مشروع Java في مستودع Sonatype Maven المركزي
استخدام إجراءات Gradle و Github لنشر مشروع Java في مستودع Sonatype Maven المركزي
في هذه المقالة ، أود إلقاء نظرة مفصلة على عملية نشر أداة Java من البداية من خلال إجراءات Github إلى مستودع Sonatype Maven المركزي باستخدام Gradle builder.
قررت كتابة هذا المقال بسبب عدم وجود برنامج تعليمي عادي في مكان واحد. كان لابد من جمع كل المعلومات قطعة قطعة من مصادر مختلفة ، علاوة على ذلك ، ليست جديدة تمامًا. من يهتم ، أهلا بك تحت القط.
إنشاء مستودع في Sonatype
الخطوة الأولى هي إنشاء مستودع في Sonatype Maven Central. لهذا نذهب هنا، قم بالتسجيل وإنشاء مهمة جديدة ، وطلب منا إنشاء مستودع. نحن نقود في منطقتنا معرف مجموعة مشروع، عنوان المشروع رابط المشروع و عنوان url لـ SCM ارتباط إلى نظام التحكم في الإصدار الذي يقع فيه المشروع. معرف مجموعة هنا يجب أن يكون بالصيغة com.example ، com.example.domain ، com.example.testsupport ، ويمكن أيضًا أن يكون في شكل رابط إلى github الخاص بك: github.com/yourusername -> io.github. اسم المستخدم الخاص بك. في أي حال ، ستحتاج إلى التحقق من ملكية هذا المجال أو الملف الشخصي. إذا قمت بتحديد ملف تعريف github ، فسيُطلب منك إنشاء مستودع عام بالاسم المطلوب.
بعد التأكيد ببعض الوقت ، سيتم إنشاء GroupId الخاص بك ويمكننا الانتقال إلى الخطوة التالية ، تكوين Gradle.
تكوين Gradle
في وقت كتابة هذا التقرير ، لم أجد مكونات إضافية لـ Gradle يمكن أن تساعد في نشر الأداة. هذا المكون الإضافي الوحيد الذي وجدته ، ومع ذلك ، رفض المؤلف تقديم المزيد من الدعم له. لذلك ، قررت أن أفعل كل شيء بنفسي ، لأنه ليس من الصعب جدًا القيام بذلك.
أول شيء يجب معرفته هو متطلبات Sonatype للنشر. هم كالتالي:
توافر أكواد المصدر و JavaDoc ، أي. واجب الحضور -sources.jar и-javadoc.jar الملفات. كما هو مذكور في الوثائق ، إذا لم يكن من الممكن توفير رموز المصدر أو الوثائق ، يمكنك عمل دمية -sources.jar أو -javadoc.jar مع README بسيط بالداخل لاجتياز الاختبار.
يجب توقيع جميع الملفات باستخدام GPG/PGPو .asc يجب تضمين الملف الذي يحتوي على التوقيع لكل ملف.
توفر pom ملف
القيم الصحيحة groupId, artifactId и version. يمكن أن يكون الإصدار عبارة عن سلسلة عشوائية ولا يمكن أن ينتهي بـ -SNAPSHOT
الحضور مطلوب name, description и url
وجود معلومات حول الترخيص والمطورين ونظام التحكم في الإصدار
هذه هي القواعد الأساسية التي يجب اتباعها عند النشر. المعلومات الكاملة متوفرة هنا.
نقوم بتنفيذ هذه المتطلبات في build.gradle ملف. أولاً ، دعنا نضيف جميع المعلومات الضرورية حول المطورين والتراخيص ونظام التحكم في الإصدار ، وكذلك تعيين عنوان url واسم ووصف المشروع. لنكتب طريقة بسيطة لهذا:
def customizePom(pom) {
pom.withXml {
def root = asNode()
root.dependencies.removeAll { dep ->
dep.scope == "test"
}
root.children().last() + {
resolveStrategy = DELEGATE_FIRST
description 'Some description of artifact'
name 'Artifct name'
url 'https://github.com/login/projectname'
organization {
name 'com.github.login'
url 'https://github.com/login'
}
issueManagement {
system 'GitHub'
url 'https://github.com/login/projectname/issues'
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
scm {
url 'https://github.com/login/projectname'
connection 'scm:https://github.com/login/projectname.git'
developerConnection 'scm:git://github.com/login/projectname.git'
}
developers {
developer {
id 'dev'
name 'DevName'
email '[email protected]'
}
}
}
}
}
بعد ذلك ، تحتاج إلى تحديد ذلك أثناء التجميع الذي تم إنشاؤه -sources.jar и-javadoc.jar الملفات. لهذا القسم java تحتاج إلى إضافة ما يلي:
java {
withJavadocJar()
withSourcesJar()
}
دعنا ننتقل إلى الشرط الأخير ، إعداد توقيع GPG / PGP. للقيام بذلك ، قم بتوصيل المكون الإضافي signing:
plugins {
id 'signing'
}
وإضافة قسم:
signing {
sign publishing.publications
}
أخيرًا ، دعنا نضيف قسمًا publishing:
publishing {
publications {
mavenJava(MavenPublication) {
customizePom(pom)
groupId group
artifactId archivesBaseName
version version
from components.java
}
}
repositories {
maven {
url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
credentials {
username sonatypeUsername
password sonatypePassword
}
}
}
}
ومن اسم المستخدم и سوناتايب المتغيرات التي تحتوي على تسجيل الدخول وكلمة المرور التي تم إنشاؤها أثناء التسجيل على sonatype.org.
هكذا النهائي build.gradle سوف تبدو مثل هذا:
كود build.gradle كامل
plugins {
id 'java'
id 'maven-publish'
id 'signing'
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
withJavadocJar()
withSourcesJar()
}
group 'io.github.githublogin'
archivesBaseName = 'projectname'
version = System.getenv('RELEASE_VERSION') ?: "0.0.1"
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
}
test {
useJUnitPlatform()
}
jar {
from sourceSets.main.output
from sourceSets.main.allJava
}
signing {
sign publishing.publications
}
publishing {
publications {
mavenJava(MavenPublication) {
customizePom(pom)
groupId group
artifactId archivesBaseName
version version
from components.java
}
}
repositories {
maven {
url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
credentials {
username sonatypeUsername
password sonatypePassword
}
}
}
}
def customizePom(pom) {
pom.withXml {
def root = asNode()
root.dependencies.removeAll { dep ->
dep.scope == "test"
}
root.children().last() + {
resolveStrategy = DELEGATE_FIRST
description 'Some description of artifact'
name 'Artifct name'
url 'https://github.com/login/projectname'
organization {
name 'com.github.login'
url 'https://github.com/githublogin'
}
issueManagement {
system 'GitHub'
url 'https://github.com/githublogin/projectname/issues'
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
scm {
url 'https://github.com/githublogin/projectname'
connection 'scm:https://github.com/githublogin/projectname.git'
developerConnection 'scm:git://github.com/githublogin/projectname.git'
}
developers {
developer {
id 'dev'
name 'DevName'
email '[email protected]'
}
}
}
}
}
أريد أن أشير إلى أننا حصلنا على الإصدار من متغير البيئة: System.getenv('RELEASE_VERSION'). سوف نكشفها أثناء التجميع ونأخذها من اسم العلامة.
جيل مفتاح PGP
أحد متطلبات Sonatype هو أن يتم توقيع جميع الملفات باستخدام مفتاح GPG / PGP. لهذا نذهب هنا وقم بتنزيل أداة GnuPG لنظام التشغيل الخاص بك.
نقوم بإنشاء زوج مفاتيح: gpg --gen-key، أدخل اسم المستخدم والبريد الإلكتروني وقم أيضًا بتعيين كلمة مرور.
اكتشفنا id مفتاحنا مع الأمر: gpg --list-secret-keys --keyid-format short. سيتم تحديد المعرف بعد الشرطة المائلة ، على سبيل المثال: rsa2048 / 9B695056
نشر المفتاح العام على الخادم https://keys.openpgp.org بالأمر: gpg --keyserver [https://keys.openpgp.org](https://keys.openpgp.org/) --send-keys 9B695056
نقوم بتصدير المفتاح السري إلى مكان تعسفي وسنحتاجه في المستقبل: gpg --export-secret-key 9B695056 > D:\gpg\9B695056.gpg
إعداد إجراءات جيثب
دعنا ننتقل إلى المرحلة النهائية ، وقم بإعداد الإنشاء والنشر التلقائي باستخدام إجراءات Github.
إجراءات Github هي ميزة تسمح لك بأتمتة سير العمل من خلال تنفيذ دورة CI / CD كاملة. يمكن تشغيل الإنشاء والاختبار والنشر من خلال أحداث مختلفة: دفع التعليمات البرمجية أو إنشاء الإصدار أو المشكلات. هذه الوظيفة مجانية تمامًا للمستودعات العامة.
في هذا القسم ، سأوضح لك كيفية إعداد كود البناء والدفع ونشره في مستودع Sonatype عند الإصدار ، وكذلك إعداد الأسرار.
نضع الأسرار
للتجميع والنشر التلقائي ، نحتاج إلى عدد من القيم السرية ، مثل معرف المفتاح ، وكلمة المرور التي أدخلناها عند إنشاء المفتاح ، ومفتاح PGP نفسه ، وتسجيل الدخول / كلمة مرور Sonatype. يمكنك ضبطها في قسم خاص في إعدادات المستودع:
نضع المتغيرات التالية:
SONATYPE_USERNAME / SONATYPE_PASSWORD - تسجيل الدخول / كلمة المرور التي أدخلناها عند التسجيل في Sonatype
SIGNING_KEYID / SIGNING_PASSWORD - تم تعيين معرف مفتاح PGP وكلمة المرور أثناء الإنشاء.
أريد أن أسهب في الحديث عن المتغير GPG_KEY_CONTENTS بمزيد من التفصيل. الحقيقة هي أننا نحتاج إلى مفتاح PGP خاص للنشر. من أجل نشرها في الأسرار ، اعتدت تعليمات بالإضافة إلى اتخاذ عدد من الإجراءات.
لنقم بتشفير مفتاحنا باستخدام gpg: gpg --symmetric --cipher-algo AES256 9B695056.gpgعن طريق إدخال كلمة مرور. يجب وضعها في متغير: SECRET_PASSPHRASE
دعنا نترجم المفتاح المشفر المستلم إلى نموذج نصي باستخدام base64: base64 9B695056.gpg.gpg > 9B695056.txt. سيتم وضع المحتوى في المتغير: GPG_KEY_CONTENTS.
بناء الإعداد عند دفع التعليمات البرمجية وإنشاء العلاقات العامة
تحتاج أولاً إلى إنشاء مجلد في جذر مشروعك: .github/workflows.
في ذلك ، قم بترميز الملف ، على سبيل المثال ، gradle-ci-build.yml بالمحتوى التالي:
name: build
on:
push:
branches:
- master
- dev
- testing
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Build with Gradle
uses: eskatos/gradle-command-action@v1
with:
gradle-version: current
arguments: build -PsonatypeUsername=${{secrets.SONATYPE_USERNAME}} -PsonatypePassword=${{secrets.SONATYPE_PASSWORD}}
سيتم تنفيذ سير العمل هذا عند الدفع إلى الفروع master, dev и testing، أيضًا عند إنشاء طلبات السحب.
يحدد قسم الوظائف الخطوات المطلوب تنفيذها على الأحداث المحددة. في هذه الحالة ، سنبني على أحدث إصدار من ubuntu ، ونستخدم Java 8 ، ونستخدم أيضًا المكون الإضافي لـ Gradle eskatos/gradle-command-action@v1والتي ، باستخدام أحدث إصدار من المنشئ ، ستقوم بتشغيل الأوامر المحددة في arguments. المتغيرات secrets.SONATYPE_USERNAME и secrets.SONATYPE_PASSWORD هذه هي الأسرار التي سألناها سابقًا.
ستنعكس نتائج البناء في علامة تبويب الإجراءات:
النشر التلقائي عند طرح إصدار جديد
لنقم بإنشاء ملف سير عمل منفصل للنشر التلقائي gradle-ci-publish.yml:
name: publish
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Prepare to publish
run: |
echo '${{secrets.GPG_KEY_CONTENTS}}' | base64 -d > publish_key.gpg
gpg --quiet --batch --yes --decrypt --passphrase="${{secrets.SECRET_PASSPHRASE}}"
--output secret.gpg publish_key.gpg
echo "::set-env name=RELEASE_VERSION::${GITHUB_REF:11}"
- name: Publish with Gradle
uses: eskatos/gradle-command-action@v1
with:
gradle-version: current
arguments: test publish -Psigning.secretKeyRingFile=secret.gpg -Psigning.keyId=${{secrets.SIGNING_KEYID}} -Psigning.password=${{secrets.SIGNING_PASSWORD}} -PsonatypeUsername=${{secrets.SONATYPE_USERNAME}} -PsonatypePassword=${{secrets.SONATYPE_PASSWORD}}
الملف مطابق تقريبًا للملف السابق ، باستثناء الحدث الذي سيتم تشغيله فيه. في هذه الحالة ، هذا هو حدث إنشاء علامة باسم يبدأ بـ v.
قبل النشر ، نحتاج إلى استخراج مفتاح PGP من الأسرار ووضعه في جذر المشروع ، وكذلك فك تشفيره. بعد ذلك ، نحتاج إلى تعيين متغير بيئة خاص RELEASE_VERSION الذي نشير إليه gradle.build ملف. كل هذا يتم في القسم Prepare to publish. نحصل على مفتاحنا من المتغير GPG_KEY_CONTENTS ، نترجمه إلى ملف gpg ، ثم نفك تشفيره بوضعه في الملف secret.gpg.
بعد ذلك ، ننتقل إلى متغير خاص GITHUB_REF، حيث يمكننا الحصول على الإصدار الذي قمنا بتعيينه عند إنشاء العلامة. هذا المتغير مناسب في هذه الحالة. refs/tags/v0.0.2 التي قطعنا منها أول 11 حرفًا للحصول على نسخة محددة. بعد ذلك ، نستخدم أوامر Gradle القياسية للنشر: test publish
التحقق من نتائج النشر في مستودع Sonatype
بمجرد إنشاء الإصدار ، يجب أن يبدأ سير العمل الموضح في القسم السابق. للقيام بذلك ، قم بإنشاء إصدار:
يجب أن يبدأ اسم العلامة بـ v. إذا اكتمل سير العمل بنجاح بعد النقر فوق نشر الإصدار ، فيمكننا الانتقال إلى Sonatype Nexus للتأكد:
ظهرت القطعة الأثرية في مستودع التدريج. يظهر فورًا في حالة الفتح ، ثم يجب نقله يدويًا إلى حالة الإغلاق بالضغط على الزر المناسب. بعد التحقق من استيفاء جميع المتطلبات ، تنتقل الأداة إلى حالة الإغلاق ولم تعد متاحة للتعديل. في هذا النموذج ، سينتهي الأمر في MavenCentral. إذا كان كل شيء على ما يرام ، يمكنك الضغط على الزر الإفراج عن، وستنتهي الأداة في مستودع Sonatype.
لكي تصل الأداة إلى MavenCentral ، عليك أن تطلبها في المهمة التي أنشأناها في البداية. ما عليك سوى القيام بذلك مرة واحدة ، لذلك ننشر للمرة الأولى. في الأوقات اللاحقة ، هذا غير مطلوب ، ستتم مزامنة كل شيء تلقائيًا. لقد قاموا بتشغيل المزامنة بالنسبة لي بسرعة ، لكن الأمر استغرق حوالي 5 أيام حتى تصبح الأداة متاحة في MavenCentral.