diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bb93d86..c5db936 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,27 +17,59 @@ name: Build +# Source-affecting paths only. Docs-only edits skip this workflow; the +# Lint and RAT workflows still run on every change. on: push: branches: [main, 'branch-*'] + paths: + - 'core/**' + - 'examples/**' + - 'native/**' + - 'proto/**' + - 'pom.xml' + - '**/pom.xml' + - 'Makefile' + - 'mvnw' + - '.mvn/**' + - '.github/workflows/build.yml' pull_request: branches: [main, 'branch-*'] + paths: + - 'core/**' + - 'examples/**' + - 'native/**' + - 'proto/**' + - 'pom.xml' + - '**/pom.xml' + - 'Makefile' + - 'mvnw' + - '.mvn/**' + - '.github/workflows/build.yml' + +concurrency: + group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }} + cancel-in-progress: true permissions: contents: read jobs: build: - name: make test - runs-on: ubuntu-latest + name: make test (JDK ${{ matrix.java }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + java: ['17', '21'] steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@v4 with: distribution: temurin - java-version: '17' + java-version: ${{ matrix.java }} cache: maven - name: Set up Rust toolchain @@ -55,5 +87,5 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('native/Cargo.lock') }} restore-keys: ${{ runner.os }}-cargo- - - name: Build native and run JVM tests + - name: Build native and run tests run: make test diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..4cf628f --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,89 @@ +# 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. + +name: Lint + +on: + push: + branches: [main, 'branch-*'] + pull_request: + branches: [main, 'branch-*'] + +concurrency: + group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + fmt-check: + name: Format check + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + cache: maven + + - name: Set up Rust toolchain + run: | + rustup update stable + rustup default stable + rustup component add rustfmt + + - name: Check Java formatting + run: ./mvnw -q spotless:check + + - name: Check Rust formatting + run: cd native && cargo fmt --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + cache: maven + + - name: Set up Rust toolchain + run: | + rustup update stable + rustup default stable + rustup component add clippy + + - name: Cache cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + native/target + key: ${{ runner.os }}-clippy-${{ hashFiles('native/Cargo.lock') }} + restore-keys: ${{ runner.os }}-clippy- + + - name: Run clippy + run: cd native && cargo clippy --all-targets -- -D warnings diff --git a/.github/workflows/pr_title_check.yml b/.github/workflows/pr_title_check.yml new file mode 100644 index 0000000..39da38e --- /dev/null +++ b/.github/workflows/pr_title_check.yml @@ -0,0 +1,45 @@ +# 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. + +name: Check PR Title + +concurrency: + group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }} + cancel-in-progress: true + +on: + pull_request: + types: [opened, edited, reopened] + +permissions: + contents: read + +jobs: + check-pr-title: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - name: Check PR title + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + if ! echo $PR_TITLE | grep -Eq '^(\w+)(\(.+\))?: .+$'; then + echo "PR title does not follow conventional commit style." + echo "Please use a title in the format: type: message, or type(scope): message" + echo "Example: feat: Add support for sort-merge join" + exit 1 + fi diff --git a/.github/workflows/rat.yml b/.github/workflows/rat.yml new file mode 100644 index 0000000..4388033 --- /dev/null +++ b/.github/workflows/rat.yml @@ -0,0 +1,50 @@ +# 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. + +name: RAT License Check + +# No `paths:` filter: license-header drift in docs or workflows +# matters too, so this gate runs on every change. +on: + push: + branches: [main, 'branch-*'] + pull_request: + branches: [main, 'branch-*'] + +concurrency: + group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + rat: + name: RAT License Check + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + cache: maven + + - name: Run Apache RAT + run: ./mvnw -B -N apache-rat:check diff --git a/Makefile b/Makefile index 10e225e..6d9b0ae 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -.PHONY: all native native-runtime-metrics jvm test clean tpch-data +.PHONY: all native native-runtime-metrics jvm test format clean tpch-data all: native jvm @@ -35,6 +35,12 @@ jvm: test: native ./mvnw test +# Apply Java + Rust formatters in place. CI verifies the equivalent +# `:check` form inline in .github/workflows/lint.yml. +format: + ./mvnw -q spotless:apply + cd native && cargo fmt --all + clean: cd native && cargo clean ./mvnw clean diff --git a/dev/release/requirements.txt b/dev/release/requirements.txt index 65bf71b..6129d25 100644 --- a/dev/release/requirements.txt +++ b/dev/release/requirements.txt @@ -1 +1,18 @@ +# 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. + PyGitHub diff --git a/docs/source/contributor-guide/code-style.md b/docs/source/contributor-guide/code-style.md index 3c6020c..50b88e2 100644 --- a/docs/source/contributor-guide/code-style.md +++ b/docs/source/contributor-guide/code-style.md @@ -19,28 +19,38 @@ under the License. # Code style +To apply Java + Rust formatters in one go: + +```sh +make format +``` + +CI verifies formatting, lint, and license headers on every PR via the +**Lint** and **RAT License Check** workflows. + ## Java -Run the Spotless formatter before committing. CI fails the build if -formatting drifts: +Spotless is configured in the parent `pom.xml`. The CI `fmt-check` job +runs: ```sh -./mvnw spotless:apply +./mvnw spotless:check ``` ## Rust -Run inside `native/`: +The CI `clippy` job runs (from `native/`): ```sh -cargo fmt +cargo fmt --all -- --check cargo clippy --all-targets -- -D warnings ``` -`-D warnings` turns clippy warnings into build failures, matching CI. +`-D warnings` escalates every clippy warning to a build failure. ## License headers -New source files need the Apache 2.0 license header. Apache RAT enforces -this during `verify` — `./mvnw verify` will fail if a tracked file is -missing the header. +Every tracked source file needs the Apache 2.0 license header. The +**RAT License Check** workflow runs `./mvnw -N apache-rat:check` on every +PR (including docs-only changes). Exclusions live in +`dev/release/rat_exclude_files.txt`. diff --git a/docs/source/contributor-guide/development.md b/docs/source/contributor-guide/development.md index 8139ac7..984d77c 100644 --- a/docs/source/contributor-guide/development.md +++ b/docs/source/contributor-guide/development.md @@ -48,6 +48,9 @@ cd native && cargo build The native library must be built before running JVM tests. +Before pushing, run `make format` to apply the Java + Rust formatters in +place. CI verifies formatting, clippy, and license headers on every PR. + The first build in a fresh checkout reaches out to `raw.githubusercontent.com` to fetch the DataFusion `.proto` files used to generate the `datafusion-proto` Java classes. Subsequent builds are @@ -80,7 +83,8 @@ The repository is a multi-module Maven build: cannot fall out of sync with the API. - `native/` — Rust crate (JNI + Arrow C Data Interface). - `proto/` — Protobuf definitions shared between Java and Rust. -- `Makefile` — top-level build orchestration (`make test`, `make tpch-data`). +- `Makefile` — top-level build orchestration (`make test`, `make format`, + `make tpch-data`). - `mvnw`, `mvnw.cmd` — bundled Maven wrapper. - `docs/` — Sphinx documentation source and build scripts.