/ DEVELOPER_GUIDELINES.md
DEVELOPER_GUIDELINES.md
  1  # Developer guidelines
  2  
  3  - [Developer guidelines](#developer-guidelines)
  4    - [Introduction](#introduction)
  5    - [Glossary](#glossary)
  6    - [Guidelines](#guidelines)
  7      - [Keep the issue tracker clean.](#keep-the-issue-tracker-clean)
  8      - [Keep CI green.](#keep-ci-green)
  9      - [Good issues, good merge requests.](#good-issues-good-merge-requests)
 10        - [Issues/feature requests](#issuesfeature-requests)
 11        - [Merge requests](#merge-requests)
 12      - [Don't push directly to `dev`, use feature branches.](#dont-push-directly-to-dev-use-feature-branches)
 13      - [Review all the things.](#review-all-the-things)
 14      - [Do not merge `WIP` merge requests.](#do-not-merge-wip-merge-requests)
 15      - [Write test.](#write-test)
 16      - [Features development lifecycle.](#features-development-lifecycle)
 17    - [Conclusion](#conclusion)
 18    - [Revisions](#revisions)
 19  
 20  The aim of this document is to describe and document all the development best practices which should be put
 21  in place when developing Gargantext. 
 22  
 23  ## Introduction
 24  
 25  Gargantext is a dynamic project, which evolved from a Python project into a full-stack functional application,
 26  with Haskell in the backend and PureScript in the frontend. As such, the project has seen many developers
 27  come and go, with work sometimes contributed spontaneously by external people (being an open source,
 28  free software). As every open source project, it's necessary to reach a common ground between developers and
 29  share a set of development guidelines to make sure the project is developed _consistently_; by "consistently"
 30  here we mean that there should be some common driving principles which should ultimately result in the
 31  project being developed in a uniform way. In other words, there should be a clear process shared between
 32  all developers about how to:
 33  
 34  - How to code in a collaborative way;
 35  - Propose and implement new features;
 36  - Report problems and write good bug reports;
 37  - Write tests (when, how, why);
 38  - Manage work effectively between branches.
 39  
 40  The rest of the document try to answer all those questions.
 41  
 42  ## Glossary
 43  
 44  - GIT: _Git_ is a distributed version control system
 45  
 46  - MR: _Merge Request_; usually called "Pull Request" in the GitHub work, is an
 47        event that takes place in software development when a contributor/developer
 48        is ready to begin the process of merging new code changes with the main
 49        project repository.
 50  
 51  - CI: _Continuous Integration_; it's a term referring to the process of automatically
 52        building and testing our software on a remote machine. In Gargantext it's integrated
 53        in Gitlab via their _runners_. A "green CI" means that all the CI steps passes correctly,
 54        and typically these steps involve building and testing the process.
 55  
 56  ## Guidelines
 57  
 58  The following is a non-exhaustive list of the development guidelines.
 59  
 60  ### Main working Branches
 61  
 62  3 main branches are used in the distributed version control system (Git) of GarganText:
 63  - _dev_ branch for latest development
 64  - _testing_ branch for testing by beta tester 
 65  - _stable_ branch for production only
 66  
 67  Accordingly _dev_ commits are then merged into _testing_ then into
 68  _stable_ if and only if the steps of this guideline are respected.
 69  
 70  For development, please add the number of the issue in the branch you
 71  are working on. For instance if you work on the issue with number #507,
 72  use the following branch: dev-507-some-keywords-here
 73  
 74  ### Keep the issue tracker clean.
 75  
 76  **Guideline: periodically scan the issue tracker for issues which are no longer relevant or are now
 77  fixed, and close those tickets. If in doubt, ping the original author and ask for information.**
 78  
 79  Periodically, we should try to make an effort in pruning old tickets, as well as closing issues
 80  which are not relevant anymore. Let's remember that an issue tracker is not an append-only log, we are
 81  supposed to make it grow _smaller_, not bigger: our primary goal should be to have the issue tracker be
 82  as empty as possible. This seems obvious but has several advantages:
 83  
 84  - It improves the external perception of the project: a project with hundreds of tickets gives the
 85    impression it's either abandoned or severely broken (i.e. "why has this project so many bugs?");
 86  - It reduces the chances of _duplication_: the more tickets, the more confusion (for newcomers as well),
 87    and it's therefore easier to accidentally open a duplicate ticket (i.e. a ticket referring to an
 88    already-known bug or feature request).
 89  
 90  ### Keep CI green.
 91  
 92  ** Before asking for a Merge Request, make sure your branch has a green CI.**
 93  
 94  **Guideline: We will not merge any MR which doesn't have green CI. 'docs' failures are allowed.**
 95  
 96  Continuous Integration (e.g. CI) is a "public proof" that the project is building and
 97  behaving correctly. Therefore, it's extremely important that we don't merge anything that doesn't
 98  successfully pass CI. If this is slowing down development it's not a CI problem, it simply means
 99  the project is not being kept to sufficiently high standards and we need to take a step back and
100  fix CI in order to be able to fearlessly march forward. Sometimes there are steps in the CI pipeline
101  which are marked as "optional" (like building the `docs`), and for those we tolerate failures.
102  Therefore, an MR in "Passed with warnings" status is acceptable, a MR with a "Failed" CI status is not.
103  
104  ### Good issues, good merge requests.
105  
106  **Guideline: Write issues and merge requests with a clear description that states the intention and/or
107  the rationale. For issues, try to add reproduction steps.**
108  
109  #### Issues/feature requests
110  
111  When opening a new issue, make sure to do the following:
112  
113  - If this is a feature request, describe why this would be a useful addition and which problem it would solve;
114  - If this is a bug report, try to clearly spell out:
115      * What the bug exactly is;
116      * How does the bug manifests itself;
117      * If relevant, useful system information like the version of GHC or the operating system.
118      * If possible, include some reproduction steps (e.g. "click on button X, select Y, etc etc").
119  
120  #### Merge requests
121  
122  When opening a MR, make sure to do the following:
123  
124  - Check your branch has a green CI first please. If you need help or
125    discussion, use the comments in the issue related to your current
126    working branch.
127  - If this is closing an issue, consider using one of the [closing patterns](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#default-closing-pattern)
128    to automatically close the associated issue when the MR is merged. For example, you can say "Fixes #XXX"
129    (where `XXX` is an issue number) in the MR description;
130  - Add a good description in the MR which summarises the problem which is solving and, if possible, the
131    approach taken to solve the issue: this will help reviewers (see "Review all the things").
132  
133  ### Don't push directly to `dev`, use feature branches.
134  
135  **Guideline: Use feature/issue branches to contribute work, but do NOT push directly to `main` or `dev`.**
136  
137  We should stop pushing directly on `dev` or the other "important" branches: Instead, we should always open
138  a new MR. There are multiple advantages in doing so:
139  
140  - Reverting work on `dev` is easier, because one can simply revert a single merge commit rather than
141    multiple commits;
142  - We reduce the risk of accidentally _undoing_ work; it already happened in that past that pushing on `dev`
143    accidentally deleted some previous work being committed, and that is very painful, especially due to
144    tendency to force push into branches.
145  - The history becomes easier to follow; we can always see which particular MR introduced a particular
146    feature or regression;
147  - New features or bugs won't get missed (see "Review all the things" section).
148  
149  Typically the argument for pushing directly to `dev` is to make things "quicker", for example to test an
150  experimental Gargantext feature. However, we should be in a position to deploy any given branch on the
151  staging server, so that we don't depend on `dev` being the branch we deploy: this reduces the pressure for
152  pushing directly into `dev`.
153  
154  ### Review all the things.
155  
156  **Guideline: Whenever possible, we should ask our colleagues to review our work.**
157  
158  If possible, we should try to review each other's work, because that helps improving the overall quality of
159  the project. Reviewing is an art in itself; we shouldn't start "cherry-picking" on every single MR, because
160  that's not the spirit. The purpose of the code review is the following:
161  
162  - Offering to the colleague a fresh perspective on a problem ("Have you tried X instead of Y"?) which he/she
163    might not have thought about;
164  - Sharing knowledge with the rest of the team (i.e. the fact I'm now the reviewer means I now know about this
165    feature, and it won't catch me off guard next time I pull the latest version of the project);
166  
167  In the spirit of faster development cycles, we shouldn't necessarily veto any MR (unless there are clear bugs),
168  but if there are concerns with the work being committed, we should share our concerns and perhaps log an issue
169  in the issue tracker to discuss further work (e.g. MR !XXX added feature Y in a way it might be problematic,
170  let's keep on eye if this turns out to be a problem.").
171  
172  To start a review, we should spontaneously pick another colleague and assign him/her as a reviewer in the
173  appropriate Gitlab UI.
174  
175  ### Do not merge `WIP` merge requests.
176  
177  **Guideline: if a Merge Request is marked as `WIP`, do not merge it, because it's still a work in progress.**
178  
179  Gitlab gives the chance of marking a MR as a draft by prepending the text "WIP:" next to the MR's title.
180  Therefore, we should honour the original author's will by not merging this MR until CI passed _and_ the
181  `WIP:` prefix has been removed from the title.
182  
183  ### Write test.
184  
185  **Guideline: try to write a test for each new feature or bug added to Gargantext. If that's hard, it
186  means you are not developing with testability in mind.**
187  
188  Testing is arguably the second most important asset of a project (the first being the non-testing code itself),
189  because it protects us from accidentally introducing regressions in the codebase. You shouldn't believe
190  the folklore of "if it compiles, it works", because it's simply not true: you need tests. Writing tests
191  has all sorts of important advantages:
192  
193  - As said, tests protect against accidentally introducing bugs into existing code;
194  - They give other developers a sort of "free documentation", because by reading the tests, they
195    can learn about the expected behaviour of the code being tested;
196  - They force the developer to think about "how do I test this?", which is annoying at first, but
197    then it encourages more modular code, because:
198    * Pure functions are the easiest to test, so that naturally promotes writing as much pure code
199      as possible;
200    * Effectful polymorphic code (i.e. polymorphic over a constrained monad `m`) is the second easiest
201      to test, so that naturally encourages writing lighter monad stacks which can be tested easily, or
202      functions over a monad `m` where `m` can be `IdentityT`/`StateT`/`ReaderT`.
203  
204  ### Features development lifecycle.
205  
206  **Guidelines: each major feature or architectural decision should be discussed with the team.**
207  
208  For each major feature introduced in Gargantext, there should be a process to propose, discuss and approve
209  the feature, for several reasons:
210  
211  - It gives a chance to all developers to chime in on the discussion, bringing in their experience or
212    expertise;
213  - It gives a chance to all developers to understand "what's coming next" without surprised further
214    down the road, with features added without they knowing about them;
215  - It ensures that each new feature or design choice in Gargantext is well understood, principled and
216    with a clear purpose;
217  - It gives us an historical record of precisely _why_ something was done; we can refer to the original
218    ticket by saying "this feature/design was discussed here and approved by the team".
219  
220  Ideally, we could have the following process, divided in 4 phases:
221  
222  - _Triage_: It starts with a developer opening a new issue in the tracker, describing the feature or the
223    design he/she wants to propose. This ticket should be marked with a `triage` label on Gitlab, and it
224    should contain:
225      * Why such feature or design choice makes sense;
226      * Which is the problem it's trying to solve;
227      * What is the impact on the rest of the system.
228  - _Discussion_: Once the ticket has been opened, it's time for other developers to chime in and discuss
229    the proposal;
230  - _Approval_: Once the proposal has been approved, it should be assigned to a developer and it should be
231    marked with an `approved` label on Gitlab. The old `triage` label should be removed;
232  - _Implementation_: Finally, the ticket gets implemented. This concludes the lifecycle.
233  
234  ## Conclusion
235  
236  We have presented a comprehensive overview on the set of best practices we should put in place within
237  Gargantext to make sure the project thrives, keeps growing and succeeds.
238  
239  ## Revisions and certification
240  
241  - To review and agree with these guidelines, read it eventually improve
242    it and commit a change as signature.
243  
244  2023-07-10: Initial version of this document