Skip to content

Commit 277a076

Browse files
committed
FINERACT-2383: Modernize and correct README page
1 parent d6323be commit 277a076

File tree

2 files changed

+366
-398
lines changed

2 files changed

+366
-398
lines changed

CONTRIBUTING.md

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,105 @@
1+
# Contributing
2+
13
Hello there!
24

3-
First of all, **Thank You** for contributing to Apache Fineract, we're grateful for your interest in our project.
5+
First of all, **Thank You** for contributing to Apache Fineract! We are grateful for your interest in this project.
6+
7+
Please join the [developer mailing list](https://fineract.apache.org/#contribute), if you have not already done so, as this is where discussions about this project take place - say _Hi_ there! Please also have a quick look at the [Code of Conduct](CODE_OF_CONDUCT.md).
8+
9+
The [JIRA Dashboard](https://issues.apache.org/jira/secure/Dashboard.jspa?selectPageId=12335824) shows what's going on. Create a login - it can take a day or two. If you face difficulties, ask on the mailing list.
10+
11+
You don't need to be a committer to provide pull requests, but [Becoming a Committer](https://cwiki.apache.org/confluence/display/FINERACT/Becoming+a+Committer) explains the process of becoming one - just in case...
12+
13+
14+
## How We Code
15+
16+
### Checkstyle and Spotless
17+
18+
This project enforces its code conventions using [checkstyle.xml](config/checkstyle/checkstyle.xml) through Checkstyle and [fineractdev-formatter.xml](config/fineractdev-formatter.xml) through Spotless. They are configured to run automatically during the normal Gradle build, and fail if there are any violations detected. You can run the following command to automatically fix spotless violations:
19+
```bash
20+
./gradlew spotlessApply
21+
```
22+
Since some checks are present in both Checkstyle and Spotless, the same command can help you fix some of the Checkstyle violations too.
23+
24+
You can also check solely for Spotless violations, but normally don't have to, because regular builds already include this:
25+
```bash
26+
./gradlew spotlessCheck
27+
```
28+
29+
We recommend that you configure your favourite Java IDE to match those conventions. For Eclipse, you can go to
30+
Window > Java > Code Style and import the aforementioned [config/fineractdev-formatter.xml](config/fineractdev-formatter.xml) under formatter section and [config/fineractdev-cleanup.xml](config/fineractdev-cleanup.xml) under cleanup section.
31+
32+
You could also use Checkstyle directly in your IDE, but you don't have to: it may just be more convenient for you. For Eclipse, use https://checkstyle.org/eclipse-cs/ and load our checkstyle.xml into it. For IntelliJ you can use [CheckStyle-IDEA](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea).
33+
34+
35+
### Code Coverage
36+
37+
Changed or added code should ideally have test coverage.
38+
39+
The project uses Jacoco to measure unit tests code coverage. To generate a report run the following command:
40+
```bash
41+
./gradlew clean build jacocoTestReport
42+
```
43+
Generated reports can be found in the build/code-coverage directory.
44+
45+
46+
### Error Handling
47+
48+
* When catching exceptions, either rethrow them, or log them. Either way, include the root cause by using `catch (SomeException e)` and then either `throw AnotherException("..details..", e)` or `LOG.error("...context...", e)`.
49+
* Completely empty catch blocks are VERY suspicious. Are you sure that you want to just "swallow" an exception? Really, 100% totally absolutely sure?? ;-) Such "normal exceptions which just happen sometimes but are actually not really errors" are almost always a bad idea, can be a performance issue, and typically are an indication of another problem - e.g. the use of a wrong API which throws an Exception for an expected condition, when really you would want to use another API that instead returns something empty or optional.
50+
* In tests, you'll typically never catch exceptions, but just propagate them, with `@Test void testXYZ() throws SomeException, AnotherException`..., so that the test fails if the exception happens. Unless you actually really want to test for the occurrence of a problem - in that case, use [JUnit's Assert.assertThrows()](https://github.com/junit-team/junit4/wiki/Exception-testing) (but not `@Test(expected = SomeException.class)`).
51+
* Never catch `NullPointerException` & Co.
52+
53+
### Logging
54+
55+
* We use [SLF4J](http://www.slf4j.org) as our logging API.
56+
* Never, ever, use `System.out` and `System.err` or `printStackTrace()` anywhere, but always `LOG.info()` or `LOG.error()` instead.
57+
* Use placeholder (`LOG.error("Could not... details: {}", something, exception)`) and never String concatenation (`LOG.error("Could not... details: " + something, exception)`)
58+
* Which Log Level is appropriate?
59+
* `LOG.error()` should be used to inform an "operator" running Fineract who supervises error logs of an unexpected condition. This includes technical problems with an external "environment" (e.g. can't reach a database), and situations which are likely bugs which need to be fixed in the code. They do NOT include e.g. validation errors for incoming API requests - that is signaled through the API response - and does (should) not be logged as an error. (Note that there is no _FATAL_ level in SLF4J; a "FATAL" event should just be logged as an _ERROR_.)
60+
* `LOG.warn()` should be using sparingly. Make up your mind if it's an error (above) - or not!
61+
* `LOG.info()` can be used notably for one-time actions taken during start-up. It should typically NOT be used to print out "regular" application usage information. The default logging configuration always outputs the application INFO logs, and in production under load, there's really no point to constantly spew out lots of information from frequently traversed paths in the code about what's going on. (Metrics are a better way.) `LOG.info()` *can* be used freely in tests though.
62+
* `LOG.debug()` can be used anywhere in the code to log things that may be useful during investigations of specific problems. They are not shown in the default logging configuration, but can be enabled for troubleshooting. Developers should typically "turn down" most `LOG.info()` which they used while writing a new feature to "follow along what happens during local testing" to `LOG.debug()` for production before we merge their PRs.
63+
* `LOG.trace()` is not used in Fineract.
64+
65+
## Change Process
66+
67+
### Dependency Upgrades
68+
69+
This project uses a number of 3rd-party libraries. We have set up [Renovate's bot](https://github.com/renovatebot/github-action) to automatically raise Pull Requests for our review when new dependencies are available.
70+
71+
Our `ClasspathHellDuplicatesCheckRuleTest` detects classes that appear in more than 1 JAR. If a version bump in [build.gradle](https://github.com/apache/fineract/blob/develop/build.gradle) causes changes in transitives dependencies, then you may have to add related `exclude` to our [dependencies.gradle](https://github.com/apache/fineract/search?q=dependencies.gradle). Running `./gradlew dependencies` helps to understand what is required.
72+
73+
### Pull Requests
74+
75+
We request that your commit message includes a FINERACT JIRA issue and a one-liner that describes the changes.
76+
Start with an upper case imperative verb (not past form), and a short but concise clear description. (E.g. "FINERACT-821: Add enforced HideUtilityClassConstructor checkstyle").
77+
78+
If your PR is failing to pass our CI build due to a test failure, then:
79+
80+
1. Understand if the failure is due to your PR or an unrelated unstable test.
81+
1. If you suspect it is because of a "flaky" test, and not due to a change in your PR, then please do not simply wait for an active maintainer to come and help you, but instead be a proactive contributor to the project - see next steps. Do understand that we may not review PRs that are not green - it is the contributor's (that's you!) responsibility to get a proposed PR to pass the build, not primarily the maintainers.
82+
1. Search for the name of the failed test on https://issues.apache.org/jira/, e.g. for `AccountingScenarioIntegrationTest` you would find [FINERACT-899](https://issues.apache.org/jira/browse/FINERACT-899).
83+
1. If you happen to read in such bug reports that tests were just recently fixed, or ignored, then rebase your PR to pick up that change.
84+
1. If you find previous comments "proving" that the same test has arbitrarily failed in at least 3 past PRs, then please do yourself raise a small separate new PR proposing to add an `@Disabled // TODO FINERACT-123` to the respective unstable test (e.g. [#774](https://github.com/apache/fineract/pull/774)) with the commit message mentioning said JIRA, as always. (Please do NOT just `@Disabled` any existing tests mixed in as part of your larger PR.)
85+
1. If there is no existing JIRA for the test, then first please evaluate whether the failure couldn't be a (perhaps strange) impact of the change you are proposing after all. If it's not, then please raise a new JIRA to document the suspected Flaky Test, and link it to [FINERACT-850](https://issues.apache.org/jira/browse/FINERACT-850). This will allow the next person coming along hitting the same test failure to easily find it, and eventually propose to ignore the unstable test.
86+
1. Then (only) Close and Reopen your PR, which will cause a new build, to see if it passes.
87+
1. Of course, we very much appreciate you then jumping onto any such bugs and helping us figure out how to fix all ignored tests!
88+
89+
[Pull Request Size Limit](https://cwiki.apache.org/confluence/display/FINERACT/Pull+Request+Size+Limit)
90+
documents that we cannot accept huge "code dump" Pull Requests, with some related suggestions.
91+
92+
Guideline for new Feature commits involving Refactoring: If you are submitting a PR for a new feature,
93+
and it involves refactoring, try to differentiate "new feature code" from "refactored" by placing
94+
them in different commits. This helps to review your code faster.
95+
96+
We have an automated bot which marks pull requests as "stale" after a while, and ultimately automatically closes them.
497

5-
Please do [join our developer mailing list](https://fineract.apache.org/#contribute), as it's where discussions about this project take place - say _Hi_ there!
698

7-
Our [JIRA Dashboard](https://issues.apache.org/jira/secure/Dashboard.jspa?selectPageId=12335824) is another good way to see what's going on (do create a Login).
99+
### Merge Strategy
8100

9-
Here are a few additional useful pointers:
101+
This project's committers typically prefer to bring your pull requests in through _Rebase and Merge_ instead of _Create a Merge Commit_. (If you are unfamiliar with GitHub's UI regarding this, note the somewhat hidden little triangle drop-down at the bottom of the PR, visible only to committers, not contributors.) This avoids the "merge commits" which we consider to be somewhat "polluting" the project's commit log history view. We understand this doesn't give an easy automatic reference to the original PR (which GitHub automatically adds to the merge commit message it generates), but we consider this an only very minor inconvenience; it's typically relatively easy to find the original PR even just from the commit message, and JIRA.
10102

11-
* https://github.com/apache/fineract/#pull-requests
12-
* https://github.com/apache/fineract/#checkstyle-and-spotless
13-
* https://github.com/apache/fineract/#logging-guidelines
14-
* https://github.com/apache/fineract/#error-handling-guidelines
103+
We expect most proposed PRs to typically consist of a single commit. Committers may use _Squash and merge_ to combine your commits at merge time, and if they do so, will rewrite your commit message as they see fit.
15104

16-
Note also [our Code of Conduct](CODE_OF_CONDUCT.md).
105+
Neither of these two are hard absolute rules, but mere conventions. Multiple commits in single PRs make sense in certain cases (e.g. branch backports).

0 commit comments

Comments
 (0)