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/)