1d81ca1aeSLucio Franco# Contributing to Tonic 202487becSLucio Franco 302487becSLucio Franco:balloon: Thanks for your help improving the project! We are so happy to have 402487becSLucio Francoyou! 502487becSLucio Franco 602487becSLucio FrancoThere are opportunities to contribute to `tonic` at any level. It doesn't 702487becSLucio Francomatter if you are just getting started with Rust or are the most weathered 802487becSLucio Francoexpert, we can use your help. 902487becSLucio Franco 1002487becSLucio Franco**No contribution is too small and all contributions are valued.** 1102487becSLucio Franco 1202487becSLucio FrancoThis guide will help you get started. **Do not let this guide intimidate you**. 1302487becSLucio FrancoIt should be considered a map to help you navigate the process. 1402487becSLucio Franco 1502487becSLucio FrancoYou may also get help with contributing in the `dev` channel, please join 1602487becSLucio Francous! 1702487becSLucio Franco 1802487becSLucio FrancoTonic is a part of the [Tokio][tokio] and [Hyperium][hyperium] project, and follows the project's 1902487becSLucio Francoguidelines for contributing. This document is based on the 2002487becSLucio Franco[`CONTRIBUTING.md` file][tokio-contrib] in the `tokio-rs/tokio` repository. 2102487becSLucio Franco 2202487becSLucio Franco[dev]: https://gitter.im/tokio-rs/dev 2302487becSLucio Franco[tokio]: https://tokio.rs 2402487becSLucio Franco[hyperium]: https://github.com/hyperium 2502487becSLucio Franco[tokio-contrib]: https://github.com/tokio-rs/tokio/blob/master/CONTRIBUTING.md 2602487becSLucio Franco 2702487becSLucio Franco## Conduct 2802487becSLucio Franco 2902487becSLucio FrancoThe `tonic` project adheres to the [Rust Code of Conduct][coc]. This describes 3002487becSLucio Francothe _minimum_ behavior expected from all contributors. 3102487becSLucio Franco 3202487becSLucio Franco[coc]: https://github.com/rust-lang/rust/blob/master/CODE_OF_CONDUCT.md 3302487becSLucio Franco 3402487becSLucio Franco## Contributing in Issues 3502487becSLucio Franco 3602487becSLucio FrancoFor any issue, there are fundamentally three ways an individual can contribute: 3702487becSLucio Franco 3802487becSLucio Franco1. By opening the issue for discussion: For instance, if you believe that you 3902487becSLucio Franco have uncovered a bug in a `tonic` crate, creating a new issue in the 4002487becSLucio Franco hyperium/tonic [issue tracker][issues] is the way to report it. 4102487becSLucio Franco 4202487becSLucio Franco2. By helping to triage the issue: This can be done by providing 4302487becSLucio Franco supporting details (a test case that demonstrates a bug), providing 4402487becSLucio Franco suggestions on how to address the issue, or ensuring that the issue is tagged 4502487becSLucio Franco correctly. 4602487becSLucio Franco 4702487becSLucio Franco3. By helping to resolve the issue: Typically this is done either in the form of 4802487becSLucio Franco demonstrating that the issue reported is not a problem after all, or more 4902487becSLucio Franco often, by opening a Pull Request that changes some bit of something in 5002487becSLucio Franco Tokio in a concrete and reviewable manner. 5102487becSLucio Franco 5202487becSLucio Franco**Anybody can participate in any stage of contribution**. We urge you to 5302487becSLucio Francoparticipate in the discussion around bugs and participate in reviewing PRs. 5402487becSLucio Franco 5502487becSLucio Franco[issues]: https://github.com/hyperium/tonic/issues 5602487becSLucio Franco 5702487becSLucio Franco### Asking for General Help 5802487becSLucio Franco 5902487becSLucio FrancoIf you have reviewed existing documentation and still have questions or are 6002487becSLucio Francohaving problems, you can open an issue asking for help. 6102487becSLucio Franco 6202487becSLucio FrancoIn exchange for receiving help, we ask that you contribute back a documentation 6302487becSLucio FrancoPR that helps others avoid the problems that you encountered. 6402487becSLucio Franco 6502487becSLucio Franco### Submitting a Bug Report 6602487becSLucio Franco 6702487becSLucio FrancoWhen opening a new issue in the `tonic` issue tracker, users will 6802487becSLucio Francobe presented with a [basic template][template] that should be filled in. If you 6902487becSLucio Francobelieve that you have uncovered a bug, please fill out this form, following the 7002487becSLucio Francotemplate to the best of your ability. Do not worry if you cannot answer every 7102487becSLucio Francodetail, just fill in what you can. 7202487becSLucio Franco 7302487becSLucio FrancoThe two most important pieces of information we need in order to properly 7402487becSLucio Francoevaluate the report is a description of the behavior you are seeing and a simple 7502487becSLucio Francotest case we can use to recreate the problem on our own. If we cannot recreate 7602487becSLucio Francothe issue, it becomes impossible for us to fix. 7702487becSLucio Franco 7802487becSLucio FrancoIn order to rule out the possibility of bugs introduced by userland code, test 7902487becSLucio Francocases should be limited, as much as possible, to using only Tokio APIs. 8002487becSLucio Franco 8102487becSLucio FrancoSee [How to create a Minimal, Complete, and Verifiable example][mcve]. 8202487becSLucio Franco 8302487becSLucio Franco[mcve]: https://stackoverflow.com/help/mcve 8402487becSLucio Franco[template]: .github/ISSUE_TEMPLATE/bug_report.md 8502487becSLucio Franco 8602487becSLucio Franco### Triaging a Bug Report 8702487becSLucio Franco 8802487becSLucio FrancoOnce an issue has been opened, it is not uncommon for there to be discussion 8902487becSLucio Francoaround it. Some contributors may have differing opinions about the issue, 9002487becSLucio Francoincluding whether the behavior being seen is a bug or a feature. This discussion 9102487becSLucio Francois part of the process and should be kept focused, helpful, and professional. 9202487becSLucio Franco 9302487becSLucio FrancoShort, clipped responses—that provide neither additional context nor supporting 9402487becSLucio Francodetail—are not helpful or professional. To many, such responses are simply 9502487becSLucio Francoannoying and unfriendly. 9602487becSLucio Franco 9702487becSLucio FrancoContributors are encouraged to help one another make forward progress as much as 9802487becSLucio Francopossible, empowering one another to solve issues collaboratively. If you choose 9902487becSLucio Francoto comment on an issue that you feel either is not a problem that needs to be 10002487becSLucio Francofixed, or if you encounter information in an issue that you feel is incorrect, 10102487becSLucio Francoexplain why you feel that way with additional supporting context, and be willing 10202487becSLucio Francoto be convinced that you may be wrong. By doing so, we can often reach the 10302487becSLucio Francocorrect outcome much faster. 10402487becSLucio Franco 10502487becSLucio Franco### Resolving a Bug Report 10602487becSLucio Franco 10702487becSLucio FrancoIn the majority of cases, issues are resolved by opening a Pull Request. The 10802487becSLucio Francoprocess for opening and reviewing a Pull Request is similar to that of opening 10902487becSLucio Francoand triaging issues, but carries with it a necessary review and approval 11002487becSLucio Francoworkflow that ensures that the proposed changes meet the minimal quality and 11102487becSLucio Francofunctional guidelines of the Tokio project. 11202487becSLucio Franco 11302487becSLucio Franco## Pull Requests 11402487becSLucio Franco 11502487becSLucio FrancoPull Requests are the way concrete changes are made to the code, documentation, 11602487becSLucio Francoand dependencies in the `tonic` repository. 11702487becSLucio Franco 11802487becSLucio FrancoEven tiny pull requests (e.g., one character pull request fixing a typo in API 11902487becSLucio Francodocumentation) are greatly appreciated. Before making a large change, it is 12002487becSLucio Francousually a good idea to first open an issue describing the change to solicit 12102487becSLucio Francofeedback and guidance. This will increase the likelihood of the PR getting 12202487becSLucio Francomerged. 12302487becSLucio Franco 12402487becSLucio Franco### Tests 12502487becSLucio Franco 12602487becSLucio FrancoIf the change being proposed alters code (as opposed to only documentation for 12702487becSLucio Francoexample), it is either adding new functionality to a crate or it is fixing 12802487becSLucio Francoexisting, broken functionality. In both of these cases, the pull request should 12902487becSLucio Francoinclude one or more tests to ensure that the crate does not regress in the future. 13002487becSLucio FrancoThere are two ways to write tests: integration tests and documentation tests 13102487becSLucio Franco(Tokio avoids unit tests as much as possible). 13202487becSLucio Franco 13302487becSLucio Franco#### Integration tests 13402487becSLucio Franco 13502487becSLucio FrancoIntegration tests go in the same crate as the code they are testing. Each sub 13602487becSLucio Francocrate should have a `dev-dependency` on `tonic` itself. This makes all 13702487becSLucio Franco`tonic` utilities available to use in tests, no matter the crate being 13802487becSLucio Francotested. 13902487becSLucio Franco 14002487becSLucio FrancoThe best strategy for writing a new integration test is to look at existing 14102487becSLucio Francointegration tests in the crate and follow the style. 14202487becSLucio Franco 14302487becSLucio Franco#### Documentation tests 14402487becSLucio Franco 14502487becSLucio FrancoIdeally, every API has at least one [documentation test] that demonstrates how to 14602487becSLucio Francouse the API. Documentation tests are run with `cargo test --doc`. This ensures 14702487becSLucio Francothat the example is correct and provides additional test coverage. 14802487becSLucio Franco 14902487becSLucio FrancoThe trick to documentation tests is striking a balance between being succinct 15002487becSLucio Francofor a reader to understand and actually testing the API. 15102487becSLucio Franco 15202487becSLucio FrancoThe type level example for `tokio_timer::Timeout` provides a good example of a 15302487becSLucio Francodocumentation test: 15402487becSLucio Franco 15502487becSLucio Franco```rust 15602487becSLucio Franco/// // import the `timeout` function, usually this is done 15702487becSLucio Franco/// // with `use tokio::prelude::*` 15802487becSLucio Franco/// use tokio::prelude::FutureExt; 15902487becSLucio Franco/// use futures::Stream; 16002487becSLucio Franco/// use futures::sync::mpsc; 16102487becSLucio Franco/// use std::time::Duration; 16202487becSLucio Franco/// 16302487becSLucio Franco/// # fn main() { 16402487becSLucio Franco/// let (tx, rx) = mpsc::unbounded(); 16502487becSLucio Franco/// # tx.unbounded_send(()).unwrap(); 16602487becSLucio Franco/// # drop(tx); 16702487becSLucio Franco/// 16802487becSLucio Franco/// let process = rx.for_each(|item| { 16902487becSLucio Franco/// // do something with `item` 17002487becSLucio Franco/// # drop(item); 17102487becSLucio Franco/// # Ok(()) 17202487becSLucio Franco/// }); 17302487becSLucio Franco/// 17402487becSLucio Franco/// # tokio::runtime::current_thread::block_on_all( 17502487becSLucio Franco/// // Wrap the future with a `Timeout` set to expire in 10 milliseconds. 17602487becSLucio Franco/// process.timeout(Duration::from_millis(10)) 17702487becSLucio Franco/// # ).unwrap(); 17802487becSLucio Franco/// # } 17902487becSLucio Franco``` 18002487becSLucio Franco 18102487becSLucio FrancoGiven that this is a *type* level documentation test and the primary way users 18202487becSLucio Francoof `tokio` will create an instance of `Timeout` is by using 18302487becSLucio Franco`FutureExt::timeout`, this is how the documentation test is structured. 18402487becSLucio Franco 18502487becSLucio FrancoLines that start with `/// #` are removed when the documentation is generated. 18602487becSLucio FrancoThey are only there to get the test to run. The `block_on_all` function is the 18702487becSLucio Francoeasiest way to execute a future from a test. 18802487becSLucio Franco 18902487becSLucio FrancoIf this were a documentation test for the `Timeout::new` function, then the 19002487becSLucio Francoexample would explicitly use `Timeout::new`. For example: 19102487becSLucio Franco 19202487becSLucio Franco```rust 19302487becSLucio Franco/// use tokio::timer::Timeout; 19402487becSLucio Franco/// use futures::Future; 19502487becSLucio Franco/// use futures::sync::oneshot; 19602487becSLucio Franco/// use std::time::Duration; 19702487becSLucio Franco/// 19802487becSLucio Franco/// # fn main() { 19902487becSLucio Franco/// let (tx, rx) = oneshot::channel(); 20002487becSLucio Franco/// # tx.send(()).unwrap(); 20102487becSLucio Franco/// 20202487becSLucio Franco/// # tokio::runtime::current_thread::block_on_all( 20302487becSLucio Franco/// // Wrap the future with a `Timeout` set to expire in 10 milliseconds. 20402487becSLucio Franco/// Timeout::new(rx, Duration::from_millis(10)) 20502487becSLucio Franco/// # ).unwrap(); 20602487becSLucio Franco/// # } 20702487becSLucio Franco``` 20802487becSLucio Franco 20926b848beSLucio Franco#### Generated code 21026b848beSLucio Franco 21126b848beSLucio FrancoWhen making changes to `tonic-build` that affects the generated code you will 21226b848beSLucio Franconeed to ensure that each of the sub crates gets updated as well. Each of the sub 21344aa46dbStottotocrates like, for example `tonic-health`, generate their gRPC code via `codegen` 214*6d93c1d0Stottotocrate. 21526b848beSLucio Franco 21626b848beSLucio Franco``` 21744aa46dbStottotocargo run --package codegen 21826b848beSLucio Franco``` 21926b848beSLucio Franco 22002487becSLucio Franco### Commits 22102487becSLucio Franco 22202487becSLucio FrancoIt is a recommended best practice to keep your changes as logically grouped as 22302487becSLucio Francopossible within individual commits. There is no limit to the number of commits 22402487becSLucio Francoany single Pull Request may have, and many contributors find it easier to review 22502487becSLucio Francochanges that are split across multiple commits. 22602487becSLucio Franco 22702487becSLucio FrancoThat said, if you have a number of commits that are "checkpoints" and don't 22802487becSLucio Francorepresent a single logical change, please squash those together. 22902487becSLucio Franco 23002487becSLucio FrancoNote that multiple commits often get squashed when they are landed (see the 23102487becSLucio Franconotes about [commit squashing]). 23202487becSLucio Franco 23302487becSLucio Franco#### Commit message guidelines 23402487becSLucio Franco 23502487becSLucio FrancoA good commit message should describe what changed and why. 23602487becSLucio Franco 23702487becSLucio Franco1. The first line should: 23802487becSLucio Franco 23902487becSLucio Franco * contain a short description of the change (preferably 50 characters or less, 24002487becSLucio Franco and no more than 72 characters) 24102487becSLucio Franco * be entirely in lowercase with the exception of proper nouns, acronyms, and 24202487becSLucio Franco the words that refer to code, like function/variable names 24302487becSLucio Franco * be prefixed with the name of the crate being changed (without the 24402487becSLucio Franco `tonic` prefix) and start with an imperative verb. 24502487becSLucio Franco 24602487becSLucio Franco Examples: 24702487becSLucio Franco 24802487becSLucio Franco * build: add regex for parsing field filters 24902487becSLucio Franco * tonic: add `Clone` impl for `Service` and `MakeService` 25002487becSLucio Franco 25102487becSLucio Franco2. Keep the second line blank. 25202487becSLucio Franco3. Wrap all other lines at 72 columns (except for long URLs). 25302487becSLucio Franco4. If your patch fixes an open issue, you can add a reference to it at the end 25402487becSLucio Franco of the log. Use the `Fixes: #` prefix and the issue number. For other 25502487becSLucio Franco references use `Refs: #`. `Refs` may include multiple issues, separated by a 25602487becSLucio Franco comma. 25702487becSLucio Franco 25802487becSLucio Franco Examples: 25902487becSLucio Franco 26002487becSLucio Franco - `Fixes: #1337` 26102487becSLucio Franco - `Refs: #1234` 26202487becSLucio Franco 26302487becSLucio FrancoSample complete commit message: 26402487becSLucio Franco 26502487becSLucio Franco```txt 26602487becSLucio Francosubcrate: explain the commit in one line 26702487becSLucio Franco 26802487becSLucio FrancoBody of commit message is a few lines of text, explaining things 26902487becSLucio Francoin more detail, possibly giving some background about the issue 27002487becSLucio Francobeing fixed, etc. 27102487becSLucio Franco 27202487becSLucio FrancoThe body of the commit message can be several paragraphs, and 27302487becSLucio Francoplease do proper word-wrap and keep columns shorter than about 27402487becSLucio Franco72 characters or so. That way, `git log` will show things 27502487becSLucio Franconicely even when it is indented. 27602487becSLucio Franco 27702487becSLucio FrancoFixes: #1337 27802487becSLucio FrancoRefs: #453, #154 27902487becSLucio Franco``` 28002487becSLucio Franco 28102487becSLucio Franco### Opening the Pull Request 28202487becSLucio Franco 28302487becSLucio FrancoFrom within GitHub, opening a new Pull Request will present you with a 28402487becSLucio Franco[template] that should be filled out. Please try to do your best at filling out 28502487becSLucio Francothe details, but feel free to skip parts if you're not sure what to put. 28602487becSLucio Franco 28702487becSLucio Franco[template]: .github/PULL_REQUEST_TEMPLATE.md 28802487becSLucio Franco 28902487becSLucio Franco### Discuss and update 29002487becSLucio Franco 29102487becSLucio FrancoYou will probably get feedback or requests for changes to your Pull Request. 29202487becSLucio FrancoThis is a big part of the submission process so don't be discouraged! Some 29302487becSLucio Francocontributors may sign off on the Pull Request right away, others may have 29402487becSLucio Francomore detailed comments or feedback. This is a necessary part of the process 29502487becSLucio Francoin order to evaluate whether the changes are correct and necessary. 29602487becSLucio Franco 29702487becSLucio Franco**Any community member can review a PR and you might get conflicting feedback**. 29802487becSLucio FrancoKeep an eye out for comments from code owners to provide guidance on conflicting 29902487becSLucio Francofeedback. 30002487becSLucio Franco 30102487becSLucio Franco**Once the PR is open, do not rebase the commits**. See [Commit Squashing] for 30202487becSLucio Francomore details. 30302487becSLucio Franco 30402487becSLucio Franco### Commit Squashing 30502487becSLucio Franco 30602487becSLucio FrancoIn most cases, **do not squash commits that you add to your Pull Request during 30702487becSLucio Francothe review process**. When the commits in your Pull Request land, they may be 30802487becSLucio Francosquashed into one commit per logical change. Metadata will be added to the 30902487becSLucio Francocommit message (including links to the Pull Request, links to relevant issues, 31002487becSLucio Francoand the names of the reviewers). The commit history of your Pull Request, 31102487becSLucio Francohowever, will stay intact on the Pull Request page. 31202487becSLucio Franco 31302487becSLucio Franco## Reviewing Pull Requests 31402487becSLucio Franco 31502487becSLucio Franco**Any Tokio and Hyperium community member is welcome to review any pull request**. 31602487becSLucio Franco 31702487becSLucio FrancoAll Tokio contributors who choose to review and provide feedback on Pull 31802487becSLucio FrancoRequests have a responsibility to both the project and the individual making the 31902487becSLucio Francocontribution. Reviews and feedback must be helpful, insightful, and geared 32002487becSLucio Francotowards improving the contribution as opposed to simply blocking it. If there 32102487becSLucio Francoare reasons why you feel the PR should not land, explain what those are. Do not 32202487becSLucio Francoexpect to be able to block a Pull Request from advancing simply because you say 32302487becSLucio Franco"No" without giving an explanation. Be open to having your mind changed. Be open 32402487becSLucio Francoto working with the contributor to make the Pull Request better. 32502487becSLucio Franco 32602487becSLucio FrancoReviews that are dismissive or disrespectful of the contributor or any other 32702487becSLucio Francoreviewers are strictly counter to the Code of Conduct. 32802487becSLucio Franco 32902487becSLucio FrancoWhen reviewing a Pull Request, the primary goals are for the codebase to improve 33002487becSLucio Francoand for the person submitting the request to succeed. **Even if a Pull Request 33102487becSLucio Francodoes not land, the submitters should come away from the experience feeling like 33202487becSLucio Francotheir effort was not wasted or unappreciated**. Every Pull Request from a new 33302487becSLucio Francocontributor is an opportunity to grow the community. 33402487becSLucio Franco 33502487becSLucio Franco### Review a bit at a time. 33602487becSLucio Franco 33702487becSLucio FrancoDo not overwhelm new contributors. 33802487becSLucio Franco 33902487becSLucio FrancoIt is tempting to micro-optimize and make everything about relative performance, 34002487becSLucio Francoperfect grammar, or exact style matches. Do not succumb to that temptation. 34102487becSLucio Franco 34202487becSLucio FrancoFocus first on the most significant aspects of the change: 34302487becSLucio Franco 34402487becSLucio Franco1. Does this change make sense for Tokio? 34502487becSLucio Franco2. Does this change make Tokio better, even if only incrementally? 34602487becSLucio Franco3. Are there clear bugs or larger scale issues that need attending to? 34702487becSLucio Franco4. Is the commit message readable and correct? If it contains a breaking change 34802487becSLucio Franco is it clear enough? 34902487becSLucio Franco 35002487becSLucio FrancoNote that only **incremental** improvement is needed to land a PR. This means 35102487becSLucio Francothat the PR does not need to be perfect, only better than the status quo. Follow 35202487becSLucio Francoup PRs may be opened to continue iterating. 35302487becSLucio Franco 35402487becSLucio FrancoWhen changes are necessary, *request* them, do not *demand* them, and **do not 35502487becSLucio Francoassume that the submitter already knows how to add a test or run a benchmark**. 35602487becSLucio Franco 35702487becSLucio FrancoSpecific performance optimization techniques, coding styles and conventions 35802487becSLucio Francochange over time. The first impression you give to a new contributor never does. 35902487becSLucio Franco 36002487becSLucio FrancoNits (requests for small changes that are not essential) are fine, but try to 36102487becSLucio Francoavoid stalling the Pull Request. Most nits can typically be fixed by the Tokio 36202487becSLucio FrancoCollaborator landing the Pull Request but they can also be an opportunity for 36302487becSLucio Francothe contributor to learn a bit more about the project. 36402487becSLucio Franco 36502487becSLucio FrancoIt is always good to clearly indicate nits when you comment: e.g. 36602487becSLucio Franco`Nit: change foo() to bar(). But this is not blocking.` 36702487becSLucio Franco 36802487becSLucio FrancoIf your comments were addressed but were not folded automatically after new 36902487becSLucio Francocommits or if they proved to be mistaken, please, [hide them][hiding-a-comment] 37002487becSLucio Francowith the appropriate reason to keep the conversation flow concise and relevant. 37102487becSLucio Franco 37202487becSLucio Franco### Be aware of the person behind the code 37302487becSLucio Franco 37402487becSLucio FrancoBe aware that *how* you communicate requests and reviews in your feedback can 37502487becSLucio Francohave a significant impact on the success of the Pull Request. Yes, we may land 37602487becSLucio Francoa particular change that makes `tonic` better, but the individual might 37702487becSLucio Francojust not want to have anything to do with `tonic` ever again. The goal is 37802487becSLucio Franconot just having good code. 37902487becSLucio Franco 38002487becSLucio Franco### Abandoned or Stalled Pull Requests 38102487becSLucio Franco 38202487becSLucio FrancoIf a Pull Request appears to be abandoned or stalled, it is polite to first 38302487becSLucio Francocheck with the contributor to see if they intend to continue the work before 38402487becSLucio Francochecking if they would mind if you took it over (especially if it just has nits 38502487becSLucio Francoleft). When doing so, it is courteous to give the original contributor credit 38602487becSLucio Francofor the work they started (either by preserving their name and email address in 38702487becSLucio Francothe commit log, or by using an `Author: ` meta-data tag in the commit. 38802487becSLucio Franco 38902487becSLucio Franco_Adapted from the [Node.js contributing guide][node]_. 39002487becSLucio Franco 39102487becSLucio Franco[node]: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md 39202487becSLucio Franco[hiding-a-comment]: https://help.github.com/articles/managing-disruptive-comments/#hiding-a-comment 39302487becSLucio Franco[documentation test]: https://doc.rust-lang.org/rustdoc/documentation-tests.html 39402487becSLucio Franco 39502487becSLucio Franco## Releasing 39602487becSLucio Franco 39702487becSLucio FrancoSince the Tonic project consists of a number of crates, many of which depend on 39802487becSLucio Francoeach other, releasing new versions to crates.io can involve some complexities. 39902487becSLucio FrancoWhen releasing a new version of a crate, follow these steps: 40002487becSLucio Franco 401ec410141SLucio Franco1. First you must pick the correct version to release, if there are breaking 402ec410141SLucio Franco changes make sure to select a semver compatible version bump. 40302487becSLucio Franco 404ec410141SLucio Franco2. In general, tonic tries to keep all crates at the same version to make it 405ec410141SLucio Franco easy to release and figure out what sub crates you need that will work with 406ec410141SLucio Franco the core version of tonic. To prepare a release branch you can follow the 407ec410141SLucio Franco commands below: 408ec410141SLucio Franco ``` 409ec410141SLucio Franco git checkout -b <release-branch-name> 410ec410141SLucio Franco ./prepare-release.sh <version> # where version is X.Y.Z 41102487becSLucio Franco ``` 41202487becSLucio Franco 413ec410141SLucio Franco3. Once all the crate versions have been updated its time to update the 414ec410141SLucio Franco changelog. Tonic uses `conventional-changelog` and it's cli to generate the 415ec410141SLucio Franco changelog. 41602487becSLucio Franco 417ec410141SLucio Franco ``` 418ec410141SLucio Franco conventional-changelog -p angular -i CHANGELOG.md -s 41902487becSLucio Franco ``` 42002487becSLucio Franco 421ec410141SLucio Franco Once the entries have been generated, you must edit the `CHANGELOG.md` file 422ec410141SLucio Franco to add the version and tag to the title and edit any changelog entries. You 423ec410141SLucio Franco must also add any breaking changes here as sometimes they get lost. 42402487becSLucio Franco 425ec410141SLucio Franco4. Once the changelog has been updated you can now create a `chore: release 426ec410141SLucio Franco vX.Y.Z` commit and push the release branch and open a release PR. 427ec410141SLucio Franco 428ec410141SLucio Franco5. Once the release PR has been approved and merged into `master` the following 429ec410141SLucio Franco command will release those changes. 430ec410141SLucio Franco 431ec410141SLucio Franco ``` 432ec410141SLucio Franco ./publish-release.sh 433ec410141SLucio Franco ``` 434ec410141SLucio Franco 435ec410141SLucio Franco6. Once all the crates have been released you now must create a release on 436ec410141SLucio Franco github using the text from the changelog. 437ec410141SLucio Franco 438