Release Redis version 8.0.2 (#19) #17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build Redis CE RPM | |
on: | |
pull_request: | |
branches: | |
- release/8.0 | |
push: | |
branches: | |
- release/8.0 | |
env: | |
VERSION: "8.0.2" | |
jobs: | |
build-containers: | |
name: Build Builder Containers | |
uses: ./.github/workflows/build_workflow_containers.yaml | |
with: | |
os: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: ["rockylinux8", "rockylinux9"] | |
package-rpm: | |
name: Build and Package | |
needs: build-containers | |
runs-on: ${{ matrix.platform == 'arm64' && 'ubuntu24-arm64-2-8' || 'ubuntu-latest-8-cores' }} | |
permissions: | |
packages: read | |
contents: read | |
strategy: | |
fail-fast: false | |
matrix: | |
platform: [amd64, arm64] | |
os: | |
- name: rockylinux | |
version: 8 | |
- name: rockylinux | |
version: 9 | |
container: | |
image: ghcr.io/${{ github.repository }}/builder:${{ matrix.os.name }}${{ matrix.os.version }} | |
credentials: | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Build Redis | |
run: | | |
# Source gcc-toolset-13 environment, since GitHub Actions's shell is invoked with `--norc` | |
source /etc/profile.d/gcc-toolset-13.sh | |
export BUILD_WITH_MODULES=yes | |
export INSTALL_RUST_TOOLCHAIN=yes | |
export DISABLE_WERRORS=yes | |
export BUILD_TLS=yes | |
export USE_SYSTEMD=yes | |
# Download and extract Redis source | |
curl -L "https://github.com/redis/redis/archive/refs/tags/${{ env.VERSION }}.tar.gz" -o redis.tar.gz | |
tar xzf redis.tar.gz | |
cd redis-${{ env.VERSION }} | |
# Build Redis | |
make -j "$(nproc)" all | |
make install PREFIX=/usr/local | |
echo "Contents of /usr/local/lib/redis/modules/:" | |
ls -la /usr/local/lib/redis/modules/ | |
- name: Set up Go | |
uses: actions/setup-go@v4 | |
with: | |
go-version: '1.21' | |
- name: Install nfpm | |
run: | | |
go install github.com/goreleaser/nfpm/v2/cmd/nfpm@latest | |
- name: Build RPM package | |
run: | | |
cp templates/nfpm.yaml.tpl nfpm.yaml | |
mkdir -p dist | |
VERSION=${{ env.VERSION }} ARCH=${{ matrix.platform }} nfpm package --packager rpm --target dist | |
- name: Upload RPM artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: redis-${{ matrix.os.version }}-${{ matrix.platform }}-rpm | |
path: dist/*.rpm | |
test-rpm: | |
name: Sanity Tests | |
needs: package-rpm | |
runs-on: ${{ matrix.platform == 'arm64' && 'ubuntu24-arm64-2-8' || 'ubuntu-latest' }} | |
container: | |
image: "${{ matrix.distro }}:${{ matrix.distro == 'quay.io/centos/centos' && 'stream' || '' }}${{ matrix.distro_version }}" | |
strategy: | |
fail-fast: false | |
matrix: | |
exclude: | |
- distro: quay.io/centos/centos | |
distro_version: 8 | |
platform: [amd64, arm64] | |
distro: | |
- rockylinux | |
- almalinux | |
- quay.io/centos/centos | |
distro_version: | |
- 8 | |
- 9 | |
steps: | |
- name: Download RPM artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: redis-${{ matrix.distro_version }}-${{ matrix.platform }}-rpm | |
path: ./rpm | |
- name: Setup systemctl replacement | |
run: | | |
# For CentOS 8, update mirrors to vault first | |
if [ "${{ matrix.distro }}" = "quay.io/centos/centos" ] && [ "${{ matrix.distro_version }}" = "8" ]; then | |
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* | |
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* | |
fi | |
# Install curl if not present | |
dnf install -y --allowerasing curl python3 | |
# Download systemctl replacement first as .py file | |
curl -L https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl3.py -o /usr/bin/systemctl3.py | |
# Handle Python interpreter path based on distribution | |
if [ "${{ matrix.distro }}" = "quay.io/centos/centos" ] && [ "${{ matrix.distro_version }}" = "8" ]; then | |
# CentOS 8 uses platform-python | |
pythonpath="/usr/libexec/platform-python" | |
else | |
# Other distributions use regular python3 | |
pythonpath="/usr/bin/python3" | |
fi | |
echo "Using Python interpreter: $pythonpath" | |
sed -i -e "s|/usr/bin/python3|$pythonpath|" /usr/bin/systemctl3.py | |
# Copy to final location after modification | |
cp /usr/bin/systemctl3.py /usr/bin/systemctl | |
chmod +x /usr/bin/systemctl | |
# Create required systemd directory structure | |
mkdir -p /run/systemd/system/ | |
- name: Update CentOS 8 mirror URLs to vault | |
if: matrix.distro == 'quay.io/centos/centos' && matrix.distro_version == '8' | |
run: | | |
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* | |
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* | |
- name: Install RPM dependencies | |
run: | | |
dnf install -y ./rpm/*.rpm || true | |
systemctl enable redis | |
systemctl start redis | |
- name: Basic Sanity Tests | |
run: | | |
for i in {1..5}; do redis-cli ping &>/dev/null && break || echo "Waiting for Redis... $i" && sleep 1; done | |
redis-cli info server || { echo "Cannot get server info"; exit 1; } | |
- name: Verify installed modules | |
run: | | |
modules=$(redis-cli module list) | |
echo "Installed modules:" | |
echo "$modules" | |
missing_modules=() | |
for module in "bf" "search" "timeseries" "ReJSON"; do | |
if ! echo "$modules" | grep -q "$module"; then | |
missing_modules+=("$module") | |
fi | |
done | |
if [ ${#missing_modules[@]} -eq 0 ]; then | |
echo "All required modules are installed" | |
else | |
echo "The following modules are missing: ${missing_modules[*]}" | |
exit 1 | |
fi | |
- name: Test RedisBloom | |
run: | | |
redis-cli BF.ADD popular_keys "redis:hash" | |
redis-cli BF.ADD popular_keys "redis:set" | |
[ "$(redis-cli BF.EXISTS popular_keys "redis:hash")" = "1" ] || { echo "RedisBloom test failed: redis:hash not found"; exit 1; } | |
[ "$(redis-cli BF.EXISTS popular_keys "redis:list")" = "0" ] || { echo "RedisBloom test failed: redis:list found unexpectedly"; exit 1; } | |
echo "RedisBloom test passed successfully" | |
- name: Test RediSearch | |
run: | | |
redis-cli FT.CREATE redis_commands ON HASH PREFIX 1 cmd: SCHEMA name TEXT SORTABLE description TEXT | |
redis-cli HSET cmd:set name "SET" description "Set the string value of a key" | |
redis-cli HSET cmd:get name "GET" description "Get the value of a key" | |
result=$(redis-cli FT.SEARCH redis_commands "value") | |
if echo "$result" | grep -q "Set the string value of a key" && \ | |
echo "$result" | grep -q "Get the value of a key"; then | |
echo "RediSearch test passed successfully" | |
else | |
echo "RediSearch test failed: expected commands not found" | |
exit 1 | |
fi | |
- name: Test RedisTimeSeries | |
run: | | |
redis-cli TS.CREATE redis:cpu:usage RETENTION 86400 | |
redis-cli TS.ADD redis:cpu:usage "*" 80 | |
redis-cli TS.ADD redis:cpu:usage "*" 65 | |
redis-cli TS.ADD redis:cpu:usage "*" 70 | |
result=$(redis-cli TS.RANGE redis:cpu:usage - + COUNT 3) | |
if echo "$result" | grep -q "80" && \ | |
echo "$result" | grep -q "65" && \ | |
echo "$result" | grep -q "70"; then | |
echo "RedisTimeSeries test passed successfully" | |
else | |
echo "RedisTimeSeries test failed" | |
exit 1 | |
fi | |
- name: Test ReJSON | |
run: | | |
redis-cli JSON.SET redis:config $ '{"maxmemory":"2gb","maxmemory-policy":"allkeys-lru"}' | |
result=$(redis-cli JSON.GET redis:config $.maxmemory-policy) | |
cleaned_result=$(echo $result | tr -d "[]\"") | |
if [ "$cleaned_result" = "allkeys-lru" ]; then | |
echo "ReJSON test passed successfully" | |
else | |
echo "ReJSON test failed: expected allkeys-lru, got $result" | |
exit 1 | |
fi | |
download-rpms: | |
name: Download RPM Artifacts | |
needs: test-rpm | |
if: github.ref == 'refs/heads/release/8.0' | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
platform: [amd64, arm64] | |
os: | |
- name: rockylinux | |
version: 8 | |
- name: rockylinux | |
version: 9 | |
steps: | |
- uses: actions/download-artifact@v4 | |
with: | |
name: redis-${{ matrix.os.version }}-${{ matrix.platform }}-rpm | |
path: rpms/${{ matrix.os.name }}${{ matrix.os.version }}/${{ matrix.platform }} | |
- name: Upload RPM directory for further processing | |
uses: actions/upload-artifact@v4 | |
with: | |
name: redis-${{ matrix.os.name }}${{ matrix.os.version }}-${{ matrix.platform }}-for-repo | |
path: rpms | |
retention-days: 1 | |
upload-rpm: | |
name: Upload RPM to S3 | |
needs: download-rpms | |
if: github.ref == 'refs/heads/release/8.0' | |
runs-on: ubuntu-latest | |
permissions: | |
id-token: write | |
strategy: | |
fail-fast: false | |
matrix: | |
os: | |
- name: rockylinux | |
version: 8 | |
- name: rockylinux | |
version: 9 | |
steps: | |
- name: Download all RPM artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: redis-${{ matrix.os.name }}${{ matrix.os.version }}-*-for-repo | |
path: combined-rpms | |
merge-multiple: true | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-region: ${{ secrets.RPM_S3_REGION }} | |
role-to-assume: ${{ secrets.RPM_S3_IAM_ARN }} | |
- name: Install GPG key | |
run: | | |
echo -e "${{ secrets.GPG_KEY }}" | gpg --batch --import | |
- name: Get GPG key ID | |
id: gpg_id | |
run: | | |
GPG_ID=$(gpg --list-keys --with-colons | grep pub | cut -d':' -f5) | |
echo "GPG_ID=$GPG_ID" >> $GITHUB_OUTPUT | |
- name: Get GPG email | |
id: gpg_email | |
run: | | |
GPG_EMAIL=$(gpg --list-keys --with-colons | grep uid | head -n1 | cut -d':' -f10 | sed 's/.*<\(.*\)>.*/\1/') | |
echo "GPG_EMAIL=$GPG_EMAIL" >> $GITHUB_OUTPUT | |
- name: Get GPG keygrip | |
id: gpg_keygrip | |
run: | | |
KEYGRIP=$(gpg --list-keys --with-keygrip | grep Keygrip | head -n1 | awk '{print $3}') | |
echo "KEYGRIP=$KEYGRIP" >> $GITHUB_OUTPUT | |
- name: Install required tools | |
run: | | |
# Install required tools | |
sudo apt-get update | |
sudo apt-get install -y rpm createrepo-c s3cmd | |
- name: Sign RPM packages | |
run: | | |
# Export and import GPG key for RPM | |
gpg --export -a "${{ steps.gpg_email.outputs.GPG_EMAIL }}" > rpm-gpg-key.asc | |
sudo rpm --import rpm-gpg-key.asc | |
# Configure GPG agent for signing | |
mkdir -p ~/.gnupg | |
echo "allow-preset-passphrase" > ~/.gnupg/gpg-agent.conf | |
gpg-connect-agent reloadagent /bye | |
# Preset passphrase for non-interactive signing | |
/usr/lib/gnupg/gpg-preset-passphrase -P "${{ secrets.GPG_PASSWORD }}" -c "${{ steps.gpg_keygrip.outputs.KEYGRIP }}" | |
# Sign new RPM packages before copying them to the final repository | |
echo "Signing new RPM packages..." | |
find combined-rpms/${{ matrix.os.name }}${{ matrix.os.version }} -name "*.rpm" -exec rpmsign --addsign --key-id "${{ steps.gpg_id.outputs.GPG_ID }}" {} \; | |
echo "Signed packages:" | |
find combined-rpms/${{ matrix.os.name }}${{ matrix.os.version }} -name "*.rpm" | sort | |
- name: Prepare repository structure | |
env: | |
RPM_S3_BUCKET: ${{ secrets.RPM_S3_BUCKET }} | |
RPM_S3_REGION: ${{ secrets.RPM_S3_REGION }} | |
run: | | |
# Create directory for the final repository | |
mkdir -p s3uploads/${{ matrix.os.name }}${{ matrix.os.version }} | |
# First download existing packages from S3 to ensure we include them in the repo metadata | |
echo "Downloading existing packages from S3..." | |
s3cmd sync --region=${{ env.RPM_S3_REGION }} s3://${{ env.RPM_S3_BUCKET }}/rpm/${{ matrix.os.name }}${{ matrix.os.version }}/ s3uploads/${{ matrix.os.name }}${{ matrix.os.version }}/ | |
# Copy all signed RPMs from both architectures to the repository directory | |
echo "Adding newly signed packages..." | |
cp -r combined-rpms/${{ matrix.os.name }}${{ matrix.os.version }}/* s3uploads/${{ matrix.os.name }}${{ matrix.os.version }}/ | |
# List all files to verify | |
echo "All packages in repository:" | |
find s3uploads -type f -name "*.rpm" | sort | |
# Create repository metadata with signatures for this OS version | |
echo "Generating repository metadata..." | |
cd s3uploads/${{ matrix.os.name }}${{ matrix.os.version }} | |
createrepo_c . | |
- name: Update packages and publish to private repo | |
env: | |
RPM_S3_BUCKET: ${{ secrets.RPM_S3_BUCKET }} | |
RPM_S3_REGION: ${{ secrets.RPM_S3_REGION }} | |
run: | | |
# Use --no-delete-removed to ensure we don't delete any existing packages | |
echo "Uploading repository to S3..." | |
s3cmd sync --acl-public --no-delete-removed --region=${{ env.RPM_S3_REGION }} s3uploads/${{ matrix.os.name }}${{ matrix.os.version }}/* s3://${{ env.RPM_S3_BUCKET }}/rpm/${{ matrix.os.name }}${{ matrix.os.version }}/ | |
echo "Repository update complete for ${{ matrix.os.name }}${{ matrix.os.version }}" |