$30 off During Our Annual Pro Sale. View Details »

How to upload a kotlin multiplatform project library.

AAkira
March 27, 2019

How to upload a kotlin multiplatform project library.

I talked about how to upload a kotlin multiplatform library at どこでもKotlin #7 〜Kotlin MPP特集〜.

https://m3-engineer.connpass.com/event/123055/

AAkira

March 27, 2019
Tweet

More Decks by AAkira

Other Decks in Technology

Transcript

  1. Bagan, Myanmar
    @_a_akira
    How to publish

    a Kotlin Multiplatform Library

    View Slide

  2. About me
    @_a_akira AAkira
    CyberAgent, Inc.
    Akira Aratani
    https://aakira.app
    "#$%&'()*+,-./012345678

    View Slide

  3. Agenda
    • MPPライブラリのパッケージ構成
    • MPPライブラリのGradleの設定
    • BintrayへのUpload

    View Slide

  4. Agenda
    • Kotlin/Nativeチュートリアル Android, iOS編

    http://aakira.app/blog/2018/10/kotlin-native
    • Kotlin Multiplatform構想 ~今やる理由編~

    https://aakira.app/blog/2018/12/kotlin-mpp-reason
    • Kotlin Multiplatform構想 ~設計編~

    https://aakira.app/blog/2018/12/kotlin-mpp-architecture
    • Kotlin Multiplatform環境でKotlin Serializationと

    Android ExtensionsのParcelize Annotationを使う

    http://aakira.app/blog/2018/12/kotlin-mpp-android-parcelable
    • NapierというKotlin Multiplatform用のログライブラリを作った

    https://aakira.app/blog/2019/02/napier

    View Slide

  5. Agenda
    • Kotlin/Nativeチュートリアル Android, iOS編

    http://aakira.app/blog/2018/10/kotlin-native
    • Kotlin Multiplatform構想 ~今やる理由編~

    https://aakira.app/blog/2018/12/kotlin-mpp-reason
    • Kotlin Multiplatform構想 ~設計編~

    https://aakira.app/blog/2018/12/kotlin-mpp-architecture
    • Kotlin Multiplatform環境でKotlin Serializationと

    Android ExtensionsのParcelize Annotationを使う

    http://aakira.app/blog/2018/12/kotlin-mpp-android-parcelable
    • NapierというKotlin Multiplatform用のログライブラリを作った

    https://aakira.app/blog/2019/02/napier

    View Slide

  6. Agenda
    Timber likeなKotlin mpp用ライブラリ
    https://github.com/AAkira/Napier

    View Slide

  7. Agenda

    View Slide

  8. Kotlin Multiplatform Libraryの

    パッケージ構成
    Yangon, Myanmar

    View Slide

  9. パッケージ構成 (~Kotlin1.3)
    .
    ├── android
    │ ├── src
    │ └── build.gradle (apply plugin: 'kotlin-platform-android')
    ├── common
    │ ├── src
    │ │ └── main
    │ └── build.gradle (apply plugin: 'kotlin-platform-common')
    ├── ios
    │ ├── src
    │ │ └── main
    │ └── build.gradle (apply plugin: 'org.jetbrains.kotlin.platform.native')
    └─── js
    ├── src
    │ └── main
    └── build.gradle (apply plugin: 'kotlin-platform-js')

    View Slide

  10. パッケージ構成 (~Kotlin1.3)
    各ディレクトリ毎にbuild.gradleがある
    .
    ├── android
    │ ├── src
    │ └── build.gradle (apply plugin: 'kotlin-platform-android')
    ├── common
    │ ├── src
    │ │ └── main
    │ └── build.gradle (apply plugin: 'kotlin-platform-common')
    ├── ios
    │ ├── src
    │ │ └── main
    │ └── build.gradle (apply plugin: 'org.jetbrains.kotlin.platform.native')
    └─── js
    ├── src
    │ └── main
    └── build.gradle (apply plugin: 'kotlin-platform-js')

    View Slide

  11. パッケージ構成 (Kotlin1.3~)
    .
    └── library
    ├── build.gradle (apply plugin: 'kotlin-multiplatform')
    └── src
    ├── androidMain
    ├── androidTest
    ├── commonMain
    ├── commonTest
    ├── iosMain
    ├── iosTest
    ├── jsMain
    ├── jsTest
    ├── jvmMain
    └── jvmTest

    View Slide

  12. パッケージ構成 (Kotlin1.3~)
    .
    └── library
    ├── build.gradle (apply plugin: 'kotlin-multiplatform')
    └── src
    ├── androidMain
    ├── androidTest
    ├── commonMain
    ├── commonTest
    ├── iosMain
    ├── iosTest
    ├── jsMain
    ├── jsTest
    ├── jvmMain
    └── jvmTest
    build.gradleは1つのみ

    View Slide

  13. パッケージ構成
    何よりも信頼出来るJakeの力強い "yes"

    @Kotlinlang slack

    View Slide

  14. パッケージ構成 (Kotlin1.3~)
    .
    └── library
    ├── build.gradle (apply plugin: 'kotlin-multiplatform')
    └── src
    ├── androidMain
    ├── androidTest
    ├── commonMain
    ├── commonTest
    ├── iosMain
    ├── iosTest
    ├── jsMain
    ├── jsTest
    ├── jvmMain
    └── jvmTest
    build.gradleは1つのみが正しい

    View Slide

  15. Talat rotfai ratchada, Bangkok, Thailand
    Kotlin Multiplatform Libraryの

    Gradle設定

    View Slide

  16. Gradle設定
    • Common
    • Android
    • iOS
    • JVM
    • JS
    今回配布するライブラリ
    .
    ├── library
    │ ├── android.gradle
    │ ├── build.gradle
    │ └── src
    │ ├── androidMain
    │ ├── androidTest
    │ ├── commonMain
    │ ├── commonTest
    │ ├── iosMain
    │ ├── iosTest
    │ ├── jsMain
    │ ├── jsTest
    │ ├── jvmMain
    │ └── jvmTest
    └─── build.gradle

    View Slide

  17. Gradle設定
    • Common
    • Android
    • iOS
    • JVM
    • JS
    今回配布するライブラリ
    .
    ├── library
    │ ├── android.gradle
    │ ├── build.gradle
    │ └── src
    │ ├── androidMain
    │ ├── androidTest
    │ ├── commonMain
    │ ├── commonTest
    │ ├── iosMain
    │ ├── iosTest
    │ ├── jsMain
    │ ├── jsTest
    │ ├── jvmMain
    │ └── jvmTest
    └─── build.gradle
    androidは

    「apply plugin: 'com.android.library'」を読み込む
    &

    android用のSDK version等の記述をする

    必要があるので分ける

    View Slide

  18. Gradle設定
    IntelliJ IDEAだとデフォルトで用意されている

    View Slide

  19. Gradle設定
    apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    androidMain.dependencies { }
    androidTest.dependencies { }
    iosMain.dependencies { }
    iosTest.dependencies { }
    iosArm32Main.dependsOn iosMain
    iosArm32Test.dependsOn iosTest
    iosArm64Main.dependsOn iosMain
    iosArm64Test.dependsOn iosTest
    jsMain.dependencies { }
    jsTest.dependencies { }
    jvmMain.dependencies { }
    jvmTest.dependencies { }
    }
    } library/build.gradle

    View Slide

  20. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    library/build.gradle

    View Slide

  21. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    library/build.gradle

    View Slide

  22. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    android用のgradleは別で定義

    (略) 詳しくはサンプルを見てください
    library/build.gradle

    View Slide

  23. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    publish用のgradleは別定義(後述)
    library/build.gradle

    View Slide

  24. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    library/build.gradle

    View Slide

  25. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    Kotlin1.3から書き方が変わった
    library/build.gradle

    View Slide

  26. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    targets {
    fromPreset(presets.android, 'android')
    fromPreset(presets.iosArm64, 'ios')
    fromPreset(presets.js, 'js')
    fromPreset(presets.jvm, 'jvm')
    }
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    androidMain.dependencies { }
    Gradle設定
    ~Kotlin1.3
    library/build.gradle

    View Slide

  27. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    library/build.gradle

    View Slide

  28. iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    androidMain.dependencies { }
    androidTest.dependencies { }
    iosMain.dependencies { }
    iosTest.dependencies { }
    iosArm32Main.dependsOn iosMain
    iosArm32Test.dependsOn iosTest
    iosArm64Main.dependsOn iosMain
    iosArm64Test.dependsOn iosTest
    jsMain.dependencies { }
    jsTest.dependencies { }
    jvmMain.dependencies { }
    jvmTest.dependencies { }
    }
    }
    Gradle設定
    それぞれの依存を定義
    library/build.gradle

    View Slide

  29. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    library/build.gradle

    View Slide

  30. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android()
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    commonMain.dependencies { }
    commonTest.dependencies { }
    Gradle設定
    library/build.gradle

    View Slide

  31. apply plugin: 'kotlin-multiplatform'
    apply from: 'android.gradle'
    apply from: rootProject.file('gradle/publish.gradle')
    kotlin {
    android {
    publishLibraryVariants("release")
    }
    iosX64('ios')
    iosArm32('iosArm32')
    iosArm64('iosArm64')
    js()
    jvm()
    sourceSets {
    Gradle設定
    library/build.gradle
    android libraryは

    release buildを指定する必要がある

    View Slide

  32. apply plugin: 'maven-publish'
    def pomConfig = {
    licenses {
    license {
    name POM_LICENSE_NAME
    url POM_LICENSE_URL
    distribution POM_LICENSE_DIST
    }
    }
    developers {
    developer {
    id POM_DEVELOPER_ID
    name POM_DEVELOPER_NAME
    organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    afterEvaluate {
    project.publishing.publications.all {
    pom.withXml {
    def root = asNode()
    root.appendNode('name', project.name)
    root.appendNode('description', POM_DESCRIPTION)
    root.appendNode('url', SITE_URL)
    root.children().last() + pomConfig
    }
    groupId = BINTRAY_PACKAGE
    if (it.name.contains('metadata')) {
    artifactId = "${project.name}"
    } else {
    artifactId = "${project.name}-$name"
    }
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle

    View Slide

  33. apply plugin: 'maven-publish'
    def pomConfig = {
    licenses {
    license {
    name POM_LICENSE_NAME
    url POM_LICENSE_URL
    distribution POM_LICENSE_DIST
    }
    }
    developers {
    developer {
    id POM_DEVELOPER_ID
    name POM_DEVELOPER_NAME
    organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle

    View Slide

  34. apply plugin: 'maven-publish'
    def pomConfig = {
    licenses {
    license {
    name POM_LICENSE_NAME
    url POM_LICENSE_URL
    distribution POM_LICENSE_DIST
    }
    }
    developers {
    developer {
    id POM_DEVELOPER_ID
    name POM_DEVELOPER_NAME
    organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    maven publish pluginをapply

    View Slide

  35. apply plugin: 'maven-publish'
    def pomConfig = {
    licenses {
    license {
    name POM_LICENSE_NAME
    url POM_LICENSE_URL
    distribution POM_LICENSE_DIST
    }
    }
    developers {
    developer {
    id POM_DEVELOPER_ID
    name POM_DEVELOPER_NAME
    organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    pomに書き込む用の変数を定義

    View Slide

  36. apply plugin: 'maven-publish'
    def pomConfig = {
    licenses {
    license {
    name "The Apache Software License, Version 2.0"
    url "http://www.apache.org/licenses/LICENSE-2.0.txt"
    distribution "repo"
    }
    }
    developers {
    developer {
    id "aakira"
    name "aakira"
    organization "aakira"
    organizationUrl "https://github.com/aakira"
    }
    }
    scm {
    url "https://github.com/aakira/Napier"
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    実際の中身

    View Slide

  37. apply plugin: 'maven-publish'
    def pomConfig = {
    licenses {
    license {
    name POM_LICENSE_NAME
    url POM_LICENSE_URL
    distribution POM_LICENSE_DIST
    }
    }
    developers {
    developer {
    id POM_DEVELOPER_ID
    name POM_DEVELOPER_NAME
    organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle

    View Slide

  38. organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    afterEvaluate {
    project.publishing.publications.all {
    pom.withXml {
    def root = asNode()
    root.appendNode('name', project.name)
    root.appendNode('description', POM_DESCRIPTION)
    root.appendNode('url', SITE_URL)
    root.children().last() + pomConfig
    }
    groupId = BINTRAY_PACKAGE
    if (it.name.contains('metadata')) {
    artifactId = "${project.name}"
    } else {
    artifactId = "${project.name}-$name"
    }
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    publishで作られる成果物に全てに対して

    View Slide

  39. organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    afterEvaluate {
    project.publishing.publications.all {
    pom.withXml {
    def root = asNode()
    root.appendNode('name', project.name)
    root.appendNode('description', POM_DESCRIPTION)
    root.appendNode('url', SITE_URL)
    root.children().last() + pomConfig
    }
    groupId = BINTRAY_PACKAGE
    if (it.name.contains('metadata')) {
    artifactId = "${project.name}"
    } else {
    artifactId = "${project.name}-$name"
    }
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    xmlを作成

    View Slide

  40. organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    afterEvaluate {
    project.publishing.publications.all {
    pom.withXml {
    def root = asNode()
    root.appendNode('name', project.name)
    root.appendNode('description', POM_DESCRIPTION)
    root.appendNode('url', SITE_URL)
    root.children().last() + pomConfig
    }
    groupId = BINTRAY_PACKAGE
    if (it.name.contains('metadata')) {
    artifactId = "${project.name}"
    } else {
    artifactId = "${project.name}-$name"
    }
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    先程指定した変数を追加

    View Slide

  41. organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    afterEvaluate {
    project.publishing.publications.all {
    pom.withXml {
    def root = asNode()
    root.appendNode('name', project.name)
    root.appendNode('description', POM_DESCRIPTION)
    root.appendNode('url', SITE_URL)
    root.children().last() + pomConfig
    }
    groupId = BINTRAY_PACKAGE
    if (it.name.contains('metadata')) {
    artifactId = "${project.name}"
    } else {
    artifactId = "${project.name}-$name"
    }
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle

    View Slide

  42. organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    afterEvaluate {
    project.publishing.publications.all {
    pom.withXml {
    def root = asNode()
    root.appendNode('name', project.name)
    root.appendNode('description', POM_DESCRIPTION)
    root.appendNode('url', SITE_URL)
    root.children().last() + pomConfig
    }
    groupId = BINTRAY_PACKAGE
    if (it.name.contains('metadata')) {
    artifactId = "${project.name}"
    } else {
    artifactId = "${project.name}-$name"
    }
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    metadataをrename

    View Slide

  43. organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    afterEvaluate {
    project.publishing.publications.all {
    pom.withXml {
    def root = asNode()
    root.appendNode('name', project.name)
    root.appendNode('description', POM_DESCRIPTION)
    root.appendNode('url', SITE_URL)
    root.children().last() + pomConfig
    }
    groupId = BINTRAY_PACKAGE
    if (it.name.contains('metadata')) {
    artifactId = "${project.name}"
    } else {
    artifactId = "${project.name}-$name"
    }
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    metadata=commonMainの部分のこと

    View Slide

  44. organization POM_ORGANIZATION_NAME
    organizationUrl POM_ORGANIZATION_URL
    }
    }
    scm {
    url SITE_URL
    }
    }
    afterEvaluate {
    project.publishing.publications.all {
    pom.withXml {
    def root = asNode()
    root.appendNode('name', project.name)
    root.appendNode('description', POM_DESCRIPTION)
    root.appendNode('url', SITE_URL)
    root.children().last() + pomConfig
    }
    groupId = BINTRAY_PACKAGE
    if (it.name.contains('metadata')) {
    artifactId = "${project.name}"
    } else {
    artifactId = "${project.name}-$name"
    }
    }
    }
    Gradle設定 - Maven Publish -
    gradle/publish.gradle
    commonMainはsuffixなし

    他はsuffixに環境名をつける
    e.g. napier-android, napier-js

    View Slide

  45. Gradle設定 - Maven Publish -
    pom-default.xml


    The Apache Software License, Version 2.0
    http://www.apache.org/licenses/LICENSE-2.0.txt
    repo




    aakira
    aakira
    aakira
    https://github.com/aakira



    https://github.com/aakira/Napier

    View Slide

  46. Gradle設定 - Maven Publish -
    • publish
    • publishAndroidReleasePublicationToMavenLocal
    • publishIosArm32PublicationToMavenLocal
    • publishIosArm64PublicationToMavenLocal
    • publishIosPublicationToMavenLocal
    • publishJsPublicationToMavenLocal
    • publishJvmPublicationToMavenLocal
    • publishKotlinMultiplatformPublicationToMavenLocal
    • publishMetadataPublicationToMavenLocal
    • publishToMavenLocal
    targetの数だけmaven publishに関するtaskが作られる

    View Slide

  47. Gradle設定 - Maven Publish -
    $ ./gradlew publishToMavenLocal
    build
    └── publications
    ├── androidRelease
    │ ├── module.json
    │ └── pom-default.xml
    ├── ios
    │ ├── module.json
    │ └── pom-default.xml
    ├── iosArm32
    │ ├── module.json
    │ └── pom-default.xml
    ├── iosArm64
    │ ├── module.json
    │ └── pom-default.xml
    ├── js
    │ ├── module.json
    │ └── pom-default.xml
    ├── jvm
    │ ├── module.json
    │ └── pom-default.xml
    ├── kotlinMultiplatform
    │ ├── module.json
    │ └── pom-default.xml
    └── metadata
    ├── module.json
    └── pom-default.xml

    View Slide

  48. build
    └── publications
    ├── androidRelease
    │ ├── module.json
    │ └── pom-default.xml
    ├── ios
    │ ├── module.json
    │ └── pom-default.xml
    ├── iosArm32
    │ ├── module.json
    │ └── pom-default.xml
    ├── iosArm64
    │ ├── module.json
    │ └── pom-default.xml
    ├── js
    Gradle設定 - Maven Publish -
    oMavenLocal

    View Slide

  49. ├── iosArm32
    │ ├── module.json
    │ └── pom-default.xml
    ├── iosArm64
    │ ├── module.json
    │ └── pom-default.xml
    ├── js
    │ ├── module.json
    │ └── pom-default.xml
    ├── jvm
    │ ├── module.json
    │ └── pom-default.xml
    ├── kotlinMultiplatform
    │ ├── module.json
    │ └── pom-default.xml
    └── metadata
    ├── module.json
    └── pom-default.xml
    Gradle設定 - Maven Publish -
    oMavenLocal

    View Slide

  50. Gradle設定 - Gradle Publish -
    /build.gradle
    buildscript {
    repositories {
    ...
    }
    dependencies {
    ...
    classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4"
    ...
    }
    }
    https://github.com/bintray/gradle-bintray-plugin

    View Slide

  51. apply plugin: 'com.jfrog.bintray'
    def getBintrayUserProperty() {
    return hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
    }
    def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    bintrayUpload.doFirst {
    publications = publishing.publications.collect {
    it.name
    }.findAll {
    it != "kotlinMultiplatform"
    }
    }
    bintrayUpload.dependsOn publishToMavenLocal
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle

    View Slide

  52. apply plugin: 'com.jfrog.bintray'
    def getBintrayUserProperty() {
    return hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
    }
    def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle

    View Slide

  53. apply plugin: 'com.jfrog.bintray'
    def getBintrayUserProperty() {
    return hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
    }
    def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle
    bintrayのpluginをapply

    View Slide

  54. apply plugin: 'com.jfrog.bintray'
    def getBintrayUserProperty() {
    return hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
    }
    def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle
    bintrayのuser名, API Keyを読み込む
    gitに追加されないlocalの

    ~/.gradle/gradle.properties
    に書いておくと良い

    View Slide

  55. def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') :
    System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle

    View Slide

  56. def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') :
    System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle
    keyをセット

    View Slide

  57. def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') :
    System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle
    upload後すぐに公開しない

    View Slide

  58. def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') :
    System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle

    View Slide

  59. def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') :
    System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = 'maven'
    name = 'napier'
    userOrg = 'aakira'
    licenses = ['Apache-2.0']
    vcsUrl = 'https://github.com/aakira/Napier.git'
    websiteUrl = 'https://github.com/aakira/Napier'
    issueTrackerUrl = 'https://github.com/aakira/Napier/issues'
    version {
    name = '0.0.1'
    vcsTag = '0.0.1'
    released = new Date()
    }
    }
    }
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle

    View Slide

  60. def getBintrayApiKeyProperty() {
    return hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') :
    System.getenv('BINTRAY_API_KEY')
    }
    bintray {
    user = getBintrayUserProperty()
    key = getBintrayApiKeyProperty()
    publish = false
    pkg {
    repo = BINTRAY_REPOSITORY
    name = BINTRAY_NAME
    userOrg = GROUP
    licenses = ['Apache-2.0']
    vcsUrl = VCS_URL
    websiteUrl = SITE_URL
    issueTrackerUrl = ISSUE_URL
    version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle

    View Slide

  61. version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    bintrayUpload.doFirst {
    publications = publishing.publications.collect {
    it.name
    }.findAll {
    it != "kotlinMultiplatform"
    }
    }
    bintrayUpload.dependsOn publishToMavenLocal
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle
    bintrayにuploadするpublicationsを指定

    View Slide

  62. version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    bintrayUpload.doFirst {
    publications = publishing.publications.collect {
    it.name
    }.findAll {
    it != "kotlinMultiplatform"
    }
    }
    bintrayUpload.dependsOn publishToMavenLocal
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle
    [project name]-kotlinMultiplatform

    というディレクトリがアップロードされてしまうので除外

    View Slide

  63. version {
    name = rootProject.ext.LIBRARY_VERSION_NAME
    vcsTag = rootProject.ext.LIBRARY_VERSION_NAME
    released = new Date()
    }
    }
    }
    bintrayUpload.doFirst {
    publications = publishing.publications.collect {
    it.name
    }.findAll {
    it != "kotlinMultiplatform"
    }
    }
    bintrayUpload.dependsOn publishToMavenLocal
    Gradle設定 - Gradle Publish -
    gradle/publish.gradle
    bintrayUpload taskにpublishToMavenLocalを依存させる

    View Slide

  64. Wat Arun, Bangkok, Thailand
    BintrayへのUpload

    View Slide

  65. BintrayへのUpload

    View Slide

  66. BintrayへのUpload
    今回はMavenを選択

    publish.gradleのBINTRAY_REPOSITORYと一致

    View Slide

  67. BintrayへのUpload

    View Slide

  68. BintrayへのUpload
    UI変わった

    View Slide

  69. BintrayへのUpload
    BINTRAY_NAME
    ISSUE_URL
    VCS_URL
    SITE_URL

    View Slide

  70. BintrayへのUpload
    $ ./gradlew clean
    $ ./gradlew bintrayUpload

    View Slide

  71. BintrayへのUpload

    View Slide

  72. BintrayへのUpload
    Publish allを選択すると公開される

    View Slide

  73. BintrayへのUpload
    /build.gradle
    buildscript {
    repositories {
    ...
    maven { url "http://dl.bintray.com/[bintray repository]/[bintray name]" }
    ...
    }
    }

    View Slide

  74. BintrayへのUpload
    /build.gradle
    buildscript {
    repositories {
    ...
    maven { url "http://dl.bintray.com/[bintray repository]/[bintray name]" }
    ...
    }
    }
    ライブラリ毎にmavenのrepositoryを書かないといけない

    View Slide

  75. BintrayへのUpload
    右上のActionから選択

    View Slide

  76. BintrayへのUpload
    それっぽい説明をちゃんと書く

    View Slide

  77. BintrayへのUpload
    /build.gradle
    buildscript {
    repositories {
    jcenter()
    }
    }

    View Slide

  78. Wat Paknam, Bangkok, Thailand
    Summary

    View Slide

  79. Summary
    • Kotlin1.3からはgradleを1つにした構成にしましょう
    • metadataの成果物はcommonのこと
    • androidの配布はreleaseを明示的に書く必要あり
    • ライブラリをローカルで参照する方法はサンプルを(時間の都合)
    • Napierのpublish.gradleコピペすればすぐ上げられる

    (先人の犠牲を無駄にするな...)

    View Slide

  80. Have a nice Kotlin
    @_a_akira
    Bagan, Myanmar

    View Slide