|
| 1 | +# Contributing to MHKiT-MATLAB |
| 2 | + |
| 3 | +Thank you for your interest in contributing to MHKiT-MATLAB! This guide will help you get started with contributing code, documentation, and bug fixes. |
| 4 | + |
| 5 | +## Quickstart |
| 6 | + |
| 7 | +Here's the high-level contribution workflow: |
| 8 | + |
| 9 | +1. **Fork** the MHKiT-MATLAB repository |
| 10 | +2. **Set up** your development environment (Python + MATLAB) |
| 11 | +3. **Create** a feature branch from `develop` |
| 12 | +4. **Write** your code with proper docstrings and tests |
| 13 | +5. **Test locally** using the docstring checker and unit tests |
| 14 | +6. **Add** an entry to `changelog.md` |
| 15 | +7. **Push** your changes and open a pull request to `develop` |
| 16 | +8. **CI runs** automated tests across all supported MATLAB/Python versions |
| 17 | +9. **Address** review feedback from maintainers |
| 18 | +10. **Merge** into `develop` once approved |
| 19 | + |
| 20 | +## Fork and Setup |
| 21 | + |
| 22 | +### Fork the Repository |
| 23 | + |
| 24 | +1. **Fork** the repository on GitHub: https://github.com/MHKiT-Software/MHKiT-MATLAB |
| 25 | + |
| 26 | +2. **Clone** your fork to your local machine: |
| 27 | + |
| 28 | + ```bash |
| 29 | + git clone https://github.com/YOUR-USERNAME/MHKiT-MATLAB.git |
| 30 | + cd MHKiT-MATLAB |
| 31 | + ``` |
| 32 | + |
| 33 | +3. **Add upstream** as a remote: |
| 34 | + ```bash |
| 35 | + git remote add upstream https://github.com/MHKiT-Software/MHKiT-MATLAB.git |
| 36 | + ``` |
| 37 | + |
| 38 | +### Development Environment Setup |
| 39 | + |
| 40 | +See INSTALL.md for detailed instructions on setting up your development environment with MATLAB and |
| 41 | +MHKiT-Python. |
| 42 | + |
| 43 | +## Development Workflow |
| 44 | + |
| 45 | +### Branching Strategy |
| 46 | + |
| 47 | +- **`master`** - Production releases only |
| 48 | +- **`develop`** - Main development branch ← **target your PRs here** |
| 49 | + |
| 50 | +### Creating a Feature Branch |
| 51 | + |
| 52 | +1. **Sync with upstream**: |
| 53 | + |
| 54 | + ```bash |
| 55 | + git checkout develop |
| 56 | + git fetch upstream |
| 57 | + git merge upstream/develop |
| 58 | + ``` |
| 59 | + |
| 60 | +2. **Create your feature branch**: |
| 61 | + |
| 62 | + ```bash |
| 63 | + git checkout -b feature/your-feature-name |
| 64 | + ``` |
| 65 | + |
| 66 | +3. **Make changes and commit regularly**: |
| 67 | + |
| 68 | + ```bash |
| 69 | + git add . |
| 70 | + git commit -m "Brief description of changes" |
| 71 | + ``` |
| 72 | + |
| 73 | +4. **Keep your branch updated**: |
| 74 | + ```bash |
| 75 | + git fetch upstream |
| 76 | + git rebase upstream/develop |
| 77 | + ``` |
| 78 | + |
| 79 | +## Writing Code |
| 80 | + |
| 81 | +## Documentation |
| 82 | + |
| 83 | +### Docstring Format |
| 84 | + |
| 85 | +All public functions **must** have properly formatted docstrings. This is loosely enforced by automated CI checks. Where a specific format is not specified, developers should use the template below as a guide. |
| 86 | + |
| 87 | +### Docstring Function Template |
| 88 | + |
| 89 | +```matlab |
| 90 | +function result = descriptive_function_name(input_1, input_2, input_3) |
| 91 | +
|
| 92 | +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 93 | +% |
| 94 | +% Brief one-line description of what the function does |
| 95 | +% |
| 96 | +% Optional extended description paragraph. Can span multiple lines |
| 97 | +% to provide additional context, mathematical background, data sources, |
| 98 | +% or important behavioral notes about the function. |
| 99 | +% |
| 100 | +% Parameters |
| 101 | +% ------------ |
| 102 | +% input_1 : type [units] |
| 103 | +% Description of first parameter. Can span multiple lines. |
| 104 | +% Additional details aligned with first line. Use two spaces for indentation |
| 105 | +% input_1.fieldname_1 : type [units] |
| 106 | +% Description of field |
| 107 | +% input_1.fieldname_2 : type [units] |
| 108 | +% Description of field |
| 109 | +% input_2 : type [units] |
| 110 | +% Description of second parameter |
| 111 | +% input_t : type [units] (optional) |
| 112 | +% Description of second parameter. Mark optional parameters |
| 113 | +% with (optional) after the type. |
| 114 | +% |
| 115 | +% Returns |
| 116 | +% --------- |
| 117 | +% output : type |
| 118 | +% Description of return value. For structure outputs, |
| 119 | +% document nested fields with indentation: |
| 120 | +% output.field1 : type [units] |
| 121 | +% Field 1 description |
| 122 | +% output.field2 : type [units] |
| 123 | +% Field description |
| 124 | +% |
| 125 | +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 126 | +
|
| 127 | +arguments (Input) |
| 128 | + input_1 struct |
| 129 | + input_2 {mustBeInteger, mustBePositive} |
| 130 | + input_3 {mustBeInteger} = 2 |
| 131 | +end |
| 132 | +
|
| 133 | +arguments (Output) |
| 134 | + result struct |
| 135 | +end |
| 136 | +
|
| 137 | +% Function implementation goes here |
| 138 | +
|
| 139 | +end |
| 140 | +``` |
| 141 | + |
| 142 | +### Use the `arguments` Block |
| 143 | + |
| 144 | +All functions must use [MATLAB's `arguments` block](https://www.mathworks.com/help/matlab/ref/arguments.html) for input/output type validation. |
| 145 | + |
| 146 | +#### Simple Example |
| 147 | + |
| 148 | +```matlab |
| 149 | +function result = calculate_energy(power, duration) |
| 150 | +
|
| 151 | +arguments |
| 152 | + power double {mustBeNumeric, mustBeFinite} |
| 153 | + duration double {mustBePositive} |
| 154 | +end |
| 155 | +
|
| 156 | +% Function implementation |
| 157 | +result = power * duration; |
| 158 | +
|
| 159 | +end |
| 160 | +``` |
| 161 | + |
| 162 | +#### Complex Example (Struct Inputs/Outputs) |
| 163 | + |
| 164 | +```matlab |
| 165 | +function mspl = band_sound_pressure_level(spsd, octave, base, fmin, fmax) |
| 166 | +
|
| 167 | +arguments (Input) |
| 168 | + spsd struct |
| 169 | + octave {mustBeInteger, mustBePositive} |
| 170 | + base {mustBeInteger} = 2 |
| 171 | + fmin {mustBeNumeric, mustBePositive} = 10 |
| 172 | + fmax {mustBeNumeric, mustBePositive} = 100000 |
| 173 | +end |
| 174 | +
|
| 175 | +arguments (Output) |
| 176 | + mspl struct |
| 177 | +end |
| 178 | +
|
| 179 | +% Function implementation |
| 180 | +mspl = struct(); |
| 181 | +
|
| 182 | +end |
| 183 | +``` |
| 184 | + |
| 185 | +#### Common Validation Functions |
| 186 | + |
| 187 | +- `mustBeNumeric` - Must be numeric type |
| 188 | +- `mustBeFinite` - No NaN or Inf values |
| 189 | +- `mustBePositive` - Greater than zero |
| 190 | +- `mustBeInteger` - Integer values only |
| 191 | +- `mustBeNonzero` - Cannot be zero |
| 192 | +- `mustBeNonempty` - Cannot be empty |
| 193 | + |
| 194 | +For custom validation, create functions in `mhkit/utils/` or module-specific directories. |
| 195 | + |
| 196 | +### Checking Your Docstrings |
| 197 | + |
| 198 | +Before submitting your PR, there is a python script to validate docstrings locally: |
| 199 | + |
| 200 | +```bash |
| 201 | +# Check all mhkit files |
| 202 | +python scripts/check_docstrings.py |
| 203 | + |
| 204 | +# Check specific directory |
| 205 | +python scripts/check_docstrings.py --path mhkit/wave |
| 206 | + |
| 207 | +# Verbose output |
| 208 | +python scripts/check_docstrings.py --verbose |
| 209 | +``` |
| 210 | + |
| 211 | +**Note**: The docstring checker actions run automatically on all PRs. Errors must be fixed before |
| 212 | +merging to develop and master. |
| 213 | + |
| 214 | +## Testing |
| 215 | + |
| 216 | +### Running Tests Locally |
| 217 | + |
| 218 | +Before submitting your PR, run the full test suite: |
| 219 | + |
| 220 | +```matlab |
| 221 | +% Navigate to tests directory |
| 222 | +cd mhkit/tests |
| 223 | +
|
| 224 | +% Run all tests |
| 225 | +runTests |
| 226 | +``` |
| 227 | + |
| 228 | +### Writing Unit Tests |
| 229 | + |
| 230 | +When adding new functionality, create tests in `mhkit/tests/`: |
| 231 | + |
| 232 | +Use the patterns in the existing test files as a guide. |
| 233 | + |
| 234 | +**Test coverage should include:** |
| 235 | + |
| 236 | +- Normal operation |
| 237 | +- Edge cases |
| 238 | +- Error conditions |
| 239 | +- Optional parameters |
| 240 | + |
| 241 | +## Changelog |
| 242 | + |
| 243 | +All contributions **must** include a changelog entry. |
| 244 | + |
| 245 | +### Adding a Changelog Entry |
| 246 | + |
| 247 | +1. Open `changelog.md` |
| 248 | + |
| 249 | +2. Add your entry at the **top** under a new "Unreleased" section (if it doesn't exist): |
| 250 | + |
| 251 | +```markdown |
| 252 | +# Unreleased |
| 253 | + |
| 254 | +## PR #XXX - Brief Feature Description |
| 255 | + |
| 256 | +- Author: @your-github-username |
| 257 | +- Description of changes |
| 258 | +- Key additions: |
| 259 | + - Bullet point 1 |
| 260 | + - Bullet point 2 |
| 261 | + |
| 262 | +[rest of existing changelog...] |
| 263 | +``` |
| 264 | + |
| 265 | +### Changelog Format Guidelines |
| 266 | + |
| 267 | +- Use format: `## PR #XXX - Title` |
| 268 | +- Include your GitHub username |
| 269 | +- List key changes as bullet points |
| 270 | +- Reference related issues if applicable |
| 271 | +- Place at the top of the file |
| 272 | + |
| 273 | +**Example:** |
| 274 | + |
| 275 | +```markdown |
| 276 | +# Unreleased |
| 277 | + |
| 278 | +## PR #185 - Add Wave Spectral Analysis Functions |
| 279 | + |
| 280 | +- Author: @contributor |
| 281 | +- Added native MATLAB implementations for wave spectral analysis |
| 282 | +- Key additions: |
| 283 | + - `wave/resource/wave_spectral_moment.m` - Calculate spectral moments |
| 284 | + - `wave/resource/wave_spectral_bandwidth.m` - Calculate spectral bandwidth |
| 285 | + - Unit tests and example live script |
| 286 | +- Closes #180 |
| 287 | +``` |
| 288 | + |
| 289 | +--- |
| 290 | + |
| 291 | +## Submitting Your PR |
| 292 | + |
| 293 | +### Pull Request Process |
| 294 | + |
| 295 | +1. **Push your changes** to your fork: |
| 296 | + |
| 297 | + ```bash |
| 298 | + git push origin feature/your-feature-name |
| 299 | + ``` |
| 300 | + |
| 301 | +2. **Create a pull request**: |
| 302 | + |
| 303 | + - Go to https://github.com/MHKiT-Software/MHKiT-MATLAB |
| 304 | + - Click "New Pull Request" |
| 305 | + - **Base branch**: `develop` ← Important! |
| 306 | + - **Compare branch**: your feature branch |
| 307 | + - Provide a clear description of your changes |
| 308 | + |
| 309 | +3. **PR requirements**: |
| 310 | + |
| 311 | + - Target `develop` branch (NOT `master`) |
| 312 | + - All CI checks must pass: |
| 313 | + - Docstring validation |
| 314 | + - Unit tests (Linux, macOS, Windows) |
| 315 | + - Code compatibility checks |
| 316 | + - Changelog entry added |
| 317 | + - Tests added/updated for new functionality |
| 318 | + |
| 319 | +4. **After submission**: |
| 320 | + - CI will automatically test across all supported MATLAB/Python versions |
| 321 | + - Address any review feedback |
| 322 | + - Once approved, maintainers will merge to `develop` |
| 323 | + |
| 324 | +Note: Sometimes github actions fail for non code related reasons. If this happens, please reach |
| 325 | +out in the discussions or issues page. It is a reasonable procedure to re-run failed actions, and |
| 326 | +possibly disable failing combinations of matlab/python versions if they are not critical. |
| 327 | + |
| 328 | +### PR Title Format |
| 329 | + |
| 330 | +Use conventional commit format: |
| 331 | + |
| 332 | +- `Feature: Add wave spectral bandwidth calculation` |
| 333 | +- `<module>: Correct NDBC data parsing for missing values` |
| 334 | +- `Actions: Fix action related bug` |
| 335 | +- `Examples: Fix typo in acoustics example` |
| 336 | +- `Fix: Incorrect sign in energy calculation` |
| 337 | + |
| 338 | +## Code Standards |
| 339 | + |
| 340 | +- **Style**: Use the templates provided above to ensure functions follow consistent style |
| 341 | +- **Clarity**: Use meaningful variable names with units, i.e. `significant_wave_height_meters` over shorter variables like `hm0`. |
| 342 | +- **Comments**: Use comments to explain complex logic, but avoid obvious comments |
| 343 | +- **Testing**: Include unit tests |
| 344 | + |
| 345 | +## Getting Help |
| 346 | + |
| 347 | +- **Documentation**: https://mhkit-software.github.io/MHKiT/ |
| 348 | +- **Issues**: https://github.com/MHKiT-Software/MHKiT-MATLAB/issues |
| 349 | +- **Discussions**: https://github.com/MHKiT-Software/MHKiT-MATLAB/discussions |
| 350 | + |
| 351 | +## License |
| 352 | + |
| 353 | +By contributing, you agree that your contributions will be licensed under the Revised BSD License. See [LICENSE](https://mhkit-software.github.io/MHKiT/license.html) for details. |
0 commit comments