发布开源库到Jitpack

1,754 阅读5分钟

发布开源库到Jitpack

本人所有文章禁止任何形式的转载,谢谢

步骤

  1. 首先代码需要发布到Github,然后进入Jitpack,然后输入我们的GitHub的地址,比如这样的的

    jitpack.io/#storytelle…

  2. 选择Commits

    commits

    点击我们需要发布的提交对应的Get it 即可。

    我们暂时不选择Releases,因为我们不能保证每一个release 在Jitpack 上是可以编译成功的,因为本地环境是由我们自己配置的,然而Jitpack 不是。所以即使我们的代码没有任何问题也不能保证编译不会出错。而我们的代码一旦提交,然后添加tag 就有点不能“挽回了”,如果编译失败,一个tag 就被我们浪费掉了,后续的tag 只能继续增加,使用force push 什么的对Jitpack 是无效的。在jitpack 中登录自己的github 账号,可以删除指定的release,但是有时间限制,大概是超过7天就不行了,可以看一下上图中的Get it 按钮的右边就有一个❄️的标记,代表这个已经不能够删除了。

  3. Maven Publish

    如果要发布一个Library,必然需要maven-publish(查看详情),这是一个Gradle 插件,可以配置我们发布的Library,比如版本、作者,依赖等信息。一般在maven central 发布的库都带有详细的bom 信息,但是jitpack 并不提供和maven central 一样的网页交互逻辑,使用者或者自己都是看不到的。

    后面的内容假定你已经添加了maven-publish 插件。

    single-pub-var

    android {
        publishing {
            singleVariant("release") {
                withSourcesJar()
            }
        }
    }
    

    如果不添加上述内容,会有一个警告(能正常工作)

    Encountered duplicate path "main/**/*/.kt" during copy operation configured with DuplicatesStrategy.WARN

    afterEvaluate {
        publishing {
            publications {
                register<MavenPublication>("release") {
                    from(components["release"])
                }
            }
        }
    }
    

    仅仅添加maven-publish,而不使用上述的代码会有错误

    ⚠️ ERROR: No build artifacts found

    上述代码来自developer.android.google.cn/build/publi…(google 的中文文档很久没有更新,建议直接查看原文)

    其实我们不需要指定譬如version,artifactId 这类信息,因为JitPack 会帮我们填写的,即便手动填写也会被命令行参数所覆盖。即使你需要指定版本等信息也不应该在此处,而是这样

    version = "1.0.0"
    afterEvaluate {
        //...
    }
    

    当然了这样配置也依然有点麻烦,如果我们的构建文件的名称是build.gradle,即这个文件的语法是groovy 的情况下是完全不需要第三步的,大概JitPack 会在应用patch 后才进行编译工作。

    如果你既不希望麻烦,也想要使用build.gradle.kts,那就需要把这段代码封装起来。封装的方法有

    1. 预编译脚本

    2. Script Plugins

    3. Gradle Plugins

    区别是前两者一旦引入便不能在进行任何配置,而后者在使用时需要手动调用函数,在这个过程是可以传入参数的。前两者之间的区别应该是预编译脚本可以导入第三方依赖。同时还存在两种“编写”的方法,分为协同构建buildSrc,不过buildSrc 比较“古老”,使用时会有一个警告,而且还会和本身的项目的依赖产生冲突,我们用协同构建就好了。

    最终就像这样

    common-publish/src/main/kotlin/common-publish.gradle.kts

    plugins {
        `maven-publish`
    }
    
    version = "1.0.1"
    
    afterEvaluate {
        publishing {
            publications {
                register<MavenPublication>("release") {
                    val component = components.find {
                        it.name == "java" || it.name == "release"
                    }
                    from(component)
                }
            }
        }
    }
    

    当前还遇到一个问题就是无法通过在根目录批量apply 插件,必须手动导入插件。如果你想关注此事的动态stackoverflow.com/questions/7…

  4. 现在就是点击Get it 的时候了

    然后你大概率会遇到这样的错误

    No matching variant of com.android.tools.build:gradle:8.1.1 was found. The consumer was configured to find a library for use during runtime, compatible with Java 8, packaged as a jar, and its dependencies declared externally, as well as attribute 'org.gradle.plugin.api-version' with value '8.0' but: - Variant 'apiElements' capability com.android.tools.build:gradle:8.1.1 declares a library, packaged as a jar, and its dependencies declared externally: - Incompatible because this component declares a component for use during compile-time, compatible with Java 11 and the consumer needed a component for use during runtime, compatible with Java 8

    信息很长,虽然我们不懂什么意思,但是可以肯定这跟Jdk 版本有关,然后项目里唯一一处跟Jdk 有关,并且与Jdk 8 有关的地方就是

    android {
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
    

    修改成

    android {
        def javaVersion = JavaVersion.VERSION_11
        compileOptions {
            sourceCompatibility javaVersion
            targetCompatibility javaVersion
        }
    
        kotlinOptions {
            jvmTarget = javaVersion.toString()
        }
    }
    

    就好了。

    然后你还可能会遇到

    Failed to apply plugin 'com.android.internal.application'. Android Gradle plugin requires Java 17 to run. You are currently using Java 11. Your current JDK is located in /usr/lib/jvm/jdk-11 You can try some of the following options: - changing the IDE settings. - changing the JAVA_HOME environment variable. - changing org.gradle.java.home in gradle.properties.

    Jitpack 默认使用jdk 11 编译所有的项目,如果我们的项目不兼容Jdk 11(基本都不兼容)的话,需要手动设置环境

    在项目根目录创建jitpack.yml,然后填写

    jdk:
        - openjdk17
    
  5. 你的项目可能还用到了ndk

    jdk:
        - openjdk8
    before_install:
        - yes | sdkmanager "cmake;3.22.1"
        - sdk install java 17.0.5-oracle
        - sdk use java 17.0.5-oracle
    

    首先设置环境为jdk8,因为sdkmanager 最高支持jdk8。在安装cmake 之后,更改jdk 版本为17。少一步都不行。

最后

还有一种发布Library 的方法就是发布到maven central,后者应用更为广泛,很多知名的开源项目都是发布在这个上面的,也有很多SDK(闭源)也会发布到这里,回想起刚学习android 时,需要手动下载jar,然后放到libs 目录下,真的是太逊了。

但是maven central 存在一个问题,即开源时用一套代码,发布时用另一套代码,因为这完全通过我们的本地环境编译然后发布的。不过JitPack 就没有这个问题,开源的代码就是发布的代码,和Github Action 类似。我觉得这种的更符合我的开源理念。我并不是说maven central 上的库都是有问题。

但是jitpack 也存在一个问题,就是服务器可能会宕机,导致项目无法编译。如果遇到之前都还好好工作突然不行的情况,可能不是你的问题,最好还是等明天看看。