Repository: scikit-hep/pyhf

Issue:
Automate deployment to PyPI
# Description

According to @lukasheinrich, the current workflow for deploying to PyPI is:

```
git checkout master
git pull
bumpversion patch
git commit
git push origin master --tags
```

This is a bit annoyingly manual and ideally should be done automatically.

Luckily, there is an [official PyPA GitHub action](https://discuss.python.org/t/official-github-action-for-publishing-to-pypi/1061) to do this:

https://github.com/pypa/gh-action-pypi-publish

However, we need GitHub actions for pyhf, so we have to wait.


Discussion:
I'm happy to take this one once we get GitHub actions.
An example of how this is actually hard without automation is that when [`v0.1.2`](https://github.com/diana-hep/pyhf/releases/tag/v0.1.2) was released to PyPI the commit got into the tags, but not the refs/heads, but still got [picked up by the CI, built and deployed](https://travis-ci.org/diana-hep/pyhf/builds/557986549). It was [later pushed to `master`](https://github.com/diana-hep/pyhf/commit/3e1e383c775a4407277dad49c810f5b16a56ef3b), but for about an hour there was a mismatch where PyPI was ahead of GitHub.

Having a CI that can properly do releases for us would solve this sort of confusing thing.
Why don't we have GitHub Actions yet?
> Why don't we have GitHub Actions yet?

GitHub Actions is still in beta. 

[![beta_version](https://user-images.githubusercontent.com/5142394/61195613-c0b27b00-a68e-11e9-96a2-091228004c2f.png)](https://github.com/features/actions)

They have tightly restricted the number of people who can enter the beta, and they denied my request to bump Lukas and diana-hep up in the queue.
We have GitHub Actions now (:tada:), and @webknjaz has done an awesome job getting [`pypi-publish`](https://github.com/pypa/gh-action-pypi-publish) up [on the GitHub Marketplace](https://github.com/marketplace/actions/pypi-publish) and ready to go. Time to use it!
There doesn't seem to be any clear examples of people using [`pypi-publish`](https://github.com/pypa/gh-action-pypi-publish) out in the wild yet, with the exception of [`pubmedpy`](https://github.com/dhimmel/pubmedpy/blob/master/.github/workflows/release.yml), so it might be worth checking out what they did.
@matthewfeickert I believe everything you need is in the README. There's also an unmerged guide here: https://github.com/pypa/packaging.python.org/pull/647.

But the idea is that you use whatever it is that you use already for *building* dists. This Action is just for uploading the artifacts.

Go to https://pypi.org/manage/account/#api-tokens, create a token just for this project, and then copy-paste it to https://github.com/diana-hep/pyhf/settings/secrets and finally use that var in the Action.
The GitHub Actions publishing guide is now up on the PyPA website: https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/ :)
Yep, for a while now. But needs updating to take into account OS-specific wheels.
> Yep, for a while now. But needs updating to take into account OS-specific wheels.

I ran into a ton of issues here, especially with Test PyPI and overlapping versioning. I don't understand setuptools_scm enough to really make it work the way I want (non-tagged versions result in {next-version}.dev{distance} and tagged versions result in {current-version}) and I made a mess of it just to make it work correctly in GitHub actions here: https://github.com/kratsg/stare/blob/master/.github/workflows/publish-package-to-pypi.yml (with a bunch of additional changes to check env variable flags and so on)

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -50,8 +50,8 @@
 
 def _is_test_pypi():
     """
-    Determine if the Travis CI environment has TESTPYPI_UPLOAD defined and
-    set to true (c.f. .travis.yml)
+    Determine if the CI environment has IS_TESTPYPI defined and
+    set to true (c.f. .github/workflows/publish-package.yml)
 
     The use_scm_version kwarg accepts a callable for the local_scheme
     configuration parameter with argument "version". This can be replaced
@@ -65,7 +65,7 @@ def _is_test_pypi():
 
     return (
         {'local_scheme': lambda version: ''}
-        if getenv('TESTPYPI_UPLOAD') == 'true'
+        if getenv('IS_TESTPYPI') == 'true'
         else False
     )
 


Test patch: