This is an automated email from the ASF dual-hosted git repository.

thisisnic pushed a commit to branch maint-22.0.0.1-r
in repository https://gitbox.apache.org/repos/asf/arrow.git

commit 47771ee172befcaf75ade1d82369ecf336ab2db3
Author: Nic Crane <[email protected]>
AuthorDate: Wed Dec 17 17:27:39 2025 +0000

    GH-48013: [R] Add CI job for musl (Alpine Linux) to replicate CRAN checks 
(#48014)
    
    ### Rationale for this change
    
    CRAN have added Alpine Linux to their additional jobs - we should make sure 
we can test for this on CI
    
    ### What changes are included in this PR?
    
    Add CI job for Alpine Linux
    
    ### Are these changes tested?
    
    Yeah, the CI job should pass
    
    ### Are there any user-facing changes?
    
    No
    * GitHub Issue: #48013
    
    Authored-by: Nic Crane <[email protected]>
    Signed-off-by: Nic Crane <[email protected]>
---
 ci/docker/alpine-linux-3.22-r.dockerfile    | 84 +++++++++++++++++++++++++++++
 ci/scripts/r_docker_configure.sh            | 16 ++++--
 ci/scripts/r_install_system_dependencies.sh | 10 ++++
 dev/tasks/tasks.yml                         |  6 +++
 docker-compose.yml                          | 32 +++++++++++
 r/src/Makevars.in                           |  2 +-
 6 files changed, 146 insertions(+), 4 deletions(-)

diff --git a/ci/docker/alpine-linux-3.22-r.dockerfile 
b/ci/docker/alpine-linux-3.22-r.dockerfile
new file mode 100644
index 0000000000..887cb6445e
--- /dev/null
+++ b/ci/docker/alpine-linux-3.22-r.dockerfile
@@ -0,0 +1,84 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Minimal Alpine Linux container with R for testing Arrow R package
+# on musl libc (CRAN runs checks on Alpine Linux 3.22)
+# Replicates CRAN's Alpine environment as closely as possible
+
+ARG arch=amd64
+FROM ${arch}/alpine:3.22
+
+# Install R and essential build tools
+# Note: bash is needed for Arrow CI scripts, even though CRAN's Alpine uses 
BusyBox
+RUN apk add \
+        R \
+        R-dev \
+        R-doc \
+        bash \
+        checkbashisms \
+        cmake \
+        curl-dev \
+        g++ \
+        gcc \
+        git \
+        linux-headers \
+        make \
+        musl-locales \
+        openssl-dev \
+        pkgconfig \
+        zlib-dev && \
+    rm -rf /var/cache/apk/* && \
+    ln -s /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
+    echo "Etc/UTC" > /etc/timezone
+
+# Set locale and timezone
+ENV LANG=C.UTF-8 \
+    LC_COLLATE=C \
+    MUSL_LOCPATH=/usr/share/i18n/locales/musl
+
+# Set CRAN repo
+RUN echo 'options(repos = c(CRAN = "https://cran.rstudio.com";))' >> 
/usr/lib/R/etc/Rprofile.site
+
+# Install pak for package management (following rhub pattern)
+RUN R -q -e 'install.packages("pak", repos = 
sprintf("https://r-lib.github.io/p/pak/%s/%s/%s/%s";, "devel", 
.Platform$pkgType, R.Version()$os, R.Version()$arch))'
+
+# Enable automatic system requirements installation
+ENV PKG_SYSREQS=true \
+    R_PKG_SYSREQS2=true
+
+# Set up parallel compilation
+RUN echo "MAKEFLAGS=-j$(R -s -e 'cat(parallel::detectCores())')" >> 
/usr/lib/R/etc/Renviron.site
+
+# Configure image and install Arrow-specific tooling
+COPY ci/scripts/r_docker_configure.sh /arrow/ci/scripts/
+COPY ci/etc/rprofile /arrow/ci/etc/
+COPY ci/scripts/r_install_system_dependencies.sh /arrow/ci/scripts/
+COPY ci/scripts/install_minio.sh /arrow/ci/scripts/
+COPY ci/scripts/install_gcs_testbench.sh /arrow/ci/scripts/
+RUN /arrow/ci/scripts/r_docker_configure.sh
+
+# Install sccache
+COPY ci/scripts/install_sccache.sh /arrow/ci/scripts/
+RUN /arrow/ci/scripts/install_sccache.sh unknown-linux-musl /usr/local/bin
+
+# Install R package dependencies
+COPY ci/scripts/r_deps.sh /arrow/ci/scripts/
+COPY r/DESCRIPTION /arrow/r/
+RUN /arrow/ci/scripts/r_deps.sh /arrow
+
+# Verify R works and this is musl
+RUN R --version && ldd --version 2>&1 | grep -q musl
diff --git a/ci/scripts/r_docker_configure.sh b/ci/scripts/r_docker_configure.sh
index 3039291ebb..b42b444e0b 100755
--- a/ci/scripts/r_docker_configure.sh
+++ b/ci/scripts/r_docker_configure.sh
@@ -39,6 +39,8 @@ elif [ "`which yum`" ]; then
   PACKAGE_MANAGER=yum
 elif [ "`which zypper`" ]; then
   PACKAGE_MANAGER=zypper
+elif [ "`which apk`" ]; then
+  PACKAGE_MANAGER=apk
 else
   PACKAGE_MANAGER=apt-get
   apt-get update --allow-releaseinfo-change # flag needed for when debian 
version changes
@@ -49,8 +51,12 @@ fi
 R_CUSTOM_CCACHE=`echo $R_CUSTOM_CCACHE | tr '[:upper:]' '[:lower:]'`
 if [ ${R_CUSTOM_CCACHE} = "true" ]; then
   # install ccache
-  $PACKAGE_MANAGER install -y epel-release || true
-  $PACKAGE_MANAGER install -y ccache
+  if [ "$PACKAGE_MANAGER" = "apk" ]; then
+    $PACKAGE_MANAGER add ccache
+  else
+    $PACKAGE_MANAGER install -y epel-release || true
+    $PACKAGE_MANAGER install -y ccache
+  fi
 
   mkdir -p ~/.R
   echo "VER=
@@ -73,7 +79,11 @@ fi
 
 # Install rsync for bundling cpp source and curl to make sure it is installed 
on all images,
 # cmake is now a listed sys req.
-$PACKAGE_MANAGER install -y rsync cmake curl
+if [ "$PACKAGE_MANAGER" = "apk" ]; then
+  $PACKAGE_MANAGER add rsync cmake curl
+else
+  $PACKAGE_MANAGER install -y rsync cmake curl
+fi
 
 # Update clang version to latest available.
 # This is only for rhub/clang20. If we change the base image from rhub/clang20,
diff --git a/ci/scripts/r_install_system_dependencies.sh 
b/ci/scripts/r_install_system_dependencies.sh
index c9795d0ec6..bc3f5a80d1 100755
--- a/ci/scripts/r_install_system_dependencies.sh
+++ b/ci/scripts/r_install_system_dependencies.sh
@@ -28,6 +28,8 @@ elif [ "`which yum`" ]; then
   PACKAGE_MANAGER=yum
 elif [ "`which zypper`" ]; then
   PACKAGE_MANAGER=zypper
+elif [ "`which apk`" ]; then
+  PACKAGE_MANAGER=apk
 else
   PACKAGE_MANAGER=apt-get
   apt-get update
@@ -39,6 +41,9 @@ case "$PACKAGE_MANAGER" in
   apt-get)
     apt-get install -y libcurl4-openssl-dev libssl-dev
     ;;
+  apk)
+    $PACKAGE_MANAGER add curl-dev openssl-dev
+    ;;
   *)
     $PACKAGE_MANAGER install -y libcurl-devel openssl-devel
     ;;
@@ -59,6 +64,11 @@ if [ "$ARROW_S3" == "ON" ] || [ "$ARROW_GCS" == "ON" ] || [ 
"$ARROW_R_DEV" == "T
         ln -s /usr/bin/python3.10 /usr/local/bin/python
         ln -s /usr/bin/pip3.10 /usr/local/bin/pip
         ;;
+      apk)
+        $PACKAGE_MANAGER add py3-pip
+        ln -s /usr/bin/python3 /usr/local/bin/python
+        ln -s /usr/bin/pip3 /usr/local/bin/pip
+        ;;
       *)
         $PACKAGE_MANAGER install -y python3-pip
         ln -s /usr/bin/python3 /usr/local/bin/python
diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml
index 749042779e..2d6e5ba9ce 100644
--- a/dev/tasks/tasks.yml
+++ b/dev/tasks/tasks.yml
@@ -669,6 +669,12 @@ tasks:
     ci: github
     template: r/github.linux.cran.yml
 
+  test-r-alpine-linux-cran:
+    ci: github
+    template: docker-tests/github.linux.yml
+    params:
+      image: alpine-linux-r
+
   test-r-macos-as-cran:
     ci: github
     template: r/github.macos.cran.yml
diff --git a/docker-compose.yml b/docker-compose.yml
index 937620f82e..cdf2026b85 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -114,6 +114,7 @@ x-hierarchy:
   # service entry, so any new image/service must be listed here.
   - almalinux-verify-rc
   - alpine-linux-cpp
+  - alpine-linux-r
   - centos-cpp-static
   - conda:
     - conda-cpp:
@@ -1771,6 +1772,37 @@ services:
     command: >
       /bin/bash -c "/arrow/ci/scripts/r_revdepcheck.sh /arrow"
 
+  alpine-linux-r:
+    # Usage:
+    #   docker compose build alpine-linux-r
+    #   docker compose run alpine-linux-r
+    # Tests R package installation on musl (Alpine Linux) for CRAN checks.
+    # R package builds C++ from source (bundled RE2 2023-03-01 supports musl).
+    # Parameters:
+    #   ALPINE_LINUX: 3.22
+    #   R: 4.5 (Alpine's R version)
+    #   ARCH: amd64, arm64v8, ...
+    image: ${REPO}:${ARCH}-alpine-linux-${ALPINE_LINUX}-r
+    build:
+      context: .
+      dockerfile: ci/docker/alpine-linux-${ALPINE_LINUX}-r.dockerfile
+      cache_from:
+        - ${REPO}:${ARCH}-alpine-linux-${ALPINE_LINUX}-r
+      args:
+        arch: ${ARCH}
+    shm_size: *shm-size
+    environment:
+      <<: [*common, *sccache]
+      LIBARROW_BINARY: "false"
+      ARROW_SOURCE_HOME: "/arrow"
+      ARROW_R_DEV: ${ARROW_R_DEV}
+      ARROW_USE_PKG_CONFIG: "false"
+      SKIP_VIGNETTES: "true"
+      NOT_CRAN: "false"
+    volumes:
+      - .:/arrow:delegated
+    command: /arrow/ci/scripts/r_test.sh /arrow
+
   ############################## Integration ##################################
 
   conda-integration:
diff --git a/r/src/Makevars.in b/r/src/Makevars.in
index f91fe503f3..af0826faac 100644
--- a/r/src/Makevars.in
+++ b/r/src/Makevars.in
@@ -31,4 +31,4 @@ PKG_LIBS=@libs@
 all: $(SHLIB) purify
 
 purify: $(SHLIB)
-       @rm -rf ../{libarrow,windows} || true
+       @rm -rf ../libarrow ../windows || true

Reply via email to