# Contributing

General guidelines for contributing to node-mapnik

## Coding Conventions

See the [Mapnik guide](https://github.com/mapnik/mapnik/blob/master/docs/contributing.md#coding-conventions).

## Documentation

Node Mapnik is documented with [JSDoc](http://usejsdoc.org/) comments embedded
in the C++ code and formatted into HTML with [documentationjs](http://documentation.js.org/). You can install DocumentationJS via `npm install -g documentation`.

API Documentation is versioned down to the **minor** patch, like `3.5`. Each version has its own directory within `/documentation`. Patch updates of Node Mapnik should overwrite current API docs. Any new minor releases should generate a new directory.

To update the [hosted documentation](http://mapnik.org/node-mapnik/documentation/):

* Clone the Node Mapnik Theme repository `git clone git@github.com:mapnik/node-mapnik-theme.git`
* Make changes to JSDoc comments
* Regenerate/generate documentation depending on if you are updating a minor patch or creating a new one: `documentation build src/*.cpp --polyglot -f html -o documentation/<version>/ --github --name "Node Mapnik <version>" -t /path/to/node-mapnik-theme -c documentation/config.json`. This should be done on your own branch.
* Merge changes into `master`
* Switch to the `gh-pages` branch: `git checkout gh-pages`
* merge changes from `master` into `gh-pages`
* commit those changes and push to Github

## Testing

In order for any code to be pulled into master it must contain tests for **100%** of all lines. The only lines that are not required to be tested are those that cover extreme cases which can not be tested with regularity, such as race conditions. 

If this case does occur you can put a comment block such as shown below to exclude the lines from test coverage.

```C++
// LCOV_EXCL_START
can_not_reach_code();
// LCOV_EXCL_END
```

## Developing / Pre-release

Create a milestone for the next release on github. If all anticipated changes are back compatible then a `patch` release is in order. If minor API changes are needed then a `minor` release is in order. And a `major` bump is warranted if a new Mapnik major version is dependent upon or major API changes are needed.

Assign tickets and pull requests you are working to the milestone you created.

## Releasing

To release a new node-mapnik version:

### Create a branch and publish binaries

**1)** Create a branch for your work

**2)** Updating the Mapnik SDK used for binaries

If your node-mapnik release requires a new Mapnik version, then a new Mapnik SDK would need to be published first.

To get a new Mapnik SDK published for Unix:

  - The Mapnik master branch must be production ready.
  - Or you can build an SDK from a testing branch. In this case the `MAPNIK_BRANCH` value [here](https://github.com/mapnik/mapnik-packaging/blob/master/.travis.yml#L8) can be edited.
  - Next you would commit to the `mapnik-packaging` repo with the message of `-m "[publish]"`.
  - Watch the end of the travis logs to get the url of the new SDK (https://travis-ci.org/mapnik/mapnik-packaging/builds/47075304#L4362)

Then, back at node-mapnik, take the new SDK version (which is generated by `git describe` and add it to the `MAPNIK_GIT` variable in the `.travis.yml`.

To get a new Mapnik SDK published for Windows:

  - The scripts at https://github.com/BergWerkGIS/mapnik-dependencies are used
  - The do not run fast enough to work on appveyor so we plan aws automation to get this working.
  - In the meantime ping @BergWerkGIS to run them and provide a new SDK.

Then, back at node-mapnik, take the new SDK version (which is generated by `git describe` and add it to the `MAPNIK_GIT` variable in the `appveyor.yml`.

**3)** Make sure all tests are passing on travis and appveyor for your branch. Check the links at https://github.com/mapnik/node-mapnik/blob/master/README.md#node-mapnik.

**4)** Within your branch edit the `version` value in `package.json` to something unique that will not clash with existing released versions. For example if the current release (check this via https://github.com/mapnik/node-mapnik/releases) is `3.1.4` then you could rename your `version` to `3.1.5-alpha` or `3.1.5-branchname`.

**5)** Commit the new version and publish binaries

Do this like:

```sh
git commit package.json -m "bump to v3.1.5-alpha [publish binary]"
```

What if you already committed the `package.json` bump and you have no changes to commit but want to publish binaries. In this case you can do:

```sh
git commit --allow-empty -m "[publish binary]"
```

If you need to republish binaries you can do this with the command below, however this should not be a common thing for you to do!

```sh
git commit --allow-empty -m "[republish binary]"
```

Note: NEVER republish binaries for an existing released version.

**6)** Test your binaries

Lots of ways to do this of course. Just updating a single dependency of node-mapnik is a good place to start: https://www.npmjs.com/browse/depended/mapnik

But the ideal way is to test a lot at once: enter mapnik-swoop.

### mapnik-swoop

Head over to https://github.com/mapbox/mapnik-swoop. Install it and run it [like so](https://github.com/mapbox/mapnik-swoop#installing) after ensuring that it is pointed at your upcoming node-mapnik version.

Ensure that all tests are passing and no dupes are reported. Only ignore failing tests for dependencies if you can confirm with the downstream maintainers of the modules that those tests are okay to fail and unrelated to your node-mapnik changes. You can check [recent builds](https://travis-ci.org/mapbox/mapnik-swoop/builds) to see if all builds were green and passing before your change. If they were red and failing before then try to resolve those issues before testing your new node-mapnik version.

**7)** Official release

An official release requires:

 - Updating the CHANGELOG.md
 - Publishing new binaries for a non-alpha version like `3.1.5`. So you'd want to merge your branch and then edit the `version` value in package json back to a decent value for release.
 - Create a github tag like `git tag --annotate 3.1.5 -m "v3.1.5"`
 - Push new tags `git push --tags`
 - Optional: Test mapnik-swoop again for your new tagged version
 - Ensure you have a clean checkout (no extra files in your check that are not known by git). You need to be careful, for instance, to avoid a large accidental file being packaged by npm. You can get a view of what npm will publish by running `make testpack`
 - Fully rebuild and ensure install from binary works: `make clean && npm install --fallback-to-build=false`
 - Then publish the module to npm repositories by running `npm publish`
