Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 6 additions & 40 deletions .github/workflows/rc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ jobs:
fail-fast: false
matrix:
platform:
- { runs_on: macos-15-intel, arch: "x86_64"}
- { runs_on: macos-14, arch: "aarch_64" }
env:
MACOSX_DEPLOYMENT_TARGET: "14.0"
Expand Down Expand Up @@ -211,46 +210,19 @@ jobs:
# llvm@14 because llvm is newer than llvm@14.
brew uninstall llvm || :

# We can remove this when we drop support for
# macos-15-intel. because macos-14 or later with arm64 uses /opt/homebrew/
# not /usr/local/.
#
# Ensure updating python@XXX with the "--overwrite" option.
# If python@XXX is updated without "--overwrite", it causes
# a conflict error. Because Python 3 installed not by
# Homebrew exists in /usr/local on GitHub Actions. If
# Homebrew's python@XXX is updated without "--overwrite", it
# tries to replace /usr/local/bin/2to3 and so on and causes
# a conflict error.
brew update
for python_package in $(brew list | grep python@ | sort -r); do
brew install --overwrite ${python_package}
done
brew install --overwrite python3

if [ "$(uname -m)" = "arm64" ]; then
# pkg-config formula is deprecated but it's still installed
# in GitHub Actions runner now. We can remove this once
# pkg-config formula is removed from GitHub Actions runner.
brew uninstall pkg-config || :
brew uninstall pkg-config@0.29.2 || :
fi
# pkg-config formula is deprecated but it's still installed
# in GitHub Actions runner now. We can remove this once
# pkg-config formula is removed from GitHub Actions runner.
brew uninstall pkg-config || :
brew uninstall pkg-config@0.29.2 || :

# We don't use Homebrew's aws-sdk-cpp and gRPC. See the
# "brew uninstall" calls below for details. So we don't install
# them instead of installing and uninstalling them.
#
# This is also needed because Homebrew doesn't provide bottles
# for them on x86_64 macOS. Homebrew treats x86_64 macOS as a
# tier 3 configuration and rarely builds bottles for it:
#
# https://docs.brew.sh/Support-Tiers#tier-3
#
# "brew bundle" fails with "no bottle available!" without this
# because it doesn't build them from source.
#
# We don't use Homebrew's Node.js too. Homebrew doesn't provide
# a bottle for it on x86_64 macOS for the same reason.
# We don't need Homebrew's Node.js for the JNI build either.
HOMEBREW_BUNDLE_BREW_SKIP="aws-sdk-cpp grpc node" \
brew bundle --file=arrow/cpp/Brewfile
# We want to link aws-sdk-cpp statically but Homebrew's
Expand Down Expand Up @@ -388,7 +360,6 @@ jobs:
tar -xf apache-arrow-java-*.tar.gz --strip-components=1
tar -xvzf jni-linux-x86_64.tar.gz
tar -xvzf jni-linux-aarch_64.tar.gz
tar -xvzf jni-macos-x86_64.tar.gz
tar -xvzf jni-macos-aarch_64.tar.gz
tar -xvzf jni-windows-x86_64.tar.gz
- name: Test that shared libraries exist
Expand All @@ -405,11 +376,6 @@ jobs:
test -f jni/arrow_orc_jni/aarch_64/libarrow_orc_jni.so
test -f jni/gandiva_jni/aarch_64/libgandiva_jni.so

test -f jni/arrow_cdata_jni/x86_64/libarrow_cdata_jni.dylib
test -f jni/arrow_dataset_jni/x86_64/libarrow_dataset_jni.dylib
test -f jni/arrow_orc_jni/x86_64/libarrow_orc_jni.dylib
test -f jni/gandiva_jni/x86_64/libgandiva_jni.dylib

test -f jni/arrow_cdata_jni/aarch_64/libarrow_cdata_jni.dylib
test -f jni/arrow_dataset_jni/aarch_64/libarrow_dataset_jni.dylib
test -f jni/arrow_orc_jni/aarch_64/libarrow_orc_jni.dylib
Expand Down
204 changes: 152 additions & 52 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,16 @@ permissions:
contents: read

env:
BUILD_JDK: "17"
DOCKER_VOLUME_PREFIX: ".docker/"
MAVEN: 3.9.16

jobs:
ubuntu:
name: AMD64 ${{ matrix.name }} JDK ${{ matrix.jdk }} Maven ${{ matrix.maven }}
build-java:
name: Build Java artifacts
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
jdk: [17, 21, 25]
maven: [3.9.16]
image: [ubuntu, conda-jni-cdata]
include:
- image: ubuntu
name: "Ubuntu"
- image: conda-jni-cdata
name: "Conda JNI"
env:
JDK: ${{ matrix.jdk }}
MAVEN: ${{ matrix.maven }}
steps:
- name: Checkout Arrow
uses: actions/checkout@v7
Expand All @@ -65,85 +53,197 @@ jobs:
- name: Cache Docker Volumes
uses: actions/cache@v6
with:
path: .docker
key: maven-${{ matrix.jdk }}-${{ matrix.maven }}-${{ hashFiles('compose.yaml', '**/pom.xml') }}
restore-keys: maven-${{ matrix.jdk }}-${{ matrix.maven }}-
- name: Execute Docker Build
path: .docker/maven-cache
key: java-build-${{ env.BUILD_JDK }}-${{ env.MAVEN }}-${{ hashFiles('compose.yaml', '**/pom.xml') }}
restore-keys: java-build-${{ env.BUILD_JDK }}-${{ env.MAVEN }}-
- name: Build without tests
env:
# Enables build caching, but not strictly required
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
JDK: ${{ env.BUILD_JDK }}
run: |
docker compose run \
--rm \
-e CI=true \
-e "DEVELOCITY_ACCESS_KEY=$DEVELOCITY_ACCESS_KEY" \
${{ matrix.image }}
ubuntu-artifacts
sudo chown -R "$(id -u):$(id -g)" .docker
- name: Pack reusable artifacts
run: |
tar -czf java-build.tgz \

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[efficiency] Arrow snapshot artifacts travel into every Docker test job twice: once inside the actions/cache of the whole .docker/maven-cache, and again in this tgz — and the cached copy is immediately rm -rf'd by the restore step (~50–150MB × 3 rows, same pattern on the cdata side). Cheaper: drop repository/org/apache/arrow from the cache (delete it after packing, or exclude it from the cache path) so the tgz is its sole carrier. Related: the 9 test jobs use fetch-depth: 0 + recursive submodules but never need history — fetch-depth: 1 saves 1–3 min each.

.docker/java-build \
.docker/maven-cache/repository/org/apache/arrow
- name: Upload reusable artifacts
uses: actions/upload-artifact@v5

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[conventions] upload-artifact@v5 / download-artifact@v6 are floating tags, while rc.yml SHA-pins both actions in 8 places (upload-artifact@043fb46d… # v7.0.1, download-artifact@3e5f45b2… # v8.0.1). Beyond the supply-chain angle, the two workflows are also on different majors of the same actions, whose hidden-file/overwrite semantics differ. Suggest pinning to the same SHAs rc.yml uses.

with:
name: java-build
path: java-build.tgz
retention-days: 1
Comment thread
xborder marked this conversation as resolved.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ci-robustness] retention-days: 1 (also on cdata-build below) breaks "Re-run failed jobs" more than 24h after the original run: build-java isn't re-run, the artifact has expired, and download-artifact errors — the only recovery is re-running the whole workflow. The old self-contained jobs were re-runnable indefinitely. Suggest the default retention (or a few days).

- name: Exclude reactor artifacts from Maven dependency cache
run: rm -rf .docker/maven-cache/repository/org/apache/arrow

macos:
name: ${{ matrix.arch }} macOS ${{ matrix.macos }} Java JDK ${{ matrix.jdk }}
runs-on: macos-${{ matrix.macos }}
test-java:
name: ${{ matrix.name || format('AMD64 Ubuntu JDK {0} Maven 3.9.16', matrix.jdk) }}
needs: build-java
runs-on: ${{ matrix.os }}
if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
jdk: [17, 21, 25]
os: [ubuntu-latest]
include:
- arch: AMD64
jdk: 17
macos: 15-intel
- arch: AArch64
jdk: 17
macos: latest
- name: AMD64 Windows Server 2022 Java JDK 17
os: windows-latest
jdk: 17
env:
JDK: ${{ matrix.jdk }}
steps:
- name: Checkout Arrow
uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: recursive
- name: Set up Java
if: ${{ !matrix.compose_service }}
uses: actions/setup-java@v6
with:
distribution: 'temurin'
java-version: ${{ matrix.jdk }}
cache: 'maven'
- name: Build
- name: Cache Docker Volumes
if: ${{ matrix.compose_service }}
uses: actions/cache@v6
with:
path: .docker/maven-cache
key: java-build-${{ env.BUILD_JDK }}-${{ env.MAVEN }}-${{ hashFiles('compose.yaml', '**/pom.xml') }}
restore-keys: java-build-${{ env.BUILD_JDK }}-${{ env.MAVEN }}-
- name: Download reusable artifacts
uses: actions/download-artifact@v6
with:
name: java-build
- name: Restore reusable artifacts
shell: bash
run: |
rm -rf \
.docker/java-build \
.docker/maven-cache/repository/org/apache/arrow
tar -xzf java-build.tgz
- name: Restore reusable artifacts for hosted runner
if: ${{ !matrix.compose_service }}
shell: bash
run: |
cp -a .docker/java-build/build build

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[correctness] This cp -a merges into ~/.m2 without first deleting ~/.m2/repository/org/apache/arrow — unlike the Docker path's rm -rf above. setup-java (cache: maven) restores stale arrow SNAPSHOTs from earlier runs (and this step causes them to be re-saved into future caches, +50–150MB per save). Failure: a PR renames/removes a module while another pom still references the old artifactId — the stale SNAPSHOT survives the merge, surefire resolves it, macOS/Windows CI passes, and clean builds break after merge. Fix: rm -rf "${HOME}/.m2/repository/org/apache/arrow" before the cp -a.

rm -rf "${HOME}/.m2/repository/org/apache/arrow"
mkdir -p "${HOME}/.m2/repository/org/apache"
cp -a .docker/maven-cache/repository/org/apache/arrow "${HOME}/.m2/repository/org/apache/"
- name: Test prebuilt artifacts on macOS/Windows

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[test-coverage] macOS/Windows lanes no longer run ci/scripts/build.sh — they test Linux-built classes only. That leaves zero Maven build coverage on Windows for PRs (rc.yml only builds the C++ JNI there) and none on macOS-Intel. A protobuf/grpc bump with a broken windows-x86_64 protoc classifier, codegen emitting a Windows-invalid path, or a Windows-specific -Werror/encoding failure previously failed the windows Build step; now it merges green (the prebuilt script even hard-fails if compilation occurs) and surfaces at release verification.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is accepted. The binaries that get distributed are built in linux eitherway. as long as the tests run in all operating systems, it is fine

if: ${{ !matrix.compose_service }}
shell: bash
env:
ARROW_JAVA_TEST_PREBUILT: "ON"
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
run: ci/scripts/build.sh . build jni
- name: Test
run: ci/scripts/test.sh . build jni
- name: Test prebuilt artifacts on Ubuntu Docker
if: ${{ matrix.compose_service }}
shell: bash
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
run: ci/scripts/test.sh . build jni
run: |
docker compose run \
--rm \
-e CI=true \
-e "DEVELOCITY_ACCESS_KEY=$DEVELOCITY_ACCESS_KEY" \
${{ matrix.compose_service }}
- name: Exclude reactor artifacts from hosted Maven dependency cache
if: ${{ !matrix.compose_service && always() }}
shell: bash
run: rm -rf "${HOME}/.m2/repository/org/apache/arrow"

windows:
name: AMD64 Windows Server 2022 Java JDK ${{ matrix.jdk }}
runs-on: windows-latest
build-cdata:
name: Build C Data artifacts
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
jdk: [17]
steps:
- name: Checkout Arrow
uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: recursive
- name: Set up Java
uses: actions/setup-java@v6
- name: Cache Docker Volumes
uses: actions/cache@v6
with:
java-version: ${{ matrix.jdk }}
distribution: 'temurin'
cache: 'maven'
- name: Build
shell: bash
path: .docker/maven-cache
key: cdata-${{ env.BUILD_JDK }}-${{ env.MAVEN }}-${{ hashFiles('compose.yaml', '**/pom.xml') }}
restore-keys: cdata-${{ env.BUILD_JDK }}-${{ env.MAVEN }}-
- name: Build C Data without tests
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
run: ci/scripts/build.sh . build jni
- name: Test
shell: bash
JDK: ${{ env.BUILD_JDK }}
run: |
docker compose run \
--rm \
-e CI=true \
-e "DEVELOCITY_ACCESS_KEY=$DEVELOCITY_ACCESS_KEY" \
cdata-artifacts
sudo chown -R "$(id -u):$(id -g)" .docker
- name: Pack reusable C Data artifacts
run: |
tar -czf cdata-build.tgz \
.docker/cdata-build \
.docker/cdata-jni-dist \
.docker/maven-cache/repository/org/apache/arrow
- name: Upload reusable C Data artifacts
uses: actions/upload-artifact@v5
with:
name: cdata-build
path: cdata-build.tgz
retention-days: 1
- name: Exclude reactor artifacts from Maven dependency cache
run: rm -rf .docker/maven-cache/repository/org/apache/arrow

test-cdata:
name: AMD64 Conda JNI JDK ${{ matrix.jdk }} Maven 3.9.16
needs: build-cdata
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
jdk: [17, 21, 25]
env:
JDK: ${{ matrix.jdk }}
steps:
- name: Checkout Arrow
uses: actions/checkout@v7
with:
submodules: recursive
- name: Cache Docker Volumes
uses: actions/cache@v6
with:
path: .docker/maven-cache
key: cdata-${{ env.BUILD_JDK }}-${{ env.MAVEN }}-${{ hashFiles('compose.yaml', '**/pom.xml') }}
restore-keys: cdata-${{ env.BUILD_JDK }}-${{ env.MAVEN }}-
- name: Download reusable C Data artifacts
uses: actions/download-artifact@v6
with:
name: cdata-build
- name: Restore reusable C Data artifacts
run: |
rm -rf \
.docker/cdata-build \
.docker/cdata-jni-dist \
.docker/maven-cache/repository/org/apache/arrow
tar -xzf cdata-build.tgz
- name: Test C Data without compiler lifecycle
env:
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
run: ci/scripts/test.sh . build jni
run: |
docker compose run \
--rm \
-e CI=true \
-e "DEVELOCITY_ACCESS_KEY=$DEVELOCITY_ACCESS_KEY" \
cdata-test-prebuilt
8 changes: 4 additions & 4 deletions c/src/main/java/org/apache/arrow/c/Format.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ static String asString(ArrowType arrowType) {
{
ArrowType.Decimal type = (ArrowType.Decimal) arrowType;
if (type.getBitWidth() == 128) {
return String.format("d:%d,%d", type.getPrecision(), type.getScale());
return String.format(Locale.ROOT, "d:%d,%d", type.getPrecision(), type.getScale());
}
return String.format(
"d:%d,%d,%d", type.getPrecision(), type.getScale(), type.getBitWidth());
Locale.ROOT, "d:%d,%d,%d", type.getPrecision(), type.getScale(), type.getBitWidth());
}
case Duration:
{
Expand All @@ -88,12 +88,12 @@ static String asString(ArrowType arrowType) {
case FixedSizeBinary:
{
ArrowType.FixedSizeBinary type = (ArrowType.FixedSizeBinary) arrowType;
return String.format("w:%d", type.getByteWidth());
return String.format(Locale.ROOT, "w:%d", type.getByteWidth());
}
case FixedSizeList:
{
ArrowType.FixedSizeList type = (ArrowType.FixedSizeList) arrowType;
return String.format("+w:%d", type.getListSize());
return String.format(Locale.ROOT, "+w:%d", type.getListSize());
}
case FloatingPoint:
{
Expand Down
Loading
Loading