diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..ea6c69f --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,38 @@ +# Build releases and (on tags) publish to PyPI +name: Release + +# always build releases (to make sure wheel-building works) +# but only publish to PyPI on tags +on: + push: + pull_request: + workflow_dispatch: + +jobs: + build-release: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: install build package + run: | + pip install --upgrade pip + pip install build + pip freeze + + - name: build release + run: | + python -m build --sdist --wheel . + ls -l dist + + - name: Publish to PyPI + if: startsWith(github.ref, 'refs/tags/') + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + pip install twine + twine upload --skip-existing dist/* diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 591bd13..aea32f6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -8,12 +8,8 @@ on: push: workflow_dispatch: -defaults: - run: - shell: bash - jobs: - build: + pytest: runs-on: ubuntu-20.04 strategy: fail-fast: false @@ -42,4 +38,4 @@ jobs: # GitHub action reference: https://github.com/codecov/codecov-action - name: Upload code test coverage uses: codecov/codecov-action@v1 - if: github.ref == 'refs/heads/master' + if: github.ref == 'refs/heads/main' diff --git a/README.md b/README.md index f826d86..ae8b820 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,11 @@ # simpervisor -[![CI](https://img.shields.io/github/workflow/status/yuvipanda/simpervisor/Test?logo=github&label=tests)](https://github.com/yuvipanda/simpervisor/actions) -[![PyPI](https://img.shields.io/pypi/v/simpervisor.svg?logo=pypi&logoColor=white)](https://pypi.python.org/pypi/simpervisor) -[![Codecov](https://img.shields.io/codecov/c/github/yuvipanda/simpervisor?logo=codecov&logoColor=white)](https://codecov.io/gh/yuvipanda/simpervisor) +[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/jupyterhub/simpervisor/Test?logo=github)](https://github.com/jupyterhub/simpervisor/actions) +[![Codecov](https://img.shields.io/codecov/c/github/jupyterhub/simpervisor?logo=codecov&logoColor=white)](https://codecov.io/gh/jupyterhub/simpervisor) +[![Latest PyPI version](https://img.shields.io/pypi/v/simpervisor?logo=pypi)](https://pypi.python.org/pypi/simpervisor) +[![Latest conda-forge version](https://img.shields.io/conda/vn/conda-forge/simpervisor?logo=conda-forge)](https://anaconda.org/conda-forge/simpervisor) +[![GitHub](https://img.shields.io/badge/issue_tracking-github-blue?logo=github)](https://github.com/jupyterhub/simpervisor/issues) +[![Discourse](https://img.shields.io/badge/help_forum-discourse-blue?logo=discourse)](https://discourse.jupyter.org/c/jupyterhub) +[![Gitter](https://img.shields.io/badge/social_chat-gitter-blue?logo=gitter)](https://gitter.im/jupyterhub/jupyterhub) Simple Python3 Supervisor library diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..76ba30d --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,100 @@ +# How to make a release + +`simpervisor` is a package [available on +PyPI](https://pypi.org/project/jupyterhub-simpervisor/) and +[conda-forge](https://conda-forge.org/). These are instructions on how to make a +release on PyPI. The PyPI release is done automatically by a GitHub workflow +when a tag is pushed. + +For you to follow along according to these instructions, you need: + +- To have push rights to the [simpervisor GitHub + repository](https://github.com/jupyterhub/simpervisor). + +## Steps to make a release + +1. Update [CHANGELOG.md](CHANGELOG.md). Doing this can be made easier with the + help of the + [choldgraf/github-activity](https://github.com/choldgraf/github-activity) + utility to list merged PRs and generate a list of contributors. + + ```bash + github-activity jupyterhub/simpervisor --output tmp-changelog-prep.md + ``` + +1. Once the changelog is up to date, checkout main and make sure it is up to date and clean. + + ```bash + ORIGIN=${ORIGIN:-origin} # set to the canonical remote, e.g. 'upstream' if 'origin' is not the official repo + git checkout main + git fetch $ORIGIN main + git reset --hard $ORIGIN/main + # WARNING! This next command deletes any untracked files in the repo + git clean -xfd + ``` + +1. Set the `version` field in [setup.py](setup.py) appropriately and make a + commit. + + ```bash + git add setup.py + VERSION=... # e.g. 1.2.3 + git commit -m "release $VERSION" + ``` + +1. Reset the `version` field in [setup.py](setup.py) appropriately with an + incremented patch version and a `dev` element, then make a commit. + + ```bash + git add setup.py + git commit -m "back to dev" + ``` + +1. Push your two commits to main. + + ```bash + # first push commits without a tags to ensure the + # commits comes through, because a tag can otherwise + # be pushed all alone without company of rejected + # commits, and we want have our tagged release coupled + # with a specific commit in main + git push $ORIGIN main + ``` + +1. Create a git tag for the pushed release commit and push it. + + ```bash + git tag -a $VERSION -m $VERSION HEAD~1 + + # then verify you tagged the right commit + git log + + # then push it + git push $ORIGIN refs/tags/$VERSION + ``` + +1. Push your two commits to main along with the annotated tags referencing + commits on main. A GitHub Workflow will trigger automatic deployment of the + pushed tag. + + ```bash + # pushing the commits standalone allows you to + # ensure you don't end up only pushing the tag + # because the commit were rejected but the tag + # wasn't + git push $ORIGIN main + + # if you could push the commits without issues + # go ahead and push the tag also + git push --follow-tags $ORIGIN main + ``` + +1. Verify that [the GitHub + workflow](https://github.com/jupyterhub/simpervisor/actions?query=workflow%3ARelease) + triggers and succeeds and that that PyPI received a [new + release](https://pypi.org/project/simpervisor/). + +1. Following the release to PyPI, an automated PR should arrive to + [conda-forge/simpervisor-feedstock](https://github.com/conda-forge/simpervisor-feedstock), + check for the tests to succeed on this PR and then merge it to successfully + update the package for `conda` on the conda-forge channel. diff --git a/setup.py b/setup.py index bfda1bc..b26dce6 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setuptools.setup( name="simpervisor", version='0.4', - url="https://github.com/yuvipanda/simpervisor", + url="https://github.com/jupyterhub/simpervisor", description='Simple async process supervisor', author="Yuvi Panda", author_email="yuvipanda@gmail.com", diff --git a/tox.ini b/tox.ini deleted file mode 100644 index ef7e063..0000000 --- a/tox.ini +++ /dev/null @@ -1,6 +0,0 @@ -[tox] -envlist = py36,py37,py38,py39 -[testenv] -deps = - -r dev-requirements.txt -commands = pytest {posargs:--maxfail 3 --verbose}