mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
822 lines
62 KiB
HTML
822 lines
62 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
|
|
<meta name="generator" content="Doxygen 1.9.5"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<title>rippled: CONTRIBUTING</title>
|
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="jquery.js"></script>
|
|
<script type="text/javascript" src="dynsections.js"></script>
|
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
|
<script type="text/javascript" src="search/search.js"></script>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
|
</head>
|
|
<body>
|
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
<div id="titlearea">
|
|
<table cellspacing="0" cellpadding="0">
|
|
<tbody>
|
|
<tr id="projectrow">
|
|
<td id="projectalign">
|
|
<div id="projectname">rippled
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<!-- end header part -->
|
|
<!-- Generated by Doxygen 1.9.5 -->
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
|
|
var searchBox = new SearchBox("searchBox", "search/",'.html');
|
|
/* @license-end */
|
|
</script>
|
|
<script type="text/javascript" src="menudata.js"></script>
|
|
<script type="text/javascript" src="menu.js"></script>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
|
|
$(function() {
|
|
initMenu('',true,false,'search.php','Search');
|
|
$(document).ready(function() { init_search(); });
|
|
});
|
|
/* @license-end */
|
|
</script>
|
|
<div id="main-nav"></div>
|
|
<!-- window showing the filter options -->
|
|
<div id="MSearchSelectWindow"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
|
</div>
|
|
|
|
<!-- iframe showing the search results (closed by default) -->
|
|
<div id="MSearchResultsWindow">
|
|
<div id="MSearchResults">
|
|
<div class="SRPage">
|
|
<div id="SRIndex">
|
|
<div id="SRResults"></div>
|
|
<div class="SRStatus" id="Loading">Loading...</div>
|
|
<div class="SRStatus" id="Searching">Searching...</div>
|
|
<div class="SRStatus" id="NoMatches">No Matches</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div><!-- top -->
|
|
<div><div class="header">
|
|
<div class="headertitle"><div class="title">CONTRIBUTING </div></div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<div class="textblock"><p >The XRP Ledger has many and diverse stakeholders, and everyone deserves a chance to contribute meaningful changes to the code that runs the XRPL.</p>
|
|
<h1><a class="anchor" id="autotoc_md44"></a>
|
|
Contributing</h1>
|
|
<p >We assume you are familiar with the general practice of <a href="https://docs.github.com/en/get-started/quickstart/contributing-to-projects">making contributions on GitHub</a>. This file includes only special instructions specific to this project.</p>
|
|
<h2><a class="anchor" id="autotoc_md45"></a>
|
|
Before you start</h2>
|
|
<p >The following branches exist in the main project repository:</p>
|
|
<ul>
|
|
<li><code>develop</code>: The latest set of unreleased features, and the most common starting point for contributions.</li>
|
|
<li><code>release</code>: The latest beta release or release candidate.</li>
|
|
<li><code>master</code>: The latest stable release.</li>
|
|
<li><code>gh-pages</code>: The documentation for this project, built by Doxygen.</li>
|
|
</ul>
|
|
<p >The tip of each branch must be signed. In order for GitHub to sign a squashed commit that it builds from your pull request, GitHub must know your verifying key. Please set up <a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification">signature verification</a>.</p>
|
|
<p >In general, external contributions should be developed in your personal <a href="https://github.com/XRPLF/rippled/fork">fork</a>. Contributions from developers with write permissions should be done in <a href="https://github.com/XRPLF/rippled">the main repository</a> in a branch with a permitted prefix. Permitted prefixes are:</p><ul>
|
|
<li>XLS-[a-zA-Z0-9]+/.+<ul>
|
|
<li>e.g. XLS-0033d/mpt-clarify-STEitherAmount</li>
|
|
</ul>
|
|
</li>
|
|
<li>[GitHub username]/.+<ul>
|
|
<li>e.g. JoelKatz/fix-rpc-webhook-queue</li>
|
|
</ul>
|
|
</li>
|
|
<li>[Organization name]/.+<ul>
|
|
<li>e.g. ripple/antithesis</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<p >Regardless of where the branch is created, please open a <em>draft</em> pull request as soon as possible after pushing the branch to Github, to increase visibility, and ease feedback during the development process.</p>
|
|
<h2><a class="anchor" id="autotoc_md46"></a>
|
|
Major contributions</h2>
|
|
<p >If your contribution is a major feature or breaking change, then you must first write an XRP Ledger Standard (XLS) describing it. Go to <a href="https://github.com/XRPLF/XRPL-Standards/discussions">XRPL-Standards</a>, choose the next available standard number, and open a discussion with an appropriate title to propose your draft standard.</p>
|
|
<p >When you submit a pull request, please link the corresponding XLS in the description. An XLS still in draft status is considered a work-in-progress and open for discussion. Please allow time for questions, suggestions, and changes to the XLS draft. It is the responsibility of the XLS author to update the draft to match the final implementation when its corresponding pull request is merged, unless the author delegates that responsibility to others.</p>
|
|
<h2><a class="anchor" id="autotoc_md47"></a>
|
|
Before making a pull request</h2>
|
|
<p >(Or marking a draft pull request as ready.)</p>
|
|
<p >Changes that alter transaction processing must be guarded by an <a href="https://xrpl.org/amendments.html">Amendment</a>. All other changes that maintain the existing behavior do not need an Amendment.</p>
|
|
<p >Ensure that your code compiles according to the build instructions in <a class="el" href="md____w_rippled_rippled_BUILD.html">`BUILD.md`</a>.</p>
|
|
<p >Please write tests for your code. If your test can be run offline, in under 60 seconds, then it can be an automatic test run by <code>rippled --unittest</code>. Otherwise, it must be a manual test.</p>
|
|
<p >If you create new source files, they must be organized as follows:</p><ul>
|
|
<li>If the files are in any of the <code>libxrpl</code> modules, the headers (<code>.h</code>) must go under <code>include/xrpl</code>, and source (<code>.cpp</code>) files must go under <code>src/libxrpl</code>.</li>
|
|
<li>All other non-test files must go under <code>src/xrpld</code>.</li>
|
|
<li>All test source files must go under <code>src/test</code>.</li>
|
|
</ul>
|
|
<p >The source must be formatted according to the style guide below.</p>
|
|
<p >Header includes must be <a href="./Builds/levelization">levelized</a>.</p>
|
|
<p >Changes should be usually squashed down into a single commit. Some larger or more complicated change sets make more sense, and are easier to review if organized into multiple logical commits. Either way, all commits should fit the following criteria:</p><ul>
|
|
<li>Changes should be presented in a single commit or a logical sequence of commits. Specifically, chronological commits that simply reflect the history of how the author implemented the change, "warts and all", are not useful to reviewers.</li>
|
|
<li>Every commit should have a good message. to explain a specific aspects of the change.</li>
|
|
<li>Every commit should be signed.</li>
|
|
<li>Every commit should be well-formed (builds successfully, unit tests passing), as this helps to resolve merge conflicts, and makes it easier to use <code>git bisect</code> to find bugs.</li>
|
|
</ul>
|
|
<h3><a class="anchor" id="autotoc_md48"></a>
|
|
Good commit messages</h3>
|
|
<p >Refer to <a href="https://cbea.ms/git-commit/">"How to Write a Git Commit Message"</a> for general rules on writing a good commit message.</p>
|
|
<p >tl;dr </p><blockquote class="doxtable">
|
|
<p >‍1. Separate subject from body with a blank line.</p><ol type="1">
|
|
<li>Limit the subject line to 50 characters.<ul>
|
|
<li>[...]shoot for 50 characters, but consider 72 the hard limit.</li>
|
|
</ul>
|
|
</li>
|
|
<li>Capitalize the subject line.</li>
|
|
<li>Do not end the subject line with a period.</li>
|
|
<li>Use the imperative mood in the subject line.<ul>
|
|
<li>A properly formed Git commit subject line should always be able to complete the following sentence: "If applied, this commit will
|
|
_your subject line here_".</li>
|
|
</ul>
|
|
</li>
|
|
<li>Wrap the body at 72 characters.</li>
|
|
<li>Use the body to explain what and why vs. how. </li>
|
|
</ol>
|
|
</blockquote>
|
|
<p>In addition to those guidelines, please add one of the following prefixes to the subject line if appropriate.</p><ul>
|
|
<li><code>fix:</code> - The primary purpose is to fix an existing bug.</li>
|
|
<li><code>perf:</code> - The primary purpose is performance improvements.</li>
|
|
<li><code>refactor:</code> - The changes refactor code without affecting functionality.</li>
|
|
<li><code>test:</code> - The changes <em>only</em> affect unit tests.</li>
|
|
<li><code>docs:</code> - The changes <em>only</em> affect documentation. This can include code comments in addition to <code>.md</code> files like this one.</li>
|
|
<li><code>build:</code> - The changes <em>only</em> affect the build process, including CMake and/or Conan settings.</li>
|
|
<li><code>chore:</code> - Other tasks that don't affect the binary, but don't fit any of the other cases. e.g. formatting, git settings, updating Github Actions jobs.</li>
|
|
</ul>
|
|
<p >Whenever possible, when updating commits after the PR is open, please add the PR number to the end of the subject line. e.g. <code>test: Add unit tests for Feature X (#1234)</code>.</p>
|
|
<h2><a class="anchor" id="autotoc_md49"></a>
|
|
Pull requests</h2>
|
|
<p >In general, pull requests use <code>develop</code> as the base branch. The exceptions are</p><ul>
|
|
<li>Fixes and improvements to a release candidate use <code>release</code> as the base.</li>
|
|
<li>Hotfixes use <code>master</code> as the base.</li>
|
|
</ul>
|
|
<p >If your changes are not quite ready, but you want to make it easily available for preliminary examination or review, you can create a "Draft" pull request. While a pull request is marked as a "Draft", you can rebase or reorganize the commits in the pull request as desired.</p>
|
|
<p >Github pull requests are created as "Ready" by default, or you can mark a "Draft" pull request as "Ready". Once a pull request is marked as "Ready", any changes must be added as new commits. Do not force-push to a branch in a pull request under review. (This includes rebasing your branch onto the updated base branch. Use a merge operation, instead or hit the "Update branch" button at the bottom of the Github PR page.) This preserves the ability for reviewers to filter changes since their last review.</p>
|
|
<p >A pull request must obtain <b>approvals from at least two reviewers</b> before it can be considered for merge by a Maintainer. Maintainers retain discretion to require more approvals if they feel the credibility of the existing approvals is insufficient.</p>
|
|
<p >Pull requests must be merged by <a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits">squash-and-merge</a> to preserve a linear history for the <code>develop</code> branch.</p>
|
|
<h3><a class="anchor" id="autotoc_md50"></a>
|
|
"Ready to merge"</h3>
|
|
<p >A pull request should only have the "Ready to merge" label added when it meets a few criteria:</p>
|
|
<ol type="1">
|
|
<li>It must have two approving reviews as described above. (Exception: PRs that are deemed "trivial" only need one approval.)</li>
|
|
<li>All CI checks must be complete and passed. (One-off failures may be acceptable if they are related to a known issue.)</li>
|
|
<li>The PR must have a good commit message.<ul>
|
|
<li>If the PR started with a good commit message, and it doesn't need to be updated, the author can indicate that in a comment.</li>
|
|
<li>Any contributor, preferably the author, can leave a comment suggesting a commit message.</li>
|
|
<li>If the author squashes and rebases the code in preparation for merge, they should also ensure the commit message(s) are updated as well.</li>
|
|
</ul>
|
|
</li>
|
|
<li>The PR branch must be up to date with the base branch (usually <code>develop</code>). This is usually accomplished by merging the base branch into the feature branch, but if the other criteria are met, the changes can be squashed and rebased on top of the base branch.</li>
|
|
<li>Finally, and most importantly, the author of the PR must positively indicate that the PR is ready to merge. That can be accomplished by adding the "Ready to merge" label if their role allows, or by leaving a comment to the effect that the PR is ready to merge.</li>
|
|
</ol>
|
|
<p >Once the "Ready to merge" label is added, a maintainer may merge the PR at any time, so don't use it lightly.</p>
|
|
<h1><a class="anchor" id="autotoc_md51"></a>
|
|
Style guide</h1>
|
|
<p >This is a non-exhaustive list of recommended style guidelines. These are not always strictly enforced and serve as a way to keep the codebase coherent rather than a set of <em>thou shalt not</em> commandments.</p>
|
|
<h2><a class="anchor" id="autotoc_md52"></a>
|
|
Formatting</h2>
|
|
<p >All code must conform to <code>clang-format</code> version 18, according to the settings in <a href="./.clang-format"><code>.clang-format</code></a>, unless the result would be unreasonably difficult to read or maintain. To demarcate lines that should be left as-is, surround them with comments like this:</p>
|
|
<div class="fragment"><div class="line">// clang-format off</div>
|
|
<div class="line">...</div>
|
|
<div class="line">// clang-format on</div>
|
|
</div><!-- fragment --><p >You can format individual files in place by running <code>clang-format -i <file>...</code> from any directory within this project.</p>
|
|
<p >There is a Continuous Integration job that runs clang-format on pull requests. If the code doesn't comply, a patch file that corrects auto-fixable formatting issues is generated.</p>
|
|
<p >To download the patch file:</p>
|
|
<ol type="1">
|
|
<li>Next to <code>clang-format / check (pull_request) Failing after #s</code> -> click <b>Details</b> to open the details page.</li>
|
|
<li>Left menu -> click <b>Summary</b></li>
|
|
<li>Scroll down to near the bottom-right under <code>Artifacts</code> -> click <b>clang-format.patch</b></li>
|
|
<li>Download the zip file and extract it to your local git repository. Run <code>git apply [patch-file-name]</code>.</li>
|
|
<li>Commit and push.</li>
|
|
</ol>
|
|
<p >You can install a pre-commit hook to automatically run <code>clang-format</code> before every commit: </p><div class="fragment"><div class="line">pip3 install pre-commit</div>
|
|
<div class="line">pre-commit install</div>
|
|
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md53"></a>
|
|
Contracts and instrumentation</h2>
|
|
<p >We are using <a href="https://antithesis.com/">Antithesis</a> for continuous fuzzing, and keep a copy of <a href="https://github.com/antithesishq/antithesis-sdk-cpp/">Antithesis C++ SDK</a> in <code>external/antithesis-sdk</code>. One of the aims of fuzzing is to identify bugs by finding external conditions which cause contracts violations inside <code>rippled</code>. The contracts are expressed as <code>XRPL_ASSERT</code> or <code>UNREACHABLE</code> (defined in <code><a class="el" href="instrumentation_8h_source.html">include/xrpl/beast/utility/instrumentation.h</a></code>), which are effectively (outside of Antithesis) wrappers for <code>assert(...)</code> with added name. The purpose of name is to provide contracts with stable identity which does not rely on line numbers.</p>
|
|
<p >When <code>rippled</code> is built with the Antithesis instrumentation enabled (using <code>voidstar</code> CMake option) and ran on the Antithesis platform, the contracts become <a href="https://antithesis.com/docs/using_antithesis/properties.html">test properties</a>; otherwise they are just like a regular <code>assert</code>. To learn more about Antithesis, see <a href="https://antithesis.com/docs/introduction/how_antithesis_works.html">How Antithesis Works</a> and <a href="https://antithesis.com/docs/using_antithesis/sdk/cpp/overview.html#">C++ SDK</a></p>
|
|
<p >We continue to use the old style <code>assert</code> or <code>assert(false)</code> in certain locations, where the reporting of contract violations on the Antithesis platform is either not possible or not useful.</p>
|
|
<p >For this reason:</p><ul>
|
|
<li>The locations where <code>assert</code> or <code>assert(false)</code> contracts should continue to be used:<ul>
|
|
<li><code>constexpr</code> functions</li>
|
|
<li>unit tests i.e. files under <code>src/test</code></li>
|
|
<li>unit tests-related modules (files under <code>beast/test</code> and <code>beast/unit_test</code>)</li>
|
|
</ul>
|
|
</li>
|
|
<li>Outside of the listed locations, do not use <code>assert</code>; use <code>XRPL_ASSERT</code> instead, giving it unique name, with the short description of the contract.</li>
|
|
<li>Outside of the listed locations, do not use <code>assert(false)</code>; use <code>UNREACHABLE</code> instead, giving it unique name, with the description of the condition being violated</li>
|
|
<li>The contract name should start with a full name (including scope) of the function, optionally a named lambda, followed by a colon <code>:</code> and a brief (typically at most five words) description. <code>UNREACHABLE</code> contracts can use slightly longer descriptions. If there are multiple overloads of the function, use common sense to balance both brevity and unambiguity of the function name. NOTE: the purpose of name is to provide stable means of unique identification of every contract; for this reason try to avoid elements which can change in some obvious refactors or when reinforcing the condition.</li>
|
|
<li>Contract description typically (except for <code>UNREACHABLE</code>) should describe the <em>expected</em> condition, as in "I assert that _expected_ is true".</li>
|
|
<li>Contract description for <code>UNREACHABLE</code> should describe the <em>unexpected</em> situation which caused the line to have been reached.</li>
|
|
<li>Example good name for an <code>UNREACHABLE</code> macro <code>"Json::operator==(Value, Value) : invalid type"</code>; example good name for an <code>XRPL_ASSERT</code> macro <code>"Json::Value::asCString : valid type"</code>.</li>
|
|
<li>Example <b>bad</b> name <code>"RFC1751::insert(char* s, int x, int start, int length) : length is greater than or equal zero"</code> (missing namespace, unnecessary full function signature, description too verbose). Good name: <code>"ripple::RFC1751::insert : minimum length"</code>.</li>
|
|
<li>In <b>few</b> well-justified cases a non-standard name can be used, in which case a comment should be placed to explain the rationale (example in <code><a class="el" href="contract_8cpp_source.html">contract.cpp</a></code>)</li>
|
|
<li>Do <b>not</b> rename a contract without a good reason (e.g. the name no longer reflects the location or the condition being checked)</li>
|
|
<li>Do not use <code>std::unreachable</code></li>
|
|
<li>Do not put contracts where they can be violated by an external condition (e.g. timing, data payload before mandatory validation etc.) as this creates bogus bug reports (and causes crashes of Debug builds)</li>
|
|
</ul>
|
|
<h2><a class="anchor" id="autotoc_md54"></a>
|
|
Unit Tests</h2>
|
|
<p >To execute all unit tests:</p>
|
|
<div class="fragment"><div class="line">(Note: Using multiple cores on a Mac M1 can cause spurious test failures. The </div>
|
|
<div class="line">cause is still under investigation. If you observe this problem, try specifying fewer jobs.)</div>
|
|
<div class="line"> </div>
|
|
<div class="line">To run a specific set of test suites:</div>
|
|
</div><!-- fragment --><p> rippled –unittest TestSuiteName </p><div class="fragment"><div class="line">Note: In this example, all tests with prefix `TestSuiteName` will be run, so if</div>
|
|
<div class="line">`TestSuiteName1` and `TestSuiteName2` both exist, then both tests will run. </div>
|
|
<div class="line">Alternatively, if the unit test name finds an exact match, it will stop </div>
|
|
<div class="line">doing partial matches, i.e. if a unit test with a title of `TestSuiteName` </div>
|
|
<div class="line">exists, then no other unit test will be executed, apart from `TestSuiteName`.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">## Avoid</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. Proliferation of nearly identical code.</div>
|
|
<div class="line">2. Proliferation of new files and classes.</div>
|
|
<div class="line">3. Complex inheritance and complex OOP patterns.</div>
|
|
<div class="line">4. Unmanaged memory allocation and raw pointers.</div>
|
|
<div class="line">5. Macros and non-trivial templates (unless they add significant value).</div>
|
|
<div class="line">6. Lambda patterns (unless these add significant value).</div>
|
|
<div class="line">7. CPU or architecture-specific code unless there is a good reason to</div>
|
|
<div class="line"> include it, and where it is used, guard it with macros and provide</div>
|
|
<div class="line"> explanatory comments.</div>
|
|
<div class="line">8. Importing new libraries unless there is a very good reason to do so.</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> </div>
|
|
<div class="line">## Seek to</div>
|
|
<div class="line"> </div>
|
|
<div class="line">9. Extend functionality of existing code rather than creating new code.</div>
|
|
<div class="line">10. Prefer readability over terseness where important logic is</div>
|
|
<div class="line"> concerned.</div>
|
|
<div class="line">11. Inline functions that are not used or are not likely to be used</div>
|
|
<div class="line"> elsewhere in the codebase.</div>
|
|
<div class="line">12. Use clear and self-explanatory names for functions, variables,</div>
|
|
<div class="line"> structs and classes.</div>
|
|
<div class="line">13. Use TitleCase for classes, structs and filenames, camelCase for</div>
|
|
<div class="line"> function and variable names, lower case for namespaces and folders.</div>
|
|
<div class="line">14. Provide as many comments as you feel that a competent programmer</div>
|
|
<div class="line"> would need to understand what your code does.</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> </div>
|
|
<div class="line"># Maintainers</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Maintainers are ecosystem participants with elevated access to the repository.</div>
|
|
<div class="line">They are able to push new code, make decisions on when a release should be</div>
|
|
<div class="line">made, etc.</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> </div>
|
|
<div class="line">## Adding and removing</div>
|
|
<div class="line"> </div>
|
|
<div class="line">New maintainers can be proposed by two existing maintainers, subject to a vote</div>
|
|
<div class="line">by a quorum of the existing maintainers.</div>
|
|
<div class="line">A minimum of 50% support and a 50% participation is required.</div>
|
|
<div class="line">In the event of a tie vote, the addition of the new maintainer will be</div>
|
|
<div class="line">rejected.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Existing maintainers can resign, or be subject to a vote for removal at the</div>
|
|
<div class="line">behest of two existing maintainers.</div>
|
|
<div class="line">A minimum of 60% agreement and 50% participation are required.</div>
|
|
<div class="line">The XRP Ledger Foundation will have the ability, for cause, to remove an</div>
|
|
<div class="line">existing maintainer without a vote.</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> </div>
|
|
<div class="line">## Current Maintainers</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Maintainers are users with maintain or admin access to the repo.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">* [bthomee](https://github.com/bthomee) (Ripple)</div>
|
|
<div class="line">* [intelliot](https://github.com/intelliot) (Ripple)</div>
|
|
<div class="line">* [JoelKatz](https://github.com/JoelKatz) (Ripple)</div>
|
|
<div class="line">* [nixer89](https://github.com/nixer89) (XRP Ledger Foundation)</div>
|
|
<div class="line">* [RichardAH](https://github.com/RichardAH) (XRP Ledger Foundation)</div>
|
|
<div class="line">* [Silkjaer](https://github.com/Silkjaer) (XRP Ledger Foundation)</div>
|
|
<div class="line">* [WietseWind](https://github.com/WietseWind) (XRPL Labs + XRP Ledger Foundation)</div>
|
|
<div class="line">* [ximinez](https://github.com/ximinez) (Ripple)</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> </div>
|
|
<div class="line">## Current Code Reviewers</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Code Reviewers are developers who have the ability to review, approve, and</div>
|
|
<div class="line">in some cases merge source code changes.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">* [HowardHinnant](https://github.com/HowardHinnant) (Ripple)</div>
|
|
<div class="line">* [scottschurr](https://github.com/scottschurr) (Ripple)</div>
|
|
<div class="line">* [seelabs](https://github.com/seelabs) (Ripple)</div>
|
|
<div class="line">* [Ed Hennis](https://github.com/ximinez) (Ripple)</div>
|
|
<div class="line">* [mvadari](https://github.com/mvadari) (Ripple)</div>
|
|
<div class="line">* [thejohnfreeman](https://github.com/thejohnfreeman) (Ripple)</div>
|
|
<div class="line">* [Bronek](https://github.com/Bronek) (Ripple)</div>
|
|
<div class="line">* [manojsdoshi](https://github.com/manojsdoshi) (Ripple)</div>
|
|
<div class="line">* [godexsoft](https://github.com/godexsoft) (Ripple)</div>
|
|
<div class="line">* [mDuo13](https://github.com/mDuo13) (Ripple)</div>
|
|
<div class="line">* [ckniffen](https://github.com/ckniffen) (Ripple)</div>
|
|
<div class="line">* [arihantkothari](https://github.com/arihantkothari) (Ripple)</div>
|
|
<div class="line">* [pwang200](https://github.com/pwang200) (Ripple)</div>
|
|
<div class="line">* [sophiax851](https://github.com/sophiax851) (Ripple)</div>
|
|
<div class="line">* [shawnxie999](https://github.com/shawnxie999) (Ripple)</div>
|
|
<div class="line">* [gregtatcam](https://github.com/gregtatcam) (Ripple)</div>
|
|
<div class="line">* [mtrippled](https://github.com/mtrippled) (Ripple)</div>
|
|
<div class="line">* [ckeshava](https://github.com/ckeshava) (Ripple)</div>
|
|
<div class="line">* [nbougalis](https://github.com/nbougalis) None</div>
|
|
<div class="line">* [RichardAH](https://github.com/RichardAH) (XRPL Labs + XRP Ledger Foundation)</div>
|
|
<div class="line">* [dangell7](https://github.com/dangell7) (XRPL Labs)</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Developers not on this list are able and encouraged to submit feedback</div>
|
|
<div class="line">on pending code changes (open pull requests).</div>
|
|
<div class="line"> </div>
|
|
<div class="line">## Instructions for maintainers</div>
|
|
<div class="line"> </div>
|
|
<div class="line">These instructions assume you have your git upstream remotes configured</div>
|
|
<div class="line">to avoid accidental pushes to the main repo, and a remote group</div>
|
|
<div class="line">specifying both of them. e.g.</div>
|
|
</div><!-- fragment --><p> $ git remote -v | grep upstream upstream <a href="https://github.com/XRPLF/rippled.git">https://github.com/XRPLF/rippled.git</a> (fetch) upstream <a href="https://github.com/XRPLF/rippled.git">https://github.com/XRPLF/rippled.git</a> (push) upstream-push <a href="#" onclick="location.href='mai'+'lto:'+'git'+'@g'+'ith'+'ub'+'.co'+'m'; return false;">git@g<span class="obfuscator">.nosp@m.</span>ithu<span class="obfuscator">.nosp@m.</span>b.com</a>:XRPLF/rippled.git (fetch) upstream-push <a href="#" onclick="location.href='mai'+'lto:'+'git'+'@g'+'ith'+'ub'+'.co'+'m'; return false;">git@g<span class="obfuscator">.nosp@m.</span>ithu<span class="obfuscator">.nosp@m.</span>b.com</a>:XRPLF/rippled.git (push)</p>
|
|
<p >$ git config remotes.upstreams upstream upstream-push </p><div class="fragment"><div class="line">You can use the [setup-upstreams] script to set this up.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">It also assumes you have a default gpg signing key set up in git. e.g.</div>
|
|
</div><!-- fragment --><p> $ git config user.signingkey 968479A1AFF927E37D1A566BB5690EEEBB952194 </p>
|
|
<h1><a class="anchor" id="autotoc_md55"></a>
|
|
(This is github's key. Use your own.)</h1>
|
|
<div class="fragment"><div class="line">### When and how to merge pull requests</div>
|
|
<div class="line"> </div>
|
|
<div class="line">The maintainer should double-check that the PR has met all the</div>
|
|
<div class="line">necessary criteria, and can request additional information from the</div>
|
|
<div class="line">owner, or additional reviews, and can always feel free to remove the</div>
|
|
<div class="line">"Ready to merge" label if appropriate. The maintainer has final say on</div>
|
|
<div class="line">whether a PR gets merged, and are encouraged to communicate and issues</div>
|
|
<div class="line">or concerns to other maintainers.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">#### Most pull requests: "Squash and merge"</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Most pull requests don't need special handling, and can simply be</div>
|
|
<div class="line">merged using the "Squash and merge" button on the Github UI. Update</div>
|
|
<div class="line">the suggested commit message, or modify it as needed.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">#### Slightly more complicated pull requests</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Some pull requests need to be pushed to `develop` as more than one</div>
|
|
<div class="line">commit. A PR author may *request* to merge as separate commits. They</div>
|
|
<div class="line">must *justify* why separate commits are needed, and *specify* how they</div>
|
|
<div class="line">would like the commits to be merged. If you disagree with the author,</div>
|
|
<div class="line">discuss it with them directly.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">If the process is reasonable, follow it. The simplest option is to do a</div>
|
|
<div class="line">fast forward only merge (`--ff-only`) on the command line and push to</div>
|
|
<div class="line">`develop`.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Some examples of when separate commits are worthwhile are:</div>
|
|
<div class="line">1. PRs where source files are reorganized in multiple steps.</div>
|
|
<div class="line">2. PRs where the commits are mostly independent and *could* be separate</div>
|
|
<div class="line"> PRs, but are pulled together into one PR under a commit theme or</div>
|
|
<div class="line"> issue.</div>
|
|
<div class="line">3. PRs that are complicated enough that `git bisect` would not be much</div>
|
|
<div class="line"> help if it determined this PR introduced a problem.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Either way, check that:</div>
|
|
<div class="line">* The commits are based on the current tip of `develop`.</div>
|
|
<div class="line">* The commits are clean: No merge commits (except when reverse</div>
|
|
<div class="line"> merging), no "[FOLD]" or "fixup!" messages.</div>
|
|
<div class="line">* All commits are signed. If the commits are not signed by the author, use</div>
|
|
<div class="line"> `git commit --amend -S` to sign them yourself.</div>
|
|
<div class="line">* At least one (but preferably all) of the commits has the PR number</div>
|
|
<div class="line"> in the commit message.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">The "Create a merge commit" and "Rebase and merge" options should be</div>
|
|
<div class="line">disabled in the Github UI, but if you ever find them available **Do not</div>
|
|
<div class="line">use them!**</div>
|
|
<div class="line"> </div>
|
|
<div class="line">### Releases</div>
|
|
<div class="line"> </div>
|
|
<div class="line">All releases, including release candidates and betas, are handled</div>
|
|
<div class="line">differently from typical PRs. Most importantly, never use</div>
|
|
<div class="line">the Github UI to merge a release.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Rippled uses a linear workflow model that can be summarized as:</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. In between releases, developers work against the `develop` branch.</div>
|
|
<div class="line">2. Periodically, a maintainer will build and tag a beta version from</div>
|
|
<div class="line"> `develop`, which is pushed to `release`.</div>
|
|
<div class="line"> * Betas are usually released every two to three weeks, though that</div>
|
|
<div class="line"> schedule can vary depending on progress, availability, and other</div>
|
|
<div class="line"> factors.</div>
|
|
<div class="line">3. When the changes in `develop` are considered stable and mature enough</div>
|
|
<div class="line"> to be ready to release, a release candidate (RC) is built and tagged</div>
|
|
<div class="line"> from `develop`, and merged to `release`.</div>
|
|
<div class="line"> * Further development for that release (primarily fixes) then</div>
|
|
<div class="line"> continues against `release`, while other development continues on</div>
|
|
<div class="line"> `develop`. Effectively, `release` is forked from `develop`. Changes</div>
|
|
<div class="line"> to `release` must be reverse merged to `develop`.</div>
|
|
<div class="line">4. When the candidate has passed testing and is ready for release, the</div>
|
|
<div class="line"> final release is merged to `master`.</div>
|
|
<div class="line">5. If any issues are found post-release, a hotfix / point release may be</div>
|
|
<div class="line"> created, which is merged to `master`, and then reverse merged to</div>
|
|
<div class="line"> `develop`.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">#### Betas, and the first release candidate</div>
|
|
<div class="line"> </div>
|
|
<div class="line">##### Preparing the `develop` branch</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. Optimally, the `develop` branch will be ready to go, with all</div>
|
|
<div class="line"> relevant PRs already merged.</div>
|
|
<div class="line">2. If there are any PRs pending, merge them **BEFORE** preparing the beta.</div>
|
|
<div class="line"> 1. If only one or two PRs need to be merged, merge those PRs [as</div>
|
|
<div class="line"> normal](#when-and-how-to-merge-pull-requests), updating the second</div>
|
|
<div class="line"> one, and waiting for CI to finish in between.</div>
|
|
<div class="line"> 2. If there are several pending PRs, do not use the Github UI,</div>
|
|
<div class="line"> because the delays waiting for CI in between each merge will be</div>
|
|
<div class="line"> unnecessarily onerous. (Incidentally, this process can also be</div>
|
|
<div class="line"> used to merge if the Github UI has issues.) Merge each PR branch</div>
|
|
<div class="line"> directly to a `release-next` on your local machine and create a single</div>
|
|
<div class="line"> PR, then push your branch to `develop`.</div>
|
|
<div class="line"> 1. Squash the changes from each PR, one commit each (unless more</div>
|
|
<div class="line"> are needed), being sure to sign each commit and update the</div>
|
|
<div class="line"> commit message to include the PR number. You may be able to use</div>
|
|
<div class="line"> a fast-forward merge for the first PR.</div>
|
|
<div class="line"> 2. Push your branch.</div>
|
|
<div class="line"> 3. Continue to [Making the release](#making-the-release) to update</div>
|
|
<div class="line"> the version number, etc.</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> The workflow may look something like:</div>
|
|
</div><!-- fragment --><p> git fetch –multiple upstreams user1 user2 user3 [...] git checkout -B release-next –no-track upstream/develop</p>
|
|
<h1><a class="anchor" id="autotoc_md56"></a>
|
|
Only do an ff-only merge if prbranch1 is either already</h1>
|
|
<h1><a class="anchor" id="autotoc_md57"></a>
|
|
squashed, or needs to be merged with separate commits,</h1>
|
|
<h1><a class="anchor" id="autotoc_md58"></a>
|
|
and has no merge commits.</h1>
|
|
<h1><a class="anchor" id="autotoc_md59"></a>
|
|
Use -S on the ff-only merge if prbranch1 isn't signed.</h1>
|
|
<p >git merge [-S] –ff-only user1/prbranch1</p>
|
|
<p >git merge –squash user2/prbranch2 git commit -S # Use the commit message provided on the PR</p>
|
|
<p >git merge –squash user3/prbranch3 git commit -S # Use the commit message provided on the PR</p>
|
|
<p >[...]</p>
|
|
<h1><a class="anchor" id="autotoc_md60"></a>
|
|
Make sure the commits look right</h1>
|
|
<p >git log –show-signature "upstream/develop..HEAD"</p>
|
|
<p >git push –set-upstream origin</p>
|
|
<h1><a class="anchor" id="autotoc_md61"></a>
|
|
Continue to "Making the release" to update the version number, so</h1>
|
|
<h1><a class="anchor" id="autotoc_md62"></a>
|
|
everything can be done in one PR.</h1>
|
|
<div class="fragment"><div class="line">You can also use the [squash-branches] script.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">You may also need to manually close the open PRs after the changes are</div>
|
|
<div class="line">merged to `develop`. Be sure to include the commit ID.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">##### Making the release</div>
|
|
<div class="line"> </div>
|
|
<div class="line">This includes, betas, and the first release candidate (RC).</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. If you didn't create one [preparing the `develop`</div>
|
|
<div class="line"> branch](#preparing-the-develop-branch), Ensure there is no old</div>
|
|
<div class="line"> `release-next` branch hanging around. Then make a `release-next`</div>
|
|
<div class="line"> branch that only changes the version number. e.g.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<p >git checkout –no-track -B release-next upstream/develop</p>
|
|
<p >v="A.B.C-bD" build=$( find -name <a class="el" href="BuildInfo_8cpp_source.html">BuildInfo.cpp</a> ) sed 's/(^.*versionString =).*$/\1 "'${v}'"/' ${build} > version.cpp && mv -vi version.cpp ${build}</p>
|
|
<p >git diff</p>
|
|
<p >git add ${build}</p>
|
|
<p >git commit -S -m "Set version to ${v}"</p>
|
|
<h1><a class="anchor" id="autotoc_md63"></a>
|
|
You could use your "origin" repo, but some CI tests work better on upstream.</h1>
|
|
<p >git push upstream-push git fetch upstreams git branch –set-upstream-to=upstream/release-next </p><div class="fragment"><div class="line"> You can also use the [update-version] script.</div>
|
|
<div class="line">2. Create a Pull Request for `release-next` with **`develop`** as</div>
|
|
<div class="line"> the base branch.</div>
|
|
<div class="line"> 1. Use the title "[TRIVIAL] Set version to X.X.X-bX".</div>
|
|
<div class="line"> 2. Instead of the default description template, use the following:</div>
|
|
</div><!-- fragment --> <h2><a class="anchor" id="autotoc_md64"></a>
|
|
High Level Overview of Change</h2>
|
|
<p >This PR only changes the version number. It will be merged as soon as Github CI actions successfully complete. </p><div class="fragment"><div class="line">3. Wait for CI to successfully complete, and get someone to approve</div>
|
|
<div class="line"> the PR. (It is safe to ignore known CI issues.)</div>
|
|
<div class="line">4. Push the updated `develop` branch using your `release-next`</div>
|
|
<div class="line"> branch. **Do not use the Github UI. It's important to preserve</div>
|
|
<div class="line"> commit IDs.**</div>
|
|
</div><!-- fragment --><p> git push upstream-push release-next:develop </p><div class="fragment"><div class="line">5. In the unlikely event that the push fails because someone has merged</div>
|
|
<div class="line"> something else in the meantime, rebase your branch onto the updated</div>
|
|
<div class="line"> `develop` branch, push again, and go back to step 3.</div>
|
|
<div class="line">6. Ensure that your PR against `develop` is closed. Github should do it</div>
|
|
<div class="line"> automatically.</div>
|
|
<div class="line">7. Once this is done, forward progress on `develop` can continue</div>
|
|
<div class="line"> (other PRs may be merged).</div>
|
|
<div class="line">8. Now create a Pull Request for `release-next` with **`release`** as</div>
|
|
<div class="line"> the base branch. Instead of the default template, reuse and update</div>
|
|
<div class="line"> the message from the previous release. Include the following verbiage</div>
|
|
<div class="line"> somewhere in the description:</div>
|
|
</div><!-- fragment --><p> The base branch is <code>release</code>. <a href="https://github.com/XRPLF/rippled/blob/develop/CONTRIBUTING.md#before-you-start">All releases (including betas)</a> go in <code>release</code>. This PR branch will be pushed directly to <code>release</code> (not squashed or rebased, and not using the GitHub UI). </p><div class="fragment"><div class="line">7. Sign-offs for the three platforms (Linux, Mac, Windows) usually occur</div>
|
|
<div class="line"> offline, but at least one approval will be needed on the PR.</div>
|
|
<div class="line"> * If issues are discovered during testing, simply abandon the</div>
|
|
<div class="line"> release. It's easy to start a new release, it should be easy to</div>
|
|
<div class="line"> abandon one. **DO NOT REUSE THE VERSION NUMBER.** e.g. If you</div>
|
|
<div class="line"> abandon 2.4.0-b1, the next attempt will be 2.4.0-b2.</div>
|
|
<div class="line">8. Once everything is ready to go, push to `release`.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<h1><a class="anchor" id="autotoc_md65"></a>
|
|
Just to be safe, do a dry run first:</h1>
|
|
<p >git push –dry-run upstream-push release-next:release</p>
|
|
<h1><a class="anchor" id="autotoc_md66"></a>
|
|
If everything looks right, push the branch</h1>
|
|
<p >git push upstream-push release-next:release</p>
|
|
<h1><a class="anchor" id="autotoc_md67"></a>
|
|
Check that all of the branches are updated</h1>
|
|
<p >git fetch upstreams git log -1 –oneline </p>
|
|
<h1><a class="anchor" id="autotoc_md68"></a>
|
|
The output should look like:</h1>
|
|
<h1><a class="anchor" id="autotoc_md69"></a>
|
|
0123456789 (HEAD -> upstream/release-next, upstream/release,</h1>
|
|
<h1><a class="anchor" id="autotoc_md70"></a>
|
|
upstream/develop) Set version to 2.4.0-b1</h1>
|
|
<h1><a class="anchor" id="autotoc_md71"></a>
|
|
Note that upstream/develop may not be on this commit, but</h1>
|
|
<h1><a class="anchor" id="autotoc_md72"></a>
|
|
upstream/release must be.</h1>
|
|
<h1><a class="anchor" id="autotoc_md73"></a>
|
|
Other branches, including some from upstream-push, may also be</h1>
|
|
<h1><a class="anchor" id="autotoc_md74"></a>
|
|
present.</h1>
|
|
<div class="fragment"><div class="line">9. Tag the release, too.</div>
|
|
</div><!-- fragment --><p> git tag <version number> git push upstream-push <version number> </p><div class="fragment"><div class="line">10. Delete the `release-next` branch on the repo. Use the Github UI or:</div>
|
|
</div><!-- fragment --><p> git push –delete upstream-push release-next </p><div class="fragment"><div class="line">11. Finally [create a new release on</div>
|
|
<div class="line"> Github](https://github.com/XRPLF/rippled/releases).</div>
|
|
<div class="line"> </div>
|
|
<div class="line">#### Release candidates after the first</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Once the first release candidate is [merged into</div>
|
|
<div class="line">release](#making-the-release), then `release` and `develop` *are allowed</div>
|
|
<div class="line">to diverge*.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">If a bug or issue is discovered in a version that has a release</div>
|
|
<div class="line">candidate being tested, any fix and new version will need to be applied</div>
|
|
<div class="line">against `release`, then reverse-merged to `develop`. This helps keep git</div>
|
|
<div class="line">history as linear as possible.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">A `release-next` branch will be created from `release`, and any further</div>
|
|
<div class="line">work for that release must be based on `release-next`. Specifically,</div>
|
|
<div class="line">PRs must use `release-next` as the base, and those PRs will be merged</div>
|
|
<div class="line">directly to `release-next` when approved. Changes should be restricted</div>
|
|
<div class="line">to bug fixes, but other changes may be necessary from time to time.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. Open any PRs for the pending release using `release-next` as the base,</div>
|
|
<div class="line"> so they can be merged directly in to it. Unlike `develop`, though,</div>
|
|
<div class="line"> `release-next` can be thrown away and recreated if necessary.</div>
|
|
<div class="line">2. Once a new release candidate is ready, create a version commit as in</div>
|
|
<div class="line"> step 1 [above](#making-the-release) on `release-next`. You can use</div>
|
|
<div class="line"> the [update-version] script for this, too.</div>
|
|
<div class="line">3. Jump to step 8 ("Now create a Pull Request for `release-next` with</div>
|
|
<div class="line"> **`release`** as the base") from the process</div>
|
|
<div class="line"> [above](#making-the-release) to merge `release-next` into `release`.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">##### Follow up: reverse merge</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Once the RC is merged and tagged, it needs to be reverse merged into</div>
|
|
<div class="line">`develop` as soon as possible.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. Create a branch, based on `upstream/develop`.</div>
|
|
<div class="line"> The branch name is not important, but could include "mergeNNNrcN".</div>
|
|
<div class="line"> E.g. For release A.B.C-rcD, use `mergeABCrcD`.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<p >git checkout –no-track -b mergeABCrcD upstream/develop </p><div class="fragment"><div class="line">2. Merge `release` into your branch.</div>
|
|
</div><!-- fragment --> <h1><a class="anchor" id="autotoc_md75"></a>
|
|
I like the "--edit --log --verbose" parameters, but they are</h1>
|
|
<h1><a class="anchor" id="autotoc_md76"></a>
|
|
not required.</h1>
|
|
<p >git merge upstream/release </p><div class="fragment"><div class="line">3. `BuildInfo.cpp` will have a conflict with the version number.</div>
|
|
<div class="line"> Resolve it with the version from `develop` - the higher version.</div>
|
|
<div class="line">4. Push your branch to your repo (or `upstream` if you have permission),</div>
|
|
<div class="line"> and open a normal PR against `develop`. The "High level overview" can</div>
|
|
<div class="line"> simply indicate that this is a merge of the RC. The "Context" should</div>
|
|
<div class="line"> summarize the changes from the RC. Include the following text</div>
|
|
<div class="line"> prominently:</div>
|
|
</div><!-- fragment --><p> This PR must be merged manually using a push. Do not use the Github UI. </p><div class="fragment"><div class="line">5. Depending on the complexity of the changes, and/or merge conflicts,</div>
|
|
<div class="line"> the PR may need a thorough review, or just a sign-off that the</div>
|
|
<div class="line"> merge was done correctly.</div>
|
|
<div class="line">6. If `develop` is updated before this PR is merged, do not merge</div>
|
|
<div class="line"> `develop` back into your branch. Instead rebase preserving merges,</div>
|
|
<div class="line"> or do the merge again. (See also the `rerere` git config setting.)</div>
|
|
</div><!-- fragment --><p> git rebase –rebase-merges upstream/develop </p>
|
|
<h1><a class="anchor" id="autotoc_md77"></a>
|
|
OR</h1>
|
|
<p >git reset –hard upstream/develop git merge upstream/release </p><div class="fragment"><div class="line">7. When the PR is ready, push it to `develop`.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<h1><a class="anchor" id="autotoc_md78"></a>
|
|
Make sure the commits look right</h1>
|
|
<p >git log –show-signature "upstream/develop^..HEAD"</p>
|
|
<p >git push upstream-push mergeABCrcD:develop</p>
|
|
<p >git fetch upstreams </p><div class="fragment"><div class="line">Development on `develop` can proceed as normal.</div>
|
|
<div class="line"> </div>
|
|
<div class="line"> </div>
|
|
<div class="line">#### Final releases</div>
|
|
<div class="line"> </div>
|
|
<div class="line">A final release is any release that is not a beta or RC, such as 2.2.0.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Only code that has already been tested and vetted across all three</div>
|
|
<div class="line">platforms should be included in a final release. Most of the time, that</div>
|
|
<div class="line">means that the commit immediately preceding the commit setting the</div>
|
|
<div class="line">version number will be an RC. Occasionally, there may be last-minute bug</div>
|
|
<div class="line">fixes included as well. If so, those bug fixes must have been tested</div>
|
|
<div class="line">internally as if they were RCs (at minimum, ensuring unit tests pass,</div>
|
|
<div class="line">and the app starts, syncs, and stops cleanly across all three</div>
|
|
<div class="line">platforms.)</div>
|
|
<div class="line"> </div>
|
|
<div class="line">*If in doubt, make an RC first.*</div>
|
|
<div class="line"> </div>
|
|
<div class="line">The process for building a final release is very similar to [the process</div>
|
|
<div class="line">for building a beta](#making-the-release), except the code will be</div>
|
|
<div class="line">moving from `release` to `master` instead of from `develop` to</div>
|
|
<div class="line">`release`, and both branches will be pushed at the same time.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. Ensure there is no old `master-next` branch hanging around.</div>
|
|
<div class="line"> Then make a `master-next` branch that only changes the version</div>
|
|
<div class="line"> number. As above, or using the</div>
|
|
<div class="line"> [update-version] script.</div>
|
|
<div class="line">2. Create a Pull Request for `master-next` with **`master`** as</div>
|
|
<div class="line"> the base branch. Instead of the default template, reuse and update</div>
|
|
<div class="line"> the message from the previous final release. Include the following verbiage</div>
|
|
<div class="line"> somewhere in the description:</div>
|
|
</div><!-- fragment --><p> The base branch is <code>master</code>. This PR branch will be pushed directly to <code>release</code> and <code>master</code> (not squashed or rebased, and not using the GitHub UI). </p><div class="fragment"><div class="line">7. Sign-offs for the three platforms (Linux, Mac, Windows) usually occur</div>
|
|
<div class="line"> offline, but at least one approval will be needed on the PR.</div>
|
|
<div class="line"> * If issues are discovered during testing, close the PR, delete</div>
|
|
<div class="line"> `master-next`, and move development back to `release`, [issuing</div>
|
|
<div class="line"> more RCs as necessary](#release-candidates-after-the-first)</div>
|
|
<div class="line">8. Once everything is ready to go, push to `release` and `master`.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<h1><a class="anchor" id="autotoc_md79"></a>
|
|
Just to be safe, do dry runs first:</h1>
|
|
<p >git push –dry-run upstream-push master-next:release git push –dry-run upstream-push master-next:master</p>
|
|
<h1><a class="anchor" id="autotoc_md80"></a>
|
|
If everything looks right, push the branch</h1>
|
|
<p >git push upstream-push master-next:release git push upstream-push master-next:master</p>
|
|
<h1><a class="anchor" id="autotoc_md81"></a>
|
|
Check that all of the branches are updated</h1>
|
|
<p >git fetch upstreams git log -1 –oneline </p>
|
|
<h1><a class="anchor" id="autotoc_md82"></a>
|
|
The output should look like:</h1>
|
|
<h1><a class="anchor" id="autotoc_md83"></a>
|
|
0123456789 (HEAD -> upstream/master-next, upstream/master,</h1>
|
|
<h1><a class="anchor" id="autotoc_md84"></a>
|
|
upstream/release) Set version to A.B.0</h1>
|
|
<h1><a class="anchor" id="autotoc_md85"></a>
|
|
Note that both upstream/release and upstream/master must be on this</h1>
|
|
<h1><a class="anchor" id="autotoc_md86"></a>
|
|
commit.</h1>
|
|
<h1><a class="anchor" id="autotoc_md87"></a>
|
|
Other branches, including some from upstream-push, may also be</h1>
|
|
<h1><a class="anchor" id="autotoc_md88"></a>
|
|
present.</h1>
|
|
<div class="fragment"><div class="line">9. Tag the release, too.</div>
|
|
</div><!-- fragment --><p> git tag <version number> git push upstream-push <version number> </p><div class="fragment"><div class="line">10. Delete the `master-next` branch on the repo. Use the Github UI or:</div>
|
|
</div><!-- fragment --><p> git push –delete upstream-push master-next </p><div class="fragment"><div class="line">11. [Create a new release on</div>
|
|
<div class="line"> Github](https://github.com/XRPLF/rippled/releases). Be sure that</div>
|
|
<div class="line"> "Set as the latest release" is checked.</div>
|
|
<div class="line">12. Finally [reverse merge the release into `develop`](#follow-up-reverse-merge).</div>
|
|
<div class="line"> </div>
|
|
<div class="line">#### Special cases: point releases, hotfixes, etc.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">On occassion, a bug or issue is discovered in a version that already</div>
|
|
<div class="line">had a final release. Most of the time, development will have started</div>
|
|
<div class="line">on the next version, and will usually have changes in `develop`</div>
|
|
<div class="line">and often in `release`.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Because git history is kept as linear as possible, any fix and new</div>
|
|
<div class="line">version will need to be applied against `master`.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">The process for building a hotfix release is very similar to [the</div>
|
|
<div class="line">process for building release candidates after the</div>
|
|
<div class="line">first](#release-candidates-after-the-first) and [for building a final</div>
|
|
<div class="line">release](#final-releases), except the changes will be done against</div>
|
|
<div class="line">`master` instead of `release`.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">If there is only a single issue for the hotfix, the work can be done in</div>
|
|
<div class="line">any branch. When it's ready to merge, jump to step 3 using your branch</div>
|
|
<div class="line">instead of `master-next`.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. Create a `master-next` branch from `master`.</div>
|
|
</div><!-- fragment --><p> git checkout –no-track -b master-next upstream/master git push upstream-push git fetch upstreams </p><div class="fragment"><div class="line">2. Open any PRs for the pending hotfix using `master-next` as the base,</div>
|
|
<div class="line"> so they can be merged directly in to it. Unlike `develop`, though,</div>
|
|
<div class="line"> `master-next` can be thrown away and recreated if necessary.</div>
|
|
<div class="line">3. Once the hotfix is ready, create a version commit using the same</div>
|
|
<div class="line"> steps as above, or use the</div>
|
|
<div class="line"> [update-version] script.</div>
|
|
<div class="line">4. Create a Pull Request for `master-next` with **`master`** as</div>
|
|
<div class="line"> the base branch. Instead of the default template, reuse and update</div>
|
|
<div class="line"> the message from the previous final release. Include the following verbiage</div>
|
|
<div class="line"> somewhere in the description:</div>
|
|
</div><!-- fragment --><p> The base branch is <code>master</code>. This PR branch will be pushed directly to <code>master</code> (not squashed or rebased, and not using the GitHub UI). </p><div class="fragment"><div class="line">7. Sign-offs for the three platforms (Linux, Mac, Windows) usually occur</div>
|
|
<div class="line"> offline, but at least one approval will be needed on the PR.</div>
|
|
<div class="line"> * If issues are discovered during testing, update `master-next` as</div>
|
|
<div class="line"> needed, but ensure that the changes are properly squashed, and the</div>
|
|
<div class="line"> version setting commit remains last</div>
|
|
<div class="line">8. Once everything is ready to go, push to `master` **only**.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<h1><a class="anchor" id="autotoc_md89"></a>
|
|
Just to be safe, do a dry run first:</h1>
|
|
<p >git push –dry-run upstream-push master-next:master</p>
|
|
<h1><a class="anchor" id="autotoc_md90"></a>
|
|
If everything looks right, push the branch</h1>
|
|
<p >git push upstream-push master-next:master</p>
|
|
<h1><a class="anchor" id="autotoc_md91"></a>
|
|
Check that all of the branches are updated</h1>
|
|
<p >git fetch upstreams git log -1 –oneline </p>
|
|
<h1><a class="anchor" id="autotoc_md92"></a>
|
|
The output should look like:</h1>
|
|
<h1><a class="anchor" id="autotoc_md93"></a>
|
|
0123456789 (HEAD -> upstream/master-next, upstream/master) Set version</h1>
|
|
<h1><a class="anchor" id="autotoc_md94"></a>
|
|
to 2.4.1</h1>
|
|
<h1><a class="anchor" id="autotoc_md95"></a>
|
|
Note that upstream/master must be on this commit. upstream/release and</h1>
|
|
<h1><a class="anchor" id="autotoc_md96"></a>
|
|
upstream/develop should not.</h1>
|
|
<h1><a class="anchor" id="autotoc_md97"></a>
|
|
Other branches, including some from upstream-push, may also be</h1>
|
|
<h1><a class="anchor" id="autotoc_md98"></a>
|
|
present.</h1>
|
|
<div class="fragment"><div class="line">9. Tag the release, too.</div>
|
|
</div><!-- fragment --><p> git tag <version number> git push upstream-push <version number> </p><div class="fragment"><div class="line">9. Delete the `master-next` branch on the repo.</div>
|
|
</div><!-- fragment --><p> git push –delete upstream-push master-next </p><div class="fragment"><div class="line">10. [Create a new release on</div>
|
|
<div class="line"> Github](https://github.com/XRPLF/rippled/releases). Be sure that</div>
|
|
<div class="line"> "Set as the latest release" is checked.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Once the hotfix is released, it needs to be reverse merged into</div>
|
|
<div class="line">`develop` as soon as possible. It may also need to be merged into</div>
|
|
<div class="line">`release` if a release candidate is under development.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. Create a branch in your own repo, based on `upstream/develop`.</div>
|
|
<div class="line"> The branch name is not important, but could include "mergeNNN".</div>
|
|
<div class="line"> E.g. For release 2.2.3, use `merge223`.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<p >git checkout –no-track -b merge223 upstream/develop </p><div class="fragment"><div class="line">2. Merge master into your branch.</div>
|
|
</div><!-- fragment --> <h1><a class="anchor" id="autotoc_md99"></a>
|
|
I like the "--edit --log --verbose" parameters, but they are</h1>
|
|
<h1><a class="anchor" id="autotoc_md100"></a>
|
|
not required.</h1>
|
|
<p >git merge upstream/master </p><div class="fragment"><div class="line">3. `BuildInfo.cpp` will have a conflict with the version number.</div>
|
|
<div class="line"> Resolve it with the version from `develop` - the higher version.</div>
|
|
<div class="line">4. Push your branch to your repo, and open a normal PR against</div>
|
|
<div class="line"> `develop`. The "High level overview" can simply indicate that this</div>
|
|
<div class="line"> is a merge of the hotfix version. The "Context" should summarize</div>
|
|
<div class="line"> the changes from the hotfix. Include the following text</div>
|
|
<div class="line"> prominently:</div>
|
|
</div><!-- fragment --><p> This PR must be merged manually using a –ff-only merge. Do not use the Github UI. </p><div class="fragment"><div class="line">5. Depending on the complexity of the hotfix, and/or merge conflicts,</div>
|
|
<div class="line"> the PR may need a thorough review, or just a sign-off that the</div>
|
|
<div class="line"> merge was done correctly.</div>
|
|
<div class="line">6. If `develop` is updated before this PR is merged, do not merge</div>
|
|
<div class="line"> `develop` back into your branch. Instead rebase preserving merges,</div>
|
|
<div class="line"> or do the merge again. (See also the `rerere` git config setting.)</div>
|
|
</div><!-- fragment --><p> git rebase –rebase-merges upstream/develop </p>
|
|
<h1><a class="anchor" id="autotoc_md101"></a>
|
|
OR</h1>
|
|
<p >git reset –hard upstream/develop git merge upstream/master </p><div class="fragment"><div class="line">7. When the PR is ready, push it to `develop`.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<h1><a class="anchor" id="autotoc_md102"></a>
|
|
Make sure the commits look right</h1>
|
|
<p >git log –show-signature "upstream/develop..HEAD"</p>
|
|
<p >git push upstream-push HEAD:develop </p><div class="fragment"><div class="line">Development on `develop` can proceed as normal. It is recommended to</div>
|
|
<div class="line">create a beta (or RC) immediately to ensure that everything worked as</div>
|
|
<div class="line">expected.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">##### An even rarer scenario: A hotfix on an old release</div>
|
|
<div class="line"> </div>
|
|
<div class="line">Historically, once a final release is tagged and packages are released,</div>
|
|
<div class="line">versions older than the latest final release are no longer supported.</div>
|
|
<div class="line">However, there is a possibility that a very high severity bug may occur</div>
|
|
<div class="line">in a non-amendment blocked version that is still being run by</div>
|
|
<div class="line">a significant fraction of users, which would necessitate a hotfix / point</div>
|
|
<div class="line">release to that version as well as any later versions.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">This scenario would follow the same basic procedure as above,</div>
|
|
<div class="line">except that *none* of `develop`, `release`, or `master`</div>
|
|
<div class="line">would be touched during the release process.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">In this example, consider if version 2.1.1 needed to be patched.</div>
|
|
<div class="line"> </div>
|
|
<div class="line">1. Create two branches in the main (`upstream`) repo.</div>
|
|
</div><!-- fragment --><p> git fetch upstreams</p>
|
|
<h1><a class="anchor" id="autotoc_md103"></a>
|
|
Create a base branch off the tag</h1>
|
|
<p >git checkout –no-track -b master-2.1.2 2.1.1 git push upstream-push</p>
|
|
<h1><a class="anchor" id="autotoc_md104"></a>
|
|
Create a working branch</h1>
|
|
<p >git checkout –no-track -b master212-next master-2.1.2 git push upstream-push</p>
|
|
<p >git fetch upstreams ``<code></p><ol type="1">
|
|
<li>Work continues as above, except usingmaster-2.1.2`as the base branch for any merging, packaging, etc.</li>
|
|
<li>After the release is tagged and packages are built, you could potentially delete both branches, e.g. <code>master-2.1.2</code> and <code>master212-next</code>. However, it may be useful to keep <code>master-2.1.2</code> around indefinitely for reference.</li>
|
|
<li>Assuming that a hotfix is also released for the latest version in parallel with this one, or if the issue is already fixed in the latest version, do no do any reverse merges. However, if it is not, it probably makes sense to reverse merge <code>master-2.1.2</code> into <code>master</code>, release a hotfix for <em>that</em> version, then reverse merge from <code>master</code> to <code>develop</code>. (Please don't do this unless absolutely necessary.) </li>
|
|
</ol>
|
|
<p></code></p>
|
|
</div></div><!-- contents -->
|
|
</div><!-- PageDoc -->
|
|
<!-- start footer part -->
|
|
<hr class="footer"/><address class="footer"><small>
|
|
Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.5
|
|
</small></address>
|
|
</body>
|
|
</html>
|