| <!--- | |
| 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. | |
| --> | |
| # Upstream Sync Process | |
| This document describes how to sync `datafusion-python` to a new version of the | |
| upstream `apache/datafusion` Rust crates. This is a recurring task: between | |
| official releases the `main` branch tracks DataFusion via crates.io or GitHub | |
| dependencies, and we periodically bump those dependencies to pick up new | |
| features and bug fixes. | |
| The work is broken into **three sequential PRs** rather than landing as one | |
| large change. Splitting reviews along these lines keeps each PR focused, makes | |
| breakage easier to bisect, and lets reviewers concentrate on one concern at a | |
| time. | |
| ## PR 1: Bump DataFusion crate dependencies and fix breakage | |
| **Goal:** update the upstream `datafusion` crate version and make the project | |
| build, test, and lint cleanly against it. | |
| 1. In the root `Cargo.toml`, update: | |
| - `[workspace.package].version` to the new major (the `datafusion-python` | |
| major tracks the upstream `datafusion` major, so a 53→54 bump moves | |
| this from `53.0.0` to `54.0.0`), and | |
| - every `datafusion` / `datafusion-*` entry in `[workspace.dependencies]` | |
| to the same new major. | |
| Per-crate manifests under `crates/` inherit these pins via | |
| `workspace = true` and need no edit. | |
| 2. Update `Cargo.lock` for the datafusion family only — leave unrelated | |
| transitives at their current pins so PR 2 can address them deliberately. | |
| List every `datafusion-*` workspace dependency with `-p`: | |
| ```bash | |
| cargo update \ | |
| -p datafusion \ | |
| -p datafusion-substrait \ | |
| -p datafusion-proto \ | |
| -p datafusion-ffi \ | |
| -p datafusion-catalog \ | |
| -p datafusion-common \ | |
| -p datafusion-functions-aggregate \ | |
| -p datafusion-functions-window \ | |
| -p datafusion-expr | |
| ``` | |
| Or pin exact versions with `--precise`, one crate at a time: | |
| ```bash | |
| cargo update -p datafusion --precise 54.0.0 | |
| # repeat for each datafusion-* sibling | |
| ``` | |
| A bare `cargo update` would refresh every transitive crate and blur the | |
| diff between PR 1 and PR 2. | |
| 3. Run the standard build and test commands and address compilation errors, | |
| API renames, signature changes, and behavior changes: | |
| - `cargo build` | |
| - `cargo test` | |
| - `pytest` | |
| - `pre-commit run --all-files` | |
| 4. Fix only what's needed to restore green CI. Resist the urge to bundle | |
| unrelated cleanups — those belong in their own PR. | |
| 5. If a breaking change in upstream requires a user-facing API change in | |
| `datafusion-python`, add the `api change` label and document the change | |
| in the PR description so it surfaces in the changelog. | |
| **Reference PRs:** [#1311](https://github.com/apache/datafusion-python/pull/1311) | |
| (DF51), [#1337](https://github.com/apache/datafusion-python/pull/1337) (DF52). | |
| ## PR 2: Consolidate transitive dependencies | |
| **Goal:** after the upstream bump, the dependency tree may have multiple | |
| versions of the same transitive crate (for example, two `arrow` versions, two | |
| `object_store` versions). Reconcile these so we ship a single coherent set. | |
| 1. Inspect the lockfile for duplicates: | |
| ```bash | |
| cargo tree --duplicates | |
| ``` | |
| 2. For each duplicate that matters (Arrow, `object_store`, `parquet`, | |
| `tokio`, `arrow-flight`, etc.), update our direct dependency declarations | |
| in `Cargo.toml` to versions compatible with what upstream DataFusion now | |
| pulls in. The goal is one version of each ecosystem-critical crate. | |
| 3. Re-run `cargo update` and re-run the full test matrix. Some duplicates are | |
| benign (small leaf crates with no FFI surface) and can be left alone if | |
| reconciliation would force a much larger change. Use judgment. | |
| 4. If consolidating forces a behavioral change visible to users (for example, | |
| a newer `pyarrow`-compatible Arrow version), call it out in the PR | |
| description. | |
| Keeping this work separate from PR 1 means PR 1 stays a "make it compile" | |
| review and PR 2 stays a "tidy the dependency graph" review. | |
| ## PR 3: Fill API and documentation gaps | |
| **Goal:** with the upstream version locked in, identify new APIs that landed | |
| upstream and decide whether to expose them, and update agent-facing | |
| documentation so it still matches the surface we ship. | |
| 1. Run the `check-upstream` skill (`.ai/skills/check-upstream/SKILL.md`) to | |
| diff the upstream Rust API against what's exposed in | |
| `python/datafusion/`. The skill covers scalar/aggregate/window/table | |
| functions, `DataFrame` methods, `SessionContext` methods, and FFI types. | |
| Invoke it from the assistant with `/check-upstream` (optionally scoped to | |
| one area, e.g. `/check-upstream scalar functions`). | |
| 2. For each gap, decide whether to: | |
| - Expose it now (small, obvious additions can land in this PR). | |
| - File a tracking issue (anything non-trivial — separate PR per feature | |
| keeps reviews focused). | |
| - Skip it (internal-only or already covered by an existing API; record | |
| the decision in the "Evaluated and not requiring exposure" sections of | |
| the skill so future runs don't re-flag it). | |
| 3. (Optional) Run the `make-pythonic` skill | |
| (`.ai/skills/make-pythonic/SKILL.md`) over any newly exposed APIs to | |
| align signatures with the project's Pythonic style (accepting plain | |
| strings for column names, raw Python values where auto-wrapping | |
| applies, etc.). Invoke it from the assistant with `/make-pythonic`. | |
| Running this *before* the audit step means examples in `SKILL.md` get | |
| updated to the final signature in one pass instead of churning twice. | |
| Larger reshapes still belong in their own PR. | |
| 4. Run the `audit-skill-md` skill (`.ai/skills/audit-skill-md/SKILL.md`) to | |
| cross-reference the user-facing skill at | |
| [`skills/datafusion_python/SKILL.md`](../../skills/datafusion_python/SKILL.md) | |
| against the current public API. The skill flags stale function names, | |
| missing newly exposed APIs, examples that drifted from idiomatic style, | |
| and missing version notes. Invoke it from the assistant with | |
| `/audit-skill-md` (optionally scoped, e.g. `/audit-skill-md dataframe`). | |
| Apply the resulting edits to `SKILL.md` and to the relevant RST pages | |
| under `docs/source/user-guide/common-operations/`. | |
| 5. If new aggregate or window functions were exposed in step 2, also update: | |
| - `docs/source/user-guide/common-operations/aggregations.rst` | |
| - `docs/source/user-guide/common-operations/windows.rst` | |
| ## Why three PRs | |
| - **Bisectable.** If a regression appears, `git bisect` lands on the | |
| responsible PR (compile fix, dependency consolidation, or API addition) | |
| rather than a single mega-commit. | |
| - **Reviewable.** Each PR has a single concern. Reviewers reading PR 1 don't | |
| need to also reason about whether new APIs are well-named. | |
| - **Skippable.** Some upstream syncs are pure version bumps with no new APIs | |
| worth exposing. PR 3 can be empty or merged as a no-op if the audit comes | |
| back clean. | |
| ## Related documents | |
| - [`README.md`](README.md) — the broader release process (this sync work | |
| feeds into the next official release). | |
| - [`.ai/skills/check-upstream/SKILL.md`](../../.ai/skills/check-upstream/SKILL.md) | |
| — API coverage audit. | |
| - [`skills/datafusion_python/SKILL.md`](../../skills/datafusion_python/SKILL.md) | |
| — user-facing agent guide kept in sync via PR 3. |