mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-10-03 05:19:07 +00:00
Prior to this commit, CONTRIBUTING.md delegated build instructions and code style to wiki pages, which are planned for removal. This commit inlines the build, code style and testing guidelines into CONTRIBUTING.md, aligns them with the current build and Checkstyle rules, and documents the commit message conventions, the security policy and the policy on AI-assisted contributions. It also adds a concise AGENTS.md extract for coding agents, and updates the README to link to the Build from Source section. Closes gh-37372 Signed-off-by: Sébastien Deleuze <sdeleuze@users.noreply.github.com>
4.0 KiB
4.0 KiB
Spring Framework agent guidelines
Concise extract of CONTRIBUTING.md, which remains the reference for humans.
Build
- Gradle build, JDK from
.sdkmanrc(currently JDK 25,sdk env install/sdk env); artifacts target Java 17+. - Scope builds to the modules you touched:
./gradlew :spring-webmvc:test, a single test with--tests <fully.qualified.ClassTests>. - Run
./gradlew :<module>:checkbefore finishing: it runs tests and Checkstyle (src/checkstyle/checkstyle.xml), which enforces most of the code style below. - NullAway null-safety checks run during compilation; fix reported errors instead of suppressing them.
- Do not run
cleanunless needed; the build is incremental and cached. - Reference docs:
./gradlew antora, output inframework-docs/build/site/index.html.
Code style
- Match surrounding code; do not reformat unrelated code; a file should look like it was written by a single author.
- Tabs, LF, UTF-8, no trailing whitespace.
- Aim for 90 characters per line for code (105 acceptable, 120 max) and ~80 for Javadoc.
- Wrap lines after separators (
,+?:&&||), never before. - K&R braces, with
else,catch, andfinallyon a new line. - Two blank lines before fields, constructors,
static {}blocks, and inner classes; one blank line after a multiline method signature. - Import order, groups separated by a blank line:
java.*, thenjavax.*+jakarta.*, then others, thenorg.springframework.*, then static imports. - No wildcard imports. No static imports in production code except constants/enum constants and third-party DSL factory methods; use them in tests (e.g.
assertThat). - Every source file: Apache 2.0 license header (
Copyright 2002-present the original author or authors., copy from an existing file), package, imports, exactly one top-level class. - Always reference fields with
this., never methods. Always add@Override. - No
varin production code. No single-character variable names. Wrap ternaries in parentheses with the non-null condition first:(foo != null ? foo : "default"). - Argument checks:
Assert.notNull(event, "Event must not be null"); state checks:Assert.state(...). - Null-safety with JSpecify: packages are
@NullMarkedinpackage-info.java, useorg.jspecify.annotations.Nullableexplicitly (e.g.private @Nullable String name;), repeat super method nullness on overrides,@Contractwhere useful. - Static utility classes:
abstract,Utilssuffix, private constructor. - No
System.out/System.errorprintStackTrace().
Javadoc
- First sentence in imperative style ("Return", not "Returns");
<p>to start extra paragraphs;{@code}for code andnull. - No blank line between method description and tags; do not indent wrapped tag descriptions.
- Add
@sinceto new classes and new public/protected methods; omit a.0patch version (@since 7.1, not7.1.0). - Tag order for types:
@author,@since,@param,@see,@deprecated; for members:@param,@return,@throws,@since,@see,@deprecated.
Tests
- Add or update tests for any code change.
- JUnit Jupiter, AssertJ (including
assertThatIllegalArgumentException()and similar), Mockito. No JUnit 4/Jupiter/TestNG assertions, no Hamcrest. - Test class names end with
Tests.
Docs
- Reference docs are AsciiDoc in
framework-docs/modules/ROOT; code snippets forinclude-code::live inframework-docs/src/main/{java,kotlin}.
Commits and pull requests
- Pull requests target
main. - Subject: imperative, capitalized verb, at most 55 characters, no
fix:/docs:prefixes, no issue/PR number, no trailing period. - Body wrapped at 72 characters explaining the motivation, followed by
Closes gh-123(orSee gh-123), then aSigned-off-by: Name <email>trailer (DCO, usegit commit -s). - Never write annotations verbatim in commit messages or PR titles (it mentions GitHub users): enclose them in backticks, as in
`@Override`. - Changes must be reviewed by a human who remains accountable for them before being submitted.