Skip to content

Commit b40c66a

Browse files
authored
fix older oses precompiled support (#649)
* fix older oses precompiled support * remarks
1 parent a162a24 commit b40c66a

File tree

8 files changed

+152
-155
lines changed

8 files changed

+152
-155
lines changed

.github/workflows/ci_linux_x86_64_gnu.yml

Lines changed: 66 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1+
# CI Strategy: Comprehensive Testing of Build and Precompiled Flows
2+
#
3+
# This workflow tests both compilation-from-source and precompiled binary distribution
4+
# strategies across multiple Ubuntu and Ruby versions to ensure broad compatibility and
5+
# reliability.
6+
#
7+
# WHY WE TEST BOTH UBUNTU 22.04 AND 24.04:
8+
# - Different system library versions (OpenSSL, zlib, libsasl2, libzstd, etc.)
9+
# - Different GCC compiler versions that affect native extension compilation
10+
# - Different glibc versions that can impact binary compatibility
11+
# - Real-world deployment scenarios where users run on various Ubuntu LTS versions
12+
# - Different Ruby versions
13+
#
14+
# COMPILATION FLOW (build_install + specs_install):
15+
# - Tests that librdkafka compiles correctly from source on each Ubuntu version
16+
# - Validates that mini_portile2 can successfully build native dependencies
17+
# - Ensures Ruby native extensions link properly with system libraries
18+
# - Verifies that the same codebase works across different toolchain versions
19+
#
20+
# PRECOMPILED FLOW (build_precompiled + specs_precompiled):
21+
# - Tests our precompiled static libraries work on different Ubuntu versions
22+
# - Validates that statically-linked binaries are truly portable across environments
23+
# - Ensures precompiled libraries don't have unexpected system dependencies
24+
# - Verifies that removing build tools doesn't break precompiled binary usage
25+
#
26+
# ARTIFACT ISOLATION:
27+
# - Each Ubuntu version gets separate artifacts (rdkafka-built-gem-22.04, etc.)
28+
# - Prevents cross-contamination of OS-specific compiled extensions
29+
# - Ensures test accuracy by matching build and test environments
30+
#
31+
# This comprehensive approach catches issues that single-platform testing would miss,
32+
# such as system library incompatibilities, compiler-specific bugs, or static linking
33+
# problems that only manifest on specific Ubuntu versions.
34+
135
name: CI Linux x86_64 GNU
236

337
concurrency:
@@ -20,41 +54,8 @@ env:
2054
BUNDLE_JOBS: 4
2155

2256
jobs:
23-
build_install:
24-
timeout-minutes: 30
25-
runs-on: ubuntu-latest
26-
steps:
27-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
28-
with:
29-
fetch-depth: 0
30-
- name: Install package dependencies
31-
run: "[ -e $APT_DEPS ] || sudo apt-get install -y --no-install-recommends $APT_DEPS"
32-
- name: Set up Ruby
33-
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
34-
with:
35-
ruby-version: '3.4' # Use one Ruby version for building
36-
bundler-cache: false
37-
- name: Build gem with mini_portile
38-
run: |
39-
set -e
40-
bundle install
41-
cd ext && bundle exec rake
42-
cd ..
43-
- name: Upload built gem and bundle
44-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
45-
with:
46-
name: rdkafka-built-gem
47-
path: |
48-
vendor/bundle/
49-
.bundle/
50-
ext/
51-
lib/
52-
retention-days: 1
53-
5457
specs_install:
5558
timeout-minutes: 30
56-
runs-on: ubuntu-latest
57-
needs: build_install
5859
strategy:
5960
fail-fast: false
6061
matrix:
@@ -65,20 +66,17 @@ jobs:
6566
- '3.2'
6667
- '3.1'
6768
- 'jruby-10.0'
69+
ubuntu-version: ['22.04', '24.04']
6870
include:
6971
- ruby: '3.4'
7072
coverage: 'true'
7173
- ruby: 'jruby-10.0'
7274
continue-on-error: true
75+
runs-on: ubuntu-${{ matrix.ubuntu-version }}
7376
steps:
7477
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
7578
with:
7679
fetch-depth: 0
77-
- name: Download built gem
78-
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
79-
with:
80-
name: rdkafka-built-gem
81-
path: ./
8280
- name: Set up Ruby
8381
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
8482
with:
@@ -108,12 +106,17 @@ jobs:
108106
echo "Sleeping 2 seconds..."
109107
sleep 2
110108
done
111-
- name: Install remaining dependencies
109+
- name: Install dependencies
112110
env:
113111
RDKAFKA_EXT_PATH: ${{ github.workspace }}/ext
114112
run: |
115113
# Only install gems that aren't Ruby-version specific
116114
bundle install
115+
- name: Build gem with mini_portile
116+
run: |
117+
set -e
118+
cd ext && bundle exec rake
119+
cd ..
117120
- name: Run all specs
118121
env:
119122
GITHUB_COVERAGE: ${{matrix.coverage}}
@@ -124,7 +127,10 @@ jobs:
124127
125128
build_precompiled:
126129
timeout-minutes: 30
127-
runs-on: ubuntu-latest
130+
# We precompile on older Ubuntu and check compatibility by running specs since we aim to
131+
# release only one precompiled version for all supported Ubuntu versions
132+
# This is why we do not want Renovate to update it automatically
133+
runs-on: ubuntu-22.04 # renovate: ignore
128134
steps:
129135
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
130136
with:
@@ -135,15 +141,29 @@ jobs:
135141
sudo apt-get install -y --no-install-recommends \
136142
build-essential \
137143
gcc \
144+
g++ \
138145
make \
139-
patch \
140146
tar \
147+
gzip \
141148
wget \
149+
curl \
150+
file \
151+
pkg-config \
152+
autoconf \
153+
automake \
154+
libtool \
155+
python3 \
156+
git \
142157
ca-certificates \
158+
patch \
143159
libsasl2-dev \
144160
libssl-dev \
145161
zlib1g-dev \
146-
libzstd-dev
162+
libzstd-dev \
163+
bison \
164+
flex \
165+
perl \
166+
binutils-dev
147167
- name: Cache build-tmp directory
148168
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
149169
with:
@@ -162,7 +182,6 @@ jobs:
162182

163183
specs_precompiled:
164184
timeout-minutes: 30
165-
runs-on: ubuntu-latest
166185
needs: build_precompiled
167186
strategy:
168187
fail-fast: false
@@ -173,9 +192,13 @@ jobs:
173192
- '3.3'
174193
- '3.2'
175194
- '3.1'
195+
ubuntu-version: ['22.04', '24.04']
176196
include:
177197
- ruby: '3.4'
198+
ubuntu-version: '24.04'
178199
coverage: 'true'
200+
201+
runs-on: ubuntu-${{ matrix.ubuntu-version }}
179202
steps:
180203
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
181204
with:
@@ -199,7 +222,6 @@ jobs:
199222
200223
echo "=== Container status ==="
201224
docker compose ps kafka
202-
203225
for i in {1..30}; do
204226
echo "=== Attempt $i/30 ==="
205227

.github/workflows/ci_linux_x86_64_musl.yml

Lines changed: 51 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
# Why We Build and Run Without Caching Native Extensions
2+
#
3+
# We intentionally compile the native librdkafka library fresh in each test job
4+
# rather than caching or pre-building it for several reasons:
5+
#
6+
# 1. Architecture Compatibility
7+
# - Pre-built native libraries (.so files) are architecture-specific
8+
# - Can cause "Exec format error" when build/runtime environments differ
9+
# - Building in the same container guarantees compatibility
10+
#
11+
# 2. Container Image Variations
12+
# - Different Ruby Alpine images may have subtle differences in:
13+
# * Base system libraries, compiler toolchains, musl libc versions
14+
# - These differences can cause pre-built libraries to fail at runtime
15+
#
16+
# 3. Simplicity and Reliability
17+
# - Single source of truth: everything builds and runs in same environment
18+
# - No artifact management complexity or potential upload/download failures
19+
# - Easier debugging when issues are contained in one job
20+
#
21+
# Trade-offs: Slightly longer CI times (~2-3 min per job) but much more reliable
22+
# than dealing with architecture mismatches and artifact corruption issues.
23+
124
name: CI Linux x86_64 musl
225

326
concurrency:
@@ -20,110 +43,76 @@ env:
2043
BUNDLE_JOBS: 4
2144

2245
jobs:
23-
build_install:
24-
timeout-minutes: 30
25-
runs-on: ubuntu-latest
26-
container:
27-
image: alpine:3.22@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1
28-
steps:
29-
- name: Install dependencies
30-
run: |
31-
apk add --no-cache git curl ca-certificates build-base linux-headers \
32-
pkgconf perl autoconf automake libtool bison flex file \
33-
ruby ruby-dev ruby-bundler bash zstd-dev zlib zlib-dev openssl-dev cyrus-sasl-dev
34-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
35-
with:
36-
fetch-depth: 0
37-
- name: Configure git safe directory
38-
run: git config --global --add safe.directory /__w/karafka-rdkafka/karafka-rdkafka
39-
- name: Build gem with mini_portile
40-
run: |
41-
set -e
42-
bundle config set --local path 'vendor/bundle'
43-
bundle install
44-
cd ext && bundle exec rake
45-
cd ..
46-
- name: Upload built gem and bundle
47-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
48-
with:
49-
name: rdkafka-built-gem-musl
50-
path: |
51-
vendor/bundle/
52-
.bundle/
53-
ext/
54-
lib/
55-
retention-days: 1
56-
5746
specs_install:
5847
timeout-minutes: 30
5948
runs-on: ubuntu-latest
60-
needs: build_install
6149
strategy:
6250
fail-fast: false
6351
matrix:
64-
ruby:
65-
- '3.4'
66-
- '3.3'
67-
- '3.2'
68-
- '3.1'
6952
include:
53+
- ruby: '3.1'
54+
alpine_version: '3.21'
55+
- ruby: '3.2'
56+
alpine_version: '3.21'
57+
- ruby: '3.2'
58+
alpine_version: '3.22'
59+
- ruby: '3.3'
60+
alpine_version: '3.21'
61+
- ruby: '3.3'
62+
alpine_version: '3.22'
63+
- ruby: '3.4'
64+
alpine_version: '3.21'
65+
coverage: 'true'
7066
- ruby: '3.4'
67+
alpine_version: '3.22'
7168
coverage: 'true'
7269
steps:
7370
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
7471
with:
7572
fetch-depth: 0
76-
- name: Download built gem
77-
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
78-
with:
79-
name: rdkafka-built-gem-musl
80-
path: ./
73+
8174
- name: Start Kafka with Docker Compose
8275
run: |
8376
docker compose up -d
8477
echo "Waiting for Kafka to be ready..."
8578
sleep 10
86-
8779
for i in {1..30}; do
8880
if docker compose exec -T kafka kafka-topics --bootstrap-server localhost:9092 --list >/dev/null 2>&1; then
8981
echo "Kafka topics command succeeded!"
9082
break
9183
fi
9284
sleep 2
9385
done
86+
9487
- name: Run all specs
9588
env:
9689
GITHUB_COVERAGE: ${{ matrix.coverage }}
97-
RDKAFKA_EXT_PATH: ${{ github.workspace }}/ext
9890
run: |
9991
docker run --rm \
10092
--network host \
10193
-v "${{ github.workspace }}:/workspace" \
10294
-w /workspace \
10395
-e "GITHUB_COVERAGE=${{ matrix.coverage }}" \
104-
-e "RDKAFKA_EXT_PATH=/workspace/ext" \
105-
ruby:${{ matrix.ruby }}-alpine \
106-
sh -c 'apk add --no-cache git build-base linux-headers bash \
107-
cyrus-sasl \
108-
cyrus-sasl-login \
109-
cyrus-sasl-crammd5 \
110-
cyrus-sasl-digestmd5 \
111-
cyrus-sasl-gssapiv2 \
112-
cyrus-sasl-scram \
113-
krb5-libs \
114-
openssl \
115-
zlib \
116-
zlib-dev \
117-
zstd-libs && \
96+
ruby:${{ matrix.ruby }}-alpine${{ matrix.alpine_version }} \
97+
sh -c 'apk add --no-cache git curl ca-certificates build-base linux-headers \
98+
pkgconf perl autoconf automake libtool bison flex file \
99+
ruby-dev ruby-bundler bash zstd-dev zlib zlib-dev openssl-dev \
100+
cyrus-sasl-dev cyrus-sasl cyrus-sasl-login \
101+
cyrus-sasl-crammd5 cyrus-sasl-digestmd5 cyrus-sasl-gssapiv2 cyrus-sasl-scram \
102+
krb5-libs openssl zlib zstd-libs && \
118103
git config --global --add safe.directory /workspace && \
119104
bundle config set --local path vendor/bundle && \
120105
bundle install && \
106+
cd ext && bundle exec rake && \
107+
cd .. && \
121108
bundle exec ruby -S rspec'
109+
122110
build_precompiled:
123111
timeout-minutes: 45
124112
runs-on: ubuntu-latest
125113
container:
126-
image: alpine:3.22@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1
114+
# Similar to GNU, we build on the oldest for ABI compatibility
115+
image: alpine:3.18@sha256:de0eb0b3f2a47ba1eb89389859a9bd88b28e82f5826b6969ad604979713c2d4f # renovate: ignore
127116
steps:
128117
- name: Install dependencies
129118
run: |

0 commit comments

Comments
 (0)