eopf-geozarr 0.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- eopf_geozarr-0.6.1/.github/CI.md +143 -0
- eopf_geozarr-0.6.1/.github/dependabot.yml +33 -0
- eopf_geozarr-0.6.1/.github/workflows/build_uv_cache.yml +42 -0
- eopf_geozarr-0.6.1/.github/workflows/ci.yml +99 -0
- eopf_geozarr-0.6.1/.github/workflows/docs.yml +41 -0
- eopf_geozarr-0.6.1/.github/workflows/release.yml +51 -0
- eopf_geozarr-0.6.1/.gitignore +216 -0
- eopf_geozarr-0.6.1/.pre-commit-config.yaml +23 -0
- eopf_geozarr-0.6.1/.vscode/launch.json +360 -0
- eopf_geozarr-0.6.1/CHANGELOG.md +142 -0
- eopf_geozarr-0.6.1/LICENSE +205 -0
- eopf_geozarr-0.6.1/PKG-INFO +421 -0
- eopf_geozarr-0.6.1/README.md +380 -0
- eopf_geozarr-0.6.1/attributes/README.md +36 -0
- eopf_geozarr-0.6.1/attributes/geo/proj/README.md +391 -0
- eopf_geozarr-0.6.1/attributes/geo/proj/schema.json +171 -0
- eopf_geozarr-0.6.1/docs/api-reference.md +505 -0
- eopf_geozarr-0.6.1/docs/architecture.md +449 -0
- eopf_geozarr-0.6.1/docs/assets/logo-eopf-sentinel-explorer-dark-icon.png +0 -0
- eopf_geozarr-0.6.1/docs/converter.md +213 -0
- eopf_geozarr-0.6.1/docs/examples.md +523 -0
- eopf_geozarr-0.6.1/docs/faq.md +531 -0
- eopf_geozarr-0.6.1/docs/geozarr-minispec.md +712 -0
- eopf_geozarr-0.6.1/docs/geozarr-specification-contribution.md +141 -0
- eopf_geozarr-0.6.1/docs/index.md +159 -0
- eopf_geozarr-0.6.1/docs/installation.md +159 -0
- eopf_geozarr-0.6.1/docs/models/sentinel1.md +54 -0
- eopf_geozarr-0.6.1/docs/models/sentinel2.md +86 -0
- eopf_geozarr-0.6.1/docs/quickstart.md +233 -0
- eopf_geozarr-0.6.1/docs/stylesheets/extra.css +82 -0
- eopf_geozarr-0.6.1/examples/convert_local.sh +14 -0
- eopf_geozarr-0.6.1/mkdocs.yml +74 -0
- eopf_geozarr-0.6.1/pyproject.toml +212 -0
- eopf_geozarr-0.6.1/setup.cfg +4 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/__init__.py +30 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/__main__.py +11 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/_version.py +34 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/cli.py +1228 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/__init__.py +45 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/fs_utils.py +499 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/geozarr.py +1766 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/sentinel1_reprojection.py +372 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/conversion/utils.py +239 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/__init__.py +48 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/__init__.py +0 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/common.py +291 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/geoproj.py +61 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/multiscales/__init__.py +13 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/multiscales/geozarr.py +98 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/multiscales/tms.py +56 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/multiscales/zcm.py +139 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/projjson.py +690 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/spatial.py +58 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/types.py +115 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/v2.py +138 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/geozarr/v3.py +68 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/s1.py +956 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/data_api/s2.py +692 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/pyz/__init__.py +4 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/pyz/common.py +467 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/pyz/v2.py +71 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/pyz/v3.py +71 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/__init__.py +2 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/common.py +5 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_band_mapping.py +77 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_converter.py +375 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_data_consolidator.py +217 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_multiscale.py +1077 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_resampling.py +212 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/s2_optimization/s2_validation.py +7 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr/types.py +134 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/PKG-INFO +421 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/SOURCES.txt +138 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/dependency_links.txt +1 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/entry_points.txt +2 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/requires.txt +14 -0
- eopf_geozarr-0.6.1/src/eopf_geozarr.egg-info/top_level.txt +1 -0
- eopf_geozarr-0.6.1/tests/__init__.py +247 -0
- eopf_geozarr-0.6.1/tests/conftest.py +285 -0
- eopf_geozarr-0.6.1/tests/test_cli_e2e.py +344 -0
- eopf_geozarr-0.6.1/tests/test_conversion.py +618 -0
- eopf_geozarr-0.6.1/tests/test_data_api/__init__.py +0 -0
- eopf_geozarr-0.6.1/tests/test_data_api/conftest.py +243 -0
- eopf_geozarr-0.6.1/tests/test_data_api/geoproj_examples/epsg26711.json +24 -0
- eopf_geozarr-0.6.1/tests/test_data_api/geoproj_examples/epsg3587.json +30 -0
- eopf_geozarr-0.6.1/tests/test_data_api/geoproj_examples/multiscales.json +63 -0
- eopf_geozarr-0.6.1/tests/test_data_api/geoproj_examples/wkt2.json +17 -0
- eopf_geozarr-0.6.1/tests/test_data_api/geozarr_examples/S2A_MSIL2A_20251008T100041_N0511_R122_T32TQM_20251008T122613.json +19094 -0
- eopf_geozarr-0.6.1/tests/test_data_api/geozarr_examples/S2B_MSIL1C_20250113T103309_N0511_R108_T32TLQ_20250113T122458.json +14123 -0
- eopf_geozarr-0.6.1/tests/test_data_api/geozarr_examples/S2C_MSIL2A_20250811T112131_N0511_R037_T29TPF_20250811T152216.json +19094 -0
- eopf_geozarr-0.6.1/tests/test_data_api/geozarr_examples/sentinel_2.json +14142 -0
- eopf_geozarr-0.6.1/tests/test_data_api/optimized_geozarr_examples/S2A_MSIL2A_20251008T100041_N0511_R122_T32TQM_20251008T122613.json +16320 -0
- eopf_geozarr-0.6.1/tests/test_data_api/optimized_geozarr_examples/S2B_MSIL1C_20250113T103309_N0511_R108_T32TLQ_20250113T122458.json +9981 -0
- eopf_geozarr-0.6.1/tests/test_data_api/optimized_geozarr_examples/S2C_MSIL2A_20250811T112131_N0511_R037_T29TPF_20250811T152216.json +16320 -0
- eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/bound_crs.json +198 -0
- eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/compound_crs.json +123 -0
- eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/datum_ensemble.json +98 -0
- eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/explicit_prime_meridian.json +47 -0
- eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/implicit_prime_meridian.json +43 -0
- eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/projected_crs.json +124 -0
- eopf_geozarr-0.6.1/tests/test_data_api/projjson_examples/transformation.json +112 -0
- eopf_geozarr-0.6.1/tests/test_data_api/s1_examples/S1A_IW_GRDH_1SDV_20241124T180254_20241124T180319_056700_06F516_BA27.json +9097 -0
- eopf_geozarr-0.6.1/tests/test_data_api/s1_examples/S1A_IW_GRDH_1SDV_20241218T180252_20241218T180317_057050_0702F2_0BC2.json +9414 -0
- eopf_geozarr-0.6.1/tests/test_data_api/s1_examples/S1C_IW_GRDH_1SDV_20250912T053648_20250912T053713_004087_0081FD_5AA4.json +7573 -0
- eopf_geozarr-0.6.1/tests/test_data_api/s2_examples/S2A_MSIL2A_20251008T100041_N0511_R122_T32TQM_20251008T122613.json +9165 -0
- eopf_geozarr-0.6.1/tests/test_data_api/s2_examples/S2B_MSIL1C_20250113T103309_N0511_R108_T32TLQ_20250113T122458.json +7836 -0
- eopf_geozarr-0.6.1/tests/test_data_api/s2_examples/S2C_MSIL2A_20250811T112131_N0511_R037_T29TPF_20250811T152216.json +9165 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geoproj.py +195 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/__init__.py +0 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_common.py +136 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/__init__.py +0 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/conftest.py +13 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/test_geozarr.py +69 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/test_tms.py +0 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/test_zcm.py +59 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/array-based-pyramid.json +44 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/custom-pyramid-levels.json +50 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/dem-multiresolution.json +68 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/geospatial-pyramid.json +59 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/power-of-2-pyramid.json +45 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_geozarr/test_multiscales/zcm_multiscales_examples/sentinel-2-multiresolution.json +87 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_projjson.py +777 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_s1.py +25 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_s2.py +25 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_spatial.py +213 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_v2.py +79 -0
- eopf_geozarr-0.6.1/tests/test_data_api/test_v3.py +80 -0
- eopf_geozarr-0.6.1/tests/test_docs.py +164 -0
- eopf_geozarr-0.6.1/tests/test_fs_utils.py +195 -0
- eopf_geozarr-0.6.1/tests/test_integration_sentinel1.py +303 -0
- eopf_geozarr-0.6.1/tests/test_integration_sentinel2.py +372 -0
- eopf_geozarr-0.6.1/tests/test_projjson.py +0 -0
- eopf_geozarr-0.6.1/tests/test_reprojection_validation.py +279 -0
- eopf_geozarr-0.6.1/tests/test_s2_band_mapping.py +37 -0
- eopf_geozarr-0.6.1/tests/test_s2_converter_simplified.py +287 -0
- eopf_geozarr-0.6.1/tests/test_s2_data_consolidator.py +567 -0
- eopf_geozarr-0.6.1/tests/test_s2_multiscale.py +210 -0
- eopf_geozarr-0.6.1/tests/test_s2_multiscale_geo_metadata.py +313 -0
- eopf_geozarr-0.6.1/tests/test_s2_resampling.py +474 -0
- eopf_geozarr-0.6.1/uv.lock +2826 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# CI/CD Documentation
|
|
2
|
+
|
|
3
|
+
This directory contains the GitHub Actions workflows and configuration for the eopf-geozarr project.
|
|
4
|
+
|
|
5
|
+
## Workflows
|
|
6
|
+
|
|
7
|
+
### 1. CI Workflow (`ci.yml`)
|
|
8
|
+
**Triggers:** Push to main, Pull requests to main
|
|
9
|
+
|
|
10
|
+
**Jobs:**
|
|
11
|
+
- **pre-commit**: Runs pre-commit hooks for code quality
|
|
12
|
+
- **test**: Runs tests on Python 3.11 and 3.12 on Ubuntu
|
|
13
|
+
- **test-network**: Runs network-dependent tests (only on main branch pushes)
|
|
14
|
+
- **docs**: Builds documentation
|
|
15
|
+
- **security**: Runs security scans with bandit and safety
|
|
16
|
+
|
|
17
|
+
**Features:**
|
|
18
|
+
- Code coverage reporting with Codecov
|
|
19
|
+
- Artifact uploads for documentation and security reports
|
|
20
|
+
- Separate network tests to avoid CI failures from external dependencies
|
|
21
|
+
|
|
22
|
+
### 2. Code Quality Workflow (`code-quality.yml`)
|
|
23
|
+
**Triggers:** Pull requests to main
|
|
24
|
+
|
|
25
|
+
**Jobs:**
|
|
26
|
+
- **lint**: Runs black, isort, flake8, and mypy
|
|
27
|
+
- **test-coverage**: Runs tests with coverage requirements (80% minimum)
|
|
28
|
+
- **security-scan**: Runs bandit and safety security checks
|
|
29
|
+
|
|
30
|
+
**Purpose:** Ensures code quality standards before merging PRs
|
|
31
|
+
|
|
32
|
+
### 3. Release Workflow (`release.yml`)
|
|
33
|
+
**Triggers:** GitHub releases
|
|
34
|
+
|
|
35
|
+
**Jobs:**
|
|
36
|
+
- **build**: Builds the Python package and validates it
|
|
37
|
+
- **publish**: Publishes to PyPI using trusted publishing
|
|
38
|
+
|
|
39
|
+
**Features:**
|
|
40
|
+
- Automated PyPI publishing on releases
|
|
41
|
+
- Package validation before publishing
|
|
42
|
+
- Uses GitHub's trusted publishing for secure PyPI uploads
|
|
43
|
+
|
|
44
|
+
### 4. Documentation Workflow (`docs.yml`)
|
|
45
|
+
**Triggers:** Push to main, Pull requests to main
|
|
46
|
+
|
|
47
|
+
**Jobs:**
|
|
48
|
+
- **build-docs**: Builds Sphinx documentation
|
|
49
|
+
- **deploy**: Deploys to GitHub Pages (main branch only)
|
|
50
|
+
|
|
51
|
+
**Features:**
|
|
52
|
+
- Automatic documentation deployment
|
|
53
|
+
- Documentation artifacts for PR previews
|
|
54
|
+
|
|
55
|
+
## Configuration Files
|
|
56
|
+
|
|
57
|
+
### Pre-commit Configuration (`.pre-commit-config.yaml`)
|
|
58
|
+
Defines hooks for:
|
|
59
|
+
- Code formatting (black, isort)
|
|
60
|
+
- Linting (flake8, mypy)
|
|
61
|
+
- Security scanning (bandit)
|
|
62
|
+
- General file checks (trailing whitespace, YAML validation, etc.)
|
|
63
|
+
|
|
64
|
+
### Dependabot Configuration (`dependabot.yml`)
|
|
65
|
+
Automated dependency updates for:
|
|
66
|
+
- Python packages (weekly)
|
|
67
|
+
- GitHub Actions (weekly)
|
|
68
|
+
- Assigned to `developmentseed/data-model-developers` team
|
|
69
|
+
|
|
70
|
+
## Setup Instructions
|
|
71
|
+
|
|
72
|
+
### For Developers
|
|
73
|
+
|
|
74
|
+
1. **Install pre-commit hooks:**
|
|
75
|
+
```bash
|
|
76
|
+
pip install -e ".[dev]"
|
|
77
|
+
pre-commit install
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
2. **Run code quality checks locally:**
|
|
81
|
+
```bash
|
|
82
|
+
black --check eopf_geozarr/
|
|
83
|
+
isort --check-only eopf_geozarr/
|
|
84
|
+
flake8 eopf_geozarr/
|
|
85
|
+
mypy eopf_geozarr/
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
3. **Run tests:**
|
|
89
|
+
```bash
|
|
90
|
+
pytest eopf_geozarr/tests/ -v --tb=short -m "not network"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### For Repository Maintainers
|
|
94
|
+
|
|
95
|
+
1. **Enable GitHub Pages:**
|
|
96
|
+
- Go to repository Settings > Pages
|
|
97
|
+
- Set source to "GitHub Actions"
|
|
98
|
+
|
|
99
|
+
2. **Configure PyPI Publishing:**
|
|
100
|
+
- Set up trusted publishing on PyPI
|
|
101
|
+
- No secrets needed with trusted publishing
|
|
102
|
+
|
|
103
|
+
3. **Configure Codecov:**
|
|
104
|
+
- Add repository to Codecov
|
|
105
|
+
- No additional configuration needed
|
|
106
|
+
|
|
107
|
+
## Code Quality Standards
|
|
108
|
+
|
|
109
|
+
- **Code Coverage:** Minimum 80% required
|
|
110
|
+
- **Code Style:** Black formatting with 100 character line length
|
|
111
|
+
- **Import Sorting:** isort with black profile
|
|
112
|
+
- **Type Checking:** mypy with strict settings
|
|
113
|
+
- **Security:** bandit security scanning
|
|
114
|
+
- **Documentation:** All public APIs must be documented
|
|
115
|
+
|
|
116
|
+
## Testing Strategy
|
|
117
|
+
|
|
118
|
+
- **Unit Tests:** Fast tests without external dependencies
|
|
119
|
+
- **Integration Tests:** Tests with real data processing
|
|
120
|
+
- **Network Tests:** Tests requiring internet access (marked with `@pytest.mark.network`)
|
|
121
|
+
- **End-to-End Tests:** CLI testing with real workflows
|
|
122
|
+
|
|
123
|
+
## Release Process
|
|
124
|
+
|
|
125
|
+
1. Update version in `pyproject.toml`
|
|
126
|
+
2. Update `CHANGELOG.md`
|
|
127
|
+
3. Create a GitHub release with tag
|
|
128
|
+
4. Package is automatically built and published to PyPI
|
|
129
|
+
|
|
130
|
+
## Troubleshooting
|
|
131
|
+
|
|
132
|
+
### Common Issues
|
|
133
|
+
|
|
134
|
+
1. **Pre-commit failures:** Run `pre-commit run --all-files` to fix issues
|
|
135
|
+
2. **Test failures:** Check if network tests are failing due to external dependencies
|
|
136
|
+
3. **Coverage failures:** Add tests or exclude lines with `# pragma: no cover`
|
|
137
|
+
4. **Security scan failures:** Review bandit reports and add exclusions if needed
|
|
138
|
+
|
|
139
|
+
### Getting Help
|
|
140
|
+
|
|
141
|
+
- Check workflow logs in the Actions tab
|
|
142
|
+
- Review the specific job that failed
|
|
143
|
+
- Common fixes are usually code formatting or missing tests
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Enable version updates for Python dependencies
|
|
4
|
+
- package-ecosystem: "pip"
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: "weekly"
|
|
8
|
+
day: "monday"
|
|
9
|
+
time: "09:00"
|
|
10
|
+
open-pull-requests-limit: 10
|
|
11
|
+
reviewers:
|
|
12
|
+
- "developmentseed/data-model-developers"
|
|
13
|
+
assignees:
|
|
14
|
+
- "developmentseed/data-model-developers"
|
|
15
|
+
commit-message:
|
|
16
|
+
prefix: "deps"
|
|
17
|
+
include: "scope"
|
|
18
|
+
|
|
19
|
+
# Enable version updates for GitHub Actions
|
|
20
|
+
- package-ecosystem: "github-actions"
|
|
21
|
+
directory: "/"
|
|
22
|
+
schedule:
|
|
23
|
+
interval: "weekly"
|
|
24
|
+
day: "monday"
|
|
25
|
+
time: "09:00"
|
|
26
|
+
open-pull-requests-limit: 5
|
|
27
|
+
reviewers:
|
|
28
|
+
- "developmentseed/data-model-developers"
|
|
29
|
+
assignees:
|
|
30
|
+
- "developmentseed/data-model-developers"
|
|
31
|
+
commit-message:
|
|
32
|
+
prefix: "ci"
|
|
33
|
+
include: "scope"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Build uv cache
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- "uv.lock"
|
|
9
|
+
- "pyproject.toml"
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
schedule:
|
|
12
|
+
- cron: "0 0 */5 * *" # Every 5 days, before cache expiry
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build-cache:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout repository
|
|
20
|
+
uses: actions/checkout@v5
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v7
|
|
24
|
+
with:
|
|
25
|
+
version: "0.8.4"
|
|
26
|
+
python-version: "3.13"
|
|
27
|
+
enable-cache: false
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies and populate cache
|
|
30
|
+
run: |
|
|
31
|
+
echo "Building global UV cache..."
|
|
32
|
+
uv sync --group dev --group test
|
|
33
|
+
echo "Cache populated successfully"
|
|
34
|
+
|
|
35
|
+
- name: Save uv caches
|
|
36
|
+
uses: actions/cache/save@v4
|
|
37
|
+
with:
|
|
38
|
+
path: |
|
|
39
|
+
~/.cache/uv
|
|
40
|
+
~/.local/share/uv
|
|
41
|
+
.venv
|
|
42
|
+
key: uv-main-${{ hashFiles('uv.lock') }}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
pre-commit:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v5
|
|
14
|
+
- uses: actions/setup-python@v6
|
|
15
|
+
with:
|
|
16
|
+
python-version: '3.11'
|
|
17
|
+
- uses: pre-commit/action@v3.0.1
|
|
18
|
+
|
|
19
|
+
test:
|
|
20
|
+
runs-on: ${{ matrix.os }}
|
|
21
|
+
strategy:
|
|
22
|
+
matrix:
|
|
23
|
+
os: [ubuntu-latest]
|
|
24
|
+
python-version: ['3.11', '3.12']
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v5
|
|
28
|
+
|
|
29
|
+
- name: Restore global uv cache
|
|
30
|
+
id: cache-restore
|
|
31
|
+
uses: actions/cache/restore@v4
|
|
32
|
+
with:
|
|
33
|
+
path: |
|
|
34
|
+
~/.cache/uv
|
|
35
|
+
~/.local/share/uv
|
|
36
|
+
.venv
|
|
37
|
+
key: uv-main-${{ hashFiles('uv.lock') }}
|
|
38
|
+
restore-keys: |
|
|
39
|
+
uv-main-
|
|
40
|
+
|
|
41
|
+
- name: Install uv
|
|
42
|
+
uses: astral-sh/setup-uv@v7
|
|
43
|
+
with:
|
|
44
|
+
version: "0.8.4"
|
|
45
|
+
python-version: "3.13"
|
|
46
|
+
enable-cache: false
|
|
47
|
+
|
|
48
|
+
- name: Install dependencies
|
|
49
|
+
run: uv sync --group dev --group test
|
|
50
|
+
|
|
51
|
+
- name: Run tests
|
|
52
|
+
run: |
|
|
53
|
+
uv run pytest tests/ -v --tb=short -m "not network" --cov=eopf_geozarr --cov-report=xml --cov-report=term-missing
|
|
54
|
+
|
|
55
|
+
- name: Upload coverage to Codecov
|
|
56
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
|
|
57
|
+
uses: codecov/codecov-action@v5
|
|
58
|
+
with:
|
|
59
|
+
file: ./coverage.xml
|
|
60
|
+
flags: unittests
|
|
61
|
+
name: codecov-umbrella
|
|
62
|
+
|
|
63
|
+
- name: Save uv caches
|
|
64
|
+
if: steps.cache-restore.outputs.cache-hit != 'true'
|
|
65
|
+
uses: actions/cache/save@v4
|
|
66
|
+
with:
|
|
67
|
+
path: |
|
|
68
|
+
~/.cache/uv
|
|
69
|
+
~/.local/share/uv
|
|
70
|
+
.venv
|
|
71
|
+
key: uv-main-${{ hashFiles('uv.lock') }}
|
|
72
|
+
|
|
73
|
+
security:
|
|
74
|
+
runs-on: ubuntu-latest
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/checkout@v5
|
|
77
|
+
|
|
78
|
+
- name: Set up Python
|
|
79
|
+
uses: actions/setup-python@v6
|
|
80
|
+
with:
|
|
81
|
+
python-version: '3.11'
|
|
82
|
+
|
|
83
|
+
- name: Install dependencies
|
|
84
|
+
run: |
|
|
85
|
+
python -m pip install --upgrade pip
|
|
86
|
+
pip install bandit safety
|
|
87
|
+
|
|
88
|
+
- name: Run security checks
|
|
89
|
+
run: |
|
|
90
|
+
bandit -r eopf_geozarr/ -f json -o bandit-report.json || true
|
|
91
|
+
safety check --json --output safety-report.json || true
|
|
92
|
+
|
|
93
|
+
- name: Upload security reports
|
|
94
|
+
uses: actions/upload-artifact@v5
|
|
95
|
+
with:
|
|
96
|
+
name: security-reports
|
|
97
|
+
path: |
|
|
98
|
+
bandit-report.json
|
|
99
|
+
safety-report.json
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
paths:
|
|
9
|
+
- "docs/**"
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-docs:
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write
|
|
15
|
+
pages: write
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v5
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v6
|
|
22
|
+
with:
|
|
23
|
+
python-version: '3.11'
|
|
24
|
+
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@v7
|
|
27
|
+
with:
|
|
28
|
+
version: "0.8.4"
|
|
29
|
+
python-version: "3.13"
|
|
30
|
+
enable-cache: false
|
|
31
|
+
|
|
32
|
+
- name: Install dependencies
|
|
33
|
+
run: uv sync --group docs
|
|
34
|
+
|
|
35
|
+
- name: Build docs
|
|
36
|
+
if: github.event_name == 'pull_request'
|
|
37
|
+
run: uv run -- mkdocs build
|
|
38
|
+
|
|
39
|
+
- name: Deploy docs
|
|
40
|
+
if: github.event_name == 'push'
|
|
41
|
+
run: uv run -- mkdocs gh-deploy --force
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v5
|
|
12
|
+
|
|
13
|
+
- name: Set up Python
|
|
14
|
+
uses: actions/setup-python@v6
|
|
15
|
+
with:
|
|
16
|
+
python-version: '3.11'
|
|
17
|
+
|
|
18
|
+
- name: Install build dependencies
|
|
19
|
+
run: |
|
|
20
|
+
python -m pip install --upgrade pip
|
|
21
|
+
pip install build twine
|
|
22
|
+
|
|
23
|
+
- name: Build package
|
|
24
|
+
run: python -m build
|
|
25
|
+
|
|
26
|
+
- name: Check package
|
|
27
|
+
run: twine check dist/*
|
|
28
|
+
|
|
29
|
+
- name: Upload build artifacts
|
|
30
|
+
uses: actions/upload-artifact@v5
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
needs: build
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
permissions:
|
|
39
|
+
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
|
40
|
+
|
|
41
|
+
steps:
|
|
42
|
+
- name: Download build artifacts
|
|
43
|
+
uses: actions/download-artifact@v6
|
|
44
|
+
with:
|
|
45
|
+
name: dist
|
|
46
|
+
path: dist/
|
|
47
|
+
|
|
48
|
+
- name: Publish to PyPI
|
|
49
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
50
|
+
with:
|
|
51
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
#poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
#pdm.lock
|
|
116
|
+
#pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
#pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# SageMath parsed files
|
|
135
|
+
*.sage.py
|
|
136
|
+
|
|
137
|
+
# Environments
|
|
138
|
+
.env
|
|
139
|
+
.envrc
|
|
140
|
+
.venv
|
|
141
|
+
env/
|
|
142
|
+
venv/
|
|
143
|
+
ENV/
|
|
144
|
+
env.bak/
|
|
145
|
+
venv.bak/
|
|
146
|
+
|
|
147
|
+
# Spyder project settings
|
|
148
|
+
.spyderproject
|
|
149
|
+
.spyproject
|
|
150
|
+
|
|
151
|
+
# Rope project settings
|
|
152
|
+
.ropeproject
|
|
153
|
+
|
|
154
|
+
# mkdocs documentation
|
|
155
|
+
/site
|
|
156
|
+
|
|
157
|
+
# mypy
|
|
158
|
+
.mypy_cache/
|
|
159
|
+
.dmypy.json
|
|
160
|
+
dmypy.json
|
|
161
|
+
|
|
162
|
+
# Pyre type checker
|
|
163
|
+
.pyre/
|
|
164
|
+
|
|
165
|
+
# pytype static type analyzer
|
|
166
|
+
.pytype/
|
|
167
|
+
|
|
168
|
+
# Cython debug symbols
|
|
169
|
+
cython_debug/
|
|
170
|
+
|
|
171
|
+
# PyCharm
|
|
172
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
173
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
174
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
175
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
176
|
+
#.idea/
|
|
177
|
+
|
|
178
|
+
# Abstra
|
|
179
|
+
# Abstra is an AI-powered process automation framework.
|
|
180
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
181
|
+
# Learn more at https://abstra.io/docs
|
|
182
|
+
.abstra/
|
|
183
|
+
|
|
184
|
+
# Visual Studio Code
|
|
185
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
186
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
188
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
189
|
+
# .vscode/
|
|
190
|
+
|
|
191
|
+
# Ruff stuff:
|
|
192
|
+
.ruff_cache/
|
|
193
|
+
|
|
194
|
+
# PyPI configuration file
|
|
195
|
+
.pypirc
|
|
196
|
+
|
|
197
|
+
# Cursor
|
|
198
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
199
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
200
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
201
|
+
.cursorignore
|
|
202
|
+
.cursorindexingignore
|
|
203
|
+
|
|
204
|
+
# Marimo
|
|
205
|
+
marimo/_static/
|
|
206
|
+
marimo/_lsp/
|
|
207
|
+
__marimo__/
|
|
208
|
+
|
|
209
|
+
tests-output/
|
|
210
|
+
|
|
211
|
+
# uv
|
|
212
|
+
uv.lock
|
|
213
|
+
.vscode/settings.json
|
|
214
|
+
|
|
215
|
+
# VCS versioning
|
|
216
|
+
src/eopf_geozarr/_version.py
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/abravalheri/validate-pyproject
|
|
3
|
+
rev: v0.24.1
|
|
4
|
+
hooks:
|
|
5
|
+
- id: validate-pyproject
|
|
6
|
+
|
|
7
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
8
|
+
rev: v0.14.3
|
|
9
|
+
hooks:
|
|
10
|
+
- id: ruff-check
|
|
11
|
+
args: ["--fix", "--show-fixes"]
|
|
12
|
+
- id: ruff-format
|
|
13
|
+
|
|
14
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
15
|
+
rev: v1.11.2
|
|
16
|
+
hooks:
|
|
17
|
+
- id: mypy
|
|
18
|
+
language_version: python
|
|
19
|
+
exclude: tests/.*
|
|
20
|
+
additional_dependencies:
|
|
21
|
+
- types-attrs
|
|
22
|
+
- typing-extensions>=4.15.0
|
|
23
|
+
- pydantic>=2.12
|