Skip to content

Windows CI for Java #9148

Windows CI for Java

Windows CI for Java #9148

Workflow file for this run

name: Java CI
permissions:
contents: read
on:
push:
branches:
- main
- release-*
- v*
paths:
- glide-core/src/**
- glide-core/redis-rs/redis/src/**
- java/**
- utils/cluster_manager.py
- .github/workflows/java.yml
- .github/workflows/install-shared-dependencies/action.yml
- .github/workflows/test-benchmark/action.yml
- .github/workflows/lint-rust/action.yml
- .github/workflows/install-engine/action.yml
- .github/workflows/create-test-matrices/action.yml
- .github/json_matrices/**
pull_request:
paths:
- glide-core/src/**
- glide-core/redis-rs/redis/src/**
- java/**
- utils/cluster_manager.py
- .github/workflows/java.yml
- .github/workflows/install-shared-dependencies/action.yml
- .github/workflows/test-benchmark/action.yml
- .github/workflows/lint-rust/action.yml
- .github/workflows/install-engine/action.yml
- .github/workflows/create-test-matrices/action.yml
- .github/json_matrices/**
workflow_dispatch:
inputs:
full-matrix:
description: "Run the full engine, host, and language version matrix"
type: boolean
default: false
run-with-macos:
description: "Run with macos included (only when necessary)"
type: choice
options:
- false
- use-self-hosted
- use-github
default: false
use-windows-self-hosted:
description: "Use self-hosted Windows runner"
type: boolean
default: false
name:
required: false
type: string
description: "(Optional) Test run name"
run-modules-tests:
description: "Run modules tests"
type: boolean
default: false
workflow_call:
inputs:
run-with-macos:
description: "Run with macos included (only when necessary)"
type: string
default: false
concurrency:
group: java-${{ github.head_ref || github.ref }}-${{ toJson(inputs) }}
cancel-in-progress: true
run-name:
# Set custom name if job is started manually and name is given
${{ github.event_name == 'workflow_dispatch' && (inputs.name == '' && format('{0} @ {1} {2}', github.ref_name, github.sha, toJson(inputs)) || inputs.name) || '' }}
jobs:
get-matrices:
runs-on: ubuntu-latest
outputs:
engine-matrix-output: ${{ steps.get-matrices.outputs.engine-matrix-output }}
host-matrix-output: ${{ steps.get-matrices.outputs.host-matrix-output }}
version-matrix-output: ${{ steps.get-matrices.outputs.version-matrix-output }}
steps:
- uses: actions/checkout@v4
- id: get-matrices
uses: ./.github/workflows/create-test-matrices
with:
language-name: java
# Run full test matrix if job started by cron or it was explictly specified by a person who triggered the workflow
run-full-matrix: ${{ github.event.inputs.full-matrix == 'true' || github.event_name == 'schedule' }}
run-with-macos: ${{ (github.event.inputs.run-with-macos) }}
# Use Windows self-hosted runner with VPC Linux instance by default for code changes
run-with-windows-self-hosted: ${{ github.event.inputs.use-windows-self-hosted == 'true' || github.event_name == 'push' || github.event_name == 'pull_request' }}
test-java:
name: Java Tests - ${{ matrix.java }}, EngineVersion - ${{ matrix.engine.version }}, Target - ${{ matrix.host.TARGET }}
needs: get-matrices
timeout-minutes: ${{ matrix.host.OS == 'windows' && 60 || 35 }}
strategy:
fail-fast: false
matrix:
java: ${{ fromJson(needs.get-matrices.outputs.version-matrix-output) }}
engine: ${{ fromJson(needs.get-matrices.outputs.engine-matrix-output) }}
host: ${{ fromJson(needs.get-matrices.outputs.host-matrix-output) }}
exclude:
# Exclude Redis 6.2 on Windows (not supported)
- engine: { type: "redis", version: "6.2" }
host: { OS: "windows" }
runs-on: ${{ matrix.host.RUNNER }}
steps:
- uses: actions/checkout@v4
- name: Output Matrix Parameters for this job
run: |
echo "Job running with the following matrix configuration:"
echo "${{ toJson(matrix) }}"
- uses: gradle/actions/wrapper-validation@v4
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: ${{ matrix.java }}
- name: Install shared software dependencies
uses: ./.github/workflows/install-shared-dependencies
with:
os: ${{ matrix.host.OS }}
target: ${{ matrix.host.TARGET }}
github-token: ${{ secrets.GITHUB_TOKEN }}
engine-version: ${{ matrix.host.OS == 'windows' && '' || matrix.engine.version }}
language: java
- name: Install protoc (protobuf)
if: runner.os != 'Windows'
uses: arduino/setup-protoc@v3
with:
version: "29.1"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/cache@v4
with:
path: |
java/target
glide-core/src/generated
key: ${{ matrix.host.TARGET }}-java
restore-keys: |
${{ matrix.host.TARGET }}-glide-core
${{ matrix.host.TARGET }}
- name: Cache Gradle dependencies
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('java/**/*.gradle*', 'java/**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Setup Python3 for Windows
if: ${{ matrix.host.OS == 'windows' }}
shell: powershell
run: |
# Create python3 symlink for Windows if python exists
if (Get-Command python -ErrorAction SilentlyContinue) {
$pythonPath = (Get-Command python).Source
$python3Path = Join-Path (Split-Path $pythonPath) "python3.exe"
if (-not (Test-Path $python3Path)) {
New-Item -ItemType HardLink -Path $python3Path -Target $pythonPath -Force
Write-Host "python3 symlink created"
} else {
Write-Host "python3 already exists"
}
} else {
Write-Host "python command not found, skipping symlink creation"
}
- name: Build java client (Windows)
if: ${{ matrix.host.OS == 'windows' }}
working-directory: java
env:
CARGO_BUILD_JOBS: ${{ github.runner_cores || '2' }}
SSH_PRIVATE_KEY_CONTENT: ${{ secrets.VALKEY_REMOTE_SSH_KEY }}
VALKEY_REMOTE_HOST: ${{ vars.VALKEY_REMOTE_HOST }}
NPM_SCOPE: ${{ vars.NPM_SCOPE }}
run: |
# Stop any existing Gradle daemons to avoid compatibility issues
.\gradlew.bat --stop
.\gradlew.bat --no-build-cache --no-daemon --continue build test -x javadoc "-Dengine-version=${{ matrix.engine.version }}" -DfocusTests=true
- name: Build java client (Linux/macOS)
if: ${{ matrix.host.OS != 'windows' }}
working-directory: java
env:
CARGO_BUILD_JOBS: ${{ github.runner_cores || '2' }}
shell: bash
run: |
./gradlew --build-cache --continue build test -x javadoc "-Dengine-version=${{ matrix.engine.version }}"
- name: Ensure no skipped files by linter (Windows)
if: ${{ matrix.host.OS == 'windows' }}
working-directory: java
shell: powershell
run: |
.\gradlew.bat --build-cache spotlessDiagnose | Select-String 'All formatters are well behaved for all files'
- name: Ensure no skipped files by linter (Linux/macOS)
if: ${{ matrix.host.OS != 'windows' }}
working-directory: java
shell: bash
run: |
./gradlew --build-cache spotlessDiagnose | grep 'All formatters are well behaved for all files'
- uses: ./.github/workflows/test-benchmark
if: ${{ matrix.engine.version == '8.0' && matrix.host.RUNNER == 'ubuntu-latest' && matrix.java == '17' }}
with:
language-flag: -java
- name: Upload test & spotbugs reports
if: always()
continue-on-error: true
uses: actions/upload-artifact@v4
with:
name: test-reports-java-${{ matrix.java }}-${{ matrix.engine.type }}-${{ matrix.engine.version }}-${{ matrix.host.RUNNER }}
path: |
java/client/build/reports/**
java/integTest/build/reports/**
utils/clusters/**
benchmarks/results/**
java/client/build/reports/spotbugs/**
test-pubsub:
name: Java PubSubTests - ${{ matrix.java }}, EngineVersion - ${{ matrix.engine.version }}, Target - ${{ matrix.host.TARGET }}
needs: get-matrices
timeout-minutes: ${{ matrix.host.OS == 'windows' && 60 || 35 }}
strategy:
fail-fast: false
matrix:
java: ${{ fromJson(needs.get-matrices.outputs.version-matrix-output) }}
engine: ${{ fromJson(needs.get-matrices.outputs.engine-matrix-output) }}
host: ${{ fromJson(needs.get-matrices.outputs.host-matrix-output) }}
exclude:
# Exclude Redis 6.2 on Windows (not supported)
- engine: { type: "redis", version: "6.2" }
host: { OS: "windows" }
runs-on: ${{ matrix.host.RUNNER }}
steps:
- uses: actions/checkout@v4
- name: Output Matrix Parameters for this job
run: |
echo "Job running with the following matrix configuration:"
echo "${{ toJson(matrix) }}"
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: ${{ matrix.java }}
- name: Install shared software dependencies
uses: ./.github/workflows/install-shared-dependencies
with:
os: ${{ matrix.host.OS }}
target: ${{ matrix.host.TARGET }}
github-token: ${{ secrets.GITHUB_TOKEN }}
engine-version: ${{ matrix.host.OS == 'windows' && '' || matrix.engine.version }}
language: java
- name: Install protoc (protobuf)
if: runner.os != 'Windows'
uses: arduino/setup-protoc@v3
with:
version: "29.1"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/cache@v4
with:
path: |
java/target
glide-core/src/generated
key: ${{ matrix.host.TARGET }}-java
restore-keys: |
${{ matrix.host.TARGET }}-glide-core
${{ matrix.host.TARGET }}
- name: Cache Gradle dependencies
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('java/**/*.gradle*', 'java/**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Test pubsub (Windows)
if: ${{ matrix.host.OS == 'windows' }}
working-directory: java
shell: powershell
env:
CARGO_BUILD_JOBS: ${{ github.runner_cores || '2' }}
SSH_PRIVATE_KEY_CONTENT: ${{ secrets.VALKEY_REMOTE_SSH_KEY }}
VALKEY_REMOTE_HOST: ${{ vars.VALKEY_REMOTE_HOST }}
run: |
# Stop any existing Gradle daemons to avoid compatibility issues
.\gradlew.bat --stop
# Run the pubsub tests with info logging
.\gradlew.bat --build-cache --info :integTest:pubsubTest "-Dengine-version=${{ matrix.engine.version }}"
- name: Test pubsub (Linux/macOS)
if: ${{ matrix.host.OS != 'windows' }}
working-directory: java
shell: bash
env:
CARGO_BUILD_JOBS: ${{ github.runner_cores || '2' }}
run: |
./gradlew --build-cache :integTest:pubsubTest "-Dengine-version=${{ matrix.engine.version }}"
- name: Upload test & spotbugs reports
if: always()
continue-on-error: true
uses: actions/upload-artifact@v4
with:
name: test-reports-pubsub-java-${{ matrix.java }}-${{ matrix.engine.type }}-${{ matrix.engine.version }}-${{ matrix.host.OS }}-${{ matrix.host.ARCH }}
path: |
java/integTest/build/reports/**
utils/clusters/**
get-containers:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.full-matrix == 'true' || github.event_name == 'schedule' }}
outputs:
engine-matrix-output: ${{ steps.get-matrices.outputs.engine-matrix-output }}
host-matrix-output: ${{ steps.get-matrices.outputs.host-matrix-output }}
version-matrix-output: ${{ steps.get-matrices.outputs.version-matrix-output }}
steps:
- uses: actions/checkout@v4
- id: get-matrices
uses: ./.github/workflows/create-test-matrices
with:
language-name: java
run-full-matrix: true
containers: true
test-java-container:
runs-on: ${{ matrix.host.RUNNER }}
needs: [get-containers]
timeout-minutes: 25
strategy:
fail-fast: false
matrix:
java: ${{ fromJson(needs.get-containers.outputs.version-matrix-output) }}
engine: ${{ fromJson(needs.get-containers.outputs.engine-matrix-output) }}
host: ${{ fromJson(needs.get-containers.outputs.host-matrix-output) }}
container:
image: ${{ matrix.host.IMAGE }}
options: ${{ join(' -q ', matrix.host.CONTAINER_OPTIONS) }} # adding `-q` to bypass empty options
steps:
- name: Install git and Java
run: |
# Set environment variable to indicate container environment for Gradle
echo "GLIDE_CONTAINER_BUILD=true" >> $GITHUB_ENV
if [[ "${{ matrix.host.OS }}" == "amazon-linux" ]]; then
yum update -y
yum install -y git tar java-${{ matrix.java }}-amazon-corretto-devel.x86_64
# Set JAVA_HOME to use the installed JDK
export JAVA_HOME=/usr/lib/jvm/java-${{ matrix.java }}-amazon-corretto.x86_64
echo "JAVA_HOME=/usr/lib/jvm/java-${{ matrix.java }}-amazon-corretto.x86_64" >> $GITHUB_ENV
echo "/usr/lib/jvm/java-${{ matrix.java }}-amazon-corretto.x86_64/bin" >> $GITHUB_PATH
# Create gradle user home and disable auto-download
mkdir -p ~/.gradle
echo "org.gradle.java.installations.auto-download=false" >> ~/.gradle/gradle.properties
echo IMAGE=amazonlinux:latest | sed -r 's/:/-/g' >> $GITHUB_ENV
elif [[ "${{ matrix.host.TARGET }}" == *"musl"* ]]; then
apk add openjdk${{matrix.java}} git bash
# Temporarily installing openjdk11 because of issue: https://github.com/valkey-io/valkey-glide/issues/4664
apk add openjdk11
export JAVA_HOME=/usr/lib/jvm/java-${{matrix.java}}-openjdk
# Create gradle user home and disable auto-download
mkdir -p ~/.gradle
echo "org.gradle.java.installations.auto-download=false" >> ~/.gradle/gradle.properties
fi
# Replace `:` in the variable otherwise it can't be used in `upload-artifact`
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install shared software dependencies
uses: ./.github/workflows/install-shared-dependencies
with:
os: ${{ matrix.host.OS }}
target: ${{ matrix.host.TARGET }}
github-token: ${{ secrets.GITHUB_TOKEN }}
language: java
engine-version: ${{ matrix.host.OS == 'windows' && '' || matrix.engine.version }}
- name: Install protoc (protobuf)
if: runner.os != 'Windows'
uses: arduino/setup-protoc@v3
with:
version: "29.1"
repo-token: ${{ secrets.GITHUB_TOKEN }}
# Ensure Rust is in PATH for container environments
- name: Setup Rust Build
if: ${{ contains(matrix.host.TARGET, 'musl') }}
run: |
export PATH="$HOME/.cargo/bin:$PATH"
echo "PATH=$HOME/.cargo/bin:$PATH" >> $GITHUB_ENV
# Install ziglang and zigbuild
pip3 install ziglang --break-system-packages
cargo install --locked cargo-zigbuild
- uses: actions/cache@v4
with:
path: |
java/target
glide-core/src/generated
key: ${{ matrix.host.IMAGE }}-java
restore-keys: ${{ matrix.host.IMAGE }}
- name: Cache Gradle dependencies
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-container-${{ hashFiles('java/**/*.gradle*', 'java/**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-container-
${{ runner.os }}-gradle-
- name: Build java wrapper
if: ${{ matrix.host.OS != 'windows' }}
working-directory: java
shell: bash
env:
GLIDE_CONTAINER_BUILD: true
CARGO_BUILD_JOBS: ${{ github.runner_cores || '2' }}
run: |
if [[ "${{ matrix.host.OS }}" == "amazon-linux" ]]; then
export JAVA_HOME=/usr/lib/jvm/java-${{matrix.java}}-amazon-corretto.x86_64
else
# TODO: Fix java version. Java matrix tests are currently broken for all OS and Java 11 is always used.
# On other OS, build auto-downloads Java 11 but this doesn't work on Alpine
# https://github.com/valkey-io/valkey-glide/issues/4664
# export JAVA_HOME=/usr/lib/jvm/java-${{matrix.java}}-openjdk
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
export PATH=$HOME/.cargo/bin:$PATH
fi
./gradlew --stacktrace --build-cache --continue build -x javadoc "-Dengine-version=${{ matrix.engine.version }}"
- name: Upload test & spotbugs reports
if: always()
continue-on-error: true
uses: actions/upload-artifact@v4
with:
name: test-reports-java-${{ matrix.java }}-${{ matrix.engine.type }}-${{ matrix.engine.version }}-${{ env.IMAGE }}-${{ matrix.host.ARCH }}
path: |
java/client/build/reports/**
java/integTest/build/reports/**
java/client/build/reports/spotbugs/**
lint-rust:
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/workflows/lint-rust
with:
cargo-toml-folder: java
github-token: ${{ secrets.GITHUB_TOKEN }}
name: lint java rust
test-modules:
if: ((github.repository_owner == 'valkey-io' && github.event_name == 'workflow_dispatch' && github.event.inputs.run-modules-tests == 'true') || github.event.pull_request.head.repo.owner.login == 'valkey-io')
environment: AWS_ACTIONS
name: Modules Tests
runs-on: [self-hosted, linux, ARM64, persistent]
timeout-minutes: 15
steps:
- name: Setup self-hosted runner access
run: sudo chown -R $USER:$USER /home/ubuntu/actions-runner/_work/valkey-glide
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: 17
- name: Install protoc (protobuf)
if: runner.os != 'Windows'
uses: arduino/setup-protoc@v3
with:
version: "29.1"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/cache@v4
with:
path: |
java/target
glide-core/src/generated
key: aarch64-unknown-linux-gnu-java
restore-keys: |
aarch64-unknown-linux-gnu-glide-core
aarch64-unknown-linux-gnu
- name: Install zig
uses: ./.github/workflows/install-zig
- name: Test java wrapper
working-directory: java
run: ./gradlew :integTest:modulesTest -Dcluster-endpoints=${{ secrets.MEMDB_MODULES_ENDPOINT }} -Dtls=true
- name: Upload test reports
if: always()
continue-on-error: true
uses: actions/upload-artifact@v4
with:
name: test-reports-modules
path: |
java/integTest/build/reports/**