يبني الأمر elide publish ملفات JAR الخاصة بالمكتبة، ويكتب ملف POM لمستخدميها، وينشرها في مستودع Maven: المستودع
المحلي افتراضيًا، أو مستودع الفريق باستخدام --to، أو Maven Central عبر Central Publisher Portal. بعدها تعتمد
مشاريع Maven و Gradle ومشاريع Elide الأخرى عليها كما تعتمد على أي مُخرَج آخر. تُضبط العملية في الكتلة publishing
داخل elide.pkl؛ ولا حاجة إلى أي إضافات.
| الوجهة | الأمر | المتطلبات |
|---|---|---|
| مستودع Maven المحلي | elide publish | groupId و version و Jar واحد |
| مستودع الفريق | elide publish --to internal | بيانات الاعتماد في متغيرات البيئة |
| Maven Central | elide publish --to central | رمز Portal و gpg وبيانات POM الوصفية وملفات JAR للمصادر و javadoc |
| لا مكان (للتحقق أولًا) | elide publish --dry-run | لا شيء |
التثبيت محليًا
يحتاج النشر إلى groupId و version المشروع ومُخرَج واحد من النوع Jvm.Jar:
amends "elide:project.pkl"
import "elide:Jvm.pkl" as Jvm
name = "greeter"
version = "1.0.0"
description = "Greets people."
artifacts {
["lib"] = new Jvm.Jar {}
}
publishing {
maven {
groupId = "dev.example"
}
}elide publishيبني Elide ملف JAR (معيدًا استخدام المخرجات المحدّثة)، ويكتب ملف POM، ويثبّت الاثنين باسم
dev.example:greeter:1.0.0 تحت ~/.m2/repository مع maven-metadata-local.xml. القيمة الافتراضية لـ artifactId
هي اسم المشروع. وإعادة تثبيت الإصدار نفسه تستبدله، فيحصل أي مستخدم على الجهاز نفسه على كل تغيير. من Maven:
<dependency>
<groupId>dev.example</groupId>
<artifactId>greeter</artifactId>
<version>1.0.0</version>
</dependency>من Gradle:
repositories { mavenLocal() }
dependencies { implementation("dev.example:greeter:1.0.0") }من مشروع Elide آخر:
dependencies {
maven {
packages { "dev.example:greeter:1.0.0" }
}
}لا يحتاج التثبيت المحلي إلى شبكة ولا إلى بيانات اعتماد. يثبّت localRepository في مكان آخر؛ ويُحلّ المسار النسبي
بالنسبة إلى ملف البيان.
التحقق قبل النشر
elide publish --dry-runيجهّز --dry-run ملف POM وملفات JAR تحت .dev/staging/publish/maven بأسماء ملفات Maven
(greeter-1.0.0.jar و greeter-1.0.0-sources.jar و greeter-1.0.0.pom) ويسردها. ويوقّعها إن كان التوقيع مفعّلًا،
ويكتب الحزمة أيضًا عند النشر إلى Maven Central، فيعرض بالضبط ما سيرسله التشغيل الفعلي. لا يُكتب شيء في أي مستودع.
محتوى ملف POM
يصف ملف POM المكتبة لمستخدميها، لا عملية البناء: الإحداثيات وبيانات pom الوصفية والتبعيات، دون <build> أو
<repositories> أو مسارات محلية.
elide.pkl | ملف POM المنشور |
|---|---|
packages، modules | تبعيات compile |
runtimeOnly | تبعيات runtime |
compileOnly، devPackages، processors، kotlinPlugins، testPackages | تُستبعد |
exclusions دون إصدار | عنصر <exclusion> على كل تبعية |
| مشروع في مساحة العمل | إحداثيات النشر لذلك المشروع |
مُخرَج شقيق في Jar.from | قيم packages و modules و runtimeOnly الخاصة به، ما لم تكن مدرجة مسبقًا |
| مسار ملف JAR محلي | خطأ: لا يستطيع المستخدمون حلّه |
مكتبات Kotlin
يسرد ملف POM أيضًا ما يضيفه Elide إلى مسار الأصناف لمشروع Kotlin دون تصريح، لأن المستخدمين يحتاجونه وقت التشغيل:
kotlin-stdlib و kotlin-reflect بإصدار Kotlin الخاص بالمشروع، ومكتبات التشغيل التي يفعّلها kotlin.features
(الروتينات المشتركة، والتسلسل). لتحديد إصدار آخر، عطّل الميزة، أو اضبط kotlin.compilerOptions.noStdlib، أو صرّح
بالتبعية بنفسك.
افتراضيًا يضم النشر كل Jar و SourceJar و JavadocJar يصرّح بها المشروع؛ ويختار artifacts مجموعة فرعية منها
بأسماء المُخرَجات. ويجب أن يضم Jar واحدًا بالضبط، وكل مصنِّف مرة واحدة فقط. يُولَّد JavadocJar لمصادر Kotlin
باستخدام Dokka (راجع تجميع JAR).
النشر إلى مستودع الفريق
سمِّ المستودع تحت repositories، ثم انشر إليه باسمه:
publishing {
maven {
groupId = "dev.example"
repositories {
["internal"] = "https://repo.example.dev/releases"
}
}
}export ELIDE_MAVEN_INTERNAL_USERNAME=ci
export ELIDE_MAVEN_INTERNAL_PASSWORD="$REPO_TOKEN"
elide publish --to internalتأتي بيانات الاعتماد من ELIDE_MAVEN_<NAME>_USERNAME و ELIDE_MAVEN_<NAME>_PASSWORD، حيث <NAME> هو اسم المستودع
بأحرف كبيرة مع تحويل كل محرف آخر إلى _ (my-repo → ELIDE_MAVEN_MY_REPO_…)، فلا يحتوي ملف البيان على أي أسرار.
يُرفع كل ملف مع المجاميع الاختبارية .md5 و .sha1 و .sha256 و .sha512، ويُحدَّث maven-metadata.xml. يعمل
ذلك مع Nexus و Artifactory و GitHub Packages وأي مستودع يقبل الرفع بصيغة Maven. ويُرفض عنوان http:// عادي غير
localhost ما لم يُستخدم --allow-http-repositories.
التوقيع باستخدام gpg
publishing {
maven {
signing { gpg { keyName = "0123ABCD" } } // `signing {}` uses gpg's default key
}
}عند ضبط signing، يوقّع النشر البعيد كل ملف باستخدام الملف التنفيذي gpg (<file>.asc). ولا يوقّع التثبيت المحلي
إلا مع --sign؛ ويعطّل --no-sign التوقيع. يطلب gpg-agent عبارة المرور؛ وفي CI اضبط ELIDE_GPG_PASSPHRASE
فيمرّرها Elide إلى gpg عبر pinentry بوضع loopback. لا يقرأ Elide المفتاح بنفسه أبدًا. وإن غاب gpg أو فشل، فلا
يُنشر شيء.
الإصدار على Maven Central
يتطلب Maven Central بيانات POM الوصفية، وملفات JAR للمصادر و javadoc، والتواقيع، وإصدارًا نهائيًا. مكتبة كاملة:
amends "elide:project.pkl"
import "elide:Jvm.pkl" as Jvm
import "elide:Publishing.pkl" as Publishing
name = "greeter"
version = "1.0.0"
description = "Greets people."
artifacts {
["lib"] = new Jvm.Jar {}
["sources"] = new Jvm.SourceJar {}
["javadoc"] = new Jvm.JavadocJar {}
}
publishing {
maven {
groupId = "dev.example"
pom {
name = "Greeter"
url = "https://github.com/example/greeter"
licenses { new { name = "Apache-2.0"; url = "https://www.apache.org/licenses/LICENSE-2.0" } }
developers { new { id = "jdoe"; name = "J. Doe" } }
scm { url = "https://github.com/example/greeter" }
}
repositories {
["central"] = new Publishing.CentralPortal {}
}
}
}أنشئ رمز مستخدم في Central Publisher Portal ثم انشر:
export ELIDE_MAVEN_CENTRAL_USERNAME=<token user>
export ELIDE_MAVEN_CENTRAL_PASSWORD=<token password>
elide publish --to centralقبل بناء أي شيء، يتحقق Elide من متطلبات Central ويبلّغ عن كل ما ينقص دفعة واحدة: name و description و url و
licenses و developers و scm.url في ملف POM، و SourceJar، و JavadocJar، وإصدار ليس -SNAPSHOT. القيمة
الافتراضية لـ description في ملف POM هي وصف المشروع. والتوقيع إلزامي للنشر إلى Central، بالمفتاح الافتراضي لـ gpg ما
لم يختر signing مفتاحًا آخر، لذا يُرفض --no-sign.
يرفع Elide حزمة واحدة موقّعة مع مجاميعها الاختبارية وينتظر أن يتحقق Portal منها. افتراضيًا
(publishingType = "USER_MANAGED") تطلق بعدها عملية النشر من Portal؛ ويطبع Elide رابط صفحتها. ومع
publishingType = "AUTOMATIC" يطلقها Portal بمجرد التحقق منها. وإن فشل التحقق، يطبع Elide أخطاء Portal. يعود
--no-wait فور انتهاء الرفع.
مساحات العمل
في مساحة عمل، اضبط الإعدادات المشتركة مرة واحدة في elide.pkl الجذري:
import "elide:Publishing.pkl" as Publishing
publishing {
maven {
groupId = "dev.example"
pom { url = "https://github.com/example/greeter"; scm { url = "https://github.com/example/greeter" } }
repositories { ["central"] = new Publishing.CentralPortal {} }
}
}يرث الأعضاء كل شيء عدا artifactId و artifacts، إذ تبقى خاصة بكل مشروع؛ وتتقدم إعدادات العضو نفسه حقلًا بحقل،
وتُدمج المستودعات حسب الاسم.
| التشغيل | ما يُنشر |
|---|---|
elide publish في الجذر | كل المشاريع |
elide publish داخل عضو | ذلك العضو وكل مشروع في مساحة العمل يعتمد عليه ملف POM الخاص به |
elide publish core util | core و util فقط؛ ويجب أن تكون مشاريع مساحة العمل التي يعتمدان عليها موجودة مسبقًا في الوجهة |
elide publish --skip-existing | كل مشروع محدد لم يصل إصداره إلى الوجهة بعد |
يُبنى كل مشروع ويُجهَّز ويُوقَّع قبل نشر أي منها، فلا يُنشر شيء إن حدث فشل في هذه المراحل. وعند النشر إلى Maven
Central، تدخل كل المشاريع في عملية نشر واحدة يتحقق منها Portal ويطلقها معًا. ويعيد --skip-existing أيضًا تشغيل
إصدار فشل في منتصفه: فيتخطى ما وصل بالفعل، ولا يتخطى أبدًا إصدار snapshot.
في CI
- run: elide publish --to central --skip-existing
env:
ELIDE_MAVEN_CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
ELIDE_MAVEN_CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
ELIDE_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}استورد مفتاح التوقيع إلى حلقة مفاتيح gpg على المشغّل في خطوة سابقة. راجع التكامل المستمر
لتثبيت Elide على المشغّل.
المرجع
elide publish: كل الخيارات.publishing: كل خصائص ملف البيان.- تصدير POM: طباعة ملف
pom.xmlللبناء بدلًا من النشر.