I have a kotlin multiplatform project that I am trying to publish to my Jetbrains Space maven repo. It successfully publishes to the repo but the name of the artifact is the name of my module in the project which is not the name as what the project is called.
example the published artifact is
com.tycz:sharedmodule-android:0.2.0
but I want it to be something like
com.tycz:myLibrary-android:0.2.0
I am using these doc's as reference
This is my build.gradle
plugins {
kotlin("multiplatform")
id("com.android.library")
id("kotlin-android-extensions")
id("kotlinx-serialization")
id("maven-publish")
}
repositories {
gradlePluginPortal()
google()
jcenter()
mavenCentral()
}
group = "com.tycz"
version = "0.2.0"
kotlin {
android{
publishLibraryVariants("release")
}
ios {
binaries {
framework {
baseName = "sharedmodule"
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.ktor:ktor-client-core:1.4.1")
implementation("io.ktor:ktor-client-json:1.4.1")
implementation("io.ktor:ktor-client-serialization:1.4.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting {
dependencies {
implementation("androidx.core:core-ktx:1.3.2")
implementation("io.ktor:ktor-client-android:1.4.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2")
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.12")
}
}
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:1.4.1")
}
}
val iosTest by getting
}
}
android {
compileSdkVersion(30)
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdkVersion(24)
targetSdkVersion(30)
versionCode = 1
versionName = "1.0"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
packagingOptions {
excludes.add("META-INF/*.kotlin_module")
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
afterEvaluate {
publishing {
repositories {
maven {
url = uri("https://maven.pkg.jetbrains.space/tyczj/p/vqi18/tweedle")
credentials {
username = "$username"
password = "$password"
}
}
}
}
}
val packForXcode by tasks.creating(Sync::class) {
group = "build"
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
val framework =
kotlin.targets.getByName<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>(
targetName
).binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
val targetDir = File(buildDir, "xcode-frameworks")
from({ framework.outputDirectory })
into(targetDir)
}
tasks.getByName("build").dependsOn(packForXcode)
How can I change the name of the artifact?
As far as I can see, maven-publish plugin derives artifactId from the Project's name attribute(link), so to change the artifact's name I would recommend setting the appropriate name at your module's settings.gradle.kts like that:
rootProject.name = 'myLibrary'
to change the module name will solve your question
before
include(":android", ":desktop", ":common")
after
include(":android", ":desktop", ":youlib")
Related
I have beow tasks in my build.gradle and just wanted to findout whether I can print the app logs while running test task.
The problem with below code is, need to quit from bootRunStartDaemon to go on to next task. So in that case cannot see app logs anymore.
def process;
tasks.register('bootRunStartDaemon') {
doLast {
ProcessBuilder builder = new ProcessBuilder(gradleCommand, "bootRun", "--args='--spring.profiles.active=it'")
builder.redirectErrorStream(true)
builder.directory(projectDir)
process = builder.start()
InputStream stdout = process.getInputStream()
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout))
while ((line = reader.readLine()) != null) {
println line
}
}
}
tasks.register('bootRunStopDaemon') {
doLast {
process.destroy();
process.waitFor();
if (process.isAlive()) {
process.destroyForcibly();
}
}
}
task healthCheck(dependsOn: bootRunStartDaemon) {
// some code
}
tasks.register('integrationTest', Test ) {
description = 'Run integration tests.'
check.dependsOn integrationTest
group = 'verification'
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
tasks.withType(Test) {
useJUnitPlatform()
// Prints any test outcomes to the console
testLogging {
events "passed", "skipped", "failed"
showStackTraces true
showExceptions true
showCauses true
exceptionFormat "full"
}
}
bootRunStopDaemon.dependsOn(bootRunStartDaemon)
healthCheck.dependsOn(bootRunStartDaemon)
integrationTest.dependsOn(healthCheck)
integrationTest.finalizedBy aggregate, bootRunStopDaemon
I have encountered a problem here. The output AAR package is referenced in other projects, and all method names are changed to var1, var2, var3.
I want to keep the name of the method in AAR consistent with the source code. What should I do?
The gradle configuration is as follows:
classpath "com.android.tools.build:gradle:4.1.2"
plugins {
id 'com.android.library'
id 'maven-publish'
}
afterEvaluate {
publishing {
publications {
release(MavenPublication) {
groupId = 'com.xxx'
artifactId = 'lib-name'
version = rootProject.ext.android.edkLibVersion
def projectName = project.getName()
artifact "build/outputs/aar/${projectName}-release.aar"
pom.withXml {
def dependenciesNode = asNode().appendNode("dependencies")
configurations.implementation.allDependencies.forEach() {
Dependency dependency ->
if (dependency.version != "unspecified" && dependency.name != "unspecified") {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}
}
}
repositories {
maven {
url = "xxx/path"
}
}
}
}
The code source files are as follows::
public interface CameraPreviewCallback {
/**
* xxxxx
*
* #param data xxxx
* #param camera xxxx
*/
void onPreviewFrame(byte[] data, Camera camera, int previewWidth, int previewHeight);
}
aar:
public interface CameraPreviewCallback {
void onPreviewFrame(byte[] var1, Camera var2, int var3, int var4);
}
What do I need to do to keep the method name in AAR unchanged
I currently have a gradle build script for a KMM multiplatform library that looks like below. I'm trying to use JaCoCo to report the test results and code coverage. I can see somewhere the test results in HTML, but I don't get to see the XML reports for test results and code coverage generated anywhere. How can I change this gradle file so that I can get the XML reports generated?
I'm using ./gradlew testCoverage
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
kotlin("plugin.serialization") version "1.4.10"
id("com.android.library")
id("kotlin-android-extensions")
jacoco
}
group = "xxx"
version = "1.0-SNAPSHOT"
repositories {
gradlePluginPortal()
google()
jcenter()
mavenCentral()
}
val coroutinesVersion = "1.3.9-native-mt"
val ktorVersion = "1.4.0"
kotlin {
android()
ios {
}
sourceSets {
val commonMain by getting {
dependencies {
// ...
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
implementation("io.ktor:ktor-client-cio:$ktorVersion")
}
}
val androidMain by getting {
dependencies {
implementation("com.google.android.material:material:1.2.0")
implementation("io.ktor:ktor-client-android:$ktorVersion")
}
}
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:$ktorVersion")
}
val targetName = System.getenv("TARGET_NAME") ?: ""
if (targetName.endsWith("xxx")){
kotlin.srcDirs("src/prod/kotlin")
} else {
kotlin.srcDirs("src/dev/kotlin")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
api("io.ktor:ktor-client-mock:$ktorVersion")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.12")
}
}
}
}
android {
compileSdkVersion(29)
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdkVersion(24)
targetSdkVersion(29)
versionCode = 1
versionName = "1.0"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
flavorDimensions("environment")
productFlavors {
create("dev") {
dimension = "environment"
}
create("prod") {
dimension = "environment"
}
}
}
jacoco {
toolVersion = "0.8.5"
}
val jacocoTestReport by tasks.creating(JacocoReport::class.java) {
reports {
xml.isEnabled = true
csv.isEnabled = false
html.isEnabled = false
}
}
val jacocoTestCoverageVerification by tasks.creating(JacocoCoverageVerification::class.java) {
dependsOn(jacocoTestReport)
violationRules {
rule {
limit {
minimum = "0.8".toBigDecimal()
}
}
}
}
val testCoverage by tasks.registering {
group = "verification"
description = "Runs the unit tests with coverage."
dependsOn("test", jacocoTestReport, jacocoTestCoverageVerification)
tasks["jacocoTestReport"].mustRunAfter("test")
tasks["jacocoTestCoverageVerification"].mustRunAfter("jacocoTestReport")
}
val packForXcode by tasks.creating(Sync::class) {
group = "build"
val mode = System.getenv("CONFIGURATION")?.toUpperCase() ?: "DEBUG"
val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
val framework = kotlin.targets.getByName<KotlinNativeTarget>(targetName).binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
val targetDir = File(buildDir, "xcode-frameworks")
from({ framework.outputDirectory })
into(targetDir)
}
tasks.getByName("build").dependsOn(packForXcode)
PS.: I intentionally masked some strings in the code that are sensitive.
I had a similar issue and solved it by specifying the source directories and execution data. You might need to change these values according to your project.
sourceDirectories.setFrom(files(project.projectDir))
executionData.setFrom(
fileTree(project.projectDir) {
setIncludes(setOf("**/**/*.exec", "**/**/*.ec"))
}
)
I'm trying to migrate from groovy to gradle-kotlin dsl, but I'm new to it, so I dont know how to configure Jfrog Artifactory. Please help me with converting that part of code to gradle-kotlin dsl:
task sourceJar(type: Jar) {
from sourceSets.main.allJava
}
artifactory {
contextUrl = "http://10.0.0.49:8081/artifactory"
publish {
repository {
repoKey = 'gradle-dev-local'
username = artifactory_username
password = artifactory_password
}
defaults {
publications('mavenJava')
publishArtifacts = true
publishPom = true
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId = "ua.tiras.oloader"
artifactId = 'core'
version = "1.0.62"
artifact("$buildDir/libs/${project.getName()}.jar")
artifact sourceJar {
classifier "sources"
}
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.api.allDependencies.each { dependency ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}
}
}
I solved it this way:
val sourcesJar by tasks.creating(Jar::class) {
dependsOn(JavaPlugin.CLASSES_TASK_NAME)
classifier = "sources"
from(sourceSets["main"].allSource)
}
publishing {
publications {
create<MavenPublication>("mavenJava") {
groupId = "ua.tiras"
artifactId = "aloader-core"
version = "0.0.4"
artifact(sourcesJar)
artifact("$buildDir/libs/${project.name}.jar")
pom {
withXml {
asNode().appendNode("dependencies").let {
for (dependency in configurations["api"].dependencies) {
it.appendNode("dependency").apply {
appendNode("groupId", dependency.group)
appendNode("artifactId", dependency.name)
appendNode("version", dependency.version)
}
}
}
}
}
}
}
}
artifactory {
setContextUrl("http://dev.tirascloud.com:8081/artifactory")
publish(delegateClosureOf<PublisherConfig> {
repository(delegateClosureOf<GroovyObject> {
setProperty("repoKey", "gradle-dev-local")
setProperty("username", project.findProperty("artifactory_username") ?: "nouser")
setProperty("password", project.findProperty("artifactory_password") ?: "nopass")
})
defaults(delegateClosureOf<GroovyObject> {
invokeMethod("publications", "mavenJava")
setProperty("publishPom", true)
setProperty("publishArtifacts", true)
})
})
resolve(delegateClosureOf<ResolverConfig> {
setProperty("repoKey", "repo")
})
I found another example - an official one JFrog:
https://github.com/jfrog/project-examples/blob/master/gradle-examples/gradle-kts-example-publish/build.gradle.kts
import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.jfrog.buildinfo", "build-info-extractor-gradle", "4.+")
}
configurations.classpath {
resolutionStrategy {
cacheDynamicVersionsFor(0, "seconds")
cacheChangingModulesFor(0, "seconds")
}
}
}
plugins {
java
`maven-publish`
}
fun javaProjects() = subprojects.filter {
File(it.projectDir, "src").isDirectory
}
val currentVersion: String by project
allprojects {
apply(plugin = "com.jfrog.artifactory")
group = "org.jfrog.test.gradle.publish"
version = currentVersion
status = "Integration"
repositories {
maven("http://127.0.0.1:8081/artifactory/libs-release")
}
}
tasks.named<ArtifactoryTask>("artifactoryPublish") {
skip = true
}
project("services") {
tasks.named<ArtifactoryTask>("artifactoryPublish") {
skip = true
}
}
configure(javaProjects()) {
apply(plugin = "java")
apply(plugin = "maven-publish")
dependencies {
testImplementation("junit:junit:4.7")
}
configure<PublishingExtension> {
publications {
register<MavenPublication>("mavenJava") {
from(components.getByName("java"))
artifact(file("$rootDir/gradle.properties"))
}
}
}
}
project("api") {
apply(plugin = "ivy-publish")
configure<PublishingExtension> {
publications {
register<IvyPublication>("ivyJava") {
from(components.getByName("java"))
artifact(file("$rootDir/settings.gradle.kts")) {
name = "gradle-settings"
extension = "txt"
type = "text"
}
// The config below will add a extra attribute to the ivy.xml
// See http://ant.apache.org/ivy/history/latest-milestone/concept.html#extra
descriptor.withXml {
val info = asNode().get("info") as groovy.util.NodeList
val first = info.first() as groovy.util.Node
first.attributes()["e:architecture"] = "amd64"
}
}
}
}
tasks.named<ArtifactoryTask>("artifactoryPublish") {
publications(publishing.publications["ivyJava"])
}
}
configure<org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention> {
clientConfig.isIncludeEnvVars = true
setContextUrl("http://127.0.0.1:8081/artifactory")
publish {
repository {
setRepoKey("libs-snapshot-local") // The Artifactory repository key to publish to
setUsername(findProperty("artifactory_user")) // The publisher user name
setPassword(findProperty("artifactory_password")) // The publisher password
// This is an optional section for configuring Ivy publication (when publishIvy = true).
ivy {
setIvyLayout("[organization]/[module]/ivy-[revision].xml")
setArtifactLayout("[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]")
setMavenCompatible(true) // Convert any dots in an [organization] layout value to path separators, similar to Maven"s groupId-to-path conversion. True if not specified
}
}
defaults {
// Reference to Gradle publications defined in the build script.
// This is how we tell the Artifactory Plugin which artifacts should be
// published to Artifactory.
publications("mavenJava")
setPublishArtifacts(true)
// Properties to be attached to the published artifacts.
setProperties(mapOf(
"qa.level" to "basic",
"dev.team" to "core"
))
setPublishPom(true) // Publish generated POM files to Artifactory (true by default)
setPublishIvy(true) // Publish generated Ivy descriptor files to Artifactory (true by default)
}
}
}
The accepted answer didn't work for me with the artifactory plugin version 4.27.1. A good place to check is definitely the already mentioned provided example by JFrog. Here is a simplified extract based on the offical example:
configure<org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention> {
clientConfig.isIncludeEnvVars = true
setContextUrl(findProperty("artifactory_url"))
publish {
repository {
setRepoKey(repoKeyValue) // The Artifactory repository key to publish to
setUsername(findProperty("artifactory_user")) // The publisher user name
setPassword(findProperty("artifactory_password")) // The publisher password
setMavenCompatible(true)
}
defaults {
publications("mypublicationreference")
setPublishArtifacts(true)
}
}
}
configure<PublishingExtension> {
publications {
register<MavenPublication>("mypublicationreference") {
from(components.getByName("java"))
artifact("$buildDir/libs/${project.name}.jar")
}
}
}
Note that the referenced properties such as artifactory_url can be defined in a gradle.properties file.
I am facing some issues with the gradle plugin to deploy/publish the jar which is generated by swagger-codegen plugin.
I already looked at this question and my needs are completely different but it is acting like this. It is deploying the jar generated by the spring-boot application instead of the codegen one.
This is my task to generate the source folder:
import io.swagger.codegen.config.CodegenConfigurator
import io.swagger.codegen.DefaultGenerator
def swaggerSourceFile = "${project.rootDir}/build/generated/swagger-json/swagger.json"
def swaggerTargetFolder = 'build/generated/java/src/main/java'
task generateApi {
inputs.file("$swaggerSourceFile")
outputs.dir("$projectDir/$swaggerTargetFolder")
doLast {
def config = new CodegenConfigurator()
config.setInputSpec("$swaggerSourceFile")
config.setOutputDir("$projectDir/$swaggerTargetFolder")
config.setLang('java')
config.setAdditionalProperties([
'apiPackage' : 'com.xyz.abc.testmanager.controller',
'modelPackage' : 'com.xyz.abc.testmanager.model',
'sourceFolder' : swaggerTargetFolder,
'groupId' : 'com.xyz.abc',
"artifactId" : 'testmanager',
'pom.version' : '1.0.' + System.getenv('BUILD_NUMBER')
])
new DefaultGenerator().opts(config.toClientOptInput()).generate()
}
}
clean.doFirst {
delete(swaggerTargetFolder)
}
configurations {
generatedCompile
}
sourceSets {
generated {
compileClasspath = configurations.generatedCompile
java {
srcDir file("${project.buildDir.path}/swagger/src/main/java")
}
}
main {
compileClasspath += generated.output
runtimeClasspath += generated.output
}
test {
compileClasspath += generated.output
runtimeClasspath += generated.output
}
}
The upload task is:
def ifJenkins = System.getenv('BUILD_NUMBER') != null ? true : false
uploadArchives {
repositories {
mavenDeployer {
if(ifJenkins){
repository(url: "http://maven.cloud.test:8081/nexus/content/repositories/releases/") {
authentication(userName: System.getenv('MAVEN_CREDS'), password: System.getenv('MAVEN_CREDS_PASSWORD'))
}
}
else
{
repository(url: "http://maven.cloud.test:8081/nexus/content/repositories/releases/") {
authentication(userName: 'test', password: 'test')
}
}
if(ifJenkins){
pom.version = "1.0." + System.getenv('BUILD_NUMBER')
pom.groupId = "com.xyz.abc"
} else{
pom.version = "0.0." + System.currentTimeMillis()
pom.groupId = "com.xyz.abc"
}
pom.artifactId = jar.baseName
pom.packaging = "jar"
pom.name = "Test Manager Client"
}
}
}
I am stuck here as I am not sure whether the problem is with the task or something else.
How do I make sure that my pom.xml generated by swagger-codegen is actually generating the jar and upload the same jar to maven?