Skip to content

Commit

Permalink
Adding page on setting up GHA
Browse files Browse the repository at this point in the history
  • Loading branch information
henryiii committed May 19, 2020
1 parent 2939bb9 commit bf8ac2e
Showing 1 changed file with 164 additions and 0 deletions.
164 changes: 164 additions & 0 deletions pages/developers/gha_basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
---
layout: page
title: GitHub Actions
permalink: /developer/gha_basic
nav_order: 7
parent: Developer information
---

# GitHub Actions

The recommended CI for Scikit-HEP is GitHub Actions (GHA), although it's
predecessor (Azure) is also in heavy usage, and other popular services (Travis,
Appveyor, and Circle CI) may be found in a few packages. GHA is preferred due
to the flexible, extensible design and the tight integration with the GitHub
permissions model (and UI). Here is a guide in setting up a new package with GHA.

GHA is made up of workflows which consist of actions. Here are some of the
workflows you will probably want in your package. These should be in a file
named `.github/workflows/main.yml` or similar.

## Header

Your main CI workflow file should begin something like this:

```yaml
name: CI

on:
pull_request:
push:
branches: master
tags:
- 'v*'

jobs:
```
This gives the workflow a nice name, and defines the conditions under which it
runs. This will run on pull requests or pushes to master, and on version tags. If
you use a develop branch, you probably will want to include that.
## Pre-commit
If you use pre-commit (and you should), this is a job that will check pre-commit for you:
```yaml
pre-commit:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- name: set PY
run: echo "::set-env name=PY::$(python -c 'import hashlib, sys;print(hashlib.sha256(sys.version.encode()+sys.executable.encode()).hexdigest())')"
- uses: actions/cache@v1
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
- uses: pre-commit/action@v1.1.0
```
## Unit tests
Implementing unit tests is also easy. Since you should be following best
practices listed in the previous sections, this becomes an almost directly
copy-and-paste formula, regardless of the package details.
```yaml
checks:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version:
- 2.7
- 3.6
- 3.8
name: Check Python ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install package
run: python -m pip install -e .[test]

- name: Test package
run: python -m pytest
```
A few things to note from above:
The matrix should contain the versions you are interested in. You can also test
on other OS's if you are building any extensions or are worried about your
package on macOS or Windows. Fail-fast is optional.
You need to use version 1 of the checkout, since version 2 strips too much
from the repository for `setuptools_scm` to work.

The formula here for installing should be identical for all users; and using
PEP 517/518 builds, you are even guaranteed a consistent wheel will be produced
just as if you were building a final package.

## Distribution: Pure Python wheels

We will cover binary wheels later, but for a simple universal (pure Python)
package, the procedure is simple.

```yaml
dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1
with:
python-version: 3.8
- name: Install wheel and sdist requirements
run: python -m pip install "setuptools>=42.0" "setuptools_scm[toml]>=3.4" "wheel"
- name: Build sdist
run: python setup.py sdist
- name: Build wheel
run: >
python -m pip wheel . -w wheels &&
ls -lh wheels &&
mkdir -p dist &&
cp wheels/<packagename>*any.whl dist/
- uses: actions/upload-artifact@v1
with:
name: DistPackage
path: dist
- uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_password }}
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
```

A few things to note that are new to this job:

We install SDist requirements by hand since `python setup.py sdist` does not
get the benefits of having pip install things. If you have any special
requirements in your `pyproject.toml`, you'll need to list them here. This is
special just for the sdist, not for making wheels (which should be done by the
PEP 517/518 process for you).

You need to put your base package name in for `<packagename>` in the copy
command; pip will put all wheels needed in the directory you specify, and you
need to just pick out your wheels for upload. You don't want to upload numpy or
some other wheel it had to build (not common anymore, but can happen).

We upload the artifact just to make it available via the GitHub PR/Checks API.
You can download a file to test locally if you want without making a release.

Finally, only on release tags, we publish to PyPI. You'll need to go to PyPI,
generate a token for your project, and put it into `pypi_password` on your
repo's secrets page.


0 comments on commit bf8ac2e

Please sign in to comment.