This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/paimon-vector-index.git
The following commit(s) were added to refs/heads/main by this push:
new 16df93c Add CONTRIBUTING.md, ASF yaml validator, and CI for
JNI/Python (#8)
16df93c is described below
commit 16df93c442042b70c25a623d9a9b557242cc03fa
Author: Jingsong Lee <[email protected]>
AuthorDate: Mon Jun 8 15:15:18 2026 +0800
Add CONTRIBUTING.md, ASF yaml validator, and CI for JNI/Python (#8)
---
.github/workflows/ci.yml | 58 ++++++++++++++++++++++++-
CONTRIBUTING.md | 53 +++++++++++++++++++++++
tools/validate_asf_yaml.py | 103 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 213 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f54c513..1a47796 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -40,6 +40,9 @@ jobs:
steps:
- uses: actions/checkout@v4
+ - name: Validate .asf.yaml
+ run: pip install pyyaml -q && python3 tools/validate_asf_yaml.py
+
- name: Install cargo-deny
uses: taiki-e/install-action@v2
with:
@@ -77,4 +80,57 @@ jobs:
uses: taiki-e/install-action@cargo-llvm-cov
- name: Test with coverage
- run: cargo llvm-cov --summary-only
+ run: cargo llvm-cov --workspace --summary-only
+
+ jni-build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Rust Cache
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.cargo/registry
+ ~/.cargo/git
+ target
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-cargo-
+
+ - name: Set up JDK 8
+ uses: actions/setup-java@v4
+ with:
+ java-version: '8'
+ distribution: 'temurin'
+
+ - name: Build JNI library
+ run: cargo build -p paimon-vindex-jni --release
+
+ python-build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Rust Cache
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.cargo/registry
+ ~/.cargo/git
+ target
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-cargo-
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
+
+ - name: Install maturin
+ run: pip install maturin
+
+ - name: Build Python module
+ working-directory: python
+ run: maturin build --release
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..3bf3f7f
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,53 @@
+<!--
+ ~ 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.
+-->
+
+# Contributing
+
+## Get Started
+
+This is a Rust project, so [rustup](https://rustup.rs/) is a great place to
start. It provides an easy way to manage your Rust installation and toolchains.
+
+This is a pure Rust project, so only `cargo` is needed. Here are some common
commands to get you started:
+
+- `cargo check`: Analyze the current package and report errors.
+- `cargo fmt`: Format the current code according to the Rust style guidelines.
+- `cargo build`: Compile the current package.
+- `cargo clippy`: Catch common mistakes and improve code quality.
+- `cargo test`: Run unit tests.
+- `cargo bench`: Run benchmark tests.
+
+## Setting up the Development Environment
+
+1. Install Rust using `rustup`. Follow the instructions on the [rustup
website](https://rustup.rs/) to install Rust on your system.
+2. Clone the repository to your local machine.
+3. Navigate to the project directory.
+
+## Making Changes
+
+1. Create a new branch for your changes.
+2. Make your changes and ensure that the code still compiles and passes all
tests.
+3. Format your code using `cargo fmt` to ensure consistency with the project's
code style.
+
+## Submitting Changes
+
+1. Once you are satisfied with your changes, push your branch to the remote
repository.
+2. Open a pull request on the project's GitHub page. Provide a clear
description of your changes and why they are necessary.
+3. Wait for reviews and address any feedback. Once the pull request is
approved and merged, your changes will be part of the project.
+
+Thank you for contributing to this project!
diff --git a/tools/validate_asf_yaml.py b/tools/validate_asf_yaml.py
new file mode 100644
index 0000000..e189125
--- /dev/null
+++ b/tools/validate_asf_yaml.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python3
+
+#
+# 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.
+#
+
+"""Validate .asf.yaml structural correctness.
+
+Checks YAML syntax, root-level structure, and type constraints for
+known fields. Does NOT reject unknown keys — the ASF infra schema
+evolves independently and unrecognized keys are silently ignored by
+the ASF gitbox service.
+
+Reference: https://github.com/apache/infrastructure-asfyaml
+"""
+
+import sys
+
+try:
+ import yaml
+except ImportError:
+ sys.exit(
+ "PyYAML is required: pip install pyyaml\n"
+ "Or use: python3 -c \"import pip; pip.main(['install', 'pyyaml'])\""
+ )
+
+ASF_YAML_PATH = ".asf.yaml"
+
+
+def validate():
+ errors = []
+
+ try:
+ with open(ASF_YAML_PATH, "r") as f:
+ data = yaml.safe_load(f)
+ except FileNotFoundError:
+ print(f"SKIP: {ASF_YAML_PATH} not found")
+ return 0
+ except yaml.YAMLError as e:
+ print(f"ERROR: Invalid YAML syntax in {ASF_YAML_PATH}: {e}")
+ return 1
+
+ if not isinstance(data, dict):
+ print(f"ERROR: {ASF_YAML_PATH} root must be a mapping")
+ return 1
+
+ # Validate types of known sections
+ for key in ("github", "notifications", "staging", "publish"):
+ if key in data and not isinstance(data[key], dict):
+ errors.append(f"'{key}' must be a mapping, got
{type(data[key]).__name__}")
+
+ github = data.get("github")
+ if isinstance(github, dict):
+ # features values must be booleans
+ features = github.get("features")
+ if isinstance(features, dict):
+ for key, val in features.items():
+ if not isinstance(val, bool):
+ errors.append(
+ f"'github.features.{key}' must be a boolean, "
+ f"got {type(val).__name__}"
+ )
+
+ # enabled_merge_buttons values must be booleans or strings
+ merge_buttons = github.get("enabled_merge_buttons")
+ if isinstance(merge_buttons, dict):
+ for key, val in merge_buttons.items():
+ if not isinstance(val, (bool, str)):
+ errors.append(
+ f"'github.enabled_merge_buttons.{key}' must be bool or
string, "
+ f"got {type(val).__name__}"
+ )
+
+ # labels must be a list of strings
+ labels = github.get("labels")
+ if labels is not None and not isinstance(labels, list):
+ errors.append(f"'github.labels' must be a list, got
{type(labels).__name__}")
+
+ if errors:
+ print(f"ERROR: {ASF_YAML_PATH} validation failed:")
+ for err in errors:
+ print(f" - {err}")
+ return 1
+
+ print(f"OK: {ASF_YAML_PATH} is valid")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(validate())