Read this guide if
Guide assumptions
This guide assumes that you:
The contribution process starts with a bug you want to fix or an idea that you want to implement. If you don't have one, feel free to pick an open ticket on github.com/matomo-org/matomo/milestones.
Once you've decided on something, continue below.
Before you can start contributing you need to get setup with git & GitHub. If needed, you can create a GitHub account here.
While logged in GitHub, visit Matomo's repository. In the upper right corner there is a Fork button. Click it. Github will copy the repository into your account. This copy (or fork) is the one you will work on. If you don't know forks, read more about forks on GitHub.
When committing, git will need to know your username and email. To set them, run the following commands:
git config --global user.name John Doe
git config --global user.email john@example.com
Clone your Matomo fork (replace myusername
with you GitHub user name):
git clone https://github.com/myusername/piwik
This will copy the entire forked repository (including all history) to the piwik folder on your machine.
Now, we'll run one more command so git remembers the original Matomo repository in addition to your fork:
git remote add upstream https://github.com/matomo-org/matomo
This will save https://github.com/matomo-org/matomo as a remote and name it upstream.
Contributions should not generate PHP errors or warnings. Applying the following settings to your php.ini
file will enable you to catch these errors:
display_errors = On
error_reporting = E_ALL | E_STRICT
Now that you have a copy of the latest Matomo source code, you can start modifying it. For this section, we'll assume there's a bug that you found and want to fix.
Before you start coding, you should make sure to keep your changes separate from the 4.x-dev
branch. This will make it much easier to track the changes specific to your feature since your changes won't be mixed with any new commits to the 4.x-dev
branch from other developers.
We'll give our new branch a name. The branch name ideally always contains the GitHub issue number eg 1111
or m1111
or if it's a Jira issue then eg dev-1111
. Optionally, a descriptive name can be added if wanted. It's not a requirement though since the branch usually exists only temporarily anyway and a PR with description etc often exists too. To add a new branch, run the following command:
git checkout -b bugfix
The checkout command will create a new branch if the -b
option is supplied, otherwise it will try to load an existing branch.
Once you've created a branch, you have a place to start working on the feature. There's nothing special about this part of the process, just fix the bug or finish the feature you're working on.
If you're working on something more complex than a bugfix, you may have the need to keep your new branch updated with changes from the main repository. Keeping your branch up to date is a two-step process.
First, on your 4.x-dev branch, pull changes from the main Matomo repository, nicknamed upstream:
git pull upstream 4.x-dev
Then, on your new branch (bugfix for this tutorial), merge with 4.x-dev:
git merge 4.x-dev
If there are conflicts, you can read this guide: How to resolve Git conflicts.
Now that you've finished the bug fix or new feature (or just part of it), it's time to commit your changes and push them to your fork (the origin
remote).
git add ModifiedFile.php AnotherFile.js
git commit -m 'Added new feature: XYZ (replace this with a descriptive commit message)'
git push
You can read this guide to learn how to commit changes. You can read this guide to learn how to push commits.
In a branch it's fine to commit often and regularly. Later, when the PR will be merged we always squash the PR meaning it will only become one commit and the PR title will become the commit message and the PR will be linked to find more information about the commit if needed. This means the individual commit messages aren't too important but should still be useful.
Now that you have pushed your changes it's time to get your changes merged. To learn more about this read our Pull Requests & Reviews guide.
Every time you change the branch you may need to run composer install (and maybe also npm install). You can automate this task by following these steps:
.git/hooks/compile.sh
containing this content#!/bin/bash
changedFiles="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
runOnChange() {
echo "$changedFiles" | grep -q "$1" && eval "$2"
}
runOnChange package-lock.json "npm install"
runOnChange composer.lock "composer install"
chmod +x .git/hooks/compile.sh
.git/hooks/post-checkout
.git/hooks/compile.sh
It will only be executed when the composer or npm actually changes.
When the version inreases and there is an update, the UI/API will automatically let you know that a migration update needs to be executed. The UI will directly present the update screen where it asks you to execute any outstanding migration updates. The API will return an error message mentioning an update is available and then you need to open the UI to execute this update or run ./console core:update --yes
.
In some cases a required migration update may not be executed. This happens for example if you're working in a different branch where the version number is higher and meanwhile in eg 4.x-dev
an update was added for a lower version number. It also happens when you're working on the current version number and an update is added to the current Matomo version number without increasing the version number. Matomo will then think it already executed the update because the version number didn't increase. You can't really detect when this happens until you run into a problem because for example a column is missing. When this happens, you need to manually set back the version number of your Matomo in the database and run for example below queries:
-- you may need to replace the DB table prefix "matomo_" and you need to set the version number to the correct version number so the not executed update script will be executed.
set @current_version = (select option_value from matomo_option x where option_name = 'version_core');
update matomo_option set option_value ='{new_version_number_you_want_to_set}' where option_name like 'version_%' and option_value = @current_version;
Note: Matomo updates are designed to always be executed multiple times. If the update already happened, for example a column was already added, then Matomo will "detect" this and not error.
Sometimes you may need to run some code on a previous version of Matomo, for example, making a change to Matomo 3. There's no current way to downgrade a database (undo an update) so in this case you'll have to use an upgraded version of Matomo with the older code.
In practice this means creating features that downgrade still work on older versions. The only exception being changing major versions. In this case there will be documentation for how to manually downgrade a database so we can run the older version (for example this faq: https://matomo.org/faq/how-to/how-do-i-downgrade-from-matomo-4-to-matomo-3/).
See our docs on Updates if you need to make changes to matomo for your pull request: https://developer.matomo.org/guides/updates-aka-migrations.
See our dedicated guide for Matomo Code Standards.
See our debugging Matomo core guide.
If you are fixing a bug, it is usually better to also submit a testcase covering this fix. Such a test will be useful to prevent the bug from reappearing again in the future.
If you are adding a new feature to Matomo, adding a new API method or modifying a core Archiving or Tracking algorithm, generally it is required to also submit new or updated unit or integration tests.
For more information about running or creating tests, read our Testing guide.
When naming unit/integration tests, it helps to use the Given, When, Then convention for writing tests.
Tests are critical part of ensuring Matomo stays a stable and useful software platform. We aim to keep test code as clean as production code so it is easy to improve and maintain.
If you've already developed a plugin (congratulations!) which you think could be included in Matomo Core, you can offer it for inclusion.
The adoption of a plugin into Matomo Core requires that we consider such criteria as (but not limited to):
In most cases, it should be enough for your plugin to be available on the Marketplace.