README.md
knife-community
===============
[![Gem Version](https://badge.fury.io/rb/knife-community.svg)](http://badge.fury.io/rb/knife-community)
[![Build Status](https://travis-ci.org/miketheman/knife-community.svg?branch=master)](http://travis-ci.org/miketheman/knife-community)
[![Dependency Status](https://gemnasium.com/miketheman/knife-community.svg)](https://gemnasium.com/miketheman/knife-community)
[![Code Climate](https://codeclimate.com/github/miketheman/knife-community/badges/gpa.svg)](https://codeclimate.com/github/miketheman/knife-community)
A Knife plugin to assist with deploying completed Chef cookbooks to the Chef Supermarket.
Intro
-----
There are sooo many ways to [deliver software][wiki:apppkg].
Apt has 'deb', Yum has 'rpm', Node has 'npm', RubyGems has 'gem', Java has 'jar', etc etc etc.
In The Land of [Chef][chef], the typical unit of shareable software is a 'cookbook'.
The centralized location for sharing cookbooks is the [Supermarket][opcs], and we already have support to download/install these elements, either it be through [knife itself][kcsi], [librarian][libr], and [berkshelf][brks], and there are probably others.
What we _don't_ have is a good method for cookbook maintainers to contribute back to the Supermarket, while semi-enforcing good habits, such as version incrementing, git tags and forming the package correctly.
Assumptions
-----------
### Basics
* You know what Git is
* You know what Chef is
* You have Push permissions to the remote GitHub repository
* You don't already have a perfected workflow that works for you
* You want to be a helpful citizen of the community
### Important
* You have **not** incremented the version number in `metadata.rb` - this will do so for you
* You have a `name` string defined in your `metadata.rb`, OR your repository name is identical to your cookbook name
* You have either committed or staged all changes to be included with this version release. Any uncommitted changed should be `git stash`ed, or stage them to be committed along with the version via `git add`
Cookbook Release Workflow
-------------------------
Assuming you have made your changes, tested your code thoroughly (one can hope!), all merged into your `master` branch, and are ready to release a new version of your cookbook, here's a flow to follow:
1. Ensure that the branch is ready to be committed. If there are uncommitted changes, error out.
1. Read in the current `metadata.rb`, inspect the `version` string, and increment it to the next tiny version. Override with CLI argument.
1. Create a git commit for the `metadata.rb` change.
1. Create a git tag with the version number (no leading "v" or the like)
1. Push all commits/tags to the set remote, typically like `git push origin master`. Override with `--branch`
1. Create a 'package' - effectively a compressed tarball - and upload it to the Supermarket
1. Have a beer, or glass of wine - you choose.
This flow can probably be used for most cookbook maintainers.
Usage
=====
Invoke
------
knife community release COOKBOOK [X.Y.Z | --remote | --branch | --devodd ]
Flags
-----
* `X.Y.Z` - String, Version in X.Y.Z format. Manually specify the version.
If unspecified, increments to the next x.y.Z version
* `--remote REMOTE` - String, Remote repository to push to. Defaults to `origin`
* `--branch BRANCHNAME` - String, Branch name. Defaults to `master`
* `--devodd` - Boolean. If specified, post-release, will bump the minor version to the next odd number, and generate another commit & push (but no tags).
This is a flow that some adopt by having even-only numbered releases, utilizing the [odd numbered ones for development][wiki:oddver].
There are other flags, run `knife community release -h` to see their specifications.
Some good ideas while working on a cookbook
-------------------------------------------
Creating a `CHANGELOG.md` that details a short message about any changes included in each release is really helpful to anyone looking at your updated cookbook and seeing if it addresses a problem they have, without delving deeper into the code.
See the CHANGELOG for this project to get an idea of how to write one.
Updating a `TODO.md` file if there are outstanding known issues, planned work for the next version, etc. A TODO file also helps anyone else in the community try to tackle a problem you haven't figured out or gotten to yet, so they can issue a pull request for your cookbook.
Follow [Semantic Versioning][semver] when choosing which version number to increment to. Start your cookbook at 0.1.0, and increment from there, until you are confident enough in a 1.0.0 version.
Test, test, test. And then test again.
[brks]: http://berkshelf.com/
[chef]: https://www.chef.io/chef/
[kcsi]: https://docs.chef.io/#ManagingCookbooksWithKnife-CookbookSite
[libr]: https://github.com/applicationsonline/librarian
[opcs]: https://supermarket.chef.io/dashboard
[semver]: http://semver.org/
[wiki:apppkg]: http://en.wikipedia.org/wiki/List_of_software_package_management_systems#Application-level_package_managers
[wiki:oddver]: http://en.wikipedia.org/wiki/Software_versioning#Odd-numbered_versions_for_development_releases