We highly appreciate it when developers help us by providing Pull Requests against the Mautic code base. In order to make this process as smooth as possible for everyone, we kindly ask you to follow this process step by step.
Before working on a change, check to see if someone else also raised the topic or maybe even started working on a PR by searching on GitHub.
Skip this section if you're not planning to build a new feature.
Do you want to add a new feature to Mautic? Keep in mind that there are many people requesting new features, so we can only add a limited amount of features in new releases.
Please check our Roadmap and existing Feature Requests to see if someone else has already suggested similiar functionality and/or is already working on it. If not, we kindly ask you to first create a new Feature Request in the appropriate section in the Community Forums, so that it can be discussed by the community prior to development work being done.
Features that are determined not to fit within the direction of the Mautic Core goals are more than welcome to be created as plugins instead.
You will need to sign the Mautic Contributors Agreement in order to contribute code to Mautic (which can be done online).
For installing the software stack, please see the Local environment setup instructions.
git clone https://github.com/USERNAME/mautic.git
Before working on a PR, you must determine on which branch you need to work. Mautic follows Semantic Versioning, which is best illustrated by an example. Let's say we just released a 3.0.0 version of Mautic, the following would apply:
|Mautic version||Breaking changes/features allowed?||New features/enhancements allowed?||Bug fixes allowed?|
You can determine on which branch to work as follows:
3.0(for example), if you are fixing a bug for an existing version of Mautic
staging, if you are adding a new feature
cd mautic composer install
https://mautic.ddev.sitedepending on your environment, and follow the steps to install Mautic locally.
Each time you want to work on a PR for a bug or on an enhancement, create a topic branch:
git checkout -b BRANCH_NAME staging
Or, if you want to provide a bug fix for the
3.0 branch, first track the remote
3.0 branch locally:
git checkout -t origin/3.0
Then create a new branch off the
3.0 branch to work on the bug fix:
git checkout -b BRANCH_NAME 3.0
Use a descriptive name for your branch (issue_XXX where XXX is the issue number is a good convention for bug fixes).
The above checkout commands automatically switch the code to the newly created branch (check the branch you are working on with
Work on the code as much as you want and commit as much as you want; but keep in mind the following:
Sometimes, a PR needs a migration. A simple example is when a country's regions are updated. Let's say a region contains a typo,
Colmbra should be
Coimbra. What if the Mautic instance already has values in the database with the old value (
Colmbra in this case)? That's where migrations come in handy. Every time a user updates their Mautic instance, migrations run automatically.
You can skip this step if you believe you don't need migrations in your PR.
An example migration scenario + code can be found here.
In order to create a migration, you can follow these steps:
bin/console doctrine:migrations:generatein your terminal. A new migration file will now be prepared for you:
$ bin/console doctrine:migrations:generate Generated new migration class to "/var/www/html/app/migrations/Version20201017195540.php"
Open the file that was just created. You will see it has two functions,
preUp()allows you to define scenarios where the migration should or should not run (e.g. only when a certain database table exists).
up()runs the actual migration and allows you to do changes in Mautic's database. You can either take inspiration from other migrations in the
app/migrationsfolder or learn more about migrations in Doctrine's documentation.
migrations:execute --up VERSION. If all looks good, you can roll back your changes with
migrations:execute --down VERSION.
You're almost ready to submit your pull request! There's three things we still need to look into:
In order to keep Mautic stable and easy to maintain, we have a hard requirement to apply the appropriate Code Standards and to write automated tests. We can't accept features and/or enhancements without appropriate tests, as it would put the stability of Mautic in danger. Why? When you try to build something in a specific part of the application, you might accidentally break another feature. With automated tests, which go through most aspects of the application, we prevent this as much as possible.
All code styling is handled automatically by the aforementioned git hook. If you setup git hook correctly (which is true if you ever run
composer update before creating a pull request), you can format your code as you like - it will be converted to Mautic code style automatically.
Each new feature should include a reference to a pull request in our End User Documentation repository or Developer Documentation repository if applicable. Any enhancements or bugfixes affecting the end-user or developer experience should also be accompanied by a PR updating the relevant resources in the Documentation.
All code contributions (especially enhancements/features) should include adequate and appropriate unit tests using PHPUnit and/or Symfony functional tests. Pull Requests without these tests will not be merged. See below for more extensive information on Automated Tests.
Before submitting your PR, update your branch (needed if it takes you a while to finish your changes):
git checkout staging git fetch upstream git merge upstream/staging git checkout BRANCH_NAME git rebase staging
staging with the branch you selected previously (e.g.
3.0) if you are working on a bug fix.
When doing the rebase command, you might have to fix merge conflicts. git status will show you the unmerged files. Resolve all the conflicts, then continue the rebase:
git add ... # add resolved files git rebase --continue
Check that all tests still pass and push your branch remotely:
git push --force origin BRANCH_NAME
You can now make a pull request on the
mautic/mautic GitHub repository.
Take care to point your pull request towards
mautic:3.0 if you want the core team to pull a bug fix based on the
To ease the core team work, always include the modified components in your pull request message and provide steps how to test your fix/feature. Keep in mind that not all testers have a thorough knowledge of all of Mautic's features, therefore clear testing steps are crucial!
We ask all contributors to follow some best practices (TODO LINK) to ensure a constructive feedback process.
If you think someone fails to keep this advice in mind and you want another perspective, please join the #dev channel on Mautic Slack.
The product team is responsible for deciding which PRs get merged, so their feedback is the most relevant. So do not feel pressured to refactor your code immediately when someone provides feedback.
Based on the feedback on the pull request, you might need to rework your PR. Before re-submitting the PR, rebase with
upstream/3.0, don't merge; and force the push to the origin:
git rebase -f upstream/staging git push --force origin BRANCH_NAME
When doing a push --force, always specify the branch name explicitly to avoid messing other branches in the repository (--force tells Git that you really want to mess with things so do it carefully).
If you want to test Pull Request from other developers, see Testing Pull Requests.
Before executing unit tests, copy the
.env.dist file to
.env then update to reflect your local environment configuration.
Running functional tests without setting the .env file with a different database will result in the configured database being overwritten.
To run the entire test suite:
bin/phpunit --bootstrap vendor/autoload.php --configuration app/phpunit.xml.dist
To run tests for a specific bundle:
bin/phpunit --bootstrap vendor/autoload.php --configuration app/phpunit.xml.dist --filter EmailBundle
To run a specific test:
bin/phpunit --bootstrap vendor/autoload.php --configuration app/phpunit.xml.dist --filter "/::testVariantEmailWeightsAreAppropriateForMultipleContacts( .*)?$/" Mautic\EmailBundle\Tests\EmailModelTest app/bundles/EmailBundle/Tests/Model/EmailModelTest.php
If you plan on running the acceptance test suite, you'll need to have the Selenium Server Standalone installed and the Chrome WebDriver available locally.
If you're on a Mac and you use Homebrew, you can install Selenium by running
brew install selenium-server-standalone.
You'll also need to download the latest Chrome WebDriver which can also be installed with:
brew cask install chromedriver
If installing manually, Unzip and move the
chromedriver file to
Once you have Selenium installed and the WebDriver available at the specified location, open and modify the plist file found at
<dict><array> block under
ProgramArguments, add the following after the line containing
... <string>-Dwebdriver.chrome.driver=/usr/local/Cellar/selenium-server-standalone/drivers/chromedriver</string> ...
If installing via Homebrew, the path to use will be: /usr/local/bin/chromedriver
With that completed, you may now start the Selenium server using
brew services start selenium-server-standalone.
Follow the standard installation procedure for Selenium server standalone. Ensure that you have the chrome driver available, and startup the server with the following command:
java -jar -Dwebdriver.chrome.driver=/path/to/chromedriver /full/path/to/selenium-server-standalone.3.x.x.jar
All test suites can be executed by running
bin/codecept run from the project root. Optionally, you can specify running just the
unit test suites by adding one of those words after the
Mautic uses PHPSTAN for some of its parts during continuous integration tests. If you want to test your specific contribution locally, install PHPSTAN globally with
composer global require phpstan/phpstan-shim.
Mautic cannot have PHPSTAN as its dev dependency, because it requires PHP7+. To run analysis on a specific bundle, run
~/.composer/vendor/phpstan/phpstan-shim/phpstan.phar analyse app/bundles/*Bundle
Found errors? Think you can improve this documentation? edit this page