Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automate release process #1138

Merged
merged 4 commits into from Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/make_release.yml
@@ -0,0 +1,66 @@
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

name: Create Release

jobs:
build:
name: Create Release
runs-on: ubuntu-latest
if: github.repository == 'napari/napari'
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Install Python
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Build Distribution
run: |
pip install wheel
python setup.py sdist bdist_wheel
jni marked this conversation as resolved.
Show resolved Hide resolved
- name: Find Release Notes
id: release_notes
run: |
TAG="${GITHUB_REF/refs\/tags\/v/}" # clean tag
VER="${TAG/rc*/}" # remove pre-release identifier
RELEASE_NOTES="$(cat docs/release/release_${VER//./_}.rst)"
# https://github.community/t5/GitHub-Actions/set-output-Truncates-Multiline-Strings/m-p/38372/highlight/true#M3322
RELEASE_NOTES="${RELEASE_NOTES//'%'/'%25'}"
RELEASE_NOTES="${RELEASE_NOTES//$'\n'/'%0A'}"
RELEASE_NOTES="${RELEASE_NOTES//$'\r'/'%0D'}"
# https://help.github.com/en/actions/reference/workflow-commands-for-github-actions
echo "::set-env name=tag::$TAG"
echo "::set-output name=contents::$RELEASE_NOTES"
- name: Create Release
id: create_release
uses: actions/create-release@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
with:
tag_name: ${{ github.ref }}
release_name: ${{ env.tag }}
body: ${{ steps.release_notes.outputs.contents }}
draft: false
prerelease: ${{ contains(github.ref, 'rc') }}
- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dist/napari-${{ env.tag }}.tar.gz
asset_name: napari-${{ env.tag }}.tar.gz
asset_content_type: application/gzip
- name: Publish PyPI Package
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_password }}
61 changes: 22 additions & 39 deletions docs/developers/RELEASE.md
Expand Up @@ -9,12 +9,22 @@ They will need to have a [PyPI](https://pypi.org) account with upload permission

You will also need the additional `release` dependencies in `requirements/release.txt` to complete the release process.

> [`MANIFEST.in`](../MANIFEST.in) determines which non-Python files are included.
> Make sure to check that all necessary ones are listed before beginning the release process.

The `napari/napari` repository must have a PyPI API token as a GitHub secret.
This likely has been done already, but if it has not, follow
[this guide](https://pypi.org/help/#apitoken) to gain a token and
[this guide](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets)
to add it as a secret.

## determining the version

The version of `napari` is automatically determined by [`versioneer`](https://github.com/warner/python-versioneer)
from the latest [`git` tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging) beginning with `v`.
Thus, you'll need to tag the [reference](https://git-scm.com/book/en/v2/Git-Internals-Git-References) with the new version number. It is likely something like `X.Y.Z`. Before making a release though we need to generate the release notes.


## generating release notes

1. Review and cleanup ``docs/release/release_dev.txt``. This may be empty if it has not been
Expand Down Expand Up @@ -49,78 +59,51 @@ Thus, you'll need to tag the [reference](https://git-scm.com/book/en/v2/Git-Inte
8. Make and merge a PR with these release notes before moving onto the next steps.


## Tagging the new release candidate
## tagging the new release candidate

First we will generate a release candidate, which will contain the letters `rc`.
Using release candidates allows us to test releases on PyPi without using up the actual
Using release candidates allows us to test releases on PyPI without using up the actual
release number.

You should include a basic message with the tag `"Version X.Y.Zrc1"`:
You can tag the current source code as a release candidate with:
```bash
$ git tag -a vX.Y.Zrc1 -m "Version X.Y.Zrc1" master
$ git tag vX.Y.Zrc1 master
```

If the tag is meant for a previous version of master, simply reference the specific commit:
```bash
$ git tag -a vX.Y.Zrc1 -m "Version X.Y.Zrc1" abcde42
$ git tag vX.Y.Zrc1 abcde42
```

Note here how we are using `rc` for release candidate to create a version of our release we can test
before making the real release.

You can read more on tagging [here](https://git-scm.com/book/en/v2/Git-Basics-Tagging).

## creating the distribution

Before creating a new distribution, make sure to delete any previous ones:
```bash
$ rm -rf dist build
```
## testing the release candidate

Now you can build the distribution:
Our CI automatically makes a release, copying the release notes to the tag and uploading the distribution to PyPI.
You can trigger this by pushing the new tag to `napari/napari`:
```bash
$ python setup.py sdist bdist_wheel
```

[`MANIFEST.in`](../MANIFEST.in) determines which non-Python files are included.
Make sure to check that all necessary ones are listed before beginning the release process.

## uploading the release candidate to PyPI

Upload the release candidate with:
```bash
$ python -m twine upload dist/napari-X.Y.Zrc1.tar.gz
$ git push upstream --tags
```

The release candidate can then be tested with

```bash
$ pip install --pre napari
```
or

```bash
$ pip install -U --pre napari
```
if napari is already installed.
It is recommended that the release candidate is tested in a virtual environment in order to isolate dependencies.

If the release candidate is not what you want, make your changes and repeat the process from the beginning but
incrementing the number after `rc` on tag (e.g. `vX.Y.Zrc2`).

Once you are satisfied with the release candidate it is time to generate the actual release.

## Generating the actual release
## generating the actual release
To generate the actual release you will now repeat the processes above but now dropping the `rc`.
For example:

```bash
$ git tag -a vX.Y.Z -m "Version X.Y.Z" master
$ rm -rf dist build
$ python setup.py sdist bdist_wheel
$ python -m twine upload dist/napari-X.Y.Z.tar.gz
```

At the very end you should push the new tags to the repo.
```bash
$ git tag vX.Y.Z master
$ git push upstream --tags
```