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
