Skip to content

Commit

Permalink
ci: add publish gradle task and release workflows (#12)
Browse files Browse the repository at this point in the history
Adds a gradle publish script and release workflows.
  • Loading branch information
malandis authored Sep 6, 2024
1 parent 7ff37fe commit 5fbb556
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/manual-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Manual Release
# Triggers a merge from main->release, which will then trigger a release
# from the release branch.
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
merge-to-release-branch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Merge main -> release
uses: devmasx/merge-branch@master
with:
type: now
from_branch: main
target_branch: release
github_token: ${{ secrets.MOMENTO_MACHINE_USER_GITHUB_TOKEN }}
58 changes: 58 additions & 0 deletions .github/workflows/on-push-to-release-branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: On push to release branch

on:
push:
branches: [release]

jobs:
release:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.release.outputs.release }}
steps:
- uses: actions/checkout@v3
- name: Set release
id: semrel
uses: go-semantic-release/action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
allow-initial-development-versions: true
force-bump-patch-version: true
# For whatever reason, this silly tool won't let you do releases from branches
# other than the default branch unless you pass this flag, which doesn't seem
# to actually have anything to do with CI:
# https://github.com/go-semantic-release/semantic-release/blob/master/cmd/semantic-release/main.go#L173-L194
# https://github.com/go-semantic-release/condition-github/blob/4c8af3fc516151423fff2f77eb08bf7082570676/pkg/condition/github.go#L42-L44
custom-arguments: '--no-ci'

- name: Output release
id: release
run: echo "release=${{ steps.semrel.outputs.version }}" >> $GITHUB_OUTPUT

publish:
runs-on: ubuntu-latest

steps:
- name: Checkout project
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: 17
distribution: 'corretto'

- name: Build project
run: make build

- name: Publish to sonatype
env:
SONATYPE_SIGNING_KEY: ${{ secrets.SONATYPE_SIGNING_KEY }}
SONATYPE_SIGNING_KEY_PASSWORD: ${{ secrets.SONATYPE_SIGNING_KEY_PASSWORD }}
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
ORG_GRADLE_PROJECT_version: ${{ needs.release.outputs.version }}
uses: gradle/gradle-build-action@v2
with:
# Note that this will require manual release from Sonatype
arguments: publishToSonatype closeSonatypeStagingRepository
77 changes: 77 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
plugins {
id("java")
id("com.diffplug.spotless") version "5.15.1"

// Publishing plugins
id("maven-publish")
id("signing")
id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
}

group = "software.momento.java"
Expand All @@ -10,6 +15,15 @@ repositories {
mavenCentral()
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17

// For publishing
withSourcesJar()
withJavadocJar()
}

dependencies {
implementation("io.lettuce:lettuce-core:6.4.0.RELEASE")
implementation("software.momento.java:sdk:1.15.0")
Expand All @@ -35,3 +49,66 @@ spotless {
googleJavaFormat("1.11.0")
}
}

publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["java"])
groupId = group.toString()
artifactId = "momento-lettuce"
version = project.version.toString()

pom {
name.set("Momento Lettuce Compatibility Client")
description.set("Momento-backed implementation of the Lettuce Redis client")
url.set("https://github.com/momentohq/momento-java-lettuce-client")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("https://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
developers {
developer {
id.set("momento")
name.set("Momento")
organization.set("Momento")
email.set("[email protected]")
}
}
scm {
connection.set("scm:git:git://github.com/momentohq/momento-java-lettuce-client.git")
developerConnection.set("scm:git:[email protected]:momentohq/momento-java-lettuce-client.git")
url.set("https://github.com/momentohq/momento-java-lettuce-client")
}
}
}
}
}

// Signing and Nexus publishing setup
val signingKey: String? = System.getenv("SONATYPE_SIGNING_KEY")
val signingPassword: String? = System.getenv("SONATYPE_SIGNING_KEY_PASSWORD")

if (signingKey != null && signingPassword != null) {
signing {
useInMemoryPgpKeys(signingKey, signingPassword)
sign(publishing.publications["mavenJava"])
}
}

val sonatypeUsername: String? = System.getenv("SONATYPE_USERNAME")
val sonatypePassword: String? = System.getenv("SONATYPE_PASSWORD")

if (sonatypeUsername != null && sonatypePassword != null) {
nexusPublishing {
repositories {
sonatype {
nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
username.set(sonatypeUsername)
password.set(sonatypePassword)
}
}
}
}
32 changes: 32 additions & 0 deletions src/main/java/momento/lettuce/MomentoRedisReactiveClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,25 +101,57 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
* A Redis client that wraps a {@link CacheClient} and provides reactive commands.
*
* @param <K> Key type.
* @param <V> Value type.
*/
public class MomentoRedisReactiveClient<K, V>
implements RedisReactiveCommands<K, V>, MomentoRedisReactiveCommands<K, V> {
private final CacheClient client;
private final String cacheName;
private final RedisCodecByteArrayConverter<K, V> codec;
private volatile EventExecutorGroup scheduler;

/**
* Creates a new {@link MomentoRedisReactiveClient}.
*
* @param client The cache client.
* @param cacheName The name of the cache to store data in.
* @param codec The codec to use for serializing and deserializing keys and values.
*/
public MomentoRedisReactiveClient(CacheClient client, String cacheName, RedisCodec<K, V> codec) {
this.client = client;
this.cacheName = cacheName;
this.codec = new RedisCodecByteArrayConverter<>(codec);
this.scheduler = ImmediateEventExecutor.INSTANCE;
}

/**
* Instantiates a new {@link MomentoRedisReactiveClient} with the provided {@link CacheClient} and
* cache name.
*
* @param client The cache client.
* @param cacheName The name of the cache to store data in.
* @param codec The codec to use for serializing and deserializing keys and values.
* @return A new {@link MomentoRedisReactiveClient}.
* @param <K> Key type.
* @param <V> Value type.
*/
public static <K, V> MomentoRedisReactiveClient<K, V> create(
CacheClient client, String cacheName, RedisCodec<K, V> codec) {
return new MomentoRedisReactiveClient<>(client, cacheName, codec);
}

/**
* Instantiates a new {@link MomentoRedisReactiveClient} with the provided {@link CacheClient} and
* cache name.
*
* @param client The cache client.
* @param cacheName The name of the cache to store data in.
* @return A new {@link MomentoRedisReactiveClient}.
*/
public static MomentoRedisReactiveClient<String, String> create(
CacheClient client, String cacheName) {
return new MomentoRedisReactiveClient<>(client, cacheName, StringCodec.UTF8);
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/momento/lettuce/utils/ExpireCondition.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ public class ExpireCondition {
private final boolean requiresLessThan;
private final boolean requiresGreaterThan;

/**
* Creates a new {@link ExpireCondition}.
*
* @param requiresExistingExpiry Whether the operation requires an existing expiry.
* @param requiresNoExpiry Whether the operation requires no expiry set.
* @param requiresLessThan Whether the operation requires the provided expiry to be less than the
* @param requiresGreaterThan Whether the operation requires the provided expiry to be greater
* than
*/
public ExpireCondition(
boolean requiresExistingExpiry,
boolean requiresNoExpiry,
Expand Down
1 change: 1 addition & 0 deletions src/main/java/momento/lettuce/utils/RangeUtils.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package momento.lettuce.utils;

/** Provides utility methods for working with ranges. */
public class RangeUtils {
/**
* Adjusts the end range from inclusive to exclusive.
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/momento/lettuce/utils/RedisResponse.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package momento.lettuce.utils;

/** Represents the response from Redis. */
public class RedisResponse {
/** The response from Redis when a command is successful. */
public static final String OK = "OK";
}
7 changes: 7 additions & 0 deletions src/main/java/momento/lettuce/utils/ValidatorUtils.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package momento.lettuce.utils;

/** Provides utility methods for validating arguments. */
public class ValidatorUtils {
/**
* Ensures that the provided value is within the range of an integer.
*
* @param value The value to check.
* @param argumentName The name of the argument.
*/
public static void ensureInIntegerRange(long value, String argumentName) {
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
throw MomentoToLettuceExceptionMapper.createIntegerOutOfRangeException(argumentName, value);
Expand Down

0 comments on commit 5fbb556

Please sign in to comment.