diff --git a/.github/workflows/build-redislite.yml b/.github/workflows/build-redislite.yml new file mode 100644 index 000000000000..de9724f44552 --- /dev/null +++ b/.github/workflows/build-redislite.yml @@ -0,0 +1,138 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on upstream's Screwdriver pipeline (pkg_ml2014 and +# validate_test jobs) at +# https://github.com/yahoo/redislite/blob/802f8a09fa23470942f8358dee1aa32dc975ea7a/screwdriver.yaml +# with its tox.ini test command. +name: Build redislite wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/redislite.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-redislite.yml' + - 'docs/packages/redislite.yaml' + push: + branches: [main] + paths: + - '.github/workflows/build-redislite.yml' + - 'docs/packages/redislite.yaml' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + # Upstream pushes no tag for its releases: 6.2.912183 is commit 802f8a0, whose tree is + # byte-identical to the PyPI sdist apart from the version. Update it alongside REDISLITE_VERSION. + REDISLITE_REF: 802f8a09fa23470942f8358dee1aa32dc975ea7a + REDIS_VERSION: '6.2.14' + REDIS_SHA256: 34e74856cbd66fdb3a684fb349d93961d8c7aa668b06f81fd93ff267d09bc277 + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: redislite + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + python: ["cp312", "cp313", "cp314", "cp314t"] + name: Build redislite ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 120 + env: + REDISLITE_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout redislite ${{ env.REDISLITE_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: yahoo/redislite + ref: ${{ env.REDISLITE_REF }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Apply patches + run: git apply --verbose python-wheels/patches/redislite/${{ env.REDISLITE_VERSION }}/*.patch + + # build_scripts/update_redis_server.py, with curl: download.redis.io answers 403 to Python-urllib. + - name: Download the Redis ${{ env.REDIS_VERSION }} sources into redis.submodule + run: | + set -eux + curl -sSfL -o redis.tar.gz "https://download.redis.io/releases/redis-${REDIS_VERSION}.tar.gz" + echo "${REDIS_SHA256} redis.tar.gz" | sha256sum -c - + mkdir redis.submodule + tar xzf redis.tar.gz --strip-components=1 -C redis.submodule + rm redis.tar.gz + + - name: Build wheel + uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + only: ${{ matrix.python }}-manylinux_riscv64 + output-dir: wheelhouse/ + env: + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + CIBW_ENVIRONMENT: PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ + CIBW_TEST_REQUIRES: pytest + CIBW_TEST_SOURCES: tests pytest.ini + CIBW_TEST_COMMAND: pytest tests + + - name: Check the Redis binaries and licences made it into the wheel + run: | + python3 - wheelhouse/*.whl <<'EOF' + import os, sys, zipfile + whl = sys.argv[1] + assert os.path.basename(whl).startswith(f"redislite-{os.environ['REDISLITE_VERSION']}-"), whl + names = zipfile.ZipFile(whl).namelist() + for want in ("redislite/bin/redis-server", "redislite/bin/redis-cli"): + assert want in names, (whl, want) + licences = {n.split(".dist-info/licenses/", 1)[1] for n in names if ".dist-info/licenses/" in n} - {""} + assert {"LICENSE.txt", "redis.submodule/COPYING", "redis.submodule/deps/lua/COPYRIGHT"} <= licences, licences + print(whl, "ok") + EOF + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: redislite-${{ env.REDISLITE_VERSION }}-${{ matrix.python }}-manylinux_riscv64 + path: wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish redislite ${{ matrix.version }} + needs: [setup, build_wheels] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + secrets: + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} + with: + artifact-pattern: redislite-${{ matrix.version }}-*-manylinux_riscv64 diff --git a/docs/packages/redislite.yaml b/docs/packages/redislite.yaml new file mode 100644 index 000000000000..19156d53223a --- /dev/null +++ b/docs/packages/redislite.yaml @@ -0,0 +1,6 @@ +package-name: redislite +source-code: https://github.com/yahoo/redislite +license: BSD-3-Clause +versions: +- version: 6.2.912183 + patched: true diff --git a/patches/redislite/6.2.912183/0001-set-the-release-version-Screwdriver-stamps-at-publis.patch b/patches/redislite/6.2.912183/0001-set-the-release-version-Screwdriver-stamps-at-publis.patch new file mode 100644 index 000000000000..32e2a9576059 --- /dev/null +++ b/patches/redislite/6.2.912183/0001-set-the-release-version-Screwdriver-stamps-at-publis.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Tue, 13 Oct 2026 18:14:17 +0000 +Subject: [PATCH 1/3] set the release version Screwdriver stamps at publish + time + +Upstream-Status: Inappropriate [upstream's Screwdriver generate_version step rewrites setup.cfg's version to 6.2. at release time and never commits it] + +redislite 6.2.912183 on PyPI was cut from commit 802f8a0 ("Upgrade redis +to 6.2.14 (#190)"), byte-identical to the released sdist apart from +setup.cfg's version field. No git tag carries that version, so stamp it +the way upstream's release pipeline does. + +Signed-off-by: Ludovic Henry +--- + setup.cfg | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/setup.cfg b/setup.cfg +index 65759b4..105c8a7 100644 +--- a/setup.cfg ++++ b/setup.cfg +@@ -35,7 +35,7 @@ project_urls = + Documentation = https://redislite.readthedocs.io/en/latest/ + Source = https://github.com/yahoo/redislite + url = https://github.com/yahoo/redislite +-version = 6.2.14 ++version = 6.2.912183 + + [options] + install_requires= +-- +2.43.0 + diff --git a/patches/redislite/6.2.912183/0002-ship-the-bundled-Redis-server-s-licence-texts-in-the.patch b/patches/redislite/6.2.912183/0002-ship-the-bundled-Redis-server-s-licence-texts-in-the.patch new file mode 100644 index 000000000000..b04126331d21 --- /dev/null +++ b/patches/redislite/6.2.912183/0002-ship-the-bundled-Redis-server-s-licence-texts-in-the.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Tue, 13 Oct 2026 18:14:27 +0000 +Subject: [PATCH 2/3] ship the bundled Redis server's licence texts in the + wheel + +Upstream-Status: To upstream [not yet submitted; the same gap exists in every redislite wheel on PyPI, so it needs a maintainer discussion rather than a drive-by PR] + +The wheel bundles redis-server and redis-cli, compiled from Redis +6.2.14 together with its vendored hiredis, linenoise, Lua and +hdr_histogram, but carries only redislite's own LICENSE.txt. Their +BSD/MIT licences require the copyright notice to travel with binary +redistribution. The singular license_file key disables setuptools' +default licence glob, so list every file explicitly; jemalloc is not +listed because the build uses MALLOC=libc. + +Signed-off-by: Ludovic Henry +--- + setup.cfg | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/setup.cfg b/setup.cfg +index 105c8a7..3b51c40 100644 +--- a/setup.cfg ++++ b/setup.cfg +@@ -26,7 +26,14 @@ classifiers = + description = Redis built into a python package + keywords = redis sqlite python service integrated + license = BSD License +-license_file = LICENSE.txt ++license_files = ++ LICENSE.txt ++ redis.submodule/COPYING ++ redis.submodule/deps/hiredis/COPYING ++ redis.submodule/deps/linenoise/linenoise.h ++ redis.submodule/deps/lua/COPYRIGHT ++ redis.submodule/deps/hdr_histogram/LICENSE.txt ++ redis.submodule/deps/hdr_histogram/COPYING.txt + long_description = file:README.md + long_description_content_type = text/markdown + name = redislite +-- +2.43.0 + diff --git a/patches/redislite/6.2.912183/0003-use-assertEqual-instead-of-the-assertEquals-alias-re.patch b/patches/redislite/6.2.912183/0003-use-assertEqual-instead-of-the-assertEquals-alias-re.patch new file mode 100644 index 000000000000..3b07e5ed4295 --- /dev/null +++ b/patches/redislite/6.2.912183/0003-use-assertEqual-instead-of-the-assertEquals-alias-re.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Tue, 13 Oct 2026 18:16:19 +0000 +Subject: [PATCH 3/3] use assertEqual instead of the assertEquals alias removed + in Python 3.12 + +Upstream-Status: To upstream [not yet submitted; it affects every Python >= 3.12 test run on any architecture, so it needs a maintainer discussion rather than a drive-by PR] + +unittest's deprecated assertEquals alias was removed in Python 3.12, so +test_configuration_modify_defaults and test_slave fail with an +AttributeError before checking anything. Upstream's tox envlist stops at +py311 and never hit it; the published cp312 wheels have the same gap. + +Signed-off-by: Ludovic Henry +--- + tests/test_configuration.py | 2 +- + tests/test_slave.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/test_configuration.py b/tests/test_configuration.py +index 26b1708..5d156bb 100644 +--- a/tests/test_configuration.py ++++ b/tests/test_configuration.py +@@ -89,7 +89,7 @@ class TestRedisliteConfiguration(unittest.TestCase): + self.assertIn('\ndaemonize no', result) + + # ensure the global defaults are not modified +- self.assertEquals( ++ self.assertEqual( + redislite.configuration.DEFAULT_REDIS_SETTINGS["daemonize"], "yes" + ) + +diff --git a/tests/test_slave.py b/tests/test_slave.py +index 1cee61e..58d0d36 100644 +--- a/tests/test_slave.py ++++ b/tests/test_slave.py +@@ -22,4 +22,4 @@ class TestRedisliteSlave(unittest.TestCase): + master.set('key', 'value') + time.sleep(.5) + value = slave.get('key').decode(encoding='UTF-8') +- self.assertEquals(value, 'value') ++ self.assertEqual(value, 'value') +-- +2.43.0 +