Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# GitHub Actions Workflows

This directory contains the GitHub Actions workflows for the project.

## Workflows

### 1. tests.yml
- **Trigger**: Push to master branch or pull requests to master
- **Purpose**: Run all tests (unit and integration) on multiple Tarantool versions
- **Runs on**: Ubuntu latest

### 2. release.yml
- **Trigger**: Creation of tags matching semantic versioning pattern (e.g., `1.4.0`, `2.0.1`)
- **Purpose**: Automatically release to Maven Central and create GitHub Release
- **Runs on**: Ubuntu latest
- **Requires secrets**:
- `OSSRH_USERNAME` - Sonatype OSSRH username
- `OSSRH_TOKEN` - Sonatype OSSRH password or token
- `MAVEN_GPG_PRIVATE_KEY` - GPG private key for signing artifacts
- `MAVEN_GPG_PASSPHRASE` - Passphrase for the GPG key
- `TARANTOOL_REGISTRY_PASSWORD` - Password for Tarantool private registry

### 3. snapshot.yml
- **Trigger**: Push to master branch (except commits starting with "Release")
- **Purpose**: Automatically deploy snapshot versions to Maven Central
- **Runs on**: Ubuntu latest
- **Requires secrets**:
- `OSSRH_USERNAME` - Sonatype OSSRH username
- `OSSRH_TOKEN` - Sonatype OSSRH password or token
- `TARANTOOL_REGISTRY_PASSWORD` - Password for Tarantool private registry

## Setup Instructions

To enable automatic releases, you need to configure the following secrets in your GitHub repository settings:

1. Go to Settings → Secrets and variables → Actions
2. Add the following secrets:
- `OSSRH_USERNAME` - Your Sonatype OSSRH username
- `OSSRH_TOKEN` - Your Sonatype OSSRH token/password
- `MAVEN_GPG_PRIVATE_KEY` - Your GPG private key (export with `gpg --export-secret-keys --armor KEY_ID`)
- `MAVEN_GPG_PASSPHRASE` - Passphrase for your GPG key
- `TARANTOOL_REGISTRY_PASSWORD` - Password for the Tarantool private registry

## Release Process

### Automatic Release
1. Create and push a new tag with semantic versioning format (e.g., `git tag 1.4.0 && git push origin 1.4.0`)
2. The release workflow will automatically:
- Build and test the project
- Sign the artifacts with GPG
- Deploy to Maven Central
- Create a GitHub Release

### Automatic Snapshot Deployment
1. Push changes to the master branch
2. The snapshot workflow will automatically:
- Build and test the project
- Deploy snapshot version to Maven Central

Note: Commits with messages starting with "Release" are excluded from snapshot deployment to avoid duplicate deployments during the release process.
33 changes: 33 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Release to Maven Central

on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+'

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Set up JDK 8
uses: actions/setup-java@v5
with:
distribution: 'zulu'
java-version: '8'
server-id: ossrh
server-username: ${{ secrets.MAVEN_CENTRAL_USER }}
server-password: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
gpg-private-key: ${{ secrets.MAVEN_CENTRAL_GPG_PRIVATE_KEY }}
gpg-passphrase: ${{ secrets.MAVEN_CENTRAL_GPG_PASSPHRASE }}

- name: Configure Git user
run: |
git config user.email "actions@github.com"
git config user.name "GitHub Actions"

- name: Publish to Maven Central
run: |
./mvnw -B clean deploy -P release -DskipTests
27 changes: 27 additions & 0 deletions .github/workflows/snapshot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Publish Snapshot to Maven Central

on:
push:
branches:
- master

jobs:
publish-snapshot:
runs-on: ubuntu-latest
if: "!startsWith(github.event.head_commit.message, 'Release')"
steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Set up JDK 8
uses: actions/setup-java@v5
with:
distribution: 'zulu'
java-version: '8'
server-id: ossrh
server-username: ${{ secrets.MAVEN_CENTRAL_USER }}
server-password: ${{ secrets.MAVEN_CENTRAL_TOKEN }}

- name: Publish Snapshot to Maven Central
run: |
./mvnw -B clean deploy -DskipTests
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@v4

- name: Set up JDK 1.8
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'zulu'
java-version: '8'
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
- uses: actions/checkout@v4

- name: Set up JDK 1.8
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'zulu'
java-version: '8'
Expand Down Expand Up @@ -101,7 +101,7 @@ jobs:
- uses: actions/checkout@v4

- name: Set up JDK 1.8
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'zulu'
java-version: '8'
Expand Down
159 changes: 69 additions & 90 deletions .mvn/wrapper/MavenWrapperDownloader.java
Original file line number Diff line number Diff line change
@@ -1,117 +1,96 @@
/*
* Copyright 2007-present the original author or authors.
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;

public class MavenWrapperDownloader {

private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.ThreadLocalRandom;

/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
public final class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "3.3.4";

/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
private static final boolean VERBOSE = Boolean.parseBoolean(System.getenv("MVNW_VERBOSE"));

/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String[] args) {
log("Apache Maven Wrapper Downloader " + WRAPPER_VERSION);

public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());

// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
if (args.length != 2) {
System.err.println(" - ERROR wrapperUrl or wrapperJarPath parameter missing");
System.exit(1);
}
System.out.println("- Downloading from: " + url);

File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
log(" - Downloader started");
final URL wrapperUrl = URI.create(args[0]).toURL();
final Path baseDir = Paths.get(".").toAbsolutePath().normalize();
final Path wrapperJarPath = baseDir.resolve(args[1]).normalize();
if (!wrapperJarPath.startsWith(baseDir)) {
throw new IOException("Invalid path: outside of allowed directory");
}
downloadFileFromURL(wrapperUrl, wrapperJarPath);
log("Done");
} catch (IOException e) {
System.err.println("- Error downloading: " + e.getMessage());
if (VERBOSE) {
e.printStackTrace();
}
System.exit(1);
}
}

private static void downloadFileFromURL(String urlString, File destination) throws Exception {
private static void downloadFileFromURL(URL wrapperUrl, Path wrapperJarPath)
throws IOException {
log(" - Downloading to: " + wrapperJarPath);
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
final String username = System.getenv("MVNW_USERNAME");
final char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
Path temp = wrapperJarPath
.getParent()
.resolve(wrapperJarPath.getFileName() + "."
+ Long.toUnsignedString(ThreadLocalRandom.current().nextLong()) + ".tmp");
try (InputStream inStream = wrapperUrl.openStream()) {
Files.copy(inStream, temp, StandardCopyOption.REPLACE_EXISTING);
Files.move(temp, wrapperJarPath, StandardCopyOption.REPLACE_EXISTING);
} finally {
Files.deleteIfExists(temp);
}
log(" - Downloader complete");
}

private static void log(String msg) {
if (VERBOSE) {
System.out.println(msg);
}
}

}
Binary file modified .mvn/wrapper/maven-wrapper.jar
Binary file not shown.
6 changes: 4 additions & 2 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
wrapperVersion=3.3.4
distributionType=source
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.4/maven-wrapper-3.3.4.jar
Loading