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