Merge pull request #410 from alex/release-automation

Write release automation software. Fixes #375
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 0f52900..b2a6c79 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,9 +1,11 @@
 coverage
 flake8
+invoke
 iso8601
 pretend
 pytest
 sphinx
 sphinx_rtd_theme
 tox
+twine
 -e .
diff --git a/docs/doing-a-release.rst b/docs/doing-a-release.rst
new file mode 100644
index 0000000..0f38206
--- /dev/null
+++ b/docs/doing-a-release.rst
@@ -0,0 +1,36 @@
+Doing a Release
+===============
+
+Doing a release of ``cryptography`` is a two part process.
+
+Bumping the version number
+--------------------------
+
+The first step in doing a release is bumping the version number in the
+software.
+
+* Update the version number in ``cryptography/__about__.py``.
+* Do a commit indicating this.
+* Send a pull request with this.
+* Wait for it to be merged.
+
+Performing the release
+----------------------
+
+The commit which merged the version number bump is now the official release
+commit for this release. You will need to have ``gpg`` installed and a ``gpg``
+key in order to do a release. Once this has happened:
+
+* Run ``invoke release {version}``.
+
+The release should now be available on PyPI and a tag should be available in
+the repository. You should verify that ``pip install cryptography`` works
+correctly:
+
+.. code-block:: pycon
+
+    >>> import cryptography
+    >>> cryptography.__version__
+    '...'
+
+Verify that this is the version you just released.
diff --git a/docs/index.rst b/docs/index.rst
index 9682337..4bbfe7f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -79,4 +79,5 @@
     contributing
     security
     api-stability
+    doing-a-release
     community
diff --git a/tasks.py b/tasks.py
new file mode 100644
index 0000000..f72f43b
--- /dev/null
+++ b/tasks.py
@@ -0,0 +1,27 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from __future__ import absolute_import, division, print_function
+
+import invoke
+
+
+@invoke.task
+def release(version):
+    """
+    ``version`` should be a string like '0.4' or '1.0'.
+    """
+    invoke.run("git tag -s {0}".format(version))
+    invoke.run("git push --tags")
+
+    invoke.run("python setup.py sdist")
+    invoke.run("twine upload -s dist/cryptography-{0}*".format(version))