Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/docs-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ jobs:
pip install --no-cache-dir Cython
pip install -r requirements.txt -r requirements_dev.txt -r requirements_docs.txt
pip install .
- run: mkdocs build
- run: python scripts/convert_notebooks.py
- run: zensical build --clean --strict
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v4.0
with:
Expand Down
19 changes: 12 additions & 7 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
jobs:
deploy:
runs-on: ubuntu-latest
# Required to push the built site to the gh-pages branch.
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v6
Expand All @@ -15,11 +18,13 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install --user --no-cache-dir Cython
pip install --user -r requirements.txt -r requirements_dev.txt
pip install --user -r requirements.txt -r requirements_dev.txt -r requirements_docs.txt
pip install --user .
# - name: PKG-TEST
# run: |
# python -m unittest discover tests/
- run: python -m pip install --upgrade pip
- run: pip install mkdocs-material mkdocstrings mkdocstrings-python mkdocs-git-revision-date-plugin mkdocs-jupyter ipykernel
- run: mkdocs gh-deploy --force
- run: python scripts/convert_notebooks.py
- run: zensical build --clean --strict
Comment on lines +21 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does GitHub Actions ubuntu-latest runner include ~/.local/bin in PATH for run steps

💡 Result:

Whether the ~/.local/bin directory is included in the PATH on GitHub Actions ubuntu-latest runners is inconsistent and can vary depending on the specific runner image version and architecture [1]. While some versions of the Ubuntu-hosted runners include /home/runner/.local/bin in the default PATH [2][1], others do not [3][4][5]. Because this behavior is not guaranteed across all runner environments, it is recommended practice to explicitly add ~/.local/bin to your PATH if your workflow depends on binaries installed there (e.g., via pip) [4][1]. To add it to the PATH for the remainder of your job, you can use the GITHUB_PATH environment file [6][7]: - name: Add ~/.local/bin to PATH run: echo "$HOME/.local/bin" >> $GITHUB_PATH Alternatively, if you only need it for a single step, you can modify the PATH variable within that step's script [8]. It is generally best to avoid relying on the default inclusion of this directory to ensure your workflows remain portable and predictable [4][1].

Citations:


🏁 Script executed:

git ls-files .github/workflows/docs.yml .github/workflows/docs-build.yml && \
echo '--- docs.yml ---' && sed -n '1,120p' .github/workflows/docs.yml && \
echo '--- docs-build.yml ---' && sed -n '1,120p' .github/workflows/docs-build.yml

Repository: opengeos/segment-geospatial

Length of output: 3191


zensical needs to be on PATH before the build step. pip install --user can place the console script under ~/.local/bin, which GitHub Actions does not guarantee is on PATH for run: steps, so zensical build --clean --strict may fail with command not found. Drop --user, or add $HOME/.local/bin to GITHUB_PATH before the build step.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docs.yml around lines 21 - 24, The docs workflow build
step can’t reliably find the zensical console script because it may be installed
under ~/.local/bin by pip install --user. Update the workflow so the zensical
command is available before the build step in the docs job, either by removing
--user from the pip installs or by adding the user bin directory to PATH via
GITHUB_PATH. Make the fix in the workflow steps that install requirements and
then run zensical build --clean --strict.

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
force_orphan: true
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ output/

docs/examples/*.geojson

# Markdown files generated from notebooks for the Zensical build
docs/examples/*.md
docs/workshops/*.md

# C extensions
*.so

Expand Down
11 changes: 0 additions & 11 deletions docs/overrides/main.html

This file was deleted.

103 changes: 0 additions & 103 deletions mkdocs.yml

This file was deleted.

9 changes: 1 addition & 8 deletions requirements_docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ deadlink
flake8
ipykernel
livereload
mkdocs
mkdocs-git-revision-date-localized-plugin
mkdocs-git-revision-date-plugin
mkdocs-jupyter>=0.26.3
mkdocs-material>=9.7.6
mkdocs-pdf-export-plugin
mkdocstrings
mkdocstrings-crystal
mkdocstrings-python
nbconvert
nbformat
Expand All @@ -26,3 +18,4 @@ tox
twine
watchdog
wheel
zensical
73 changes: 73 additions & 0 deletions scripts/convert_notebooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""Convert Jupyter notebooks in the docs folder to Markdown for Zensical.

Zensical does not yet support the mkdocs-jupyter plugin, so this script
converts every notebook under ``docs/examples`` and ``docs/workshops`` to a
Markdown file of the same name before the site is built. A download link to
the original notebook (which Zensical copies into the site as a static file)
is prepended to each page.

Usage:
python scripts/convert_notebooks.py
"""

import pathlib
import sys

import nbformat
from nbconvert import MarkdownExporter

ROOT = pathlib.Path(__file__).resolve().parents[1]
NOTEBOOK_DIRS = ["docs/examples", "docs/workshops"]
REPO_URL = "https://github.com/opengeos/segment-geospatial"


def convert_notebook(nb_path: pathlib.Path) -> pathlib.Path:
"""Convert a single notebook to a Markdown file alongside it.

Args:
nb_path: Path to the ``.ipynb`` file to convert.

Returns:
pathlib.Path: Path to the generated ``.md`` file.
"""
notebook = nbformat.read(nb_path, as_version=4)
exporter = MarkdownExporter()
body, _ = exporter.from_notebook_node(notebook)

rel_path = nb_path.relative_to(ROOT)
header = (
f"[![Download notebook]"
f"(https://img.shields.io/badge/Download-notebook-blue)]"
f"({REPO_URL}/blob/main/{rel_path.as_posix()})\n\n"
)

md_path = nb_path.with_suffix(".md")
md_path.write_text(header + body, encoding="utf-8")
return md_path


def main() -> None:
"""Convert all notebooks in the configured docs directories.

Conversion continues past individual failures so that one broken
notebook does not hide the status of the others; the script exits
with a non-zero status if any notebook failed to convert.
"""
failures = []
for dir_name in NOTEBOOK_DIRS:
for nb_path in sorted((ROOT / dir_name).glob("*.ipynb")):
try:
md_path = convert_notebook(nb_path)
except Exception as e:
failures.append(nb_path)
print(f"FAILED to convert {nb_path.relative_to(ROOT)}: {e}")
else:
print(f"Converted {nb_path.relative_to(ROOT)} -> {md_path.name}")

if failures:
print(f"{len(failures)} notebook(s) failed to convert.")
sys.exit(1)


if __name__ == "__main__":
main()
109 changes: 109 additions & 0 deletions zensical.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
[project]
site_name = "segment-geospatial"
site_url = "https://samgeo.gishub.org"
site_description = "A Python package for segmenting geospatial data with the Segment Anything Model (SAM)"
repo_url = "https://github.com/opengeos/segment-geospatial"

nav = [
{ "Home" = "index.md" },
{ "Installation" = "installation.md" },
{ "Usage" = "usage.md" },
{ "REST API" = "api.md" },
{ "Contributing" = "contributing.md" },
{ "FAQ" = "faq.md" },
{ "Changelog" = "changelog.md" },
{ "Report Issues" = "https://github.com/opengeos/segment-geospatial/issues" },
{ "Examples" = [
"examples/satellite.md",
"examples/automatic_mask_generator.md",
"examples/automatic_mask_generator_hq.md",
"examples/input_prompts.md",
"examples/input_prompts_hq.md",
"examples/box_prompts.md",
"examples/text_prompts.md",
"examples/text_prompts_batch.md",
"examples/fast_sam.md",
"examples/text_swimming_pools.md",
"examples/arcgis.md",
"examples/maxar_open_data.md",
"examples/sam2_automatic.md",
"examples/sam2_predictor.md",
"examples/sam2_video.md",
"examples/sam2_box_prompts.md",
"examples/sam2_point_prompts.md",
"examples/sam2_text_prompts.md",
"examples/tree_mapping.md",
"examples/image_captioning.md",
"examples/sam3_image_segmentation.md",
"examples/sam3_image_segmentation_jpg.md",
"examples/sam3_interactive.md",
"examples/sam3_batch_segmentation.md",
"examples/sam3_video_segmentation.md",
"examples/sam3_video_prompts.md",
"examples/sam3_video_masks.md",
"examples/sam3_automated_segmentation.md",
"examples/sam3_object_tracking.md",
"examples/sam3_point_prompts.md",
"examples/sam3_point_prompts_batch.md",
"examples/sam3_box_prompts.md",
"examples/sam3_tiled_segmentation.md",
"examples/detectree2.md",
] },
{ "Workshops" = [
"workshops/purdue.md",
"workshops/cn_workshop.md",
"workshops/IPPN_2024.md",
"workshops/AIforGood_2025.md",
] },
{ "API Reference" = [
{ "caption module" = "caption.md" },
{ "common module" = "common.md" },
{ "samgeo module" = "samgeo.md" },
{ "samgeo2 module" = "samgeo2.md" },
{ "samgeo3 module" = "samgeo3.md" },
{ "fast_sam module" = "fast_sam.md" },
{ "hq_sam module" = "hq_sam.md" },
{ "text_sam module" = "text_sam.md" },
{ "detectree2 module" = "detectree2.md" },
{ "api module" = "api.md" },
] },
]

[project.theme]
features = [
"content.code.copy",
"navigation.instant",
"navigation.top",
"search.highlight",
]

[project.theme.icon]
repo = "fontawesome/brands/github"

[[project.theme.palette]]
media = "(prefers-color-scheme: light)"
scheme = "default"
toggle.icon = "lucide/sun"
toggle.name = "Switch to dark mode"

[[project.theme.palette]]
media = "(prefers-color-scheme: dark)"
scheme = "slate"
toggle.icon = "lucide/moon"
toggle.name = "Switch to light mode"

[project.plugins.mkdocstrings.handlers.python]
paths = ["."]

[project.plugins.mkdocstrings.handlers.python.options]
docstring_style = "google"

[project.markdown_extensions.attr_list]

[project.markdown_extensions.toc]
permalink = true

[project.markdown_extensions.pymdownx.superfences]

[project.markdown_extensions.pymdownx.highlight]
linenums = true
Loading