# Contributing {#contributing}


Pull requests are always welcome. If you fix or improve anything, feel free to float a PR back upstream.


## Getting started {#getting-started}


1. [Fork icey on GitHub](https://github.com/auscaster/icey)
2. Create a feature branch (`git checkout -b my-feature`)
3. Build and run the tests to make sure everything passes before you start:

```bash
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON
cmake --build build --parallel $(nproc)
ctest --test-dir build --output-on-failure
```


## Code style {#code-style}


The project uses `clang-format` with a custom config (`.clang-format` in the repo root). The highlights:

- **C++20**, LLVM base style
- 4-space indent, no tabs
- Allman braces for definitions, K&R for control flow
- Pointer/reference left-aligned (`int* p`, not `int *p`)
- No column limit; manual formatting is preserved
- Constructor initialiser lists: comma-first, one per line

Format your changes before committing:

```bash
clang-format -i src/path/to/file.cpp
```

Repo-specific structure and design rules live in [conventions.md](https://auscaster.com/icey/docs/concepts/conventions.md). Read that alongside this page if you are adding modules, moving public headers, or changing runtime-facing behaviour.


## Commit messages {#commit-messages}


Use [conventional commits](https://www.conventionalcommits.org/): `feat:`, `fix:`, `refactor:`, `test:`, `docs:`, `chore:`, etc. Keep the subject line short, lowercase, imperative mood.

```
fix: resolve null pointer in WebRTC peer connection
refactor: replace raw pointers with unique_ptr in http client
```


## Tests {#tests}


If your change touches runtime behaviour, add or update a test. Tests live in `tests/` and module-local `src/*/tests/` directories and are built when `-DBUILD_TESTS=ON` is set. Run them with:

```bash
ctest --test-dir build --output-on-failure
```


## Documentation {#documentation}


The docs toolchain is pinned under [`docs/package.json`](/icey/docs/_media/4f704660e89abc7aac16.json) and built through the top-level `Makefile`.

Use these commands:

```bash
make docs        # doxygen xml + Sourcey site
make docs-dev    # regenerate xml, then run Sourcey dev server
make docs-api-md # optional: refresh the docs/api markdown mirror
make docs-check  # refresh markdown mirror, build site, and run API overview QA
make docs-docker # same docs build inside the docs container
```

The split is deliberate:

- `docs/sourcey.config.ts` tells Sourcey how to render the site
- Doxygen generates XML under `build/doxygen/xml`
- Sourcey reads that XML directly for the `API Reference` tab
- `docs/api/*.md` is an optional markdown mirror generated by the pinned Moxygen commit in `docs/package.json`
- `make docs-api-md` passes `--source-root $(pwd)` so file-level Doxygen grouping is reconstructed consistently
- `make docs-check` also fails if any top-level module overview table regresses to blank description rows

The normal docs path is `make docs`. Use `make docs-api-md` only when you want the repo-local markdown mirror refreshed as well.


## Release flow {#release-flow}


Write the changelog, set `VERSION`, and run `make release VERSION="$(tr -d '[:space:]' < VERSION)"` before committing the reviewed release candidate. `bash scripts/release-publish-readiness.sh` checks that derived metadata matches the committed version. Push one plain semantic-version tag at the merged `main` commit; the tag workflows pin archive hashes and publish owned channels without a post-tag commit.

Use [releasing.md](https://auscaster.com/icey/docs/concepts/releasing.md) for the exact commands, package registry boundaries, and readback checks.


## Licence {#licence}


By contributing you agree that your work will be licensed under the [LGPL-2.1+](../LICENSE.md) licence.
