如何使用 artifactoryPublish 发布发布和调试工件

How to use artifactoryPublish to publish release and debug artifacts

我有 Android 个在发布和调试版本中构建 AAR 或 APK 的 Studio 项目。我想将这些发布到我的 Artifactory 服务器上不同的存储库。 JFrog examples 似乎没有涵盖这种情况。

这是否意味着最佳做法是仅构建发布版或仅构建调试版,然后根据构建类型选择上传内容和上传位置?

对于快照+发布版本,您可以使用sonatype(又名mavencentral)。几周前我做了一个简短的指南,你可能会发现它有一些用处。 How to publish Android AARs - snapshots/release to Mavencentral

我配置了我的 android 库 build.gradle 文件,编译后的 aar 文件可以上传到不同的 repos,具体取决于构建类型。
例如,您想将调试工件发布到 'libs-debug-local' 存储库并将工件发布到 'libs-release-local' 存储库。

//First you should configure all artifacts you want to publish
publishing {
    publications {

        //Iterate all build types to make specific 
        //artifact for every build type
        android.buildTypes.all { variant ->

            //it will create different 
            //publications ('debugAar' and 'releaseAar')
            "${variant.name}Aar"(MavenPublication) {
                def manifestParser = new com.android.builder.core.DefaultManifestParser()

                //Set values from Android manifest file
                groupId manifestParser.getPackage(android.sourceSets.main.manifest.srcFile)
                version = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
                artifactId project.getName()

                // Tell maven to prepare the generated "*.aar" file for publishing
                artifact("$buildDir/outputs/aar/${project.getName()}-${variant.name}.aar")
            }
        }
    }
}

//After configuring publications you should
//create tasks to set correct repo key
android.buildTypes.all { variant ->

    //same publication name as we created above
    def publicationName = "${variant.name}Aar"

    //new task name
    def taskName = "${variant.name}Publication"

    //in execution time setting publications and repo key, dependent on build type
    tasks."$taskName" << {
        artifactoryPublish {
            doFirst {
                publications(publicationName)
                clientConfig.publisher.repoKey = "libs-${variant.name}-local"
            }
        }
    }

    //make tasks assembleDebug and assembleRelease dependent on our new tasks
    //it helps to set corrent values for every task
    tasks."assemble${variant.name.capitalize()}".dependsOn(tasks."$taskName")
}

//Inside artifactory block just set url and credential, without setting repo key and publications
artifactory {
    contextUrl = 'http://artifactory.cooperok.com:8081/artifactory'
    publish {
        repository {
            username = "username"
            password = "password"
        }
        defaults {
            publishArtifacts = true

            // Properties to be attached to the published artifacts.
            properties = ['qa.level': 'basic', 'dev.team': 'core']
        }
    }
}

就是这样。现在,如果你 运行 命令

Win : gradlew assembleRelease artifactoryPublish Mac : ./gradlew assembleRelease artifactoryPublish

aar 文件将上传到 'libs-release-local' 存储库。
如果你 运行

Win : gradlew assembleDebug artifactoryPublish Mac : ./gradlew assembleDebug artifactoryPublish

它将上传到 'libs-debug-local' 存储库

此配置的一个缺点是您应该始终 运行 artifactoryPublish 任务和 assembleDebug/Release 任务

无法通过@cooperok 的回答获得发布工作,否则它对我有很大帮助。

这是我的代码:

apply plugin: 'com.android.library'
apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 23
        versionCode 1
        versionName "0.0.1"
    }

    publishNonDefault true

    buildTypes {
        debug {
            minifyEnabled false
            debuggable true
        }
        release {
            minifyEnabled false
            debuggable false
        }
        snapshot {
            minifyEnabled false
            debuggable false
        }
    }

}

task androidJavadocs(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath +=    project.files(android.getBootClasspath().join(File.pathSeparator))
}

task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
    classifier = 'javadoc'
    from androidJavadocs.destinationDir
}

task androidSourcesJar(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.srcDirs
}

artifacts {
    archives androidSourcesJar
    archives androidJavadocsJar
}

publishing {
    publications {
        android.buildTypes.all { variant ->
            "${variant.name}"(MavenPublication) {
                def manifestParser = new com.android.builder.core.DefaultManifestParser()
                groupId manifestParser.getPackage(android.sourceSets.main.manifest.srcFile)
                if("${variant.name}".equalsIgnoreCase("release")){
                    version = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
                }else if ("${variant.name}".equalsIgnoreCase("debug")){
                    version = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile).concat("-${variant.name}".toUpperCase().concat("-SNAPSHOT"))
                }else{
                    version = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile).concat("-${variant.name}".toUpperCase())
                }

                artifactId project.getName()

                artifact("$buildDir/outputs/aar/${project.getName()}-${variant.name}.aar")
                artifact androidJavadocsJar

                pom.withXml {
                    def dependencies = asNode().appendNode('dependencies')
                    configurations.getByName("_releaseCompile").getResolvedConfiguration().getFirstLevelModuleDependencies().each {
                        def dependency = dependencies.appendNode('dependency')
                        dependency.appendNode('groupId', it.moduleGroup)
                        dependency.appendNode('artifactId', it.moduleName)
                        dependency.appendNode('version', it.moduleVersion)
                    }
                }
            }
        }
    }
}

android.buildTypes.all { variant ->

    model {
        tasks."generatePomFileFor${variant.name.capitalize()}Publication" {
            destination = file("$buildDir/publications/${variant.name}/generated-pom.xml")
        }
    }

    def publicationName = "${variant.name}"

    def taskName = "${variant.name}Publication"

    task "$taskName"() << {
        artifactoryPublish {
            doFirst {
                tasks."generatePomFileFor${variant.name.capitalize()}Publication".execute()
                publications(publicationName)
                clientConfig.publisher.repoKey = "${variant.name}".equalsIgnoreCase("release") ? "libs-release-local" :
                        "libs-snapshot-local"
            }
        }
    }


    tasks."assemble${variant.name.capitalize()}".dependsOn(tasks."$taskName")

}


artifactory {
    contextUrl = 'http://172.16.32.220:8081/artifactory'
    publish {
        repository {
            username = "admin"
            password = "password"
        }
        defaults {
            publishPom = true
            publishArtifacts = true
            properties = ['qa.level': 'basic', 'dev.team': 'core']
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
}

试试这个:-

def runTasks = gradle.startParameter.taskNames

artifactory {
    contextUrl = "${artifactory_contextUrl}"
    publish {
        repository {
            if ('assembleRelease' in runTasks)
                repoKey = "${artifactory_repository_release}"
            else if ('assembleDebug' in runTasks)
                repoKey = "${artifactory_repository_debug}"

            username = "${artifactory_user}"
            password = "${artifactory_password}"
            maven = true
        }
        defaults {
            publishArtifacts = true
            if ('assembleRelease' in runTasks)
                publications("${artifactory_publication_release}")
            else if ('assembleDebug' in runTasks)
                publications("${artifactory_publication_debug}")
            publishPom = true
            publishIvy = false
        }
    }
}

其中 artifactory_repository_release=libs-release-local 和 artifactory_repository_debug=libs-debug-local

您要在其上发布库的 artifactory 仓库 arr。

gradle 更新为“com.android.tools.build:gradle:3.x.x”后 不再适合我。

我的最终解决方案是:

artifactory {
    contextUrl = ARTIFACTORY_URL
    //The base Artifactory URL if not overridden by the publisher/resolver
    publish {
        repository {
            File debugFile = new File("$buildDir/outputs/aar/${SDK_NAME}-debug.aar");
            if ( debugFile.isFile() )
                repoKey = 'libs-snapshot-local'
            else
                repoKey = 'libs-release-local'

            username = ARTIFACTORY_USER
            password = ARTIFACTORY_PWD
            maven = true
        }
        defaults {
            File debugFile = new File("$buildDir/outputs/aar/${SDK_NAME}-debug.aar");
            if ( debugFile.isFile() )
                publications("debugAar")
            else
                publications("releaseAar")

            publishArtifacts = true
            // Properties to be attached to the published artifacts.
            properties = ['qa.level': 'basic', 'dev.team': 'core']
            // Is this even necessary since it's TRUE by default?
            // Publish generated POM files to Artifactory (true by default)
            publishPom = true
        }
    }
}

publishing {
    publications {
        //Iterate all build types to make specific
        //artifact for every build type
        android.buildTypes.all {variant ->
            //it will create different
            //publications ('debugAar' and 'releaseAar')
            "${variant.name}Aar"(MavenPublication) {
                writeNewPom(variant.name)
                groupId GROUP_NAME
                artifactId SDK_NAME
                version variant.name.endsWith('debug') ? VERSION_NAME + "-SNAPSHOT" : VERSION_NAME
                // Tell maven to prepare the generated "*.aar" file for publishing
                artifact("$buildDir/outputs/aar/${SDK_NAME}-${variant.name}.aar")
            }
        }
    }
}

def writeNewPom(def variant) {
    pom {
        project {
            groupId GROUP_NAME
            artifactId SDK_NAME
            version variant.endsWith('debug') ? VERSION_NAME + "-SNAPSHOT" : VERSION_NAME
            packaging 'aar'

            licenses {
                license {
                    name 'The Apache Software License, Version 2.0'
                    url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    distribution 'repo'
                }
            }
        }
    }.withXml {
        def dependenciesNode = asNode().appendNode('dependencies')

        configurations.api.allDependencies.each {dependency ->
            if (dependency.group != null) {
                def dependencyNode = dependenciesNode.appendNode('dependency')
                dependencyNode.appendNode('groupId', dependency.group)
                dependencyNode.appendNode('artifactId', dependency.name)
                dependencyNode.appendNode('version', dependency.version)
            }
        }
    }.writeTo("$buildDir/publications/${variant}Aar/pom-default.xml")
}

您无需编写复杂的 Groovy 代码即可实现此目的。我有这个用于项目 build.gradle:

artifactory {
    contextUrl = 'https://artifactory.test.com/artifactory'
    publish {
        repository {
            repoKey = 'gradle-testing-local'
            username = artifactory_username
            password = artifactory_password
        }
        defaults {
            publications('debugAar')
            publications('releaseAar')
            publishArtifacts = true

            properties = ['qa.level': 'basic', 'q.os': 'android', 'dev.team': 'core']
            publishPom = true
        }
    }
}

这是我的模块build.gradle:

publishing {
    publications {
        android.buildTypes.all { variant ->
            "${variant.name}Aar"(MavenPublication) {
                groupId libraryGroupId
                version libraryVersion
                artifactId "library-${variant.name}"

                artifact("$buildDir/outputs/aar/library-${variant.name}.aar")
            }
        }
    }
}

这里要注意一个关键点,无论你在项目 build.gradle 的 artifactory.publish.defaults 中放入什么,在 publications() 下都必须匹配模块 build.gradle 的循环:“$ {variant.name}Aar"(MavenPublication).

另一件事是您还设置了 artifactory_username 和 artifactory_password (来自 Artifactory 的加密版本)在 ~/.gradle/gradle/gradle.properties.

artifactory {
        contextUrl = "${artifactory_contextUrl}"
        
        publish {
            repository {
                repoKey = 'your repo key'
                username = "${artifactory_user}"
                password = "${artifactory_password}"
                mavenCompatible = true

            }
            defaults {
                publications('mavenJava')
                publishBuildInfo = true
                publishArtifacts = true
                publishPom = true
            }


        }
        resolve {
            repository {
                repoKey = 'yourrepokey'
                username = "${artifactory_user}"
                password = "${artifactory_password}"
                maven = true

            }
        }
    }
    publishing {
        publications {
            mavenJava(MavenPublication) {
                groupId = "$group"
                artifactId = "$rootProject.name"
                version = "${ver}"
                from components.java
                artifact jar
                artifact javadocJar
                artifact sourcesJar
            }
        }
    }