# Contributing to the RAPTOR code

_This file was copied and slightly modified from the MEQ code version maintained by A. Merle._

* Contributions to this code are welcome, whether they be bugfixes or new additions.
* To avoid duplication, it is strongly recommended that you first discuss the proposed modification by opening an [issue](https://gitlab.epfl.ch/spc/raptor/issues)
* If not done so already, please study and sign a Contributor License Agreement, as discussed below, before pushing proposed modifications to the code in order to clarify ownership and copyright issues.
* Please follow the technical guidelines below to learn how to structure and propose contributions.

## Contributor License Agreement (CLA)
Note that you need a license to use the code in the first place. In addition, contributors pushing code to EPFL need to sign a CLA as specified below.

We use an industry-standard agreements based on the [Apache CLA](https://www.apache.org/licenses/contributor-agreements.html) format. They come in two flavours.

* Individual license agreement [`license/CLA_individual_RAPTOR.md`](license/CLA_individual_RAPTOR.md) (for individual contributors)
* Organization-wide license agreement [`license/CLA_organization_RAPTOR.md`](license/CLA_organization_RAPTOR.md) (signed once for all contributors belonging to the same organization)
* 
Which one to sign depends on your situation.
Please sign one of the two license agreements and return it to olivier.sauter@epfl.ch
 

## Technical guidelines
* It is highly recommended that you use always the same identity to sign your commits for RAPTOR. It should preferably be "FirstName LastName <email.address@work.place>". For example, you can set it up with the following commands:

  ```
  $ git config --global user.name "Antoine Merle"
  $ git config --global user.email "antoine.merle@epfl.ch"
  ```
  The `--global` flag can be ommitted to configure only your current `RAPTOR` local repository.
* To work on an issue, open a merge request with corresponding branch.
* Best practices for merge requests:
  * the merge request should have a well defined goal and avoid spurious modifications of unrelated code
  * a collection of small focused merge requests is preferable to a large more general single merge request
  * the goal and method used should be summarized in the title and description of the merge request
  * a new entry should be added to the "Unreleased" section of the [CHANGELOG.md](CHANGELOG.md) file containing the merge request ID and a short summary. For example:
  ```
  - !169: `README.md`: updated, and added `CONTRIBUTORS.md`
  ```
  * merge requests will only be merged once the CI/CD pipeline succeeds
  * new features should be accompanied by new CI/CD tests
  * once the merge request is ready you should assign it to one the code maintainers (O. Sauter, S. van Mulders or F. Felici)
* RAPTOR uses the "fast-forward merge" merge method for merge requests, meaning that a merge request can only be merged into the `master` branch if the current `master` branch is an ancestor of your branch (see [this page](https://docs.gitlab.com/ee/user/project/merge_requests/methods/#fast-forward-merge) for more details). This was chosen to allow small compact merge requests to be merged without a merge commit and provide a linear history when there is no parallel development ongoing.

  The overview tab of the merge request gives you information whether the branch can be merged or not. If not, a message such as "The source branch is 1 commit behind the target branch" will be displayed. You can resolve this by either merging the target branch into your branch or rebasing your branch onto the target branch (rebasing might be preferable for a merge request with a small number of commits, while merging might be more suited for larger ones). While rebasing is an attractive solution to simplify the commit history, the following caveats should be considered:
  * rebasing branches containing merge commits is a complex operation which should be handled with care. Merging might be a better option here. Otherwise check the `--rebase-merges` option.
  * If you rebase a branch that other branches depend on, then you will also need to rebase those branches or the rebased commits will be duplicated. Merging might be a better option in that case.
  * GitLab sometimes offer the possibility to rebase the branch by clicking on a button. But if you then need to make further local changes to this branch, and your local repository merges the local branch with the remote branch when using `git pull` (see [this man page](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pullrebase) for more details), then the `pull` operation will result in a duplication of the rebased commits.
  * when rebasing locally a simple push will be rejected after rebasing since the remote branch is not an ancestor of the local branch anymore. To overcome this you can use the `--force-with-lease` option which guarantees that the remote branch has not been modified since you last synced your local repository. The full rebase workflow should then be:
    ```
    # Checkout the feature branch
    $ git checkout <feature-branch>
    # Pull latest changes of the feature branch
    $ git pull origin
    # Rebase the feature branch on origin/master
    $ git rebase origin/master
    # Push the rebased branch to the remote
    $ git push origin <feature-branch> --force-with-lease
    ```
* For SPC users, more information on `git` and `GitLab` is available on [GIT](https://spcwiki.epfl.ch/wiki/GIT) and [GitLab](https://spcwiki.epfl.ch/wiki/GIT/GitLab) pages on the SPCwiki (SPC access required).
