Skip to content

CI Linux Ubuntu aarch64 GNU #242

CI Linux Ubuntu aarch64 GNU

CI Linux Ubuntu aarch64 GNU #242

# CI Strategy: Comprehensive Testing of Build and Precompiled Flows
#
# This workflow tests both compilation-from-source and precompiled binary distribution
# strategies across multiple Ubuntu and Ruby versions to ensure broad compatibility and
# reliability.
#
# WHY WE TEST BOTH UBUNTU 22.04 AND 24.04:
# - Different system library versions (OpenSSL, zlib, libsasl2, libzstd, etc.)
# - Different GCC compiler versions that affect native extension compilation
# - Different glibc versions that can impact binary compatibility
# - Real-world deployment scenarios where users run on various Ubuntu LTS versions
# - Different Ruby versions
#
# COMPILATION FLOW (build_install + specs_install):
# - Tests that librdkafka compiles correctly from source on each Ubuntu version
# - Validates that mini_portile2 can successfully build native dependencies
# - Ensures Ruby native extensions link properly with system libraries
# - Verifies that the same codebase works across different toolchain versions
#
# PRECOMPILED FLOW (build_precompiled + specs_precompiled):
# - Tests our precompiled static libraries work on different Ubuntu versions
# - Validates that statically-linked binaries are truly portable across environments
# - Ensures precompiled libraries don't have unexpected system dependencies
# - Verifies that removing build tools doesn't break precompiled binary usage
#
# ARTIFACT ISOLATION:
# - Each Ubuntu version gets separate artifacts (rdkafka-built-gem-22.04, etc.)
# - Prevents cross-contamination of OS-specific compiled extensions
# - Ensures test accuracy by matching build and test environments
#
# This comprehensive approach catches issues that single-platform testing would miss,
# such as system library incompatibilities, compiler-specific bugs, or static linking
# problems that only manifest on specific Ubuntu versions.
name: CI Linux Ubuntu aarch64 GNU
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
branches: [ master ]
schedule:
- cron: '0 4 * * *'
permissions:
contents: read
env:
BUNDLE_RETRY: 6
BUNDLE_JOBS: 4
jobs:
specs_install:
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
ruby:
- '4.0.0-preview2'
- '3.4'
- '3.3'
- '3.2'
- 'jruby-10.0'
ubuntu-version: ['22.04', '24.04']
include:
- ruby: '3.4'
coverage: 'true'
- ruby: 'jruby-10.0'
continue-on-error: true
runs-on: ubuntu-${{ matrix.ubuntu-version }}-arm
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Ruby
uses: ruby/setup-ruby@d697be2f83c6234b20877c3b5eac7a7f342f0d0c # v1.269.0
with:
ruby-version: ${{matrix.ruby}}
bundler-cache: false
- name: Start Kafka with Docker Compose
run: |
docker compose -f docker-compose.yml up -d
echo "Waiting for Kafka to be ready..."
sleep 10
echo "=== Container status ==="
docker compose ps kafka
for i in {1..30}; do
echo "=== Attempt $i/30 ==="
echo "Testing kafka-topics command..."
if docker compose exec -T kafka kafka-topics --bootstrap-server localhost:9092 --list >/dev/null 2>&1; then
echo "Kafka topics command succeeded!"
break
else
echo "Kafka topics command failed (exit code: $?)"
fi
echo "Sleeping 2 seconds..."
sleep 2
done
- name: Install dependencies
env:
RDKAFKA_EXT_PATH: ${{ github.workspace }}/ext
run: |
# Only install gems that aren't Ruby-version specific
bundle install
- name: Build gem with mini_portile
run: |
set -e
cd ext && bundle exec rake
cd ..
- name: Run all specs in PLAINTEXT
env:
GITHUB_COVERAGE: ${{matrix.coverage}}
RDKAFKA_EXT_PATH: ${{ github.workspace }}/ext
continue-on-error: ${{ matrix.continue-on-error || false }}
run: |
bundle exec rspec
- name: Verify Kafka warnings
run: bin/verify_kafka_warnings
build_precompiled:
timeout-minutes: 30
# We precompile on older Ubuntu and check compatibility by running specs since we aim to
# release only one precompiled version for all supported Ubuntu versions
# This is why we do not want Renovate to update it automatically
runs-on: ubuntu-22.04-arm # renovate: ignore
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential \
gcc \
g++ \
make \
tar \
gzip \
wget \
curl \
file \
pkg-config \
autoconf \
automake \
libtool \
python3 \
git \
ca-certificates \
patch \
libsasl2-dev \
libssl-dev \
zlib1g-dev \
libzstd-dev \
bison \
flex \
perl \
binutils-dev
- name: Cache build-tmp directory
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ext/build-tmp
key: build-tmp-${{ runner.os }}-${{ hashFiles('ext/*.sh', 'ext/Rakefile') }}-v2
- name: Build precompiled librdkafka.so
run: |
cd ext
./build_linux_aarch64_gnu.sh
- name: Upload precompiled library
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: librdkafka-precompiled-linux
path: ext/
retention-days: 1
specs_precompiled:
timeout-minutes: 30
needs: build_precompiled
strategy:
fail-fast: false
matrix:
ruby:
- '4.0.0-preview2'
- '3.4'
- '3.3'
- '3.2'
ubuntu-version: ['22.04', '24.04']
include:
- ruby: '3.4'
ubuntu-version: '24.04'
coverage: 'true'
runs-on: ubuntu-${{ matrix.ubuntu-version }}-arm
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Download precompiled library
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: librdkafka-precompiled-linux
path: ext/
- name: Set up Ruby
uses: ruby/setup-ruby@d697be2f83c6234b20877c3b5eac7a7f342f0d0c # v1.269.0
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: false
- name: Start Kafka with Docker Compose
run: |
docker compose -f docker-compose.yml up -d
echo "Waiting for Kafka to be ready..."
sleep 10
echo "=== Container status ==="
docker compose ps kafka
for i in {1..30}; do
echo "=== Attempt $i/30 ==="
echo "Testing kafka-topics command..."
if docker compose exec -T kafka kafka-topics --bootstrap-server localhost:9092 --list >/dev/null 2>&1; then
echo "Kafka topics command succeeded!"
break
else
echo "Kafka topics command failed (exit code: $?)"
fi
echo "Sleeping 2 seconds..."
sleep 2
done
- name: Install bundle with precompiled library
env:
GITHUB_COVERAGE: ${{ matrix.coverage }}
RDKAFKA_EXT_PATH: ${{ github.workspace }}/ext
run: |
bundle install
echo "Bundle install completed with precompiled library"
- name: Remove build dependencies to test static linking
continue-on-error: true
run: |
echo "Removing build dependencies to verify precompiled library is truly self-contained..."
# Remove packages one by one to avoid dependency conflicts
packages_to_remove="build-essential gcc g++ make patch tar wget libsasl2-dev libssl-dev zlib1g-dev libzstd-dev"
for package in $packages_to_remove; do
if dpkg -l | grep -q "^ii.*$package "; then
echo "Removing $package..."
sudo dpkg --remove --force-depends $package 2>/dev/null || echo "Could not remove $package"
else
echo "$package is not installed"
fi
done
echo "Build dependencies removal completed"
echo "Remaining build tools:"
which gcc g++ make 2>/dev/null || echo "No build tools found in PATH (good!)"
- name: Run specs with precompiled library and PLAINTEXT
env:
GITHUB_COVERAGE: ${{ matrix.coverage }}
RDKAFKA_EXT_PATH: ${{ github.workspace }}/ext
RDKAFKA_PRECOMPILED: "true"
run: |
bundle exec rspec
- name: Verify Kafka warnings
run: bin/verify_kafka_warnings
ci-success:
name: CI Linux Ubuntu aarch64 GNU Success
runs-on: ubuntu-latest
if: always()
needs:
- specs_install
- build_precompiled
- specs_precompiled
steps:
- name: Check all jobs passed
if: |
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled') ||
contains(needs.*.result, 'skipped')
run: exit 1
- run: echo "All CI checks passed!"