github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/CONTRIBUTING.md (about) 1 Contents 2 ======== 3 4 1. [Getting started](#getting-started) 5 2. [Dependency management](#dependency-management) 6 3. [Code formatting](#code-formatting) 7 4. [Workflow](#workflow) 8 5. [Community](#community) 9 10 Quick links 11 =========== 12 13 Issue tracker: https://bugs.launchpad.net/juju/+bugs 14 15 Documentation: 16 * https://docs.jujucharms.com/ 17 * [source tree docs](doc/) 18 19 Community: 20 * https://jujucharms.com/community/ 21 * https://discourse.jujucharms.com/ 22 * [#juju on freenode](http://webchat.freenode.net/?channels=juju) 23 24 Getting started 25 =============== 26 27 Thanks for your interest in Juju! Contributions like yours make good projects 28 great. Before contributing please read the following sections describing the 29 tools and conventions of this project. This file is a companion to 30 [README](README.md) and it is assumed that file has been read and followed 31 prior. 32 33 Specifically, the following commands should already have been run: 34 35 ```bash 36 go get -d -v github.com/juju/juju/... 37 cd $GOPATH/src/github.com/juju/juju 38 make install-dependencies 39 ``` 40 41 The `-d` option means the source (for Juju and its dependencies) is only 42 downloaded and not built. This is required since the dependencies may be out 43 of sync and fail to build properly. See the 44 [Dependency management](#dependency-management) section for more information. 45 46 Git 47 --- 48 49 Juju uses `git` for version control. To get started, install it and configure 50 your username: 51 52 ```bash 53 git config --global user.name "A. Hacker" 54 git config --global user.email "a.hacker@example.com" 55 ``` 56 57 For information on setting up and using `git`, check out the following: 58 59 * https://www.atlassian.com/git/tutorials/ 60 * http://git-scm.com/book/en/Getting-Started-Git-Basics 61 * [GitHub bootcamp](https://help.github.com/categories/54/articles) 62 63 GitHub 64 ------ 65 66 The upstream Juju repository is hosted on [Github](http://github.com). Patches 67 to Juju are contributed through pull requests (more on that in the 68 [Pushing](#pushing) section). So you should have a github account and a fork 69 there. The following steps will help you get that ready: 70 71 1. Sign up for GitHub (a free account is fine): https://github.com/join 72 2. Add your ssh public key to your account: https://github.com/settings/ssh 73 3. Hit the "Fork" button on the web page for the Juju repo: 74 https://github.com/juju/juju 75 76 At this point you will have your own copy under your github account. Note 77 that your fork is not automatically kept in sync with the official Juju repo 78 (see [Staying in sync](#staying-in-sync)). 79 80 Note that Juju has dependencies hosted elsewhere with other version control 81 tools. 82 83 Local clone 84 ----------- 85 86 To contribute to Juju you will also need a local clone of your GitHub fork. 87 The earlier `go get` command will have already cloned the Juju repo for you. 88 However, that local copy is still set to pull from and push to the upstream 89 Juju github account. Here is how to fix that (replace <USERNAME> with your 90 github account name): 91 92 ```bash 93 cd $GOPATH/src/github.com/juju/juju 94 git remote set-url origin git@github.com:<USERNAME>/juju.git 95 ``` 96 97 To simplify staying in sync with upstream, give it a "remote" name: 98 99 ```bash 100 git remote add upstream https://github.com/juju/juju.git 101 ``` 102 103 Add the check script as a git hook: 104 105 ```bash 106 cd $GOPATH/src/github.com/juju/juju 107 ln -s scripts/pre-push.bash .git/hooks/pre-push 108 ``` 109 110 This will ensure that any changes you commit locally pass a basic sanity 111 check. Using pre-push requires git 1.8.2 or later, though alternatively 112 running the check as a pre-commit hook also works. 113 114 Staying in sync 115 --------------- 116 117 Make sure your local copy and github fork stay in sync with upstream: 118 119 ```bash 120 cd $GOPATH/src/github.com/juju/juju 121 git pull upstream develop 122 git push 123 ``` 124 125 Dependency management 126 ===================== 127 128 In the top-level directory of the Juju repo, there is a file, 129 [Gopkg.lock](Gopkg.lock), that holds the revision ids of all the external 130 projects that Juju depends on. That file is used to freeze the code in 131 external repositories so that Juju is insulated from changes to those repos. 132 133 dep 134 ------ 135 136 [dep](https://golang.github.io/dep) is the tool that does the freezing. 137 After getting the Juju code, you need to get `dep`: 138 139 ```bash 140 go get github.com/golang/dep 141 ``` 142 143 This installs the `dep` application. You can then run `dep` from the 144 root of juju, to set the revision number on the external repositories: 145 146 ```bash 147 cd $GOPATH/src/github.com/juju/juju 148 make dep 149 ``` 150 151 Now you are ready to build, run, test, etc. 152 153 Staying up-to-date 154 ------------------ 155 156 The [Gopkg.lock](Gopkg.lock) file can get out of date, for example when you 157 have changed Gopkg.toml. When it is out of date, run `dep`. In practice, you 158 can wait until you get a compile error about an external package not 159 existing/having an incorrect API, and then rerun `dep ensure -v`. 160 161 Updating dependencies 162 --------------------- 163 164 If you update a repo that Juju depends on, you will need to recreate 165 `Gopkg.lock`: 166 167 ```bash 168 make rebuild-dependencies [dep-update=true] 169 ``` 170 171 Code formatting 172 =============== 173 174 Go already provides a tool, `go fmt`, that facilitates a standardized 175 format to go source code. The Juju project has one additional policy. 176 177 Imports 178 ------- 179 180 Import statements are grouped into 3 sections: standard library, 3rd party 181 libraries, juju imports. The tool "go fmt" can be used to ensure each 182 group is alphabetically sorted. eg: 183 184 ```go 185 import ( 186 "fmt" 187 "time" 188 189 "labix.org/v2/mgo" 190 "github.com/juju/loggo" 191 gc "gopkg.in/check.v1" 192 193 "github.com/juju/juju/state" 194 "github.com/juju/juju/worker" 195 ) 196 ``` 197 198 Because "gopkg.in/check.v1" will be referenced frequently in test suites, its 199 name gets a default short name of just "gc". 200 201 Workflow 202 ======== 203 204 As a project Juju follows a specific workflow: 205 206 1. sync with upstream 207 2. create a local feature branch 208 3. make desired changes 209 4. test the changes 210 5. push the feature branch to your github fork 211 6. reviews 212 7. auto-merge 213 8. continuous-integration 214 215 Naturally it is not so linear in practice. Each of these is elaborated below. 216 217 Sync with upstream 218 ------------------ 219 220 First check that the branch is on develop: 221 222 ```bash 223 git branch 224 * develop 225 old_feature 226 ``` 227 228 Then pull in the latest changes from upstream, assuming you have done the setup 229 as above: 230 231 ```bash 232 git pull upstream develop 233 ``` 234 235 Feature branches 236 ---------------- 237 238 All development should be done on feature branches based on a current copy of 239 develop. So after pulling up your local repo, make a new branch for your work: 240 241 ```bash 242 git checkout -b new_feature 243 ``` 244 245 Testing 246 ------- 247 248 Some tests may require local lxd to be installed, see 249 [installing lxd via snap](https://stgraber.org/2016/10/17/lxd-snap-available/). 250 251 Juju uses the `gocheck` testing framework. `gocheck` is automatically installed 252 as a dependency of `juju`. You can read more about `gocheck` at 253 http://godoc.org/gopkg.in/check.v1. `gocheck` is integrated into the source of 254 each package so the standard `go test` command is used to run `gocheck` tests. 255 For example 256 257 ```bash 258 go test github.com/juju/juju/... 259 ``` 260 261 will run all the tests in the Juju project. By default `gocheck` prints only 262 minimal output, and as `gocheck` is hooked into the testing framework via a 263 single `go test` test per package, the usual `go test -v` flags are less 264 useful. As a replacement the following commands produce more output from 265 `gocheck`. 266 267 ```bash 268 go test -gocheck.v 269 ``` 270 271 is similar to `go test -v` and outputs the name of each test as it is run as 272 well as any logging statements. It is important to note that these statements 273 are buffered until the test completes. 274 275 ```bash 276 go test -gocheck.vv 277 ``` 278 279 extends the previous example by outputting any logging data immediately, rather 280 than waiting for the test to complete. By default `gocheck` will run all tests 281 in a package, selected tests can by run by passing `-gocheck.f` to match a 282 subset of test names. 283 284 ```bash 285 go test -gocheck.f '$REGEX' 286 ``` 287 288 Finally, because by default `go test` runs the tests in the current package, 289 and is not recursive, the following commands are equal, and will produce no 290 output. 291 292 ```bash 293 cd $GOPATH/src/github.com/juju/juju 294 go test 295 go test github.com/juju/juju 296 ``` 297 298 Testing and MongoDB 299 ------------------- 300 301 Many tests use a standalone instance of mongod as part of their setup. The 302 `mongod` binary found in `$PATH` is executed by these suites. 303 304 Some tests (particularly those under ./store/...) assume a MongoDB instance 305 that supports Javascript for map-reduce functions. These functions are not 306 supported by juju-mongodb and the associated tests will fail unless disabled 307 with an environment variable: 308 309 ```bash 310 JUJU_NOTEST_MONGOJS=1 go test github.com/juju/juju/... 311 ``` 312 313 Pushing 314 ------- 315 316 When ready for feedback, push your feature branch to github, optionally after 317 collapsing multiple commits into discrete changes: 318 319 ```bash 320 git rebase -i --autosquash develop 321 git push origin new_feature 322 ``` 323 324 Go to the web page (https://github.com/$YOUR_GITHUB_USERNAME/juju) and hit the 325 "Pull Request" button, selecting develop as the target. 326 327 This creates a numbered pull request on the github site, where members of the 328 Juju project can see and comment on the changes. 329 330 Make sure to add a clear description of why and what has been changed, and 331 include the Launchpad bug number if one exists. 332 333 It is often helpful to mention newly created proposals on the Discourse forum, 334 especially if you would like a specific developer to be aware of the proposal. 335 336 Note that updates to your GitHub project will automatically be reflected in 337 your pull request. 338 339 Be sure to have a look at: 340 341 https://help.github.com/articles/using-pull-requests 342 343 Sanity checking PRs and unit tests 344 ---------------------- 345 346 All PRs run pre-merge check - unit tests and a small but representative sample 347 of functional tests. This check is re-run anytime the PR changes, for example 348 when a new commit is added. 349 350 You can also initiate this check by commenting !!build!! in the PR. 351 352 Code review 353 ----------- 354 355 The Juju project uses peer review of pull requests prior to merging to 356 facilitate improvements both in code quality and in design. 357 358 Once you have created your pull request, it will be reviewed. Make sure to 359 address the feedback. Your request might go through several rounds of feedback 360 before the patch is approved or rejected. Once you get an approval from a 361 member of the Juju project, you are ready to have your patch merged. 362 Congratulations! 363 364 Continuous integration 365 ---------------------- 366 367 Continuous integration is automated through Jenkins: 368 369 The bot runs on all commits during the PRE process, as well as handles merges. 370 Use the `$$merge$$` comment to land a PR. 371 372 Static Analysis 373 --------------- 374 375 Static Analysis of the code is provided by 376 [gometalinter](https://github.com/alecthomas/gometalinter). 377 378 The Static Analysis runs every linter in parallel over the Juju code base with 379 the aim to spot any potential errors that should be resolved. As a default all 380 the linters are disabled and only a selection of linters are run on each pass. 381 The linters that are run, are known to pass with the state of the current code 382 base. 383 384 You can independently run the linters on the code base to validate any issues 385 before committing or pushing using the following command from the root of the 386 repo: 387 388 ```bash 389 ./scripts/gometalinter.bash 390 ``` 391 392 If you already have the `git` hook installed for pre-pushing, then the linters 393 will also run during that check. 394 395 Adding new linters can be done, by editing the `./scripts/gometalinter.bash` 396 file to also including/removing the desired linters. 397 398 Additionally to turn off the linter check for pushing or verifying then setting 399 the environment variable `IGNORE_GOMETALINTER` beforehand will cause this to 400 happen. 401 402 Community 403 ========= 404 405 The Juju community is growing and you have a number of options for interacting 406 beyond the workflow and the [issue tracker](https://bugs.launchpad.net/juju/+bugs). 407 408 Use the following links to contact the community: 409 410 - Community page: https://jujucharms.com/community/ 411 - IRC channel on freenode: `#juju` 412 - Discourse forum: [https://discourse.jujucharms.com/](https://discourse.jujucharms.com/)