1Contributing to OpenBMC 2======================= 3 4First off, thanks for taking the time to contribute! The following is a set of 5guidelines for contributing to an OpenBMC repository which are hosted in the 6[OpenBMC Organization](https://github.com/openbmc) on GitHub. Feel free to 7propose changes to this document. 8 9## Code of Conduct 10 11We enthusiastically adhere to our 12[Code of Conduct](https://github.com/openbmc/docs/blob/master/code-of-conduct.md). 13If you have any concerns, please check that document for guidelines on who can 14help you resolve them. 15 16Structure 17--------- 18 19OpenBMC has quite a modular structure, consisting of small daemons with a 20limited set of responsibilities. These communicate over D-Bus with other 21components, to implement the complete BMC system. 22 23The BMC's interfaces to the external world are typically through a separate 24daemon, which then translates those requests to D-Bus messages. 25 26These separate projects are then compiled into the final system by the 27overall 'openbmc' build infrastructure. 28 29For future development, keep this design in mind. Components' functionality 30should be logically grouped, and keep related parts together where it 31makes sense. 32 33Starting out 34------------ 35 36If you're starting out with OpenBMC, you may want to take a look at the issues 37tagged with 'bitesize'. These are fixes or enhancements that don't require 38extensive knowledge of the OpenBMC codebase, and are easier for a newcomer to 39start working with. 40 41Check out that list here: 42 43 https://github.com/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+user%3Aopenbmc+label%3Abitesize 44 45If you need further details on any of these issues, feel free to add comments. 46 47Performing code reviews is another good way to get started. Go to 48https://gerrit.openbmc-project.xyz and click on the "all" and "open" 49menu items, or if you are interested in a particular repository - for 50example, "bmcweb" - type "status:open project:openbmc/bmcweb" into the 51search bar and press the "search" button. Then select a review. 52Remember to be positive and add value with every review comment. 53 54Coding style 55------------ 56 57Components of the OpenBMC sources should have a consistent style. If the source is 58coming from another project, we choose to follow the existing style of the 59upstream project. Otherwise, conventions are chosen based on the language. 60 61### Python 62 63Python source should all conform to PEP8. This style is well established 64within the Python community and can be verified with the 'pycodestyle' tool. 65 66https://www.python.org/dev/peps/pep-0008/ 67 68### Python Formatting 69 70If a repository has a setup.cfg file present in its root directory, 71then CI will automatically verify the Python code meets the [pycodestyle](http://pycodestyle.pycqa.org/en/latest/intro.html) 72requirements. This enforces PEP 8 standards on all Python code. 73 74OpenBMC standards for Python match with PEP 8 so in general, a blank setup.cfg 75file is all that's needed. If so desired, enforcement of 80 76(vs. the default 79) chars is fine as well: 77``` 78[pycodestyle] 79max-line-length = 80 80``` 81By default, pycodestyle does not enforce the following rules: E121, E123, E126, 82E133, E226, E241, E242, E704, W503, and W504. These rules are ignored because 83they are not unanimously accepted and PEP 8 does not enforce them. It is at the 84repository maintainer's discretion as to whether to enforce the aforementioned 85rules. These rules can be enforced by adding the following to the setup.cfg: 86``` 87[pycodestyle] 88ignore= NONE 89``` 90 91### JavaScript 92 93We follow the 94[Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html). 95 96[Example .clang-format](https://www.github.com/openbmc/docs/blob/master/style/javascript/.clang-format) 97 98### HTML/CSS 99 100We follow the 101[Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html). 102 103### C 104 105For C code, we typically use the Linux coding style, which is documented at: 106 107 http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst 108 109In short: 110 111 - Indent with tabs instead of spaces, set at 8 columns 112 113 - 80-column lines 114 115 - Opening braces on the end of a line, except for functions 116 117This style can mostly be verified with 'astyle' as follows: 118 119 astyle --style=linux --indent=tab=8 --indent=force-tab=8 120 121### C++ 122 123See [C++ Style and Conventions](./cpp-style-and-conventions.md). 124 125Planning changes 126---------------- 127 128If you are making a nontrivial change, you should plan how to 129introduce it to the OpenBMC development community. 130 131If you are planning a new function, you should get agreement that your 132change will be accepted. As early as you can, introduce the change 133via the OpenBMC Discord server or email list to start 134the discussion. You may find a better way to do what you need. 135 136Submitting changes 137------------------ 138 139We use git for almost everything. Most projects in OpenBMC use Gerrit to review 140patches. Changes to an upstream project (e.g. Yocto Project, systemd, or the 141Linux kernel) might need to be sent as patches or a git pull request. 142 143### Organizing Commits 144 145A good commit does exactly one thing. We prefer many small, atomic commits to 146one large commit which makes many functional changes. 147 - Too large: "convert foo to new API; also fix CVE 1234 in bar" 148 - Too small: "move abc.h to top of include list" and "move xyz.h to bottom of 149 include list" 150 - Just right: "convert foo to new API" and "convert foo from tab to space" 151 152Other commit tips: 153 - If your change has a specification, sketch out your ideas first 154 and work to get that accepted before completing the details. 155 - Work at most a few days before seeking review. 156 - Commit and review header files before writing code. 157 - Commit and review each implementation module separately. 158 159Often, creating small commits this way results in many commits that are 160dependent on prior commits; Gerrit handles this situation well, so feel free to 161push commits which are based on your change still in review. However, when 162possible, your commit should stand alone on top of master - "Fix whitespace in 163bar()" does not need to depend on "refactor foo()". Said differently, ensure 164that topics that are not related to each other semantically are also not 165related to each other in Git until they are merged into master. 166 167When pushing a stack of patches, these commits will show up with that same 168relationship in Gerrit. This means that each patch must be merged in order of 169that relationship. So if one of the patches in the middle needs to be changed, 170all the patches from that point on would need to be pushed to maintain the 171relationship. This will effectively rebase the unchanged patches, which would 172in turn trigger a new CI build. Ideally, changes from the entire patchset could 173be done all in one go to reduce unnecessary rebasing. 174 175When someone makes a comment on your commit in Gerrit, modify that commit and 176send it again to Gerrit. This typically involves `git rebase --interactive` or 177`git commit --amend`, for which there are many guides online. As mentioned in 178the paragraph above, when possible you should make changes to multiple patches 179in the same stack before you push, in order to minimize CI and notification 180churn from the rebase operations. 181 182Commits which include changes that can be tested by a unit test should also 183include a unit test to exercise that change, within the same commit. Unit tests 184should be clearly written - even more so than production code, unit tests are 185meant primarily to be read by humans - and should test both good and bad 186behaviors. Refer to the 187[testing documentation](https://github.com/openbmc/docs/blob/master/testing/local-ci-build.md) 188for help writing tests, as well as best practices. 189 190Ensure that your patch doesn't change unrelated areas. Be careful of 191accidental whitespace changes - this makes review unnecessarily difficult. 192 193### Formatting Commit Messages 194 195Your commit message should explain: 196 197 - Concisely, *what* change are you making? e.g. "libpldm: Add APIs to enable 198 PLDM Requester" This first line of your commit message is the subject line. 199 - Comprehensively, *why* are you making that change? In some cases, like a 200 small refactor, the why is fairly obvious. But in cases like the inclusion of 201 a new feature, you should explain why the feature is needed. 202 - Concisely, *how* did you test? (see below). 203 204Try to include the component you are changing at the front of your subject line; 205this typically comes in the form of the class, module, handler, or directory you 206are modifying. e.g. "apphandler: refactor foo to new API" 207 208Loosely, we try to follow the 50/72 rule for commit messages - that is, the 209subject line should not exceed 50 characters and the body should not exceed 72 210characters. This is common practice in many projects which use Git. 211 212All commit messages must include a "Signed-off-by" line, which indicates that 213you the contributor have agreed to the Developer Certificate of Origin 214(see below). This line must include the full name you commonly use, often a 215given name and a family name or surname. (ok: Sam Samuelsson, Robert A. 216Heinlein; not ok: xXthorXx, Sam, RAH) 217 218### Testing 219 220Each commit is expected to be tested. The expectation of testing may vary from 221subproject to subproject, but will typically include running all applicable 222automated tests and performing manual testing. Each commit should be tested 223separately, even if they are submitted together (an exception is when commits 224to different projects depend on each other). 225 226Commit messages should include a "Tested" field describing how you tested the 227code changes in the patch. Example: 228``` 229 Tested: I ran unit tests with "make check" (added 2 new tests) and manually 230 tested on Witherspoon that Foo daemon no longer crashes at boot. 231``` 232 233If the change required manual testing, describe what you did and what happened; 234if it used to do something else before your change, describe that too. If the 235change can be validated entirely by running unit tests, say so in the "Tested:" 236field. 237 238### Linux Kernel 239 240The guidelines in the Linux kernel are very useful: 241 242https://www.kernel.org/doc/html/latest/process/submitting-patches.html 243 244https://www.kernel.org/doc/html/latest/process/submit-checklist.html 245 246Your contribution will generally need to be reviewed before being accepted. 247 248 249Submitting changes via Gerrit server to OpenBMC 250----------------------------------------------- 251 252The OpenBMC Gerrit server supports GitHub credentials, its link is: 253 254 https://gerrit.openbmc-project.xyz/#/q/status:open 255 256_One time only_: Execute one of the OpenBMC Contributor License Agreements: 257 258* [Individual CLA](https://github.com/openbmc/openbmc/files/1860742/OpenBMC.ICLA.pdf) 259* [Corporate CLA](https://github.com/openbmc/openbmc/files/1860741/OpenBMC.CCLA.pdf) 260 261If you work for someone, consider asking them to execute the corporate CLA. This 262allows other contributors that work for your employer to skip the CLA signing process. 263 264After signing a CLA, send it to openbmc@lists.ozlabs.org. 265 266_One time setup_: Login to the WebUI with your GitHub credentials and verify on 267your Account Settings that your SSH keys were imported: 268 269 https://gerrit.openbmc-project.xyz/#/settings/ 270 271Most repositories are supported by the Gerrit server, the current list can be 272found under Projects -> List: 273 274 https://gerrit.openbmc-project.xyz/#/admin/projects/ 275 276If you're going to be working with Gerrit often, it's useful to create an SSH 277host block in ~/.ssh/config. Ex: 278``` 279Host openbmc.gerrit 280 Hostname gerrit.openbmc-project.xyz 281 Port 29418 282 User your_github_id 283``` 284 285From your OpenBMC git repository, add a remote to the Gerrit server, where 286'openbmc_repo' is the current git repository you're working on, such as 287phosphor-state-manager, and 'openbmc.gerrit' is the name of the Host previously 288added: 289 290 `git remote add gerrit ssh://openbmc.gerrit/openbmc/openbmc_repo` 291 292Gerrit uses [Change-Ids](https://gerrit-review.googlesource.com/Documentation/user-changeid.html) to identify commits that belong to the same 293review. Configure your git repository to automatically add a 294Change-Id to your commit messages. The steps are: 295 296 `gitdir=$(git rev-parse --git-dir)` 297 298 `scp -p -P 29418 openbmc.gerrit:hooks/commit-msg ${gitdir}/hooks` 299 300To submit a change set, commit your changes, and push to the Gerrit server, 301where 'gerrit' is the name of the remote added with the git remote add command: 302 303 `git push gerrit HEAD:refs/for/master` 304 305Gerrit will show you the URL link to your review. You can also find 306your reviews from the [OpenBMC Gerrit server](https://gerrit.openbmc-project.xyz) search bar 307or menu (All > Open, or My > Changes). 308 309Invite reviewers to review your changes. Each OpenBMC repository has 310a `MAINTAINERS` file that lists required reviewers who are subject 311matter experts. Those reviewers may add additional reviewers. To add 312reviewers from the Gerrit web page, click the "add reviewers" icon by 313the list of reviewers. 314 315You are expected to respond to all comments. And remember to use the 316"reply" button to publish your replies for others to see. 317 318The review results in the proposed change being accepted, rejected for 319rework, or abandoned. When you re-work your change, remember to use 320`git commit --amend` so Gerrit handles the update as a new patch of 321the same review. 322 323Each repository is governed by a small group of maintainers who are 324leaders with expertise in their area. They are responsible for 325reviewing changes and maintaining the quality of the code. You'll 326need a maintainer to accept your change, and they will look to the 327other reviewers for guidance. When accepted, your change will merge 328into the OpenBMC project. 329 330 331References to non-public resources 332---------------------------------------- 333 334Code and commit messages shall not refer to companies' internal documents 335or systems (including bug trackers). Other developers may not have access to 336these, making future maintenance difficult. 337 338Code contributed to OpenBMC must build from the publicly available sources, 339with no dependencies on non-public resources (URLs, repositories, etc). 340 341Best practices for D-Bus interfaces 342---------------------------------- 343 344 * New D-Bus interfaces should be reusable 345 346 * Type signatures should and use the simplest types possible, appropriate 347 for the data passed. For example, don't pass numbers as ASCII strings. 348 349 * D-Bus interfaces are defined in the `phosphor-dbus-interfaces` repository at: 350 351 https://github.com/openbmc/phosphor-dbus-interfaces 352 353See: http://dbus.freedesktop.org/doc/dbus-api-design.html 354 355 356Best practices for C 357-------------------- 358 359There are numerous resources available elsewhere, but a few items that are 360relevant to OpenBMC work: 361 362 * Do not use `system(<some shell pipeline>)`. Reading and writing from 363 files should be done with the appropriate system calls. 364 365 Generally, it's much better to use `fork(); execve()` if you do need to 366 spawn a process, especially if you need to provide variable arguments. 367 368 * Use the `stdint` types (eg, `uint32_t`, `int8_t`) for data that needs to be 369 a certain size. Use the `PRIxx` macros for printf, if necessary. 370 371 * Don't assume that `char` is signed or unsigned. 372 373 * Beware of endian considerations when reading to & writing from 374 C types 375 376 * Declare internal-only functions as `static`, declare read-only data 377 as `const` where possible. 378 379 * Ensure that your code compiles without warnings, especially for changes 380 to the kernel. 381 382## Pace of Review 383 384Contributors who are used to code reviews by their team internal to their own 385company, or who are not used to code reviews at all, are sometimes surprised by 386the pace of code reviews in open source projects. Try to keep in mind that those 387reviewing your patch may be contributing to OpenBMC in a volunteer or 388partial-time capacity, may be in a timezone far from your own, and may 389have very deep review queues already of patches which have been waiting longer 390than yours. Do everything you can to make it easy for the reviewer to review 391your contribution. 392 393If you feel your patch has been missed entirely, of course, it's 394alright to email the maintainers (addresses available in MAINTAINERS file) or 395ping them on Discord - but a reasonable timeframe to do so is on the order of a 396week, not on the order of hours. 397 398The maintainers' job is to ensure that incoming patches are as correct and easy 399to maintain as possible. Part of the nature of open source is attrition - 400contributors can come and go easily - so maintainers tend not to put stock in 401promises such as "I will add unit tests in a later patch" or "I will be 402implementing this proposal by the end of next month." This often manifests as 403reviews which may seem harsh or exacting; please keep in mind that the community 404is trying to collaborate with you to build a patch that will benefit the project 405on its own. 406 407Developer's Certificate of Origin 1.1 408------------------------------------- 409 410 By making a contribution to this project, I certify that: 411 412 (a) The contribution was created in whole or in part by me and I 413 have the right to submit it under the open source license 414 indicated in the file; or 415 416 (b) The contribution is based upon previous work that, to the best 417 of my knowledge, is covered under an appropriate open source 418 license and I have the right under that license to submit that 419 work with modifications, whether created in whole or in part 420 by me, under the same open source license (unless I am 421 permitted to submit under a different license), as indicated 422 in the file; or 423 424 (c) The contribution was provided directly to me by some other 425 person who certified (a), (b) or (c) and I have not modified 426 it. 427 428 (d) I understand and agree that this project and the contribution 429 are public and that a record of the contribution (including all 430 personal information I submit with it, including my sign-off) is 431 maintained indefinitely and may be redistributed consistent with 432 this project or the open source license(s) involved. 433