Thanks for taking the time to contribute. Athanor is a young library — PRs, bug reports, and design feedback all welcome.
Development setup
Prerequisites: Elixir ~> 1.17 and Erlang/OTP ~> 26. The CI matrix
runs against Elixir 1.17 / 1.18 / 1.19 on OTP 26 / 27.
git clone https://github.com/Arsenalist/athanor.git
cd athanor
mix deps.get
mix test
Format before pushing:
mix format
Build docs locally to preview:
mix docs && open doc/index.html
Branching & PRs
- Branch off
main. Name branches anything sensible —fix/,feat/,docs/prefixes appreciated but not enforced. - Keep PRs focused: one logical change per PR. Big rewrites get reviewed faster when split.
- Every PR needs a
CHANGELOG.mdentry under## [Unreleased]. Match the section style of prior entries (### Added/### Changed/### Fixed/### Removed). - Every PR runs the CI matrix. PRs that don't pass
mix testormix format --check-formattedwon't be merged.
Tests
- Library code (under
lib/athanor/) needs corresponding tests undertest/athanor/.lib/athanor/foo.ex→test/athanor/foo_test.exs. - Tests are
use ExUnit.Case, async: trueby default. Anything that touchesApplication.get_env/put_envmust reset state inon_exit. - The architecture suite (
test/athanor/tree_architecture_test.exs) enforces the host-agnostic boundary: noAmplifyWeb.*, noAmplify.*, noEcto.*, noJason.*references inlib/athanor/. Consumer-specific bindings go behind runtime config — seeAthanor.Components.Textfor the canonical pattern.
Semantic versioning policy
While in 0.x:
- Minor bump (0.x → 0.x+1) — any public API change, including
breaking changes, new behaviour callbacks, new required fields on
existing structs. Document under
### Changedor### Removed. - Patch bump (0.x.y → 0.x.y+1) — bug fixes, doc improvements, internal refactors that don't change public behavior.
Once we hit 1.0, we switch to strict SemVer (major bumps for breaking
changes).
Public API contract
Anything documented in @moduledoc or with @doc is part of the
public contract. Anything else is implementation detail and may change
between patch releases.
Modules under Athanor.Internal.* (none today, but reserved) are
explicitly private.
Boundary rules
Athanor is host-agnostic by design — it must work in any Phoenix app, not just the one that gave it life. Don't add:
- Runtime dependencies on host applications (Amplify, anyone else's app code).
- Ecto / database concerns. Components accept and emit maps.
- JSON encoding/decoding — the caller supplies maps, the caller
encodes for storage.
Jasonis dev-test only. - Gettext / locale-specific helpers. The host app handles i18n.
The lib/athanor/components/ tree may grow with primitive components
(text, heading, button, divider, columns, image). Heavier or
host-specific components (rich-text editors, asset pickers, product
selectors) stay in consumer apps and integrate via the
Athanor.Component behaviour + :custom field type.
Releases
Releases happen from main only:
- Update version in
mix.exs. - Promote
## [Unreleased]to## [x.y.z] - YYYY-MM-DDinCHANGELOG.md. - Commit + tag (
git tag vX.Y.Z && git push --tags). mix hex.publishfrom the tagged commit.
Reporting bugs
Open an issue with:
- Elixir / OTP /
phoenix_live_viewversions. - Minimal reproduction.
- Expected vs. actual.
Security issues: email instead of opening a public issue — address listed on the maintainer's GitHub profile.
License
By contributing, you agree your changes are licensed under the MIT License that covers the rest of the project.