Skip to content

Latest commit

 

History

History
183 lines (132 loc) · 8.88 KB

File metadata and controls

183 lines (132 loc) · 8.88 KB

Contributing to Permit.Ecto

Thank you for your interest in contributing to Permit.Ecto! This document provides guidelines and information for contributors.

Code of Conduct

This project adheres to a Code of Conduct. By participating, you are expected to uphold this code.

Getting started

Development environment

Prerequisites

  • Elixir 1.12+ and OTP 24+
    • If implementing a proposed feature requires bumping Elixir or OTP, we're open to considering that.
  • Git
  • PostgreSQL - Required for running tests and development of Ecto-dependent features

Developing and testing the permit_ecto package requires a running Postgres instance as this package provides database integration for Permit's authorization system.

Setup

  1. Clone the repository and install dependencies:

    git clone https://github.com/curiosum-dev/permit_ecto.git
    cd permit_ecto
    mix deps.get
  2. Set up your test database (configure in config/test.exs):

    MIX_ENV=test mix do ecto.create, ecto.migrate
  3. Run tests to ensure everything is working:

    mix test

When running Credo and Dialyzer, please use MIX_ENV=test to ensure tests and support files are validated, too.

How to contribute

Before proceeding: where to discuss things?

The best place to discuss fresh ideas for the library's future and ask any sorts of questions (not strictly constituting an issue as defined below) is the Permit channel in Elixir's Slack workspace. You can also use the appropriate GitHub Discussions channel. We're usually easiest approachable via Slack, though 😉

For example, if you've got a general question about Permit.Ecto's development direction, or about its intended behaviour in a specific scenario, it's more convenient to open up a discussion on Slack (or use GitHub discussions) than to file an issue right away.

However, if there's clearly a bug you'd like to report, or you have a specific feature idea that you'd like to explain, it's perfect material for a GitHub issue inside the project!

Reporting issues

Before creating an issue, please:

  1. Search existing issues to avoid duplicates
  2. Use the issue templates when available
  3. For bug reports, provide detailed information:
    • Elixir/OTP versions
    • Permit.Ecto version
    • Ecto and Postgres versions
    • Minimal reproduction case
    • Expected vs actual behavior
  4. For feature requests, check against roadmap outlined in main Permit README and provide the following:
    • Purpose of the new feature
    • Intended usage syntax (or pseudocode)
    • Expected implementation complexity (if possible to gauge)
    • Expected impact on other existing features and backward compatibility
    • How it relates to Ecto query generation and authorization scoping

Pull requests

Before you start

  • Check existing PRs to avoid duplicate work
  • Open an issue for discussion on significant changes (we follow the 1 issue <-> 1 PR principle)
  • Follow our coding standards (see below)

PR process

  1. Fork the repository and create a feature branch
  2. Make your changes with clear, focused commits
  3. Add tests for new functionality
  4. Update documentation as needed, including README
  5. Run the full test suite as well as all static checks
  6. Submit your PR with a clear description

PR Requirements

  • Code compiles without warnings (mix compile --warnings-as-errors)
  • Tests pass (mix test)
    • Includes added tests to new features and fixed bugs.
    • Tests pass for all combinations of tool versions covered by the CI matrix (see .github/workflows/elixir.yml).
  • Code follows style guidelines (MIX_ENV=test mix credo)
    • Run Credo in test environment to ensure tests and support code adheres to style rules as well.
  • Types are correct (MIX_ENV=test mix dialyzer)
    • Run Credo in test environment to ensure tests and support code has correct typing as well.
    • Precise typing is encouraged for all newly added modules and functions.
    • Ignores are permitted with an inline comment with proper justification.
  • Documentation is updated: a bare minimum is updates to affected public API parts
    • Functions intended for usage by application code must have descriptions of arguments, purpose, and usage examples.
    • For crucial additions to features, README must also be updated.
  • Database tests include proper cleanup and isolation
  • Commit messages are clear and descriptive
    • If already used throughout commit history, use Conventional Commits.
    • Otherwise, use single-line messages formatted as: Commit purpose in imperative mode [#issue_number].
      • Focus on what vs how, and keep it simple
      • Example: Fix incorrect query generation for has_many associations [#123]

Development guidelines

Code style

We use Credo for code analysis:

MIX_ENV=test mix credo

Key principles:

  • Clarity over cleverness - write readable code and avoid introducing new DSLs as much as possible. Permit.Ecto focuses on clean Ecto query generation from authorization rules. Prefer pure Elixir for easier debugging and code clarity. Use macros wisely and only when needed.
  • Minimal dependencies - Permit.Ecto should only rely on what's needed for its Ecto integration scope. Core Permit functionality belongs in the main permit package, while Phoenix-specific features belong in permit_phoenix.
  • Follow Elixir conventions - use standard patterns and don't fight the platform. Avoid common Elixir anti-patterns. Write functional, idiomatic Elixir code.
  • Follow Ecto conventions - use Ecto query patterns appropriately, handle dynamic queries safely, and ensure proper query composition.
  • Avoid RDBMS-specific features - whenever possible, implement features in a way that's independent on whether Postgres, MySQL or any other DB is used.
  • Document public APIs - include @doc and @moduledoc written as if you were the one who is to read them. Avoid @moduledoc false unless a module is deeply private. As long as typing in Elixir relies on Dialyzer, do type with @spec extensively, use Permit.Types and Permit.Ecto.Types wherever applicable, and avoid typing with the likes of map(), any(), or term() where possible.
  • Handle errors gracefully - always consider what's the correct scheme of error propagation. There is no globally assumed convention of whether to use error tuples or exceptions, you should use whatever feels appropriate and in line with adjacent elements of the system.

Testing

  • Write tests for all new functionality and bug fixes
  • Maintain high test coverage
  • Use descriptive test names
  • Test both success and failure cases
  • Test query generation correctness - ensure generated Ecto queries match expected authorization scoping
  • Test association handling - verify proper query generation for has_one, has_many, and belongs_to relationships
  • Clean up test data - use correct setup to ensure tests don't leave side effects in the database

Commit messages

Follow Conventional Commits format if already used in the repository. Otherwise, write single-line messages in imperative mode and mark related issue number with [#number].

Branching strategy

Follow Conventional Branch format if already used in the repository. Otherwise, use issue_number-issue_name as branch names. Create feature branches off main or master and avoid a nested branch tree.

Release process

Releases are handled by maintainers:

  1. Version bump in mix.exs
  2. Update CHANGELOG.md
  3. Create GitHub release
  4. Publish to Hex.pm

Community

Getting help

Recognition

We are eager to publicly recognize your valuable input as a Permit.Ecto contributor! Your contributions will be highlighted in subsequent release notes, as well as blog posts announcing community contributions.

Questions?

Feel free to:

Thank you for contributing to Permit.Ecto! 🎉