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