Contributing to AshOaskit
View SourceBug fixes, documentation improvements, and focused feature proposals are welcome.
How Can I Contribute?
Reporting Bugs
Before submitting a bug report:
- Check existing issues first
- Include your Elixir and OTP versions (
elixir --version) - Provide minimal reproduction steps
- Include the full error message and stacktrace
Suggesting Enhancements
- Open an issue describing the enhancement
- Explain the use case and benefits
- Consider how it fits with existing functionality
Pull Requests
- Fork the repository
- Create a feature branch (
git checkout -b feat/amazing-feature) - Make your changes
- Run quality checks (
mix check) - Commit using conventional commits
- Push and open a PR
Development Setup
git clone https://github.com/futhr/ash_oaskit.git
cd ash_oaskit
mix deps.get
mix test
Development Workflow
mix test # Run tests
mix coveralls.html # Run tests with coverage
mix check # Run full quality suite
MIX_ENV=no_optional mix compile --no-optional-deps --warnings-as-errors
mix docs # Generate documentation
mix dialyzer # Run dialyzer
mix credo --strict # Run credo
Code Quality Requirements
All contributions must:
- Pass
mix format --check-formatted - Pass
mix credo --strict - Pass
mix dialyzer - Have 100% test coverage for new code
- Include
@specfor all public functions - Document public functions where the name and types do not tell the whole story
Elixir Style
Use mix format and the project's Credo configuration as the enforceable baseline,
with the community Elixir Style Guide
as supplementary guidance.
- Limit nesting to two levels inside functions. Credo counts
if,unless,case,cond, anonymous functions,for, andwithtoward this limit. - Prefer pattern-matched function clauses and guards for dispatch on data shapes.
- Use pipelines for successive transformations of the same value.
- Use
Map.update,put_in, andupdate_ininstead of manually rebuilding each layer of a nested map. Preserve the intended behavior for missing keys. - Extract helpers around meaningful operations, not merely to hide nesting.
- Keep explicit conditionals when they express the decision more clearly.
Commit Messages
We use Conventional Commits:
feat:New featuresfix:Bug fixesdocs:Documentation changesrefactor:Code refactoring (no functional changes)test:Test additions or changeschore:Maintenance tasks (deps, CI, etc.)
Examples:
feat: add support for custom type mappings
fix: handle nil values in constraint processing
docs: improve TypeMapper documentation
test: add coverage for edge cases in V31 generatorProject Structure
lib/
├── ash_oaskit.ex # Main module with public API
├── ash_oaskit/
│ ├── support/controller.ex # Phoenix controller
│ ├── generators/
│ │ ├── v30.ex # OpenAPI 3.0 generator
│ │ └── v31.ex # OpenAPI 3.1 generator
│ ├── open_api.ex # Core spec generation logic
│ └── core/type_mapper.ex # Ash type to JSON Schema mapping
└── mix/
└── tasks/
├── ash_oaskit.generate.ex # Mix task for CLI generation
└── ash_oaskit.install.ex # Igniter installation taskTesting Guidelines
- Write tests for all new functionality
- Use descriptive test names that explain the behavior
- Group related tests with
describeblocks - Use property-based assertions when exact output varies
- Test both success and error cases
Keep tests focused on observable behavior:
describe "feature_name/1" do
test "uses the configured JSON:API field name" do
assert Config.json_field_name(Post, :published_at) == "publishedAt"
end
test "rejects an unsupported OpenAPI version" do
assert_raise ArgumentError, fn ->
AshOaskit.spec(domains: [Blog], version: "2.0")
end
end
endDocumentation
- All public modules must have
@moduledoc - Write module documentation around the reader's task, not the source layout
- Add examples where they clarify behavior or configuration
- Keep implementation details out of public documentation unless callers rely on them
Releasing
Publication is allowed only from an annotated vVERSION tag whose commit is on protected
main. The publish workflow reruns the complete gate, builds the package outside the repository,
publishes through the protected hex-publish environment, downloads the registry tarball, compares
it byte-for-byte with the validated build, and attests those registry bytes.
The canonical repository must keep these external controls enabled:
- protect
main, require every current Continuous Integration job, require the branch to be up to date, and forbid force pushes and deletion; - protect
v*tags from creation except by maintainers and forbid updates and deletion; - configure
hex-publishwith administrator bypass disabled, a required reviewer, and av*deployment-tag policy; - scope
HEX_API_KEYto the environment and a Hex key that can publish onlyash_oaskit.
Verify the controls before every release:
mix run --no-start scripts/verify_release_controls.exs
Run this with a maintainer's authenticated gh CLI. It checks effective rulesets,
current CI job names, immutable release tags, environment approval, deployment tag
policy, and the presence of the environment secret. GitHub cannot reveal an existing
secret for migration: set a package-scoped key in hex-publish manually, then remove
the repository-scoped copy. Confirm the key's package permissions in Hex itself.
The environment reviewer is the repository owner; self-review remains allowed so
a sole maintainer can explicitly approve a release. Administrator bypass is disabled.
Then update the version and changelog, merge the release commit to main, wait for required CI,
and create an annotated tag with git tag -a vVERSION -m vVERSION. Never move or reuse a tag.
Release Process
Releases are managed by maintainers using git_ops:
- Run
mix checkand the release-controls verifier above. - Preview changes with
mix git_ops.release --dry-run --output /path/to/release-preview. - Apply the proposed version/changelog changes on a branch and merge them through a reviewed PR.
- After required CI passes on
main, create and push only the annotated release tag.
Do not use the local mix release alias to push a release commit directly to protected main.
It commits and tags locally and does not replace the reviewed release process.
Questions?
Feel free to open an issue for questions or join discussions in existing issues.