Appendix A — Anatomy of a well-set-up repo

geoai-datacubes: a walk-through of the reference implementation

The BuckAI Observatory’s geoai-datacubes went through every step of this handbook during its road to JOSS submission in July 2026. This appendix maps the concepts in each chapter to the actual files in that repo, so you can see a working example of every pattern.

Use it as a template: fork the ideas, copy the config files, adapt for your project.


Top-level anatomy

Files you’ll see when you land on the repo:

geoai-datacubes/
├── README.md                    # ← ten-minute rule (Chapter 1)
├── LICENSE                      # ← MIT (Chapter 1)
├── CITATION.cff                 # ← how to cite (Chapter 1)
├── CONTRIBUTORS.md              # ← who did what
├── CONTRIBUTING.md              # ← how to contribute (JOSS requires this)
├── CODE_OF_CONDUCT.md           # ← Contributor Covenant v2.1 (JOSS requires this)
├── CHANGELOG.md                 # ← version history with rationale
├── pyproject.toml               # ← package metadata + extras (Chapter 3)
├── MANIFEST.in                  # ← sdist trim list (Chapter 3)
├── Dockerfile                   # ← reproducible env (Chapter 6)
├── .env.example                 # ← the config file, sanitised
├── .gitignore                   # ← secrets, data, checkpoints (Chapter 1)
├── .gitattributes               # ← linguist-documentation for notebooks
├── paper.md                     # ← JOSS paper (Chapter 7)
├── paper.bib                    # ← JOSS references (Chapter 7)
├── geoai_datacubes/             # ← the Python package itself
├── tests/                       # ← 89 pytest tests (Chapter 5)
├── smoke-tests/                 # ← SLURM-or-bash integration tests
├── slurm_examples/              # ← HPC job templates
├── notebooks/                   # ← 4 Colab-ready pedagogical notebooks
├── docs/                        # ← install + providers + fusion + JOSS quickstart
├── .github/workflows/           # ← tests + publish + docker + draft-pdf
└── ...

Every one of these files exists because it earned its place. If you’re starting fresh, this list is a good target.


pyproject.toml — the package config

View the file →

Highlights worth copying:

  • dynamic = ["version"] + [tool.setuptools_scm] — version derived from git tags.
  • Four named optional-dependency extras (ml, geoai, notebooks, planet, all) that split the heavy dependencies (torch, ultralytics, geoai-py) into opt-in slices.
  • [project.urls] pointing at Homepage, Documentation, and Issues — GitHub uses these on the PyPI page.
  • Classifiers set to Development Status :: 4 - Beta and Topic :: Scientific/Engineering :: Atmospheric Science, GIS, Physics.

MANIFEST.in — trimming the sdist

View the file →

Trims 200+ MB of notebooks, sample outputs, and cached checkpoints out of the source distribution. Result: the sdist on PyPI is ~500 KB.


GitHub Actions workflows

.github/workflows/ — four workflows:

  • tests.yml — matrix (Ubuntu × 3 Python versions) on every push and PR. Covers ~85% of the package via 89 tests.
  • publish.yml — OIDC Trusted Publishing to PyPI on release: published events. Requires approval on the pypi environment.
  • docker.yml — builds + pushes the GHCR image on every tag. Semantic-version tag scheme :0.1.0, :0.1, :latest.
  • draft-pdf.yml — uses openjournals/openjournals-draft-action@master to compile paper.md via the Inara/pandoc pipeline. Uploads paper.pdf as a workflow artifact.

Tests

tests/ — 89 tests. Roughly:

  • Fusion pipeline tests (the scientific-correctness backbone).
  • Mission-registry configuration tests (does each mission profile validate?).
  • Band-normalisation dispatch tests (does each kind map to the right recipe?).
  • Tile-splitting + NaN-handling tests.
  • Reader/writer tests for GeoTIFF and Zarr paths.

Not every function has a test. Every function that would silently produce wrong scientific results does have a test.


paper.md + paper.bib

paper.md is the JOSS paper. It’s 982 words at submission (Jan 2026 policy soft cap: 1000). It cites 16 references, all present in paper.bib, none dangling.

Structure worth borrowing:

  1. YAML front matter — five authors, three affiliations, ORCIDs.
  2. Summary — 250 words, all 26 supported missions cited inline for each mission’s canonical reference.
  3. Statement of need — 300 words, three numbered architectural decisions.
  4. Research applications — 70 words, three papers citing the software as evidence of use.
  5. Relationship to related tooling — one paragraph, honest, tight.
  6. Other related tooling — one paragraph naming pystac, rasterio, xarray, torchgeo.
  7. Acknowledgements — three sentences on funding, one sentence on AI-assistance disclosure.
  8. # References — blank body, pandoc fills it in.

CITATION.cff

CITATION.cff has all five authors, ORCIDs where available, both concept and version DOIs listed as identifiers:, and a preferred-citation: block ready for the JOSS paper DOI once accepted.


Notebooks

notebooks/ — four Colab-ready notebooks with self-bootstrapping install cells:

  • 00_geoai_datacubes_tour.ipynb — the multi-mission tour.
  • 01_classification.ipynb — LULC classification with pretrained weights bundled.
  • 02_building_detection.ipynb — in-development scaffold, marked WIP at the top.
  • 03_with_opengeos_geoai.ipynb — integration demo with opengeos/geoai.

The first cell in each notebook does !pip install geoai-datacubes (from PyPI) so a fresh Colab runtime works without cloning the repo.

Note: JOSS explicitly says notebooks are not the core software artifact — the package is. Notebooks are pedagogical entry points and demos. Structure your repo so the package works standalone; the notebooks are the sales pitch.


Docs

docs/ — topic-specific reference pages spun out of what would otherwise be a 50 KB README:

  • install.md — install + first-run recipe
  • providers.md — provider trade-offs and switching
  • fusion.md — multi-mission fusion
  • configuration.md — parameter tables
  • credentials.md — Sentinel Hub + Planet setup
  • data_layers.md — 26-mission band / range / normalisation reference
  • adding_a_mission.md — how to wire a new mission profile
  • HPC_QUICKSTART.md — cluster-side install + SLURM training

Split your README when it hits ~50 KB. A wall of Markdown on the front page is worse than a short README that links out to specific pages.


What you should copy verbatim

Reasonable things to fork from geoai-datacubes and adapt:

  • pyproject.toml structure and the extras split.
  • .gitignore list.
  • MANIFEST.in structure.
  • Dockerfile micromamba pattern.
  • All four .github/workflows/ files.
  • CONTRIBUTING.md (which is itself derived from numpy/scipy patterns).
  • CODE_OF_CONDUCT.md (Contributor Covenant v2.1 verbatim).
  • paper.md YAML front matter format.

Adapt-not-copy: the actual code, the mission-registry design, the domain-specific documentation.

Do not copy: the specific mission list, band metadata, or scientific choices — those are geoai-datacubes-specific and won’t apply to your project.