From 8edcd74e352d3a050c1f5d713ae3559eeb5a0634 Mon Sep 17 00:00:00 2001 From: roberto_esaclear Date: Thu, 23 Apr 2026 15:01:06 +0200 Subject: [PATCH 1/8] v1.0.0 --- .github/workflows/docker.yml | 29 +- .github/workflows/publish.yml | 22 +- .github/workflows/python-ci.yml | 57 + MANIFEST.in | 12 + README.md | 15 +- docs/_site/developer_guide/contributing.html | 13 +- docs/_site/user_guide/installation.html | 19 +- docs/_site/user_guide/troubleshooting.html | 13 +- docs/api/index.html | 4 +- docs/api/sarpyx___init__.html | 4 +- docs/api/sarpyx_cli___init__.html | 4 +- ...x_cli_algorithms_AdaptiveThresholding.html | 4 +- docs/api/sarpyx_cli_algorithms___init__.html | 4 +- docs/api/sarpyx_cli_decode.html | 4 +- docs/api/sarpyx_cli_focus.html | 4 +- docs/api/sarpyx_cli_main.html | 4 +- docs/api/sarpyx_cli_shipdet.html | 4 +- docs/api/sarpyx_cli_unzip.html | 4 +- docs/api/sarpyx_cli_upload.html | 4 +- docs/api/sarpyx_cli_utils.html | 4 +- docs/api/sarpyx_cli_worldsar.html | 4 +- docs/api/sarpyx_processor___init__.html | 4 +- .../sarpyx_processor_algorithms___init__.html | 4 +- ...x_processor_algorithms_backprojection.html | 4 +- ...sarpyx_processor_algorithms_constants.html | 4 +- ...rpyx_processor_algorithms_mbautofocus.html | 4 +- docs/api/sarpyx_processor_algorithms_rda.html | 4 +- docs/api/sarpyx_processor_core___init__.html | 4 +- docs/api/sarpyx_processor_core_aux.html | 4 +- .../sarpyx_processor_core_code2physical.html | 4 +- docs/api/sarpyx_processor_core_constants.html | 4 +- docs/api/sarpyx_processor_core_decode.html | 4 +- .../sarpyx_processor_core_dim_updater.html | 4 +- docs/api/sarpyx_processor_core_focus.html | 4 +- docs/api/sarpyx_processor_core_meta.html | 4 +- docs/api/sarpyx_processor_core_signal.html | 4 +- docs/api/sarpyx_processor_core_spectrum.html | 4 +- .../sarpyx_processor_core_subaperture.html | 4 +- ...x_processor_core_subaperture_full_img.html | 4 +- .../api/sarpyx_processor_core_transforms.html | 4 +- docs/api/sarpyx_processor_core_utilis.html | 4 +- docs/api/sarpyx_processor_data___init__.html | 4 +- .../api/sarpyx_processor_data_formatters.html | 4 +- docs/api/sarpyx_processor_data_readers.html | 4 +- docs/api/sarpyx_processor_data_writers.html | 4 +- docs/api/sarpyx_processor_utils___init__.html | 4 +- docs/api/sarpyx_processor_utils_mem.html | 4 +- docs/api/sarpyx_processor_utils_metrics.html | 4 +- docs/api/sarpyx_processor_utils_summary.html | 4 +- docs/api/sarpyx_processor_utils_unzip.html | 4 +- docs/api/sarpyx_processor_utils_viz.html | 4 +- docs/api/sarpyx_science___init__.html | 4 +- docs/api/sarpyx_science_indices.html | 4 +- docs/api/sarpyx_sla___init__.html | 4 +- docs/api/sarpyx_sla_core___init__.html | 4 +- docs/api/sarpyx_sla_core_meta.html | 4 +- docs/api/sarpyx_sla_core_spectrum.html | 4 +- docs/api/sarpyx_sla_metrics.html | 4 +- docs/api/sarpyx_sla_utilis.html | 4 +- docs/api/sarpyx_snapflow___init__.html | 4 +- docs/api/sarpyx_snapflow_engine.html | 4 +- docs/api/sarpyx_snapflow_op.html | 4 +- docs/api/sarpyx_snapflow_snap2stamps.html | 4 +- ...sarpyx_snapflow_snap2stamps_pipelines.html | 4 +- docs/api/sarpyx_utils___init__.html | 4 +- docs/api/sarpyx_utils_complex_losses-OLD.html | 4 +- docs/api/sarpyx_utils_dem_utils.html | 4 +- docs/api/sarpyx_utils_executor.html | 4 +- docs/api/sarpyx_utils_geos.html | 4 +- docs/api/sarpyx_utils_grid.html | 4 +- docs/api/sarpyx_utils_hf.html | 4 +- docs/api/sarpyx_utils_io.html | 4 +- docs/api/sarpyx_utils_losses.html | 4 +- docs/api/sarpyx_utils_meta.html | 4 +- docs/api/sarpyx_utils_metrics.html | 4 +- docs/api/sarpyx_utils_nisar_utils.html | 4 +- docs/api/sarpyx_utils_peorb.html | 4 +- docs/api/sarpyx_utils_rfigen.html | 4 +- docs/api/sarpyx_utils_sar_loss.html | 4 +- docs/api/sarpyx_utils_up.html | 4 +- docs/api/sarpyx_utils_viz.html | 4 +- docs/api/sarpyx_utils_wkt_utils.html | 4 +- docs/api/sarpyx_utils_zarr_utils.html | 4 +- docs/api_coverage_checklist.json | 2 +- docs/architecture.html | 4 +- docs/configuration.html | 6 +- docs/contributing.html | 4 +- docs/developer_guide/contributing.md | 42 +- docs/faq.html | 4 +- docs/generate_static_site.py | 1 - docs/index.html | 4 +- docs/installation.html | 8 +- docs/quickstart.html | 4 +- docs/testing.html | 6 +- docs/usage.html | 4 +- docs/user_guide/installation.md | 34 +- docs/user_guide/troubleshooting.md | 13 +- pdm.lock | 4082 ----------------- pyproject.toml | 11 +- pyscripts/worldsar.py | 74 +- sarpyx/__init__.py | 22 +- sarpyx/cli/main.py | 30 +- sarpyx/cli/worldsar.py | 76 +- sarpyx/processor/core/dim_updater.py | 7 +- sarpyx/utils/worldsar_h5.py | 861 +++- tests/test_cli_main.py | 26 +- tests/test_sentinel_subap_pipeline.py | 19 +- tests/test_worldsar_h5.py | 331 +- uv.lock | 2 +- 109 files changed, 1618 insertions(+), 4539 deletions(-) create mode 100644 .github/workflows/python-ci.yml create mode 100644 MANIFEST.in delete mode 100755 pdm.lock diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9f1f734..7a5a189 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -2,18 +2,29 @@ # CI/CD – Docker build, test, and publish # ────────────────────────────────────────────────────────────── # Triggers: -# • Pushes to main that touch Docker-related files → build + test + push :latest -# • Manual dispatch from main → build + test + optional push +# • Pull requests touching Docker/runtime files → build + smoke test +# • Pushes to main touching Docker/runtime files → build + smoke test + push +# • Manual dispatch → build + smoke test + optional push # ────────────────────────────────────────────────────────────── name: Docker Build & Publish on: + pull_request: + paths: + - "Dockerfile" + - "docker-compose.yml" + - "entrypoint.sh" + - "pyproject.toml" + - "sarpyx/**" + - "tests/**" + - "support/**" push: branches: [main] paths: - "Dockerfile" - "docker-compose.yml" + - "entrypoint.sh" - "sarpyx/**" - "tests/**" - "pyproject.toml" @@ -32,7 +43,6 @@ jobs: # ──────────────────── Build & Test ──────────────────────── build-and-test: runs-on: ubuntu-latest - if: github.ref == 'refs/heads/main' timeout-minutes: 260 steps: @@ -62,11 +72,11 @@ jobs: cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - # - name: Run Docker build tests (disabled) - # run: | - # docker run --rm ${{ env.DOCKER_IMAGE }}:ci sh -c "\ - # python3.11 -m pip install pytest && \ - # python3.11 -m pytest /workspace/tests/test_docker.py -v --tb=short" + - name: Run Docker smoke tests + run: | + docker run --rm ${{ env.DOCKER_IMAGE }}:ci sh -lc "\ + python3.11 -m pip install --no-cache-dir pytest==8.4.0 && \ + python3.11 -m pytest /workspace/tests/test_docker.py -q --tb=short" - name: Move cache # prevents ever-growing cache run: | @@ -78,9 +88,8 @@ jobs: needs: build-and-test runs-on: ubuntu-latest if: >- - github.ref == 'refs/heads/main' && ( - github.event_name == 'push' || + (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_image == 'true') ) timeout-minutes: 60 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a03907f..314817a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,4 +1,3 @@ -# GitHub Actions workflow for publishing a Python package from main only. name: Publish Python Package to PyPI on: @@ -15,23 +14,18 @@ jobs: uses: actions/checkout@v4 - name: Configure Python Environment - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: "3.x" + python-version: "3.12" - - name: Install GDAL System Dependencies - run: | - sudo apt-get update - sudo apt-get install -y gdal-bin libgdal-dev - - - name: Configure PDM Environment - uses: pdm-project/setup-pdm@v4 - with: - python-version: "3.x" - cache: true + - name: Set up uv + uses: astral-sh/setup-uv@v4 - name: Build Python Package - run: pdm build + run: uv build + + - name: Validate distributions + run: uvx twine check dist/* - name: Upload Distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml new file mode 100644 index 0000000..06fa34d --- /dev/null +++ b/.github/workflows/python-ci.yml @@ -0,0 +1,57 @@ +name: Python CI + +on: + pull_request: + push: + branches: + - main + +jobs: + test-build: + runs-on: ubuntu-latest + timeout-minutes: 60 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Set up uv + uses: astral-sh/setup-uv@v4 + + - name: Sync environment + run: uv sync --group dev + + - name: Run tests + run: uv run pytest -q + + - name: Build distributions + run: uv build + + - name: Audit built wheel contents + run: | + python - <<'PY' + from pathlib import Path + import zipfile + + wheels = sorted(Path("dist").glob("*.whl")) + if not wheels: + raise SystemExit("No wheel produced in dist/") + + forbidden_roots = {"docs", "tests", "outputs", "pyscripts"} + with zipfile.ZipFile(wheels[0]) as wheel: + offenders = sorted( + name for name in wheel.namelist() + if name.split("/", 1)[0] in forbidden_roots + ) + + if offenders: + print("Forbidden wheel entries detected:") + for name in offenders: + print(name) + raise SystemExit(1) + PY diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..c908243 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,12 @@ +include LICENSE +include README.md +include pyproject.toml +recursive-include sarpyx *.py +prune build +prune dist +prune docs/_site +prune outputs +prune sarpyx.egg-info +global-exclude __pycache__ +global-exclude *.py[cod] +global-exclude .DS_Store diff --git a/README.md b/README.md index 61f9c80..0cf899e 100755 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@
- + User Manual - + Quick Start @@ -40,13 +40,16 @@ make recreate Using uv (recommended) ```bash -uv sync --extra copernicus +uv sync ``` -For development installation with extras: +For development, testing, and optional Copernicus tooling: ```bash -uv sync --extra copernicus --extra dev --extra test --extra docs +uv sync --group dev +uv sync --group dev --extra copernicus +uv run pytest -q +uv build ``` @@ -61,7 +64,7 @@ python -m pip install -e . ## Docs -See `docs/user_manual.md` for full CLI usage and end-to-end workflows. +See [docs/user_guide/README.md](docs/user_guide/README.md) for usage and workflows, and [docs/developer_guide/contributing.md](docs/developer_guide/contributing.md) for contributor commands. ## Container grid configuration diff --git a/docs/_site/developer_guide/contributing.html b/docs/_site/developer_guide/contributing.html index b237aee..ef9873b 100644 --- a/docs/_site/developer_guide/contributing.html +++ b/docs/_site/developer_guide/contributing.html @@ -230,16 +230,9 @@

Running Tests

Documentation

Building Documentation

-

We use Sphinx for documentation generation:

-
# Install documentation dependencies
-pip install -e ".[docs]"
-
-# Build documentation
-cd docs
-make html
-
-# Serve documentation locally
-python -m http.server 8000 -d _build/html
+

The checked-in source docs live under docs/. To refresh the static site:

+
python docs/generate_static_site.py
+python -m http.server 8000 -d docs/_site
 

Documentation Guidelines

    diff --git a/docs/_site/user_guide/installation.html b/docs/_site/user_guide/installation.html index 603b558..a383e9b 100644 --- a/docs/_site/user_guide/installation.html +++ b/docs/_site/user_guide/installation.html @@ -81,15 +81,15 @@