elect86 / magik

Maven Artifacts on Github International for Kotlin
Apache License 2.0
43 stars 6 forks source link
git github github-repository maven maven-repository

magik

Turn your personal Github repository into your personal maven repository.

I was tired of Github Packages requiring authentication even for public access, Sonatype and Maven Central being a pain to setup, the first supporting only one snapshot at time (and you need to deal with cache) and Nexus in general being incredibly slow in comparison, therefore I decided to go on my own and write this

Usually it was already possible doing something like that, but this implicitely meant you had to have the repo cloned locally and manually committ and push. Now these limitations are gone, allowing for even faster development cycles.

What this plugin does is the following, for each project/module:

Welcome Magik (MAven repository on Github written In Kotlin)

plugins {
  id("elect86.magik") version "0.3.3"
}

image

How to use

You have two options (!). Too many, I know, sorry. You can use: 1) a Github repository acting as a pure Maven repository 2) Github Packages without the authentication hassle, even for just consuming dependencies

Method 1, Github repository as Maven repository

Authentication

You should first be sure to be able to connect to GitHub using ssh.

Then create a personal access token, be sure to check repo. Then copy the token and paste it in gradle.property in your home (~/.gradle) as

githubToken=ghp_...

Take in account github is convention, you can change it with whatever you want (read the next section). Magik will look for your token in a variable names as ${githubRepositoryName}Token

Publishing
publishing {
    publications {
         // you can pass a name to overwrite the default "maven"
         // createGithubPublication("my-name") 
        createGithubPublication { this: MavenPublication
            // if your project already defines `groupId`, `artifactId` and `version`, then you can skip these here
            groupId = "org.gradle.sample"
            artifactId = "prova"
            version = "0.1"

            from(components["java"])
        }.github {
            // this adds another (snapshot) publication, copying from the previous one: 
            // - gav coordinates 
            // - component type (java, javaPlatform or war)
            // - name, by default appended with the `Snapshot` postfix, 
            // eg: publishMavenPublicationToGithubRepository ->
            // ->  publishMavenSnapshotPublicationToGithubRepository
            addSnapshotPublication()
        }
    }
    // don't use `repositories.github(..)`, it won't work
    // the dsl construct is necessary to distinguish it from a consume-only repo
    repositories {
        // don't use github(domain: String), that's for fetching, it won't work for publishing
        github {
            // this is optional since `github` is the default value, but it determines 
            // the token name to fetch and the consequent publishing task name 
            // eg: publishMavenPublicationToGithubRepository
            name = "github" 

            // this is mandatory instead: $owner/$repo on github domain
            domain = "kotlin-graphics/mary" // aka https://github.com/kotlin-graphics/mary
        }
    }
}
Fetching
repositories {
    github("kotlin-graphics/mary")
}

or

repositories {
    github("kotlin-graphics", "mary")
}
Publishing

Run publish(Maven)PublicationTo(Github)Repository or publishAllPublicationsTo(Github)Repository

where Maven is the publication name (capitalized) and Github the repository name (capitalized)

> Task :publishMavenPublicationToGithubRepository

kotlin.graphics:gli:0.8.3.0-18 published on kotlin-graphics/mary!

The printed GAV coordinates can then be easily copied and pasted where needed :)

Settings

Sometimes it happens you forget to commit before publishing. In order to avoid these situations, the default setting commitWithChanges will warn you whenever you are committing while there are changes to be committed or not staged for commit.

This requires git being available on path though, which is automatically set at begin in gitOnPath.

defaultCommitWithChanges will instead automatically highlight the given answer when asking if you want to commit anyway with changes.

[magik] Do you want to continue publishing anyway? Y/[N]:

dryRun for running without uploading anything.

verbose is self explanatory.

magik {
    commitWithChanges.convention(false)
    defaultCommitWithChanges.convention(false)
    gitOnPath.convention(configuringProject.exec {
        commandLine("git", "--version")
        standardOutput = ByteArrayOutputStream() // disable output with a dummy instance
    }.exitValue == 0)
    dryRun.convention(false)
    verbose.convention(false)
}

Setting the repository in settings.gradle.kts for all the modules in a multi-module project

Since this is a Project plugin (which applies to build.gradle.kts), there is no support for settings.gradle.kts. So, in case you prefer to apply the repositories once in the settings, just fallback to:

"https://raw.githubusercontent.com/$organization/$repo/$branch"

For example, settings.gradle.kts:

dependencyResolutionManagement {
    repositories {
        mavenCentral()
        maven("https://raw.githubusercontent.com/kotlin-graphics/mary/master")
    }
}

Method 2, clients consuming Github Packages without having to set up authentication

Create a token with the read:packages scope and add a credentials file in the root of your repository (branch master/main) hosting the packages with your nickname on the first line, and the token you just created on the second line (without the prefix ghp_, otherwise Github will detect the token code in the next commit and delete the corresponding token)

Example, mary's credentials

elect86
7V1YljEcKShzwPzPJuAPP0X55urEhF0RBWG2
Fetching
repositories {
    githubPackages("kotlin-graphics/mary")
}

Advantages and limitations

Big advantage for both: they rely on the Github infrastructure (aka bandwidth and reliability)

Method 1, advantages:
Disadvantages:
Method 2, advantages:
Disadvantages: