github.com/m3db/m3@v1.5.0/DEVELOPMENT.md (about) 1 # Development Guide 2 3 M3 is a large, active codebase. This guide is for all potential code 4 contributors, designed to make it easier to get started with contributing to M3. 5 6 ## Setup Development Environment 7 8 Fork <https://github.com/m3db/m3> to your own user or org account on GitHub. 9 10 Clone the fork: 11 12 ```bash 13 mkdir -p $GOPATH/src/github.com/m3db 14 cd $GOPATH/src/github.com/m3db 15 git clone git@github.com:<fork_user_or_org>/m3.git 16 ``` 17 18 **Note**: You must push all commits/branches/etc to the fork, not to the upstream repository. 19 20 Verify that `git clone` set the repository's upstream: 21 22 ```shell 23 $ git remote -v 24 origin git@github.com:<fork_user_or_org>/m3.git (fetch) 25 origin git@github.com:<fork_user_or_org>/m3.git (push) 26 ``` 27 28 Install dependencies: 29 30 ```bash 31 cd m3 32 make install-vendor-m3 33 ``` 34 35 You can build each M3 component using `make` and the relevant task 36 37 - A single combined database and coordinator node ideal for local development: `make m3dbnode` 38 - An M3 Coordinator node: `make m3coordinator` 39 - An M3 Aggregator node: `make m3aggregator` 40 - An M3 Query node: `make m3query` 41 42 <!-- TODO: Why? What is this? Why do I need it? --> 43 44 ## Running the M3 Stack Locally 45 46 Follow the instructions in [this README][local-readme]. 47 48 [local-readme]: ./scripts/development/m3_stack/README.md 49 50 ## Updating Mocks and Generated Files 51 52 <!-- TODO: What might these be? --> 53 54 If changes require updates to mocks or other generated files, make sure to 55 update those files. There are `make` targets to help with generation: 56 57 - Mocks: `make mock-gen` 58 - Protobuf: `make proto-gen` (Requires Docker) 59 - Thrift: `make thrift-gen` (Requires Docker) 60 61 Don't forget to account for changes to generated files in tests. 62 63 ## Scoping Pull Requests 64 65 Inspired by Phabricator's article about 66 [Recommendations on Revision Control][phab-one-idea], and particularly 67 because pull requests tend to be squash-merged, try to keep PRs focused 68 on one idea (or the minimal number of ideas for the change to be viable). 69 70 The advantages of smaller PRs are: 71 72 - Quicker to write + quicker to review = faster iteration 73 - Easier to spot errors 74 - Less cognitive overhead (and net time invested) for reviewers due to 75 reduced scope 76 - Avoids scope creep 77 - Clearly establishes that all parts of the PR are related 78 79 Because of this, contributors are encouraged to keep PRs as small as 80 possible. Given that this does introduce some developer overhead (e.g. 81 needing to manage more PRs), _how_ small is unspecified; reviewers 82 can request breaking PRs down further as necessary, and contributors 83 should work with reviewers to find the right balance. 84 85 [phab-one-idea]: https://secure.phabricator.com/book/phabflavor/article/recommendations_on_revision_control/#one-idea-is-one-commit 86 87 ## Testing Changes 88 89 M3 has an extensive test suite to ensure that we're able to validate changes. You can find more notes about the testing strategies employed in [TESTING][TESTING.md]. 90 91 While the CI suite runs all tests before allowing the merging of pull requests 92 , developers should test their changes during development and before 93 pushing updates. 94 95 To test code, use `go test` from the root directory: 96 97 ```shell 98 go test -v ./src/... 99 ``` 100 101 The time required to run the entire suite has increased significantly. We recommend only running tests for both (1) any packages with changes and (2) any packages that 102 import the changed packages. An example of this is: 103 104 ```bash 105 changed=$(git diff --name-only HEAD^ HEAD | xargs -I {} dirname {} | sort | uniq) 106 for pkg in $changed; do 107 affected=$(grep -r "$pkg" ./src | cut -d: -f1 | grep -v mock | xargs -I{} dirname {} | sort | uniq) 108 go test -v -race "./$pkg" $affected 109 done 110 ``` 111 112 Contributors are free to do whatever due diligence that they feel helps them to 113 be most productive. Our only request is that contributors don't use CI jobs as a first-pass filter to determine whether a change is sane or not. 114 115 Once tests are passing locally, push to a new remote branch to create a pull 116 request, or push to an existing branch to update a pull request. If the CI 117 suite reports any errors, attempt to reproduce failures locally and fix them 118 before continuing. 119 120 For larger or more intensive tests (e.g. "big" unit tests, integration tests), 121 you may need additional build tags to scope the tests down to a smaller 122 subset, for example: 123 124 ```shell 125 # example integration test 126 $ go test ./integration -tags integration -run TestIndexBlockRotation -v 127 128 # example big unit test 129 $ go test -tags big ./services/m3dbnode/main -run TestIndexEnabledServer -v 130 ``` 131 132 ## Code Review 133 134 Please follow the following guidelines when submitting or reviewing pull 135 requests: 136 137 - Merging is blocked on approval by 1 or more users with write access. We 138 recommend 2+ for large, complex, or nuanced changes. 139 - Pull requests should contain clear descriptions and context per the 140 pull request template. 141 - The [Technical Steering Committee (TSC)][GOVERNANCE.md] must approve breaking changes 142 under the current versioning guarantees (see [COMPATIBILITY][COMPATIBILITY.md]). 143 - You should follow the [STYLEGUIDE][STYLEGUIDE.md] to the extent reasonable 144 within the scope of the pull request. 145 - You should validate changed codepaths should by unit tests that cover at least one 146 nominal case and one error case. 147 - Pull requests are only merged with a green build. Don't merge with 148 build failures, even if they're known and unrelated. 149 - Flaky or otherwise unreliable CI failures count as hard failures. Commit fixes 150 or skips for flaky tests or other failures first. 151 152 Your pull request is most likely to be accepted if it: 153 154 - Includes tests for new functionality. 155 - Follows the guidelines in [Effective 156 Go](https://golang.org/doc/effective_go.html) and the [Go team's common code 157 review comments](https://github.com/golang/go/wiki/CodeReviewComments). 158 - Has a [good commit 159 message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 160 - It prefixes the name of the pull request with the component you are updating in the format "[component] Change title" (for example "[dbnode] Support out of order writes"). 161 162 ## Updating the CHANGELOG 163 164 After a pull request is merged, summarize significant changes in the 165 [CHANGELOG][CHANGELOG.md]. Since the you don't know the PR number ahead of time, 166 do this as a subsequent commit after the merged PR (though you can prepare the 167 CHANGELOG PR in tandem with the referenced PR). 168 169 The format of the CHANGELOG entry should be: 170 171 ```text 172 - TYPE **COMPONENT**: Description (#PR_NUMBER) 173 ``` 174 175 Omit the `TYPE` should if it's a feature. If the change isn't a 176 feature, `TYPE` should be either `FIX` or `PERF`. Add new types of changes 177 to this document before used if you can't categorize them by the 178 existing types. 179 180 Add new CHANGELOG entries to the current "unreleased" section at 181 the top of the CHANGELOG as long as they're within the scope of that potential 182 version. If no unreleased section exists, add one using the 183 appropriate proposed semver. If an unreleased section exists but the new change 184 requires a different semver change (e.g. the unreleased version is a patch 185 version bump, but the new change requires a minor version bump), update the version 186 on the existing section. See [COMPATIBILITY][COMPATIBILITY.md] 187 for more information on versioning. 188 189 An example CHANGELOG addition: 190 191 ```text 192 # 0.4.5 (unreleased) 193 194 - FIX **DB**: Index data race in FST Segment reads (#938) 195 ``` 196 197 ## Cutting a Release 198 199 1. Check you have a GitHub API access token with the `repo` scope 200 2. Checkout the commit you want to release (all releases must be on master) 201 3. Create a tag with the version you want to release 202 - E.g. `git tag -a v0.7.0 -m "v0.7.0"` 203 - Read [COMPATIBILITY][COMPATIBILITY.md] for semver information. 204 4. Push the tag 205 - E.g. `git push origin v0.7.0` 206 5. Run `make GITHUB_TOKEN=<GITHUB_API_ACCESS_TOKEN> release` 207 6. Update [CHANGELOG.md](CHANGELOG.md) and commit it to master 208 7. Copy and paste the text from [CHANGELOG.md](CHANGELOG.md) into the release notes [on GitHub][releases]. 209 210 [CHANGELOG.md]: https://github.com/m3db/m3/blob/master/CHANGELOG.md 211 212 [COMPATIBILITY.md]: https://github.com/m3db/m3/blob/master/COMPATIBILITY.md 213 214 [GOVERNANCE.md]: https://github.com/m3db/m3/blob/master/GOVERNANCE.md 215 216 [STYLEGUIDE.md]: https://github.com/m3db/m3/blob/master/STYLEGUIDE.md 217 218 [TESTING.md]: https://github.com/m3db/m3/blob/master/TESTING.md 219 220 [m3db.io]: https://m3db.io/ 221 222 [releases]: https://github.com/m3db/m3/releases