Four pull requests into Apache Sedona
For a software engineering course at ANU, four of us had to contribute to a real open source project. We chose Apache Sedona, the engine for processing geospatial data on Spark. My work involves training deep learning models on geospatial data, so I wanted to see how one of the big engines in this space works under the hood.
Starting smaller than I wanted to
My first pick was a geography feature for nearest-neighbour joins. The maintainer, Jia Yu, politely pointed me to the issues marked as good first issues instead. At the time it felt like a step down. Looking back, it was the right call, because the smaller issues taught me how the project works: its pull request template, its title format, its tests, and the ASF's rules for disclosing AI-assisted code.
So I started with read_feather, which reads Feather files into Sedona's GeoPandas API. A teammate had already added the matching to_feather, so I mirrored his work.
The bug my tests couldn't see
My tests passed. Then Jia reviewed the pull request and reproduced a crash I had missed: on Spark 3.5.0, a Feather file whose first geometry was null failed to load, because Spark guesses a column's type from its first value. My tests ran on a newer Spark, where the same file worked.

The fix was small. I switched to a helper the project already had for exactly this case and added a regression test with the null geometry first. The lesson was bigger. Passing tests only tell you the code works on the setup you tested, not on the versions your users actually run.
One fix leads to another
Next I took a bug that had been open since 2024: ST_Pixelize failed on shapes smaller than one pixel. The fix was to return the pixel that contains the shape, and I checked it against the old algorithm on 3,000 shapes.
While working on it, I noticed something else in the drawing code. It joined all of a polygon's rings into one line, so a polygon with a hole was drawn with a stray line and a gap in its fill. That became my third pull request. Each ring is now drawn separately, and the output for 5,000 polygons without holes is unchanged.
The one I didn't plan
The fourth came from a discussion thread. A user reported that a GeoPackage file with a NULL geometry failed to load. I traced the cause, explained it, and offered a fix. Jia asked me to open an issue first, which I did, and the fix was merged two days later.
That one felt different, because it started with someone actually using Sedona and running into a problem.
Waiting is part of the work
Pull requests from forks don't run the project's tests until a maintainer approves them, and maintainers have their own priorities. I learned to make each pull request easy to review and then wait, with at most one polite reminder. All four were eventually merged.

I used Claude Code as a pair-programming assistant throughout and disclosed it in every pull request, as the ASF asks. I chose the approach, reviewed every change and ran the tests myself.
Your tests show it works on your machine. A good reviewer shows you where it doesn't.