Skip to content

Latest commit

 

History

History
122 lines (73 loc) · 6.19 KB

File metadata and controls

122 lines (73 loc) · 6.19 KB

Contribution Guide

Please read and understand the contribution guide before creating an issue or pull request.

Table of Contents

AI/LLM Usage

If you use AI tools (Claude Code, Cursor, Copilot, etc.) to assist with your contribution, please read and follow our AI/LLM Contribution Policy.

Viability

When requesting or submitting new features, first consider whether it might be useful to others. Think about whether your feature is likely to be used by other users of the project.

Procedure

Before filing an issue:

  • Attempt to replicate the problem, to ensure that it wasn't a coincidental incident.
  • Check to make sure your feature suggestion isn't already present within the project.
  • Check the pull requests tab to ensure that the bug doesn't have a fix in progress.
  • Check the pull requests tab to ensure that the feature isn't already in progress.

Before submitting a pull request:

  • Check the codebase to ensure that your feature doesn't already exist.
  • Check the pull requests to ensure that another person hasn't already submitted the feature or fix.
  • Test your changes locally. As an open source project maintained by volunteers, we rely on contributors to verify their changes before submission. This includes running the test suite and manually testing the feature or fix.

Requirements

  • Follow PSR-12 Coding Standard. Run composer fix to fix most code style issues automatically.

  • Ensure ESLint rules are followed. Run pnpm lint:fix to fix most code style issues automatically.

  • Add tests! - Your patch won't be accepted if it doesn't have tests.

  • Document any change in behaviour - Make sure the README.md and any other relevant documentation are up-to-date. If you are changing the API in some way, please also open an accompanying PR in the api-docs repository.

  • Consider our release cycle - We try to follow SemVer v2.0.0. Randomly breaking public APIs is not an option.

  • One pull request per feature - If you want to do more than one thing, send multiple pull requests.

  • Send coherent history - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting.

Testing, Code Style, and Static Analysis

Backend (PHP)

  • Pest is used for testing. Write feature and/or unit tests.
  • PHP CS Fixer comes as a dev dependency. Run composer fix before you commit.
  • PHPStan is used for static analysis. Run composer analyse and ensure your code has no errors.

Frontend (TypeScript/React)

  • Vitest with Testing Library is used for testing React components.
  • We target 100% test coverage for frontend code. All React components and utilities should have accompanying tests to verify their functionality.
  • Run pnpm verify to check linting, TypeScript errors, and run all tests.
  • Run pnpm test:run SomeFile to run specific tests.

APIs, Backwards Compatibility, and Deprecation

APIs have to accommodate to old clients' requirements as upgrade paths are very slow for some of them.

Deprecations have to be communicated to users upfront.

Note The V1 Web API (public/API/API_*.php files) is in maintenance mode. Bug fixes are acceptable, but new features should be implemented in the V2 JSON:API instead.

Implementation Details

Authorization

Define abilities in policies.

Authorize explicitly in controllers/actions. There is a variety of custom abilities, we don't want to end up in a hit or miss scenario. Do not use authorizeResource() in Controllers' constructor.

Use FormRequests in controllers for validation. Ignore Form Requests' authorization capabilities (should be done in controllers/actions instead).

Controllers, Actions, Reusable Action Classes

Controllers should be slim, start with an ability authorization, even if it's an "always-public" route.

In case of complex procedures, delegate to a reusable Action that can be injected from the container. If too much is going on in a controller's action it might be a good candidate to be extracted into a dedicated action. Especially if it's something that can be reused.

Frontend assets

This is not a Single Page Application. The project uses Inertia.js with React for page components.

Avoid inline styles and custom CSS unless there's a compelling reason. The project uses TailwindCSS and it should cover most styling needs.

The UI is actively migrating from Blade/Livewire to React. All new frontend work should use React with TypeScript and have comprehensive test coverage.

"Management app"

Back-office administration uses Filament. Admin resources, pages, and widgets are located in app/Filament/. Use Filament for internal management tools rather than building custom React admin interfaces.

Routes

Middleware gets applied for basic abilities (guest, auth, can:accessManagementTools) - specific abilities should be authorized in controller actions.

Slugs are kebab-cased and appended to model IDs (which in turn can be hashed/masked). This allows keeping /create, /edit, etc routes without having to deal with conflicts.

Route keys for route model binding should be validated in the respective RouteServiceProvider.

Translating the Application

We welcome contributions to translate the RetroAchievements website into different languages. To get started, please refer to our translations guide for detailed instructions on how to add or update translations.