|
| 1 | += Spring AI Contributor Guidelines |
| 2 | + |
| 3 | +Do you have something you'd like to contribute to **Spring AI**? |
| 4 | +We welcome pull requests, but ask that you carefully read this document first to understand how best to submit them; |
| 5 | +what kind of changes are likely to be accepted; and what to expect from the Spring team when evaluating your submission. |
| 6 | + |
| 7 | +Please refer back to this document as a checklist before issuing any pull request; this will save time for everyone! |
| 8 | + |
| 9 | +== Code of Conduct |
| 10 | +This project adheres to the Contributor Covenant link:CODE_OF_CONDUCT.adoc[code of conduct]. |
| 11 | +By participating, you are expected to uphold this code. Please report unacceptable behavior to |
| 12 | + |
| 13 | + |
| 14 | +== Understand the basics |
| 15 | + |
| 16 | +Not sure what a *pull request* is, or how to submit one? Take a look at GitHub's excellent documentation: |
| 17 | +https://help.github.com/articles/using-pull-requests/[Using Pull Requests] first. |
| 18 | + |
| 19 | +== Search GitHub ticket first; create an issue if necessary |
| 20 | + |
| 21 | +Is there already an issue that addresses your concern? Search the |
| 22 | +https://github.com/spring-projects/spring-ai/issues[GitHub issue tracker] to see if you can find something similar. |
| 23 | +If not, please create a new issue before submitting a pull request unless the change is truly trivial, e.g. typo fixes, |
| 24 | +removing compiler warnings, etc. |
| 25 | + |
| 26 | +== Developer Certificate of Origin |
| 27 | + |
| 28 | +All commits must include a __Signed-off-by__ trailer at the end of each commit message to indicate that the contributor agrees to the Developer Certificate of Origin. |
| 29 | +For additional details, please refer to the blog post https://spring.io/blog/2025/01/06/hello-dco-goodbye-cla-simplifying-contributions-to-spring[Hello DCO, Goodbye CLA: Simplifying Contributions to Spring]. |
| 30 | + |
| 31 | +== Fork the Repository |
| 32 | + |
| 33 | +1. Go to https://github.com/spring-projects/spring-ai[https://github.com/spring-projects/spring-ai] |
| 34 | +2. Hit the "fork" button and choose your own GitHub account as the target |
| 35 | +3. For more detail see https://help.github.com/fork-a-repo/[Fork A Repo]. |
| 36 | + |
| 37 | +== Setup your Local Development Environment |
| 38 | + |
| 39 | +1. `git clone --recursive [email protected]:<your-github-username>/spring-ai.git` |
| 40 | +2. `cd spring-ai` |
| 41 | +3. `git remote show` |
| 42 | +_you should see only 'origin' - which is the fork you created for your own GitHub account_ |
| 43 | +4. `git remote add upstream [email protected]:spring-projects/spring-ai.git` |
| 44 | +5. `git remote show` |
| 45 | +_you should now see 'upstream' in addition to 'origin' where 'upstream' is the SpringIO repository from which releases are built_ |
| 46 | +6. `git fetch --all` |
| 47 | +7. `git branch -a` |
| 48 | +_you should see branches on origin as well as upstream, including 'main'_ |
| 49 | + |
| 50 | +== A Day in the Life of a Contributor |
| 51 | + |
| 52 | +* _Always_ work on topic branches (Typically use the GitHub issue ID as the branch name). |
| 53 | +- For example, to create and switch to a new branch for issue GH-123: `git checkout -b GH-123` |
| 54 | +* You might be working on several different topic branches at any given time, but when at a stopping point for one of those branches, commit (a local operation). |
| 55 | +* Please follow the "Commit Guidelines" described in |
| 56 | +https://git-scm.com/book/ms/v2/Distributed-Git-Contributing-to-a-Project[this chapter of Pro Git]. |
| 57 | +* Then to begin working on another issue (say GH-101): `git checkout GH-101`. The _-b_ flag is not needed if that |
| 58 | +branch already exists in your local repository. |
| 59 | +* When ready to resolve an issue or to collaborate with others, you can push your branch to origin (your fork), |
| 60 | +e.g.: `git push origin GH-123` |
| 61 | +* If you want to collaborate with another contributor, have them fork your repository (add it as a remote) and |
| 62 | +`git fetch <your-username>` to grab your branch. |
| 63 | +Alternatively, they can use `git fetch --all` to sync their local state with all of their remotes. |
| 64 | +* If you grant that collaborator push access to your repository, they can even apply their changes to your branch. |
| 65 | +* When ready for your contribution to be reviewed for potential inclusion in the main branch of the canonical |
| 66 | +spring-ai repository (what you know as 'upstream'), issue a pull request to the SpringSource repository |
| 67 | +(for more detail, see https://help.github.com/articles/using-pull-requests/[Using pull requests]). |
| 68 | +* The project lead may merge your changes into the upstream main branch as-is, he may keep the pull request open yet |
| 69 | +add a comment about something that should be modified, or he might reject the pull request by closing it. |
| 70 | +* A prerequisite for any pull request is that it will be cleanly merge-able with the upstream main's current state. |
| 71 | +**This is the responsibility of any contributor.** |
| 72 | +If your pull request cannot be applied cleanly, the project lead will most likely add a comment requesting that you make |
| 73 | +it merge-able. |
| 74 | +For a full explanation, see https://git-scm.com/book/en/Git-Branching-Rebasing[the Pro Git section on rebasing]. |
| 75 | +As stated there: _"> Often, you’ll do this to make sure your commits apply cleanly on a remote branch — perhaps in a |
| 76 | +project to which you’re trying to contribute but that you don’t maintain."_ |
| 77 | + |
| 78 | +== Keeping your Local Code in Sync |
| 79 | +* As mentioned above, you should always work on topic branches (since 'main' is a moving target). However, you do want |
| 80 | +to always keep your own 'origin' main branch in synch with the 'upstream' main. |
| 81 | +* Within your local working directory, you can sync up all remotes' branches with: `git fetch --all` |
| 82 | +* While on your own local main branch: `git pull upstream main` (which is the equivalent of fetching upstream/main |
| 83 | +and merging that into the branch you are in currently) |
| 84 | +* Now that you're in synch, switch to the topic branch where you plan to work, e.g.: `git checkout -b GH-123` |
| 85 | +* When you get to a stopping point: `git commit` |
| 86 | +* If changes have occurred on the upstream/main while you were working you can synch again: |
| 87 | +- Switch back to main: `git checkout main` |
| 88 | +- Then: `git pull upstream main` |
| 89 | +- Switch back to the topic branch: `git checkout GH-123` (no -b needed since the branch already exists) |
| 90 | +- Rebase the topic branch to minimize the distance between it and your recently synched main branch: `git rebase main` |
| 91 | +(Again, for more detail see https://git-scm.com/book/en/Git-Branching-Rebasing[the Pro Git section on rebasing]). |
| 92 | +* **Note** You cannot rebase if you have already pushed your branch to your remote because you'd be rewriting history |
| 93 | +(see **'The Perils of Rebasing'** in the article). |
| 94 | +If you rebase by mistake, you can undo it as discussed |
| 95 | +https://stackoverflow.com/questions/134882/undoing-a-git-rebase[in this StackOverflow discussion]. |
| 96 | +Once you have published your branch, you need to merge in the main rather than rebasing. |
| 97 | +* Now, if you issue a pull request, it is much more likely to be merged without conflicts. |
| 98 | +Most likely, any pull request that would produce conflicts will be deferred until the issuer of that pull request makes |
| 99 | +these adjustments. |
| 100 | +* Assuming your pull request is merged into the 'upstream' main, you will actually end up pulling that change into |
| 101 | +your own main eventually, and at that time, you may decide to delete the topic branch from your local repository and |
| 102 | +your fork (origin) if you pushed it there. |
| 103 | +- to delete the local branch: `git branch -d GH-123` |
| 104 | +- to delete the branch from your origin: `git push origin :GH-123` |
| 105 | + |
| 106 | +== Maintain a linear commit history |
| 107 | + |
| 108 | +When merging to main, the project __always__ uses fast-forward merges. |
| 109 | +When issuing pull requests, please ensure that your commit history is linear. |
| 110 | +From the command line you can check this using: |
| 111 | + |
| 112 | +---- |
| 113 | +log --graph --pretty=oneline |
| 114 | +---- |
| 115 | + |
| 116 | +As this may cause lots of typing, we recommend creating a global alias, e.g. `git logg` for this: |
| 117 | + |
| 118 | +---- |
| 119 | +git config --global alias.logg 'log --graph --pretty=oneline' |
| 120 | +---- |
| 121 | + |
| 122 | +This command, will provide the following output, which in this case shows a nice linear history: |
| 123 | + |
| 124 | +---- |
| 125 | +* c129a02e6c752b49bacd4a445092a44f66c2a1e9 INT-2721 Increase Timers on JDBC Delayer Tests |
| 126 | +* 14e556ce23d49229c420632cef608630b1d82e7d INT-2620 Fix Debug Log |
| 127 | +* 6140aa7b2cfb6ae309c55a157e94b44e5d0bea4f INT-3037 Fix JDBC MS Discard After Completion |
| 128 | +* 077f2b24ea871a3937c513e08241d1c6cb9c9179 Update Spring Social Twitter to 1.0.5 |
| 129 | +* 6d4f2b46d859c903881a561c35aa28df68f8faf3 INT-3053 Allow task-executor on <reply-listener/> |
| 130 | +* 56f9581b85a8a40bbcf2461ffc0753212669a68d Update Spring Social Twitter version to 1.0.4 |
| 131 | +---- |
| 132 | + |
| 133 | +If you see intersecting lines, that usually means that you forgot to rebase you branch. |
| 134 | +As mentioned earlier, **please rebase against main** before issuing a pull request. |
| 135 | + |
| 136 | +== Mind the whitespace |
| 137 | + |
| 138 | +Please carefully follow the whitespace and formatting conventions already present in the framework. |
| 139 | + |
| 140 | +1. Tabs, not spaces |
| 141 | +2. Unix (LF), not DOS (CRLF) line endings |
| 142 | +3. Eliminate all trailing whitespace |
| 143 | +4. Wrap Javadoc at 90 characters |
| 144 | +5. Aim to wrap code at 120 characters, but favor readability over wrapping |
| 145 | +6. Preserve existing formatting; i.e. do not reformat code for its own sake |
| 146 | +7. Search the codebase using `git grep` and other tools to discover common |
| 147 | +naming conventions, etc. |
| 148 | +8. Latin-1 (ISO-8859-1) encoding for Java sources; use `native2ascii` to convert |
| 149 | +if necessary |
| 150 | + |
| 151 | +== Add Apache license header to all new classes |
| 152 | + |
| 153 | +[source, java] |
| 154 | +---- |
| 155 | +/* |
| 156 | + * Copyright 2016 the original author or authors. |
| 157 | + * |
| 158 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 159 | + * you may not use this file except in compliance with the License. |
| 160 | + * You may obtain a copy of the License at |
| 161 | + * |
| 162 | + * https://www.apache.org/licenses/LICENSE-2.0 |
| 163 | + * |
| 164 | + * Unless required by applicable law or agreed to in writing, software |
| 165 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 166 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 167 | + * See the License for the specific language governing permissions and |
| 168 | + * limitations under the License. |
| 169 | + */ |
| 170 | +
|
| 171 | +package ...; |
| 172 | +---- |
| 173 | + |
| 174 | +== Update license header to modified files as necessary |
| 175 | + |
| 176 | +Always check the date range in the Apache license header. For example, if you've modified a file in 2016 whose header |
| 177 | +still reads |
| 178 | + |
| 179 | +[source java] |
| 180 | +---- |
| 181 | + * Copyright 2002-2011 the original author or authors. |
| 182 | +---- |
| 183 | + |
| 184 | +then be sure to update it to 2016 appropriately |
| 185 | + |
| 186 | +[source java] |
| 187 | +---- |
| 188 | + * Copyright 2002-2016 the original author or authors. |
| 189 | +---- |
| 190 | + |
| 191 | +== Use @since tags |
| 192 | + |
| 193 | +Use @since tags for newly-added public API types and methods e.g. |
| 194 | + |
| 195 | +[source java] |
| 196 | +---- |
| 197 | +/** |
| 198 | + * ... |
| 199 | + * |
| 200 | + * @author First Last |
| 201 | + * @since 3.0 |
| 202 | + * @see ... |
| 203 | + */ |
| 204 | +---- |
| 205 | + |
| 206 | +== Submit JUnit test cases for all behavior changes |
| 207 | + |
| 208 | +Search the codebase to find related unit tests and add additional @Test methods within. It is also acceptable to submit test cases on a per GitHub issue basis. |
| 209 | + |
| 210 | +== Squash commits |
| 211 | + |
| 212 | +Use `git rebase --interactive`, `git add --patch` and other tools to "squash" multiple commits into atomic changes. |
| 213 | +In addition to the man pages for git, there are many resources online to help you understand how these tools work. |
| 214 | + |
| 215 | +== Use your real name in git commits |
| 216 | + |
| 217 | +Please configure git to use your real first and last name for any commits you intend to submit as pull requests. For example, this is not acceptable: |
| 218 | + |
| 219 | + Author: Nickname < [email protected]> |
| 220 | + |
| 221 | +Rather, please include your first and last name, properly capitalized, as submitted against the SpringSource contributor license agreement: |
| 222 | + |
| 223 | + Author: First Last < [email protected]> |
| 224 | + |
| 225 | +This helps ensure traceability against the CLA, and also goes a long way to ensuring useful output from tools like `git shortlog` and others. |
| 226 | + |
| 227 | +You can configure this globally via the account admin area GitHub (useful for fork-and-edit cases); globally with |
| 228 | + |
| 229 | + git config --global user.name "First Last" |
| 230 | + git config --global user.email [email protected] |
| 231 | + |
| 232 | +or locally for the *spring-ai* repository only by omitting the '--global' flag: |
| 233 | + |
| 234 | + cd spring-ai |
| 235 | + git config user.name "First Last" |
| 236 | + git config user.email [email protected] |
| 237 | + |
| 238 | +== Run all tests prior to submission |
| 239 | + |
| 240 | +Make sure that all tests pass prior to submitting your pull request. |
| 241 | + |
| 242 | +== Mention your pull request on the associated GitHub issue |
| 243 | + |
| 244 | +Add a comment to the associated GitHub issue(s) linking to your new pull request. |
| 245 | + |
| 246 | +== Provide a Link to the GitHub issue in the Associated Pull Request |
| 247 | + |
| 248 | +There are multiple ways to link a Pull Request to a GitHub issue as described |
| 249 | +https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue[here]. |
| 250 | + |
| 251 | +One way would be to add a GitHub issue link to your first commit comment of the pull request on the second line, |
| 252 | +so your commit message may look like this: |
| 253 | + |
| 254 | +---- |
| 255 | + GH-1: Add Contribution Guidelines |
| 256 | +
|
| 257 | + Fixes GH-1 (https://github.com/spring-projects/spring-ai/issues/1) |
| 258 | +
|
| 259 | + * add `CONTRIBUTING.adoc` describing the Contribution procedure |
| 260 | + * mention Contribution Guidelines in the `README.md` |
| 261 | + * mention CODE_OF_CONDUCT in the `README.md` |
| 262 | +---- |
| 263 | + |
| 264 | +Also by using specific |
| 265 | +https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword[keywords] |
| 266 | +you can link to a GitHub issue like so: |
| 267 | + |
| 268 | + Closes #10 |
0 commit comments