From e8ab74870e3beeafe4e66574cafd514b5156fe2b Mon Sep 17 00:00:00 2001 From: Petar Shtuchkin Date: Tue, 17 Feb 2026 18:05:37 +0200 Subject: [PATCH 1/2] ci: add reusable run-tests action and support custom test image/tag These changes are to enable running nightly tests against Redis unstable builds and custom builds. The PR follows the same idea as in Jedis: https://github.com/redis/jedis/pull/4425 Main changes * Created a new reusable action `.github/actions/run-tests/action.yml` that is intended to be run by workflows in this and external repositories. * Moved all the steps from `integration.yml` to the new action, with modifications allowing the use of a custom image tag instead of a baked-in version. What was changed in `integration.yml`: * Uses the run-tests action to run the tests * Allows running tests against a custom image tag (this is indicated in the run-name, if used) Docker Compose * Added the `CLIENT_LIBS_TEST_IMAGE_TAG` variable to Docker Compose. I'm using a separate `CLIENT_LIBS_TEST_IMAGE_TAG` variable to clearly separate regular versions set with REDIS_VERSION from image tags. * Added the `CLIENT_LIBS_TEST_IMAGE` variable, it's not directly used in Makefile or workflows, but is supported in run-tests action. Added it for consitency with Jedis which originally has the ability to use different image url. Changes to `Makefile` * Added direct setting of `domainsocket` and `sentineldomainsocket` properties when invoking maven because `TestSettings.java` didn't respect REDIS_ENV_WORK_DIR value and always tried to open sockets using relative paths * If `CLIENT_LIBS_TEST_IMAGE_TAG` is present, then the `version` argument is ignored. Changes to the workflow logic * `CLIENT_LIBS_TEST_IMAGE_TAG`, along with `CLIENT_LIBS_TEST_IMAGE`, is passed to `make start` if any or both are present. Then Docker Compose gets them from the environment. ``` make start CLIENT_LIBS_TEST_IMAGE=redislabsdev/client-libs-test CLIENT_LIBS_TEST_IMAGE_TAG=custom-1235-debian-amd64 ``` run-tests action allows setting a different image name using `CLIENT_LIBS_TEST_IMAGE` (not used in `integration.yml`). setup-maven action was updated from `1.8.0` to `1.19.0` to allow disabling secondary checkout using `checkout-enabled` option and avoid incorrect chekouts when using run-tests externally Minor changes * Docker Compose is started with `--quiet-pull` to reduce noise. * Docker Compose is started with the `--wait` option, which is a more correct way to wait for readiness. * `make stop` is used instead `docker-compose stop` for consistency with `make start` and to enable any tear-down logic inluded in Makefile --- .github/actions/run-tests/action.yml | 167 ++++++++++++++++++ .github/workflows/integration.yml | 74 +++----- Makefile | 19 +- .../resources/docker-env/docker-compose.yml | 4 +- 4 files changed, 210 insertions(+), 54 deletions(-) create mode 100644 .github/actions/run-tests/action.yml diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml new file mode 100644 index 0000000000..429aea0b9b --- /dev/null +++ b/.github/actions/run-tests/action.yml @@ -0,0 +1,167 @@ +# Note: this action is used as a part of redis oss release and test automation in +# redis-developer/redis-oss-release-automation repo +name: 'Run Lettuce Tests' +description: 'Run Lettuce tests in a containerized environment' + +inputs: + redis_version: + description: 'Redis version to test against' + required: false + client_libs_test_image_tag: + description: 'Custom client libs test image tag to use instead of redis_version' + required: false + default: '' + client_libs_test_image: + description: 'Custom client libs test image name to use' + required: false + default: '' + java_version: + description: 'Java version to use' + required: false + default: '8' + java_distribution: + description: 'Java distribution to use' + required: false + default: 'temurin' + codecov_token: + description: 'Codecov token for uploading coverage' + required: false + default: '' + # repository and ref are required for correct checkout when using action + # externally (e.g.: in redis-developer/redis-oss-release-automation) + repository: + description: 'Git repository to checkout' + required: false + default: '' + ref: + description: 'Git ref to checkout' + required: false + default: '' + redis_env_work_dir: + description: 'Redis env work directory' + required: false + default: '' + redis_env_conf_dir: + description: 'Redis env conf directory' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + repository: ${{ inputs.repository }} + ref: ${{ inputs.ref }} + + - name: Validate inputs and prepare environment + shell: bash + id: args + env: + REDIS_VERSION: ${{ inputs.redis_version }} + CLIENT_LIBS_TEST_IMAGE: ${{ inputs.client_libs_test_image }} + CLIENT_LIBS_TEST_IMAGE_TAG: ${{ inputs.client_libs_test_image_tag }} + REDIS_ENV_WORK_DIR: ${{ inputs.redis_env_work_dir }} + REDIS_ENV_CONF_DIR: ${{ inputs.redis_env_conf_dir }} + REDIS_VERSION_LABEL: ${{ inputs.client_libs_test_image_tag || inputs.redis_version }} + run: | + make_args=() + + if [ -n "$CLIENT_LIBS_TEST_IMAGE" ]; then + make_args+=(CLIENT_LIBS_TEST_IMAGE="$CLIENT_LIBS_TEST_IMAGE") + fi + + if [ -n "$CLIENT_LIBS_TEST_IMAGE_TAG" ]; then + make_args+=(CLIENT_LIBS_TEST_IMAGE_TAG="$CLIENT_LIBS_TEST_IMAGE_TAG") + elif [ -n "$REDIS_VERSION" ]; then + make_args+=(version="$REDIS_VERSION") + else + echo "Error: redis_version or client_libs_test_image_tag input is required" + exit 1 + fi + + echo "make_args=${make_args[*]}" | tee -a ${GITHUB_OUTPUT} + echo "redis_version_label=$REDIS_VERSION_LABEL" | tee -a ${GITHUB_OUTPUT} + + if [ -z "$REDIS_ENV_CONF_DIR" ]; then + REDIS_ENV_CONF_DIR=$(readlink -f "${{ github.action_path }}/../../../src/test/resources/docker-env") + fi + echo "redis_env_conf_dir=$REDIS_ENV_CONF_DIR" | tee -a ${GITHUB_OUTPUT} + + if [ -n "$REDIS_ENV_WORK_DIR" ]; then + echo "redis_env_work_dir=$REDIS_ENV_WORK_DIR" | tee -a ${GITHUB_OUTPUT} + else + REDIS_ENV_WORK_DIR=$(mktemp -du) + echo "redis_env_work_dir=$REDIS_ENV_WORK_DIR" | tee -a ${GITHUB_OUTPUT} + fi + + - name: Set up Java + uses: actions/setup-java@v4 + with: + java-version: ${{ inputs.java_version }} + distribution: ${{ inputs.java_distribution }} + cache: 'maven' + + - name: Setup Maven + uses: s4u/setup-maven-action@v1.19.0 + with: + # we already checked out the code and + # checkout without params breaks external usage of the run-tests action + checkout-enabled: false + java-version: ${{ inputs.java_version }} + + - name: Install missing dependencies to container + shell: bash + run: | + sudo apt update + + + - name: Set up Docker Compose environment + shell: bash + run: | + mkdir -m 777 $REDIS_ENV_WORK_DIR + make start ${{ steps.args.outputs.make_args }} + env: + REDIS_ENV_CONF_DIR: ${{ steps.args.outputs.redis_env_conf_dir }} + REDIS_ENV_WORK_DIR: ${{ steps.args.outputs.redis_env_work_dir }} + + - name: Maven offline + shell: bash + run: | + mvn -q dependency:go-offline + continue-on-error: true + + - name: Run tests + shell: bash + run: | + export TEST_WORK_FOLDER=$REDIS_ENV_WORK_DIR + echo $TEST_WORK_FOLDER + ls -la $TEST_WORK_FOLDER + make test-coverage + env: + REDIS_ENV_WORK_DIR: ${{ steps.args.outputs.redis_env_work_dir }} + JVM_OPTS: -Xmx3200m + TERM: dumb + + - name: Tear down Docker Compose environment + if: always() + shell: bash + run: | + make stop + continue-on-error: true + + - name: Upload coverage reports to Codecov + if: inputs.codecov_token != '' + uses: codecov/codecov-action@v4 + with: + token: ${{ inputs.codecov_token }} + + - name: Upload test failure reports to Codecov + if: always() && inputs.codecov_token != '' + uses: codecov/test-results-action@v1 + with: + fail_ci_if_error: false + files: ./target/surefire-reports/TEST*,./target/failsafe-reports/TEST* + verbose: ${{ runner.debug }} + token: ${{ inputs.codecov_token }} diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 6dff0a6144..3e536a5acf 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -1,4 +1,6 @@ name: Continuous Integration +run-name: "Continuous Integration${{ github.event.inputs.client_libs_test_image_tag != '' && format(' using image: {0}', github.event.inputs.client_libs_test_image_tag) || '' }}" + on: push: paths-ignore: @@ -17,10 +19,16 @@ on: schedule: - cron: '0 1 * * *' # nightly build workflow_dispatch: + inputs: + client_libs_test_image_tag: + description: 'Custom client libs test image tag to use instead of redis_version' + required: false + default: '' jobs: build: name: Build and Test + if: github.event.inputs.client_libs_test_image_tag == '' runs-on: ubuntu-latest strategy: fail-fast: false @@ -32,54 +40,28 @@ jobs: - "8.0" - "7.4" - "7.2" - env: - REDIS_ENV_WORK_DIR: ${{ github.workspace }}/work - steps: - name: Checkout project uses: actions/checkout@v4 - - name: Set Java up in the runner - uses: actions/setup-java@v4 - with: - java-version: '8' - distribution: 'temurin' - cache: 'maven' - - name: Setup Maven - uses: s4u/setup-maven-action@v1.8.0 - with: - java-version: 8 - - name: Install missing dependencies to container - run: | - sudo apt update - - name: Set up Docker Compose environment - run: | - mkdir -m 777 $REDIS_ENV_WORK_DIR - make start version=${{ matrix.redis_version }} - - name: Maven offline - run: | - mvn -q dependency:go-offline - continue-on-error: true - - name: Run tests - run: | - export TEST_WORK_FOLDER=$REDIS_ENV_WORK_DIR - echo $TEST_WORK_FOLDER - ls -la $TEST_WORK_FOLDER - make test-coverage - env: - JVM_OPTS: -Xmx3200m - TERM: dumb - - name: Tear down Docker Compose environment - run: | - docker compose $COMPOSE_ENV_FILES -f src/test/resources/docker-env/docker-compose.yml down - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 + + - uses: ./.github/actions/run-tests with: - token: ${{ secrets.CODECOV_TOKEN }} - - name: Upload test failure reports to Codecov - uses: codecov/test-results-action@v1 - if: always() # always upload test results to include test failures + redis_version: ${{ matrix.redis_version }} + codecov_token: ${{ secrets.CODECOV_TOKEN }} + redis_env_work_dir: ${{ github.workspace }}/work + redis_env_conf_dir: ${{ github.workspace }}/src/test/resources/docker-env + + build_using_custom_image: + name: Build and Test using custom image + if: github.event.inputs.client_libs_test_image_tag != '' + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: ./.github/actions/run-tests with: - fail_ci_if_error: false - files: ./target/surefire-reports/TEST*,./target/failsafe-reports/TEST* - verbose: ${{ runner.debug }} - token: ${{ secrets.CODECOV_TOKEN }} + client_libs_test_image_tag: ${{ github.event.inputs.client_libs_test_image_tag }} + codecov_token: ${{ secrets.CODECOV_TOKEN }} + redis_env_work_dir: ${{ github.workspace }}/work + redis_env_conf_dir: ${{ github.workspace }}/src/test/resources/docker-env diff --git a/Makefile b/Makefile index fd46426838..5827503f1d 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ PROFILE ?= ci SUPPORTED_TEST_ENV_VERSIONS := 8.6 8.4 8.2 8.0 7.4 7.2 DEFAULT_TEST_ENV_VERSION := 8.6 REDIS_ENV_WORK_DIR := $(or ${REDIS_ENV_WORK_DIR},$(ROOT_DIR)/work) +MVN_SOCKET_ARGS := -Ddomainsocket="$(REDIS_ENV_WORK_DIR)/socket-6482" -Dsentineldomainsocket="$(REDIS_ENV_WORK_DIR)/socket-26379" start: @if [ -z "$(version)" ]; then \ @@ -13,12 +14,18 @@ start: version="$(DEFAULT_TEST_ENV_VERSION)"; \ fi; \ fi; \ - if ! echo "$(SUPPORTED_TEST_ENV_VERSIONS)" | grep -qw "$$version"; then \ + if [ -n "$$CLIENT_LIBS_TEST_IMAGE_TAG" ]; then \ + display_version="image tag $$CLIENT_LIBS_TEST_IMAGE_TAG"; \ + echo "Using $$display_version"; \ + version=""; \ + elif ! echo "$(SUPPORTED_TEST_ENV_VERSIONS)" | grep -qw "$$version"; then \ echo "Error: Invalid version '$$version'. Supported versions are: $(SUPPORTED_TEST_ENV_VERSIONS)."; \ exit 1; \ + else \ + display_version="version $$version"; \ fi; \ echo "Version: $(version)"; \ - default_env_file="src/test/resources/docker-env/.env"; \ + default_env_file="src/test/resources/docker-env/.env"; \ custom_env_file="src/test/resources/docker-env/.env.v$$version"; \ env_files="--env-file $$default_env_file"; \ if [ -f "$$custom_env_file" ]; then \ @@ -27,15 +34,15 @@ start: echo "Environment work directory: $(REDIS_ENV_WORK_DIR)"; \ rm -rf "$(REDIS_ENV_WORK_DIR)"; \ mkdir -p "$(REDIS_ENV_WORK_DIR)"; \ - docker compose $$env_files -f src/test/resources/docker-env/docker-compose.yml --parallel 1 up -d; \ - echo "Started test environment with Redis version $$version." + docker compose $$env_files -f src/test/resources/docker-env/docker-compose.yml --parallel 1 up -d --wait --quiet-pull; \ + echo "Started test environment with Redis $$display_version."; test: - mvn -DskipITs=false clean compile verify -P$(PROFILE) + mvn -DskipITs=false $(MVN_SOCKET_ARGS) clean compile verify -P$(PROFILE) test-coverage: - mvn -DskipITs=false clean compile verify jacoco:report -P$(PROFILE) + mvn -DskipITs=false $(MVN_SOCKET_ARGS) clean compile verify jacoco:report -P$(PROFILE) stop: docker compose --env-file src/test/resources/docker-env/.env -f src/test/resources/docker-env/docker-compose.yml down; \ diff --git a/src/test/resources/docker-env/docker-compose.yml b/src/test/resources/docker-env/docker-compose.yml index 10cb2aca67..848ed5e2be 100644 --- a/src/test/resources/docker-env/docker-compose.yml +++ b/src/test/resources/docker-env/docker-compose.yml @@ -1,7 +1,7 @@ x-client-libs-image: &client-libs-image - image: "redislabs/client-libs-test:${REDIS_VERSION:-8.6.0}" + image: "${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test}:${CLIENT_LIBS_TEST_IMAGE_TAG:-${REDIS_VERSION:-8.6.0}}" x-client-libs-stack-image: &client-libs-stack-image - image: "redislabs/client-libs-test:${REDIS_STACK_VERSION:-8.6.0}" + image: "${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test}:${CLIENT_LIBS_TEST_IMAGE_TAG:-${REDIS_STACK_VERSION:-${REDIS_VERSION:-8.6.0}}}" services: # Test infrastructure used for simulating network issues to test multi-db client failover From 557e9ac58f9d56171e28c5bde01b1f43c66d1ae1 Mon Sep 17 00:00:00 2001 From: "aleksandar.todorov" Date: Thu, 19 Feb 2026 16:16:24 +0200 Subject: [PATCH 2/2] Try grouped output --- .github/actions/run-tests/action.yml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml index 429aea0b9b..74452f2107 100644 --- a/.github/actions/run-tests/action.yml +++ b/.github/actions/run-tests/action.yml @@ -66,6 +66,7 @@ runs: REDIS_ENV_CONF_DIR: ${{ inputs.redis_env_conf_dir }} REDIS_VERSION_LABEL: ${{ inputs.client_libs_test_image_tag || inputs.redis_version }} run: | + echo "::group::Validate inputs" make_args=() if [ -n "$CLIENT_LIBS_TEST_IMAGE" ]; then @@ -83,7 +84,9 @@ runs: echo "make_args=${make_args[*]}" | tee -a ${GITHUB_OUTPUT} echo "redis_version_label=$REDIS_VERSION_LABEL" | tee -a ${GITHUB_OUTPUT} + echo "::endgroup::" + echo "::group::Prepare environment paths" if [ -z "$REDIS_ENV_CONF_DIR" ]; then REDIS_ENV_CONF_DIR=$(readlink -f "${{ github.action_path }}/../../../src/test/resources/docker-env") fi @@ -95,6 +98,7 @@ runs: REDIS_ENV_WORK_DIR=$(mktemp -du) echo "redis_env_work_dir=$REDIS_ENV_WORK_DIR" | tee -a ${GITHUB_OUTPUT} fi + echo "::endgroup::" - name: Set up Java uses: actions/setup-java@v4 @@ -111,17 +115,17 @@ runs: checkout-enabled: false java-version: ${{ inputs.java_version }} - - name: Install missing dependencies to container - shell: bash - run: | - sudo apt update - - - name: Set up Docker Compose environment shell: bash run: | + echo "::group::Create work directory" mkdir -m 777 $REDIS_ENV_WORK_DIR + echo "Work directory: $REDIS_ENV_WORK_DIR" + echo "::endgroup::" + + echo "::group::Start Redis containers" make start ${{ steps.args.outputs.make_args }} + echo "::endgroup::" env: REDIS_ENV_CONF_DIR: ${{ steps.args.outputs.redis_env_conf_dir }} REDIS_ENV_WORK_DIR: ${{ steps.args.outputs.redis_env_work_dir }} @@ -129,16 +133,18 @@ runs: - name: Maven offline shell: bash run: | + echo "::group::Download Maven dependencies" mvn -q dependency:go-offline + echo "::endgroup::" continue-on-error: true - name: Run tests shell: bash run: | + echo "::group::Run test suite" export TEST_WORK_FOLDER=$REDIS_ENV_WORK_DIR - echo $TEST_WORK_FOLDER - ls -la $TEST_WORK_FOLDER make test-coverage + echo "::endgroup::" env: REDIS_ENV_WORK_DIR: ${{ steps.args.outputs.redis_env_work_dir }} JVM_OPTS: -Xmx3200m @@ -148,7 +154,9 @@ runs: if: always() shell: bash run: | + echo "::group::Stop Redis containers" make stop + echo "::endgroup::" continue-on-error: true - name: Upload coverage reports to Codecov