aepfli / gradle-gitlab-repositories

Handling Maven GitLab dependencies made easy. Define multiple tokens and selectively apply them to repositories, remove the need for repeating Credential handling blocks for different environments.
Eclipse Public License 2.0
13 stars 1 forks source link

Gradle Kotlin DSL has issues with gitlab.upload without a delegate #14

Closed cmdjulian closed 2 years ago

cmdjulian commented 3 years ago

Hey, I'm having difficulties using your awesome looking project. Regardless of what I'm trying, I can't figure out what I have to put into the owner parameter. Using Kotlin DSL with this it gives me:

* What went wrong:
Execution failed for task ':publishScripts-engine-apiPublicationToGitLab-Project-XXXXXXXXRepository'.
> Failed to publish publication 'scripts-engine-api' to repository 'GitLab-Project-XXXXXXXX'
   > Could not PUT 'https://gitlab.com/api/v4/projects/XXXXXXXX/packages/maven/REDACTED.jar'. Received status code 401 from server: Unauthorized

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

I'm using the following gradle.kts file:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.5.31"
    id("maven-publish")
    id("at.schrottner.gitlab-repositories") version "0.4.1"
}

repositories {
    mavenCentral()
}

java.sourceCompatibility = JavaVersion.VERSION_11
java.targetCompatibility = JavaVersion.VERSION_11

dependencies {
    // Spring
    implementation("org.springframework.boot:spring-boot-autoconfigure:2.5.4")

    // Validation
    implementation("org.hibernate:hibernate-validator:7.0.1.Final")

    // Jackson
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.12.5")

    // Kotlin
    implementation(kotlin("reflect"))
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "${JavaVersion.VERSION_11}"
    }
}

tasks.withType<Jar> {
    manifest {
        attributes("Implementation-Title" to project.name, "Implementation-Version" to "${project.version}")
    }
    archiveFileName.set("api.jar")
}

gitLab {
    val gitLabPrivateToken: String by project
    // jobToken will be applied automatically
    token(at.schrottner.gradle.auths.PrivateToken::class.java) {
        name = "privateToken"
        value = gitLabPrivateToken
    }
}

publishing {
    publications {
        create<MavenPublication>("api"){
            artifact(tasks["jar"])
        }
    }

    repositories {
        maven(gitLab.upload(this,"XXXXXXXX"))
    }
}
aepfli commented 3 years ago

hi,

thanks for reaching out. I have to say i am not that familiar with gradle and kotlin BUT the owner versions is just an old way of setting the maven repository with gradle groovy without the maven directive.

Can you try simply using

    repositories {
        maven(gitLab.upload("<your project id>"))
    }

Furthermore it looks like there is not an issue with the defined repository, but with the authorization:

you can check if the token has enough permission by using following curl command, which will upload a file to the generic package registry.

curl --header "PRIVATE-TOKEN: <your_access_token>" \
     --upload-file path/to/file.txt \
     "https://gitlab.example.com/api/v4/projects/<your project id>/packages/generic/my_package/0.0.1/file.txt"

I hope this helps.

Best regards Simon

PS; thank you for using my plugin, and opening an issue (this is the first one)

aepfli commented 3 years ago

i will also take with me, that i will add some more kotlin examples, and tests

cmdjulian commented 3 years ago

Thanks for you fast reply! The following works so I guess my token is fine.

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.5.31"
    id("maven-publish")
}

repositories {
    mavenCentral()
}

java.sourceCompatibility = JavaVersion.VERSION_11
java.targetCompatibility = JavaVersion.VERSION_11

dependencies {
    // Spring
    implementation("org.springframework.boot:spring-boot-autoconfigure:2.5.4")

    // Validation
    implementation("org.hibernate:hibernate-validator:7.0.1.Final")

    // Jackson
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.12.5")

    // Kotlin
    implementation(kotlin("reflect"))
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "${JavaVersion.VERSION_11}"
    }
}

tasks.withType<Jar> {
    manifest {
        attributes("Implementation-Title" to project.name, "Implementation-Version" to "${project.version}")
    }
    archiveFileName.set("api.jar")
}

publishing {
    publications {
        create<MavenPublication>("scripts-engine-api"){
            artifact(tasks["jar"])
        }
    }

    repositories {
        maven {
            name = "GitLab"
            url = uri("https://gitlab.com/api/v4/groups/XXXXXXXX/-/packages/maven")

            if (System.getenv("CI_JOB_TOKEN") != null) {
                // use ci token in gitlab pipeline
                credentials(HttpHeaderCredentials::class) {
                    name = "Job-Token"
                    value = System.getenv("CI_JOB_TOKEN")
                }
            } else {
                // use private token when run locally
                val gitLabPrivateToken: String by project
                credentials(HttpHeaderCredentials::class) {
                    name = "Private-Token"
                    value = gitLabPrivateToken
                }
            }

            authentication {
                create<HttpHeaderAuthentication>("header")
            }
        }
    }
}
cmdjulian commented 3 years ago

When I try you proposed solution I'm getting the following error:

> Task :publishApiPublicationToMavenRepository FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':publishApiPublicationToMavenRepository'.
> Cannot convert the provided notation to a File or URI: at.schrottner.gradle.RepositoryActionHandler$1@5d0b0d4a.
  The following types/formats are supported:
    - A String or CharSequence path, for example 'src/main/java' or '/usr/include'.
    - A String or CharSequence URI, for example 'file:/usr/include'.
    - A File instance.
    - A Path instance.
    - A Directory instance.
    - A RegularFile instance.
    - A URI or URL instance.
    - A TextResource instance.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2s
6 actionable tasks: 5 executed, 1 up-to-date

This is my gradle file now:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.5.31"
    id("maven-publish")
    id("at.schrottner.gitlab-repositories") version "0.4.1"
}

repositories {
    mavenCentral()
}

java.sourceCompatibility = JavaVersion.VERSION_11
java.targetCompatibility = JavaVersion.VERSION_11

dependencies {
    // Spring
    implementation("org.springframework.boot:spring-boot-autoconfigure:2.5.4")

    // Validation
    implementation("org.hibernate:hibernate-validator:7.0.1.Final")

    // Jackson
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.12.5")

    // Kotlin
    implementation(kotlin("reflect"))
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "${JavaVersion.VERSION_11}"
    }
}

tasks.withType<Jar> {
    manifest {
        attributes("Implementation-Title" to project.name, "Implementation-Version" to "${project.version}")
    }
    archiveFileName.set("api.jar")
}

gitLab {
    val gitLabPrivateToken: String by project
    // jobToken will be applied automatically
    token(at.schrottner.gradle.auths.PrivateToken::class.java) {
        name = "privateToken"
        value = gitLabPrivateToken
    }
}

publishing {
    publications {
        create<MavenPublication>("api"){
            artifact(tasks["jar"])
        }
    }

    repositories {
        maven(gitLab.upload("XXXXXXXX"))
    }
}
aepfli commented 3 years ago

Thank you - i will enhance my integration tests today in the evening. (Or at least try to) so I can provide you a working example. Sorry that my initial suggestions did not work

cmdjulian commented 3 years ago

No problem! Thank you for your help!
I'm thrilled to test it out! :)

aepfli commented 3 years ago

so i debugged, and i am printing things to the terminal, but i am not getting any smarter :D

somehow following code is not returning an Action Object but an RepositoryActionHandler aka itself. https://github.com/aepfli/gradle-gitlab-repositories/blob/main/src/main/groovy/at/schrottner/gradle/RepositoryActionHandler.groovy#L67-L86

i am not sure why this is happening, but i will investigate further

aepfli commented 3 years ago

the bug is still valid, but there is a workaround:

publishing {
    repositories {
        gitLab.upload(this,"<your project id>") {
            name.set("Test") // i recommend to name it, for easier usage :)
        }
    }
}

I uploaded with this code to the test repository, and everything worked as intended, please check.

I still need to investigate, why the other approach has such a strange behaviour, but for now it is not as important as we do have a workarround

aepfli commented 3 years ago

@cmdjulian is the workarround working for you for now, if not i will try to put more effort into this in the current week :)

aepfli commented 2 years ago

added kotlin test cases directly into main, so we have some kind of verification that this works as intended with the workarround configuration - i will most likely rework the RepositoryHandler to actually implement the MavenArtifactRepository Action interface

aepfli commented 2 years ago

i also improved the documentation a little bit - it should cover now more kotlin cases.

A big todo is now to also try to download a dependency via tests, as i currently only verify the configuration via logs, but not actually via a real fetch.

aepfli commented 2 years ago

@cmdjulian i created a pre release - https://github.com/aepfli/gradle-gitlab-repositories/releases/tag/0.5.0-beta1

I took care of the whole setup, and i added tests to cover this.

The DSL does not look really intuitive for Kotlin (it was not my initial goal) and i will try to improve this, as soon as i have time.

I would highly appreciate some feedback regarding 0.5.0-beta1 thank you