Contributing
Development Guide
Where Does Code Belong?
ICOW.jl depends on SimOptDecisions.jl for the simulation framework. When contributing, consider where your code belongs:
| Change Type | Where It Goes |
|---|---|
| New simulation mode or policy type | ICOW.jl (src/Stochastic/ or src/EAD/) |
| Changes to cost/damage physics | ICOW.jl (src/Core/) |
New AbstractConfig, AbstractScenario, etc. |
ICOW.jl (submodule types.jl) |
Changes to simulate, explore, or framework logic |
SimOptDecisions.jl |
| New integration methods or outcome types | SimOptDecisions.jl |
If you need to modify SimOptDecisions, open a PR there first, then update ICOW.jl to use the new version.
Development Environment
Clone the repo and instantiate:
git clone https://github.com/dossgollin-lab/ICOW.jl
cd ICOW.jl
julia --project -e 'using Pkg; Pkg.instantiate()'SimOptDecisions is an unregistered dependency. If instantiate fails, add it manually:
julia --project -e 'using Pkg; Pkg.add(url="https://github.com/dossgollin-lab/SimOptDecisions.git")'Running Tests
Run the full test suite:
julia --project test/runtests.jlOr from the Julia REPL:
using Pkg
Pkg.test()Tests are organized by module in test/:
test/core/– Core physics functionstest/ead/– EAD simulation modetest/stochastic/– Stochastic simulation mode
Code Style
We use JuliaFormatter with BlueStyle.
Format locally before committing:
using JuliaFormatter
format(".", BlueStyle())The CI will auto-format and commit if you forget, but it’s cleaner to format locally.
Test Conventions
Keep tests minimal. Test key invariants, not every possible case:
- Zero/edge cases: If inputs are 0, output should be 0 (or baseline)
- Monotonicity: Increasing defenses must always increase cost
- Component sums: Verify that parts add up to totals
- Type stability: One test per file using
@inferred
Include comments explaining the physical reasoning:
# W >= 0; defense heights must be non-negative
@test_throws AssertionError FloodDefenses(-1.0, 0, 0, 0, 0)
# 0 <= P < 1; resistance percentage must be a valid fraction
@test_throws AssertionError FloodDefenses(0, 0, 1.5, 0, 0)CI Workflows
Three GitHub Actions run on every PR:
| Workflow | What It Does |
|---|---|
| Tests | Runs test suite on Julia 1.10, 1.11, 1.12 |
| Format | Auto-formats with JuliaFormatter (BlueStyle) |
| Docs | Builds Quarto documentation |
All checks must pass before merging.
Pull Request Workflow
- Fork the repo or create a feature branch
- Make your changes
- Run tests locally:
julia --project test/runtests.jl - Format your code:
format(".", BlueStyle()) - Open a PR against
main - Wait for CI to pass
- The maintainer will review and merge
That’s it. No complex review process – just open a PR and it will be merged once CI passes.