Contributing to AshOaskit

View Source

Bug 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

  1. Fork the repository
  2. Create a feature branch (git checkout -b feat/amazing-feature)
  3. Make your changes
  4. Run quality checks (mix check)
  5. Commit using conventional commits
  6. 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 @spec for all public functions
  • Document public functions where the name and types do not tell the whole story

Commit Messages

We use Conventional Commits:

  • feat: New features
  • fix: Bug fixes
  • docs: Documentation changes
  • refactor: Code refactoring (no functional changes)
  • test: Test additions or changes
  • chore: 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 generator

Project Structure

lib/
 ash_oaskit.ex              # Main module with public API
 ash_oaskit/
    controller.ex          # Phoenix controller
    generators/
       v30.ex             # OpenAPI 3.0 generator
       v31.ex             # OpenAPI 3.1 generator
    open_api.ex            # Core spec generation logic
    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 task

Testing Guidelines

  • Write tests for all new functionality
  • Use descriptive test names that explain the behavior
  • Group related tests with describe blocks
  • 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
end

Documentation

  • 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-publish with administrator bypass disabled, a required reviewer, and a v* deployment-tag policy;
  • scope HEX_API_KEY to the environment and a Hex key that can publish only ash_oaskit.

Verify the controls before every release:

gh api repos/futhr/ash_oaskit/environments/hex-publish
gh api repos/futhr/ash_oaskit/environments/hex-publish/deployment-branch-policies
gh api repos/futhr/ash_oaskit/branches/main/protection
gh api repos/futhr/ash_oaskit/rulesets

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:

  1. Ensure all tests pass: mix check
  2. Run mix release (alias for mix git_ops.release) — updates changelog, bumps version, commits, and tags
  3. Push with tags: git push --follow-tags
  4. CI will publish to Hex.pm on the v* tag

Questions?

Feel free to open an issue for questions or join discussions in existing issues.