Skip to content

Release Redis version 8.0.2 #16

Release Redis version 8.0.2

Release Redis version 8.0.2 #16

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 }}"