# Sonata project contribution Thanks for your interest in Sonata projects! This document is about issues and pull requests. ## Summary * [Issues](#issues) * [Pull Requests](#pull-requests) * [Code Reviews](#code-reviews) ## Issues First, check if you are up to date: is your version still supported, and are you using the latest patch version? GitHub Issues is for **issues**, as opposed to question on how to use Sonata. If you are not sure this is a bug, or simply want to ask such a question, please post your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/sonata), using the `sonata` tags. If you happen to find a bug, we kindly request you report it. However, before submitting it, please check the [project documentation available online](https://sonata-project.org/bundles/). Then, if it appears that it is indeed a real bug, you may report it using Github by following these points are taken care of: * Check if the bug is not already reported! * The title sums up the issue with clarity. * A description of the workflow needed to reproduce the bug. Please try to make sentences, dumping an error message by itself is frowned upon. * If your issue is an error page, you must provide us with a stack trace. With recent versions of Symfony, you can even get stack traces as plain text at the end of the page. Just look for "Stack Trace (Plain Text)", and copy/paste what you see. **Do not** make a screenshot of the stack trace, as screenshots are not indexed by search engines and will make it difficult for other people to find your bug report. If you have an issue when using the Symfony CLI, use the `-vvv` option to get a stack trace. * Screenshots should be considered additional data, and therefore, you should always provide a textual description of the bug. It is strongly recommended to provide them when reporting UI-related bugs. * If you need to provide code, make sure you know how to get syntactic coloration, in particular with [fenced code blocks](https://help.github.com/articles/creating-and-highlighting-code-blocks/). When you feel the code is to long, use external code pastebin like https://gist.github.com/ or http://hastebin.com/ . If this is not sufficient, just create a repository to show the issue. > _NOTE:_ Don't hesitate to give as much information as you can (OS, PHP > version, extensions...) ## Pull Requests All the sonata team will be glad to review your code changes propositions! :smile: But please, read the following before. ### The content #### Coding style Each project follows [PSR-1](http://www.php-fig.org/psr/psr-1/), [PSR-2](http://www.php-fig.org/psr/psr-2/) and [Symfony Coding Standards](http://symfony.com/doc/current/contributing/code/standards.html) for coding style, [PSR-4](http://www.php-fig.org/psr/psr-4/) for autoloading. Please [install PHP Coding Standard Fixer](http://cs.sensiolabs.org/#installation) and run this command before committing your modifications: ```bash php-cs-fixer fix --verbose ``` #### The documentation The documentation is mostly written with the `rst` format, and can be found in the `Resources/doc` directory. You can test the doc rendering with the `make docs` command, but to do this, you will need [Sphinx][sphinx_install]. Just like php dependencies can be managed with Composer, python dependencies can be managed with [pip][pip_install]. To get sphinx, simply run the following command. ```bash pip install --requirement Resources/doc/requirements.txt --user ``` Some python binaries should be downloaded to `~/.local/bin` for Linux or `~/Library/Python/2.7/bin` for Mac OS, [modify your `$PATH` environment variable](http://www.linfo.org/path_env_var.html) so that it contains this path and then, from the root of the project, run `make docs` If `make docs` is successful, you should be able to see your modifications: ```bash $YOUR_FAVORITE_BROWSER Resources/doc/_build/html/index.html ``` If your PR contains a new feature, you must add documentation for it. Of course, you can also create PRs consisting only in documentation changes. Documentation contributions should comply with [the Symfony documentation standards][sf_docs_standards]. #### The tests If your PR contains a fix, tests should be added to prove the bug. If your PR contains an addition, a new feature, this one has to be fully covered by tests. Some rules have to be respected about the test: * Annotations about coverage are prohibited. This concerns: * `@covers` * `@coversDefaultClass` * `@coversNothing` * `@codeCoverageIgnore` * `@codeCoverageIgnoreStart` * `@codeCoverageIgnoreEnd` * All test methods should be prefixed by `test`. Example: `public function testItReturnsNull()`. * All test method names must be in camel case format. * As opposed, the `@test` annotation is prohibited. * Most of the time, the test class should have the same name as the targeted class, suffixed by `Test`. * The `@expectedException*` annotations are prohibited. Use `PHPUnit_Framework_TestCase::setExpectedException()`. ##### Using test doubles Since version 4.5, PHPUnit requires and [integrates](https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.prophecy) the [phpspec/prophecy](https://github.com/phpspec/prophecy). Historically, Sonata has been using [the built-in test doubles implementation](https://phpunit.de/manual/current/en/test-doubles.html), but [has decided to move to Prophecy](https://github.com/sonata-project/dev-kit/issues/89), which is more concise than its built-in counterpart is most cases. This means the current Sonata codebase currently uses both implementations. If you want to contribute a test that uses test doubles, please follow these rules : 1. All new test classes MUST use Prophecy. 2. If you are changing an existing test method, you MUST use the same implementation it already uses, and focus on the goal of your PR and only on that. 3. If you are changing an existing test class, you MUST use the same implementation it already uses, to be more consistent. 4. You MAY submit a PR that migrates a test class from the built-in test double implementation to Prophecy, but it must migrate it entirely. The PR should only be about the migration. ### Writing a Pull Request #### The subject Ideally, a Pull Request should concern one and **only one** subject, so that it remains clear, and independent changes can be merged quickly. If you want to fix a typo and improve the performance of a process, you should try as much as possible to do it in a **separate** PR, so that we can quickly merge one while discussing the other. The goal is to have a clear commit history and make a possible revert easier. If you found an issue/typo while writing your change that is not related to your work, please do another PR for that. In some rare cases, you might be forced to do it on the same PR. In this kind of situation, please add a comment on your PR explaining why you feel it is the case. #### The Change log For each PR, a change log must be provided. There are few cases where no change log is necessary: * When you fix a bug on an unreleased feature. * When your PR concerns only the documentation (fix or improvement). **Do not** edit the `CHANGELOG.md` directly though, because having every contributor write PR with changes in the same file, at roughly the same line is a recipe for conflicts. Instead, fill in the dedicated section that should appear in a textaread when submitting your PR. Your note can be put on one of these sections: * `Added` for new features. * `Changed` for changes in existing functionality. * `Deprecated` for deprecation of features that will be removed in next major release. * `Removed` for deprecated features removed in this release. * `Fixed` for any bug fixes. * `Security` to invite users to upgrade in case of vulnerabilities. More information about the followed changelog format: [keepachangelog.com](http://keepachangelog.com/) #### The base branch Before writing a PR, you have to check on which branch your changes should be based. Each project follows [semver](http://semver.org/) convention for release management. Here is a short table resuming on which you have to start: Kind of modification | Backward Compatible (BC) | Type of release | Branch to target | Label | -------------------- | ------------------------ | --------------- | ----------------------- | ----- | Bug fixes | Yes | Patch | `3.x` | | Bug fixes | Not on legacy | Patch | `3.x` | | Bug fixes | No (Only if no choice) | Major | `master` | | Feature | Yes | Minor | `3.x` | | Feature | No (Only if no choice) | Major | `master` | | Deprecation | Yes (Have to) | Minor | `3.x` | | Deprecation removal | No (Can't be) | Major | `master` | | Notes: * Branch `3.x` is the branch of the **latest stable** patch releases and has to be used for Backward Compatible bug fixes only. * Branch `3.x` is the branch of the **latest stable** minor release and has to be used for Backward compatible enhancement PRs. **No bug fix will be accepted here**, except if the bug fix concerns `3.x` and **only this one**. Bug fixes merged on `3.x` will be ported on other branches by fallback merging. * If you PR is not **Backward Compatible** but can be, it **must** be: * Changing a function/method signature? Prefer create a new one and deprecate the old one. * Code deletion? Don't. Please deprecate it instead. * If your BC PR is accepted, you can do a new one on the `master` branch which removes the deprecated code. * SYMFONY DOC REF (same logic)? If you have a non-BC PR to propose, please try to create a related BC PR first. This BC PR should mark every piece of code that needs to be removed / uncommented / reworked in the corresponding non-BC PR with the following marker comment : `NEXT_MAJOR`. When the BC PR is merged in the stable branch, wait for the stable branch to be merged in the unstable branch, and then work on your non-BC PR. For instance, assuming you want to introduce a new method to an existing interface, you should do something like this: ```php