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