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 276Please note that all meta-\* layers are separate repositories, so you need to 277follow the [subtree workflow](./subtree.md) when contributing there. 278 279If you're going to be working with Gerrit often, it's useful to create an SSH 280host block in ~/.ssh/config. Ex: 281``` 282Host openbmc.gerrit 283 Hostname gerrit.openbmc-project.xyz 284 Port 29418 285 User your_github_id 286``` 287 288From your OpenBMC git repository, add a remote to the Gerrit server, where 289'openbmc_repo' is the current git repository you're working on, such as 290phosphor-state-manager, and 'openbmc.gerrit' is the name of the Host previously 291added: 292 293 `git remote add gerrit ssh://openbmc.gerrit/openbmc/openbmc_repo` 294 295Gerrit uses [Change-Ids](https://gerrit-review.googlesource.com/Documentation/user-changeid.html) to identify commits that belong to the same 296review. Configure your git repository to automatically add a 297Change-Id to your commit messages. The steps are: 298 299 `gitdir=$(git rev-parse --git-dir)` 300 301 `scp -p -P 29418 openbmc.gerrit:hooks/commit-msg ${gitdir}/hooks` 302 303To submit a change set, commit your changes, and push to the Gerrit server, 304where 'gerrit' is the name of the remote added with the git remote add command: 305 306 `git push gerrit HEAD:refs/for/master` 307 308Gerrit will show you the URL link to your review. You can also find 309your reviews from the [OpenBMC Gerrit server](https://gerrit.openbmc-project.xyz) search bar 310or menu (All > Open, or My > Changes). 311 312Invite reviewers to review your changes. Each OpenBMC repository has 313a `MAINTAINERS` file that lists required reviewers who are subject 314matter experts. Those reviewers may add additional reviewers. To add 315reviewers from the Gerrit web page, click the "add reviewers" icon by 316the list of reviewers. 317 318You are expected to respond to all comments. And remember to use the 319"reply" button to publish your replies for others to see. 320 321The review results in the proposed change being accepted, rejected for 322rework, or abandoned. When you re-work your change, remember to use 323`git commit --amend` so Gerrit handles the update as a new patch of 324the same review. 325 326Each repository is governed by a small group of maintainers who are 327leaders with expertise in their area. They are responsible for 328reviewing changes and maintaining the quality of the code. You'll 329need a maintainer to accept your change, and they will look to the 330other reviewers for guidance. When accepted, your change will merge 331into the OpenBMC project. 332 333 334References to non-public resources 335---------------------------------------- 336 337Code and commit messages shall not refer to companies' internal documents 338or systems (including bug trackers). Other developers may not have access to 339these, making future maintenance difficult. 340 341Code contributed to OpenBMC must build from the publicly available sources, 342with no dependencies on non-public resources (URLs, repositories, etc). 343 344Best practices for D-Bus interfaces 345---------------------------------- 346 347 * New D-Bus interfaces should be reusable 348 349 * Type signatures should and use the simplest types possible, appropriate 350 for the data passed. For example, don't pass numbers as ASCII strings. 351 352 * D-Bus interfaces are defined in the `phosphor-dbus-interfaces` repository at: 353 354 https://github.com/openbmc/phosphor-dbus-interfaces 355 356See: http://dbus.freedesktop.org/doc/dbus-api-design.html 357 358 359Best practices for C 360-------------------- 361 362There are numerous resources available elsewhere, but a few items that are 363relevant to OpenBMC work: 364 365 * Do not use `system(<some shell pipeline>)`. Reading and writing from 366 files should be done with the appropriate system calls. 367 368 Generally, it's much better to use `fork(); execve()` if you do need to 369 spawn a process, especially if you need to provide variable arguments. 370 371 * Use the `stdint` types (eg, `uint32_t`, `int8_t`) for data that needs to be 372 a certain size. Use the `PRIxx` macros for printf, if necessary. 373 374 * Don't assume that `char` is signed or unsigned. 375 376 * Beware of endian considerations when reading to & writing from 377 C types 378 379 * Declare internal-only functions as `static`, declare read-only data 380 as `const` where possible. 381 382 * Ensure that your code compiles without warnings, especially for changes 383 to the kernel. 384 385## Pace of Review 386 387Contributors who are used to code reviews by their team internal to their own 388company, or who are not used to code reviews at all, are sometimes surprised by 389the pace of code reviews in open source projects. Try to keep in mind that those 390reviewing your patch may be contributing to OpenBMC in a volunteer or 391partial-time capacity, may be in a timezone far from your own, and may 392have very deep review queues already of patches which have been waiting longer 393than yours. Do everything you can to make it easy for the reviewer to review 394your contribution. 395 396If you feel your patch has been missed entirely, of course, it's 397alright to email the maintainers (addresses available in MAINTAINERS file) or 398ping them on Discord - but a reasonable timeframe to do so is on the order of a 399week, not on the order of hours. 400 401The maintainers' job is to ensure that incoming patches are as correct and easy 402to maintain as possible. Part of the nature of open source is attrition - 403contributors can come and go easily - so maintainers tend not to put stock in 404promises such as "I will add unit tests in a later patch" or "I will be 405implementing this proposal by the end of next month." This often manifests as 406reviews which may seem harsh or exacting; please keep in mind that the community 407is trying to collaborate with you to build a patch that will benefit the project 408on its own. 409 410Developer's Certificate of Origin 1.1 411------------------------------------- 412 413 By making a contribution to this project, I certify that: 414 415 (a) The contribution was created in whole or in part by me and I 416 have the right to submit it under the open source license 417 indicated in the file; or 418 419 (b) The contribution is based upon previous work that, to the best 420 of my knowledge, is covered under an appropriate open source 421 license and I have the right under that license to submit that 422 work with modifications, whether created in whole or in part 423 by me, under the same open source license (unless I am 424 permitted to submit under a different license), as indicated 425 in the file; or 426 427 (c) The contribution was provided directly to me by some other 428 person who certified (a), (b) or (c) and I have not modified 429 it. 430 431 (d) I understand and agree that this project and the contribution 432 are public and that a record of the contribution (including all 433 personal information I submit with it, including my sign-off) is 434 maintained indefinitely and may be redistributed consistent with 435 this project or the open source license(s) involved. 436