1. Overview
Đối với các package (gói) Android, có một số cách xuất bản thư viện mã nguồn mở, chẳng hạn như jitpack, maven và jcenter.
Dễ nhất là jitpack.io
Chỉ cần sao chép URL git repo của bạn và dán nó, và sau một vài cú nhấp chuột, bạn đã hoàn tất! Thế nhưng cũng như mọi thứ khác trong cuộc sống, bạn phải hy sinh một vài thứ để làm cho nó trở nên thật dễ dàng.
Chúng ta cần phải thêm nó theo cách thủ công vào build.gradle (level Project) như được hiển thị bên dưới và chúng ta cũng không thể có toàn quyền kiểm soát phần mềm đã xuất bản của mình và cách nó được phân phối ra cộng đồng lập trình như chúng ta làm trong JCenter.
1 2 3 4 |
maven <span class="token punctuation">{</span> url <span class="token string">'https://maven.fabric.io/public'</span> <span class="token punctuation">}</span> |
Nếu bạn muốn tìm hiểu kho lưu trữ từ xa (remote repository) là gì và cách nó hoạt động, bạn có thể kiểm tra tại đây.
Bạn sẽ thắc mắc là tại sao chúng ta lại chọn JCenter mà không phải là Jitpack?
Chia sẻ thư viện trong JCenter khó hơn một chút so với Jitpack nhưng nó đi kèm với một số lợi thế lớn. Là một trong những trung tâm Maven phổ biến nhất, nó giới thiệu package của bạn cho một lượng lớn khán giả (audience), tuy nhiên, bạn vẫn có toàn quyền sở hữu và có thể kiểm soát cách package của bạn phát triển. Về cơ bản, bạn tải package của mình lên một trong các kho lưu trữ Maven công khai của mình và yêu cầu đưa nó vào JCenter. Sau khi được nhóm Bintray chấp thuận, package của bạn sẽ có thể tìm kiếm được trên JCenter và có sẵn miễn phí để tải xuống.
2. Publish your library
- Đầu tiên, chúng ta sẽ cần phải publish project của mình trên Github.
- Sau đó, chúng ta cần tạo một tài khoản trên BintrayOss.. Nó phải là oss (open source plan)
- Tại trang chính, click “Add New Repository”.
- Điền đầy đủ các thông tin bắt buộc
- Name: Tên thư viện
- Type: Kiểu Library : nên đặt là Maven
- Licenses: Library licenses
- Description: mô tả về Library, hãy chắc chắn rằng đây là một lời giải thích rõ ràng, rành mạch nhé.
- Chúng ta đã tạo thư viện. Bây giờ chúng ta nên tạo package (gói) cho thư viện. Nhấp vào “Add New Package”
- Lại điền đầy đủ các thông tin bắt buộc:
- Name: Tên gói
- Description: mô tả
- Licenses: Package licenses
- Maturity: Mô tả trạng thái phát triển của thư viện. Nếu đó là thư viện sẵn sàng sản xuất, bạn sẽ chọn “Official”, nếu không, bạn có thể chọn bất kỳ tùy chọn nào bạn cảm thấy gần với trạng thái của dự án nhất.
- Website: Git repo url of project.
- Issue tracker: Issues url hoặc git project repo
- Version control: Git repo with .git postfix
Sau đó click “Create Package”.
- Go to package page sau đó click “New Version”.
- Set version của library và sau đó click “Create Version”
Đây là phần cuối của thiết lập Bintray. Bây giờ chúng ta sẽ thiết lập dự án của mình.
- Đầu tiên, chúng ta nên thêm classpathes của Bintray và Maven vào gradle dependencies (level Project):
1 2 3 4 5 |
dependencies <span class="token punctuation">{</span> classpath <span class="token string">"com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4"</span> classpath <span class="token string">"com.github.dcendents:android-maven-gradle-plugin:2.1"</span> <span class="token punctuation">}</span> |
- Sau đó, trong tệp thư viện build.gradle, chúng ta nên thêm một số trường cần thiết. Các trường này cần các tập lệnh tạo sẵn để tải thư viện lên bintray một cách dễ dàng.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
ext <span class="token punctuation">{</span> bintrayRepo <span class="token operator">=</span> <span class="token string">'TestLibrary'</span> <span class="token comment">// Repo name in bintray dashboard</span> bintrayName <span class="token operator">=</span> <span class="token string">'com.example.testlibrary'</span> <span class="token comment">// package name of the bintray repo</span> publishedGroupId <span class="token operator">=</span> <span class="token string">'com.example.testlibrary'</span> <span class="token comment">// this is the ID we want to see in implementation line</span> libraryName <span class="token operator">=</span> <span class="token string">'testlibrary'</span> <span class="token comment">// this is the module name of library</span> artifact <span class="token operator">=</span> <span class="token string">'testlibrary'</span> <span class="token comment">// this is the artifact we want to see in implementation line</span> libraryDescription <span class="token operator">=</span> <span class="token string">'Test project library description'</span> <span class="token comment">// description of library</span> siteUrl <span class="token operator">=</span> <span class="token string">'https://github.com/mitsinsar/TestProject'</span> <span class="token comment">// git repo url</span> gitUrl <span class="token operator">=</span> <span class="token string">'https://github.com/mitsinsar/TestProject.git'</span> <span class="token comment">// git repo vcs url</span> libraryVersion <span class="token operator">=</span> <span class="token string">'1.0.3'</span> <span class="token comment">// library version</span> developerId <span class="token operator">=</span> <span class="token string">'msinansari'</span> <span class="token comment">// This is your bintray username</span> developerName <span class="token operator">=</span> <span class="token string">'Mithat Sinan Sari'</span> <span class="token comment">// Developer's name</span> developerEmail <span class="token operator">=</span> <span class="token string">'<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>'</span> <span class="token comment">// Developer's email</span> licenseName <span class="token operator">=</span> <span class="token string">'The Apache Software License, Version 2.0'</span> <span class="token comment">// for example, The Apache Software License, Version 2.0</span> licenseUrl <span class="token operator">=</span> <span class="token string">'http://www.apache.org/licenses/LICENSE-2.0.txt'</span> <span class="token comment">// for example, http://www.apache.org/licenses/LICENSE-2.0.txt</span> allLicenses <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"Apache-2.0"</span><span class="token punctuation">]</span> <span class="token comment">// array of licenses, for example, ["Apache-2.0"]</span> <span class="token punctuation">}</span> |
Đừng quên thêm “apply from x.gradle” vào cuối build.gradle của mô-đun thư viện.
publish.gradle là một tệp mà chúng ta sẽ tạo ở bước tiếp theo. Bây giờ, chỉ cần thêm đoạn mã bên dưới vào build.gradle của mô-đun của bạn.
1 2 |
apply from<span class="token operator">:</span> <span class="token string">'publish.gradle'</span> |
Sau đó, chúng ta cần tạo tệp gradle mới trong mô-đun thư viện và dán vào bên dưới ý chính để giúp chúng ta tải lên bintray một cách dễ dàng.
Ví dụ: publish.gradle.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
apply plugin<span class="token operator">:</span> <span class="token string">'com.jfrog.bintray'</span> apply plugin<span class="token operator">:</span> <span class="token string">'com.github.dcendents.android-maven'</span> version <span class="token operator">=</span> libraryVersion group <span class="token operator">=</span> publishedGroupId <span class="token comment">// Maven Group ID for the artifact</span> install <span class="token punctuation">{</span> repositories<span class="token punctuation">.</span>mavenInstaller <span class="token punctuation">{</span> <span class="token comment">// This generates POM.xml with proper parameters</span> pom <span class="token punctuation">{</span> project <span class="token punctuation">{</span> packaging <span class="token string">'aar'</span> groupId publishedGroupId artifactId artifact <span class="token comment">// Add your description here</span> name libraryName description libraryDescription url siteUrl <span class="token comment">// Set your license</span> licenses <span class="token punctuation">{</span> license <span class="token punctuation">{</span> name licenseName url licenseUrl <span class="token punctuation">}</span> <span class="token punctuation">}</span> developers <span class="token punctuation">{</span> developer <span class="token punctuation">{</span> id developerId name developerName email developerEmail <span class="token punctuation">}</span> <span class="token punctuation">}</span> scm <span class="token punctuation">{</span> connection gitUrl developerConnection gitUrl url siteUrl <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> task <span class="token function">sourcesJar</span><span class="token punctuation">(</span>type<span class="token operator">:</span> <span class="token class-name">Jar</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> from android<span class="token punctuation">.</span>sourceSets<span class="token punctuation">.</span>main<span class="token punctuation">.</span>java<span class="token punctuation">.</span>srcDirs classifier <span class="token operator">=</span> <span class="token string">'sources'</span> <span class="token punctuation">}</span> task <span class="token function">javadoc</span><span class="token punctuation">(</span>type<span class="token operator">:</span> <span class="token class-name">Javadoc</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> source <span class="token operator">=</span> android<span class="token punctuation">.</span>sourceSets<span class="token punctuation">.</span>main<span class="token punctuation">.</span>java<span class="token punctuation">.</span>srcDirs classpath <span class="token operator">+=</span> project<span class="token punctuation">.</span><span class="token function">files</span><span class="token punctuation">(</span>android<span class="token punctuation">.</span><span class="token function">getBootClasspath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token class-name">File</span><span class="token punctuation">.</span>pathSeparator<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> task <span class="token function">javadocJar</span><span class="token punctuation">(</span>type<span class="token operator">:</span> <span class="token class-name">Jar</span><span class="token punctuation">,</span> dependsOn<span class="token operator">:</span> javadoc<span class="token punctuation">)</span> <span class="token punctuation">{</span> classifier <span class="token operator">=</span> <span class="token string">'javadoc'</span> from javadoc<span class="token punctuation">.</span>destinationDir <span class="token punctuation">}</span> artifacts <span class="token punctuation">{</span> archives javadocJar archives sourcesJar <span class="token punctuation">}</span> <span class="token comment">// Bintray</span> <span class="token class-name">Properties</span> properties <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Properties</span><span class="token punctuation">(</span><span class="token punctuation">)</span> properties<span class="token punctuation">.</span><span class="token function">load</span><span class="token punctuation">(</span>project<span class="token punctuation">.</span>rootProject<span class="token punctuation">.</span><span class="token function">file</span><span class="token punctuation">(</span><span class="token string">'local.properties'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">newDataInputStream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> bintray <span class="token punctuation">{</span> user <span class="token operator">=</span> properties<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">"bintray.user"</span><span class="token punctuation">)</span> key <span class="token operator">=</span> properties<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">"bintray.apikey"</span><span class="token punctuation">)</span> configurations <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'archives'</span><span class="token punctuation">]</span> pkg <span class="token punctuation">{</span> repo <span class="token operator">=</span> bintrayRepo name <span class="token operator">=</span> bintrayName desc <span class="token operator">=</span> libraryDescription websiteUrl <span class="token operator">=</span> siteUrl vcsUrl <span class="token operator">=</span> gitUrl licenses <span class="token operator">=</span> allLicenses publish <span class="token operator">=</span> <span class="token boolean">true</span> publicDownloadNumbers <span class="token operator">=</span> <span class="token boolean">true</span> version <span class="token punctuation">{</span> desc <span class="token operator">=</span> libraryDescription <span class="token comment">// Uncomment 4 lines below to enable gpg auto signing</span> <span class="token comment">//gpg {</span> <span class="token comment">// sign = true //Determines whether to GPG sign the files. The default is false</span> <span class="token comment">// passphrase = properties.getProperty("bintray.gpg.password")</span> <span class="token comment">//}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Cuối cùng, chúng ta cần thêm tên người dùng bintray và API Key vào tệp local.properties như hình dưới đây:
1 2 3 |
bintray<span class="token punctuation">.</span>user<span class="token operator">=</span>########### bintray<span class="token punctuation">.</span>apikey<span class="token operator">=</span>############## |
Và bây giờ, chúng ta chỉ cần chạy command line dưới đây:
- ./gradlew install
- ./gradlew bintrayUpload
TRƯỜNG HỢP BUILD THẤT BẠI
Thỉnh thoảng nó thất bại vì Javadoc. Đầu tiên bạn nên kiểm tra xem mọi thứ có chính xác không. Các ký tự không phải ascii cũng không build được. Nếu bạn chắc chắn rằng mọi thứ đều chính xác, thì bạn có thể disable Javadoc. Chỉ cần sao chép-dán phạm vi này vào thư viện build.gradle.
Bạn có thể xem tại đây để tìm hiểu về Javadoc
1 2 3 4 |
subprojects <span class="token punctuation">{</span> tasks<span class="token punctuation">.</span><span class="token function">withType</span><span class="token punctuation">(</span><span class="token class-name">Javadoc</span><span class="token punctuation">)</span><span class="token punctuation">.</span>all <span class="token punctuation">{</span> enabled <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
IMPORTANT NOTE for 401 Unauthorized;
Nếu bạn đang xuất bản thư viện của mình dưới một tổ chức (organisation),Thứ nhất: Bạn nên sử dụng tên người dùng và khóa api của chủ sở hữu tổ chức
Thứ hai: Bạn nên đặt userOrg = ‘your_organisation_name’ trong publish.gradle
Thứ ba: Hoặc để có trường hợp sử dụng tốt hơn, hãy kiểm tra ý chính bên dưới
This is in the library build.gradle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="token comment">// This is in the library build.gradle</span> ext <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> userOrganisation <span class="token operator">=</span> <span class="token string">'your_organisation_name'</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token comment">// This is in publish.gradle</span> bintray <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> pkg <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> userOrg <span class="token operator">=</span> userOrganisation <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Sau khi gọi hai command line trên theo thứ tự, (nếu mọi thứ đều đúng, nó sẽ thông báo “Build Successful”). Sau đó, chúng ta sẽ có thể xem phiên bản mới nhất trong bảng điều khiển (dashboard);
Sau khi click vào last version, chúng ta sẽ thấy “Version Publication Date” và đoạn mã “<dependency />”.
Cuối cùng, chúng ta sẽ click vào nút “Add to JCenter”, viết mô tả thư viện và chờ phê duyệt.
Sau khi được phê duyệt, nó sẽ được implemented giống như:
1 2 3 4 |
dependecies <span class="token punctuation">{</span> implementation <span class="token string">'com.example.testlibrary:testlibrary:1.0.3'</span> <span class="token punctuation">}</span> |
Vậy là xong rồi.
Thanks for reading.
Nguồn tham khảo: