How to contribute new features
From LimeSurvey Manual
Contribution process
We welcome bug fixes and new features from the community. If you want your feature to become part of LimeSurvey, so that it keeps working when you update, proceed as follows:
- Use the latest version from GitHub for your development.
- Open a ticket in the bug tracker in the right project:
- Bug reports for a bug
- Feature requests for a new feature
- Development for internal changes (refactoring etc.)
- For a new feature, describe it as detailed as possible, including how you want to implement it: what code you want to add, which files you plan to change, which parts of the user interface have to be extended.
- We will assign the ticket to one of our developers and discuss your approach. Tell us about your plans before you start coding. Otherwise you might implement it in a way we cannot accept, for example because of security problems.
- Once the implementation is agreed, write the code and create a pull request on GitHub (see below). Follow the Standard for Git commit messages.
- Write unit or functional tests for your new functionality. If you don't know how, read Regression and unit tests or ask on the LimeSurvey Discord server.
- A developer reviews your code. After any open points are solved, your feature will be part of the next release.
For bug fixes that are small and clear, you can create the pull request right away, together with the bug report.
Please put new features into new files as much as possible.
Internal contribution process
(This section is only relevant for employees of LimeSurvey GmbH.)
As above, but with branches in the main repository instead of a fork, following gitflow. Especially:
- New features are always on feature branches.
- New features are never merged into develop-minor or develop-major before QA.
- Bug fixes are in bug branches and always have a pull request on GitHub for code review and comments.
- Pull requests with a single author are squashed and merged.
- Trivial fixes can be applied in the development branch directly (trivial fixes are e.g. one line, or changing a localization typo in multiple lines).
Most importantly, nothing is ever merged into master or the develop branches without:
- QA
- Code review
How to create a pull request?
- Find out the branch your change is based on:
- New backward-compatible features: develop-minor
- New backward-incompatible features: develop-major
- Bug fixes: master
- Create a separate branch from it for your bug fix or feature (see Branch naming) and develop on that branch.
- Push your branch to the repository (internal developers) or to your personal fork (external contributors).
- Open https://github.com/LimeSurvey/LimeSurvey, go to the Pull requests tab and click New pull request.
- Select the branch from step 1 as base and your branch as compare.
- For the title, use the same format as required in the Standard for Git commit messages. The description is pre-filled with a template: follow it, link the Mantis issue, and describe what you changed and how to test it.
- Create the pull request.
New pull requests automatically get the labels Needs code review and Needs testing. The automated checks start right away. If one of them fails, fix it before asking for a review. What each check does and how to reproduce it locally is described in Continuous integration.
How to merge a pull request?
After a pull request has been reviewed and tested, the responsible person merges it. Rules:
- Always squash when merging on GitHub (there is an option in the dropdown of the merge button).
- Always make sure that the squashed commit has a proper commit message.
- If the pull request fixes several issues, all of them must be part of the commit message.
Branch naming
Bug branches are named bug/12345-short-description, where the number is the related Mantis issue on bugs.limesurvey.org.
Feature branches are named feature/12345-short-description, where the number is the related Mantis issue on bugs.limesurvey.org.
See also these gitflow examples.
Specification
All new features should be specified using scenarios or user stories.
QA
New features must be tested by a QA team or tester before they are merged. The tester should not be part of the same sprint team that developed the feature.
Documentation
Make sure all PHPDoc blocks are correct.
All relevant manual pages should be updated before merging. Say from which version on the new feature is available.
Tests
Acceptance tests
Each new feature should have a folder with acceptance tests. The folder name includes the ticket number, for example:
tests/functional/acceptance/15532-em-warnings/<test classes>
The acceptance tests correspond to the user stories in the specification. They make sure that the feature keeps working as intended when the code is changed later.
Add the new test files to one of the functional test suites in phpunit.xml. Otherwise they never run in CI.
Unit tests
Unit tests go into tests/unit/, in the subfolder that matches the code under test (for example tests/unit/services/ for application/models/services/).
How to run and write tests is described in Regression and unit tests.
Static analysis
Check your code with the analysis tools before you push: correct docblocks, no unused variables, and PSR-12 code style. CI runs the same tools on every pull request, see Continuous integration.
Install the tools with:
composer install
This installs the development tools into vendor/. The vendor/ folder is part of the repository and contains only the production packages (installed with --no-dev). Do not commit the changes that the development install makes in vendor/, especially in vendor/composer/.
Code sniffer
Home page: https://github.com/PHPCSStandards/PHP_CodeSniffer
PHP_CodeSniffer checks your code for style violations. Check a file or folder with:
./vendor/bin/phpcs --standard=tests/rulesets/phpcs_ruleset.xml <file or folder>
Fix most violations automatically with:
./vendor/bin/phpcbf --standard=tests/rulesets/phpcs_ruleset.xml <file or folder>
Example output:
---------------------------------------------------------------------------------------------------
FOUND 273 ERRORS AND 98 WARNINGS AFFECTING 260 LINES
---------------------------------------------------------------------------------------------------
2 | ERROR | [ ] Missing file doc comment
3 | ERROR | [ ] Missing doc comment for class QuestionEditorController
5 | ERROR | [ ] Missing doc comment for function accessRules()
25 | ERROR | [ ] Missing parameter comment
25 | ERROR | [x] Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
26 | ERROR | [ ] Tag @return cannot be grouped with parameter tags in a doc comment
Setup in PhpStorm: https://www.jetbrains.com/help/phpstorm/using-php-code-sniffer.html
Mess detector
Home page: https://phpmd.org/
PHP Mess Detector finds unused variables and code that is too complex. Run it with:
./vendor/bin/phpmd <file or folder> text tests/rulesets/phpmd_ruleset.xml
Newer parts of the code, such as application/models/services/ and application/libraries/Api/, are checked with the stricter rule set tests/rulesets/phpmd_ruleset_strict.xml (see the test script in composer.json).
Example output:
application/controllers/QuestionEditorController.php:240 The method actionSaveQuestionData() has an NPath complexity of 8652. The configured NPath complexity threshold is 200.
application/controllers/QuestionEditorController.php:240 The method actionSaveQuestionData() has 142 lines of code. Current threshold is set to 100. Avoid really long methods.
application/controllers/QuestionEditorController.php:444 Avoid unused parameters such as '$returnArray'.
Setup in PhpStorm: https://www.jetbrains.com/help/phpstorm/using-php-mess-detector.html
Psalm
Home page: https://psalm.dev/
Psalm makes sure your docblocks are correct and that you never access anything that could be null. Run it with:
./vendor/bin/psalm -c psalm-all.xml <file to check>
psalm-all.xml is the configuration CI uses to check the whole application/ folder. psalm-strict.xml applies stricter rules to a list of newer files and folders, such as application/libraries/Api/.
Example output:
INFO: MissingReturnType - application/controllers/QuestionEditorController.php:54:21 - Method QuestionEditorController::actionView does not have a return type, expecting void
ERROR: PossiblyNullPropertyFetch - application/controllers/QuestionEditorController.php:58:24 - Cannot get property on possibly null variable $oSurvey of type Survey|null
Setup in PhpStorm: https://www.jetbrains.com/help/phpstorm/using-psalm.html
Release process
LimeSurvey has three kinds of releases (see also the current release schedule):
| Release | Contains | Branch | When |
|---|---|---|---|
| Patch release | Bug fixes | master |
Every Monday, for all supported versions |
| Minor release | New features that keep backward compatibility | develop-minor, merged into master |
About every 8 weeks, or as needed |
| Major release | Changes that break backward compatibility, e.g. dropping support for a PHP version or a browser | develop-major |
When such changes are ready |
This means:
- A bug fix that is merged into
masteris released the following Monday. - A new feature is released with the next minor or major release after it has passed QA and code review and was merged into its develop branch.
