-
Notifications
You must be signed in to change notification settings - Fork 40.7k
Team Practices
As a team we are constantly refining the practices that we use to manage the Spring Boot project. This document provides an overview the most important ones.
If you’re an external contributor, you might find this document interesting, but you probably want to read Working with the Code instead.
The overriding principal adopted by the team is that it should be possible for any member to work on any aspect of the project. Most of the processes and practices that we have implemented are driven by this vision.
We believe it’s important that no single individual ever owns a specific part of the project. We don’t want a single point of failure. As much as possible, we try to automate things away.
We strive to make Spring Boot an inclusive project and include a code of conduct that we enforce. Whenever possible we avoid oppressive language and follow IEFT recommendations. This extends to the issue tracker where will routinely edit issue descriptions, for example, replacing "Hi Guys" with "Hi Team".
It’s not really possible for Spring Boot to use semantic versioning since every release would have to be a major. Instead we try to use the version number as an indicator of the amount of pain that an upgrade will cause.
The version number format used by Spring Boot is <major>.<minor>.<patch>(-<qualifier>)
.
Patch releases should be API compatible drop-in replacements for users. They should only contain bug fixes.
Minor versions contain new features. It should generally be possible to upgrade from a previous minor release without too much effort as long as the major version has not changes and no deprecated methods are being used.
Major versions are reserved for large breaking changes. It’s expected that users will need to do some work when upgrading major versions.
It’s important to remember that upgrades are not an enjoyable task for most users. As a team we should always provide as much help as possible and have empathy for our users.
We should always carefully consider the reasons behind any change that we make. It’s sometimes better for us to take on the pain that we’d otherwise inflict on our users. For example, we often choose to support older versions of Java even though we’d like to use newer language features ourselves.
Deprecated classes and methods must be annotated with @Deprecated
and include a @deprecated
javadoc tag.
The tag should be of the form @deprecated since <version> for removal in <version> in favor of <replacement>
.
See this page for more details about our deprecation policy.
New features should target the upcoming minor release and should not be included in patch releases. Bugs should be targeted to the oldest supported release, unless they are particularly risky or hard to fix in an older branch.
The upgrade policy for third-party dependencies is documented here. We use a tool called Bomr to upgrade dependencies.
Minor versions will always try to move to the latest version of a third-party dependency.
We try to move dependencies on other Spring projects to their SNAPSHOT versions about a week or two before we release. This helps us identify issues early to fix them, but not suffer too much instability in our own build.
The smoke tests are particularly helpful in ensuring that all Spring dependencies work well together.
Spring Boot releases minor versions every 6 months. We release on the 3rd Thursday of the month.
Details of the schedule are availble here.
Spring Boot is a popular project and as a result it has a lot of issues raised against it. In order to deal with the volume of issues, we have had to put in several processes to help with issue managed management.
Out issue process is documented in this wiki page. It covers the triage process, the labels we use and the milestone that have.
We used GitHub’s "saved replies" feature to quickly provide common respones in issues. For example, it’s common for us to close issues that are questions rather than bugs.
A list of our saved replies are available here.
Every now and then we like to try and find an issue that is suitable for someone that hasn’t contributed to Spring Boot before. Our aim is to encourage people that wouldn’t usually contribute to open source to give it a go.
First timer issues are labeled for: first-timers-only
and usually have a much more detailed description than regular issues.
The first person to claim the issue is assigned and we then work with them so that they can contribute a pull-request.
Spring Boot has a vibrant community of contributors the regularly send pull requests. We triage pull requests in the same way as issues and will assign them to a specific milestone.
Once we assign a pull request to a milestone, any related issue is labeled as status: superseded
and closed.
Details on how to merge a pull request are documented here.
Commit messages are a vital tool when trying to debug a regression. Spring Boot follows these 7 rules for commit messages:
-
Separate subject from body with a blank line
-
Limit the subject line to 50 characters
-
Capitalize the subject line
-
Do not end the subject line with a period
-
Use the imperative mood in the subject line
-
Wrap the body at 72 characters
-
Use the body to explain what and why vs. how
In addition, almost all commit messages include a reference to a GitHub issue or pull request.
We reference issues using See
, Fixes
or Closes
then gh-NNNN
.
For example:
Allow optional ConfigDataLocationResolver results Update `ConfigData` so that it signal if is considered optional. This update allows `ConfigDataLocationResolvers` to return results that behave in the same way as `optional:` prefixed locations without the user themselves needing to prefix the location string. Closes gh-25894
The following blogs are worth reading on the subject:
The main
branch of the Spring Boot repository contains the latest version of Spring Boot.
This is usually the next minor or major version, but it may also be the next patch release if maintenance branches have not yet been created.
We keep maintenance branches in form <major>.<minor>.x
for all active versions.
For example, if main
is for an upcoming 2.3.0
version, we’d have 2.2.x
and 2.1.x
maintenance branches.
Spring Boot uses forward-merges to apply fixes from maintenance branches forward. Please read Working with Git Branches for more details.
As much as possible we try to make the Spring Boot codebase appear as if it were written in a single voice.
To do this, we rely on tools such as checkstyle and the spring-javaformat
code formatter.
We also regularly "polish" code to improve it and bring consistency.
We hope that by having a consistent code style, it will be easier for contributors and the team to work on difference areas of the codebase.
We want to ensure that Spring Boot works well with any IDE but we’re especially invested in Eclipse and IntelliJ. See Working with the Code for detailed instructions on how to setup your IDE.
Our codebase is automatically formatted using the spring-javaformat
project.
Whilst there are pros and cons to auto-formatting, we’ve found it to be beneficial.
There, however, are still a few things that need manual teeaks:
Fluient APIs are often very hard to read when auto-formatted. To fix this, you can try moving to a one-statement-per-line style rather than chaining calls.
Some fluent APIs also offer lambda callback variants which will look much better.
If those tips don’t work, using @formatter: off
/@formatter: on
can be used as a last resort.
For formatter will not touch whitespace in a method body, but we generally like to remove it. Removing body whitespace helps to make it easier to see where methods begin and end.
If you have method body that is becoming long and hard to read, you might want to extract some private methods from it.
Note
|
Other Spring projects have different opinions on whitespace. Spring Framework has additional lines around constructors and when method signatures wrap. Spring Data uses whitespace within the method body. |
We use checkstyle to bing as much consistency as possible to our codebase and catch potential programming issue early.
We will add new rules to the spring-javaformat
project if we find things that we enforce.
Although checkstyle can be pain sometimes, we found it helpful overall and it’s especially useful for contributors.
Naming classes and methods is something that cannot be automated so we generally rely on team review. We try to follow the conventions already established by the Spring Framework.
Class and method names in Spring Boot can be quite long, especially for classes that are more internal.
Every member of the team is encouraged to make "Polish" commits whenvever they find code that could be improved. A polish commit is a commit that makes the code easier to read or reason about, but does not change functionality.
Spring Boot relies heavily on tests to ensure that code works as expected. Test are written using JUnit 5 and assertions are made using AssertJ. We use Mockito for mocking.
Mostly there’s a 1-1 mapping between a class and its unit tests.
For example, SpringApplication.java
will have a related SpringApplicationTests.java
file.
The top comment of the *Tests
file has comment so that it’s easy to ctrl
+ click
back to the class being tested:
/**
* Tests for {@link SpringApplication}.
*
* @author ...
*/
class SpringApplicationTests {
...
}
Sometimes we need to test the interactions between several classes.
In these situations, we’ll use +*IntegrationTests
as the test suffix.
We also have "smoke test" projects that we use for high level integration tests.
We like to use BDD (behavior driven development) style method names whevener possible.
These are of the form: <method-under-test>[when<condition>]<expecation>
.
For example: readLoadsFile
might test that the read
method loads file contents.
Or readWhenFileIsEmptyThrowsException
might check that the read
method throws an exception if the file is empty.
Note
|
Over the years we’ve refined out test naming conventions so things aren’t as consistent as we’d like. Polish commits can be used if you find an older set of tests that need migrating. |
Javadoc is a very important part of the Spring Boot API. All classes and all public methods should have high quality documentation.
Advice that code should be "self documenting" is really applicable for our code so we tend have quite a lot of duplication in our javadoc.
For example, a method javadoc may include a "Returns …" commend and have a @returns
tag as well.
Often writing javadoc is a good way to verify that a class or method is named correctly. If you find yourself writing different terms in the javadoc, then perhaps the code should be renamed.
We like to include @author
tags in order to give recognition to contributors.
Although this is also available in git, it’s nice to have the @author
tag as well since it appears when browsing jar contents in an IDE.
We add @since
tags to public classes and public methods to help users know when something was added.
The tags are not required for package-private classes.
Wiki Documentations Doc Samples Asciidoctor Formatting Generated Asciidoctor Snippets Extensions