Creating GitHub Action to Deploy Projects into a Private Maven Repository
Tags: java, kotlin, git
Published: 2020-07-02 19:35:04

---
title: Creating GitHub Action to Deploy Projects into a Private Maven Repository
published: true
date: 2020-07-01 22:32:55 UTC
tags: java,kotlin,git
canonical_url: 
---

I have been heavily using other CI/CD platforms like GitLab, BitBucket, Jenkins, and Azure DevOps but I can definitely say GitHub nailed it. It has a different and easy-to-use approach and I am surprised that you can add custom runners for your CI/CD pipeline.

I will create a very simple Kotlin application to show how to deploy a library in a private Maven repository. I am going to use [Repsy](https://repsy.io) for Maven repository hosting. It gives 3 GB of free storage and should be sufficient for most cases.

Let's create a Gradle project, your IDE will help with this, or you can install Gradle CLI from the official [gradle](https://gradle.org/) site or you can use [SdkMan](https://sdkman.io/) for this purpose.

```shell
sdk i gradle
```

Gradle CLI will help you to bootstrap your project.

```shell
mkdir hello-actions-kotlin-lib
cd hello-actions-kotlin-lib
gradle init
```

Gradle will ask us a bunch of questions. I will select the `library` type for project generation

```
Select the type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 3
```

Kotlin for programming language selection. I'm happy to see plenty of options there.

```
Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 4
```

And going to use Kotlin DSL instead of Groovy.

```
Select build script DSL:
  1: Kotlin
  2: Groovy
Enter selection (default: Kotlin) [1..2] 1
```

Just press enter for the default project name or you can enter another one suitable for you.

```
Project name (default: hello-actions-kotlin-lib):
```

For the source package selection, I am going to use my GitHub TLD but feel free to use your package structure.

```
Source package (default: hello.actions.kotlin.lib): com.github.firatkucuk.hello_actions_kotlin_lib
```

As a final question gradle will ask you the Java version. You may want to select the Latest LTS version (21) or one one the safest ones `8` or `11`. I'll choose 17.

```
Enter target version of Java (min. 7) (default: 21): 17
```

It seems a little bit long but that’s OK. Gradle will create a simple `Library.kt` file. Let’s rename it `Hello.kt` and change the content.

```kotlin
package com.github.firatkucuk.hello_actions_kotlin_lib;

class Hello {
    fun sayHello(text: String): String {
        return "Hello $text"
    }
}
```

And same for the test file `LibraryTest.kt`. Let's rename it to `HelloTest.kt` and change the test file content to:

```kotlin
package com.github.firatkucuk.hello_actions_kotlin_lib

import kotlin.test.Test
import kotlin.test.assertEquals

class HelloTest {
    @Test fun sayHelloMethodReturnsHello() {
        val classUnderTest = Hello()
        assertEquals("Hello World", classUnderTest.sayHello("World"), "sayHello method should return 'Hello World'")
    }
}

```

Now, we can test the build operation:

```shell
gradle build
```

The next phase is publishing our library to our private maven repository in [repsy.io](https://respy.io). After signup, [repsy](https://repsy.io) creates a default repository that can be used with the account password. So you only need to sign up, and that’s all.

Let’s modify our `build.gradle.kts` file for publishing the artifact. The most important part is adding a `maven-publish` plugin and a publishing section with the credentials from repsy.

```kotlin
version = "1.0.0"

plugins {
    // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
    id("org.jetbrains.kotlin.jvm") version "1.9.10"

    // Apply the java-library plugin for API and implementation separation.
    `java-library`
    `maven-publish`
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

val repsyUrl: String by project
val repsyUsername: String by project
val repsyPassword: String by project

publishing {
    publications {
        create<MavenPublication>("maven") {
            from(components["java"])
        }
    }

    repositories {
        maven {
            url = uri(repsyUrl)
            credentials {
                username = repsyUsername
                password = repsyPassword
            }
        }
    }
}

dependencies {
    // Use the Kotlin JUnit 5 integration.
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")

    // Use the JUnit 5 integration.
    testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.3")

    testRuntimeOnly("org.junit.platform:junit-platform-launcher")

    // This dependency is exported to consumers, that is to say found on their compile classpath.
    api("org.apache.commons:commons-math3:3.6.1")

    // This dependency is used internally, and not exposed to consumers on their own compile classpath.
    implementation("com.google.guava:guava:32.1.1-jre")
}

// Apply a specific Java toolchain to ease working on different environments.
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

tasks.named<Test>("test") {
    // Use JUnit Platform for unit tests.
    useJUnitPlatform()
}

```

Our project implementation is completed. Let’s create git integration of our project. First, create an empty git project called `hello-actions-kotlin-lib` on GitHub. After that, we commit the changes and push files to GitHub.

```shell
git init
git add .
git commit -m "initial commit"
git remote add origin git@github.com:YOUR_GITHUB_USER_NAME/hello-actions-kotlin-lib.git
git push origin main
```

The next step is integrating your project with GitHub Actions. Go to `https://github.com/YOUR_USER_NAME/hello-actions-kotlin-lib/actions/new`

Please Find the **Java with Gradle** Action. Then you can click the **Set up this workflow** button. An online editor will be opened up.

Let’s directly commit the changes and we’re gonna see our Action will run immediately. GitHub action will fail so please ignore this. It requires some properties file we’re gonna add properties as GitHub secret.

We need to create a GitHub secret for our `gradle.properties` file. But because of the limitations. GitHub cannot use file content as secrets. GitLab has the same restriction once upon a time then they’ve introduced File types but we need to create a text file our local computer. The content should be something like this:

```properties
repsyUrl=https://repo.repsy.io/mvn/YOUR_REPSY_USERNAME/default
repsyUsername=YOUR_REPSY_USERNAME
repsyPassword=YOUR_REPSY_PASSWORD
```

We need to encode this with base64. There are many online base64 converters. If you’re using Mac/Linux it should be easy like this:

```bash
base64 -w0 gradle.properties
```

Let's copy the output and create a secret. Go to `https://github.com/YOUR_USER_NAME/hello-actions-kotlin-lib/settings/secrets`

Add a GitHub secret called GRADLE_PROPERTIES and paste the encoded string into it.

Now we can open our pipeline configuration file and make the latest changes. Go To `https://github.com/YOUR_USER_NAME/hello-actions-kotlin-lib/blob/master/.github/workflows/gradle.yml` and click the edit button. We will add some extra steps for injecting Gradle properties.

```yaml
name: Java CI with Gradle

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4.1.1

      - name: Set up JDK 17
        uses: actions/setup-java@v3.13.0
        with:
          java-version: 17

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        env:
          GRADLE_PROPERTIES: ${{ secrets.GRADLE_PROPERTIES }}
        run: mkdir -p ~/.gradle && echo $GRADLE_PROPERTIES | base64 -d > ~/.gradle/gradle.properties && cat ~/.gradle/gradle.properties && ./gradlew build

      - name: publish
        run: ./gradlew publish

```

That’s all you can find the source code [here](https://github.com/firatkucuk/hello-actions-kotlin-lib).