π π¦ & test & publish #2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: π π¦ & test & publish | |
on: | |
create: # is used for publishing to PyPI and TestPyPI | |
tags: # any tag regardless of its name, no branches | |
- >- | |
** | |
branches-ignore: | |
- >- | |
** | |
push: # publishes to TestPyPI pushes to the main branch | |
branches: # any branch but not tag | |
- >- | |
** | |
tags-ignore: | |
- >- | |
** | |
pull_request: | |
jobs: | |
pre-setup: | |
name: Pre-set global build settings | |
runs-on: ubuntu-latest | |
defaults: | |
run: | |
shell: python | |
outputs: | |
dist_version: ${{ steps.scm_version.outputs.dist_version }} | |
is_untagged_devel: >- | |
${{ steps.not_tagged_check.outputs.is_untagged_devel || false }} | |
is_tagged: ${{ steps.tagged_check.outputs.is_tagged || false }} | |
profiling_enabled: >- | |
${{ steps.profiling_check.outputs.profiling_enabled || false }} | |
cache_key_files: >- | |
${{ steps.calc_cache_key_files.outputs.files_hash_key }} | |
steps: | |
- name: Switch to using Python 3.8 by default | |
uses: actions/setup-python@v2 | |
with: | |
python-version: 3.8 | |
- name: >- | |
Mark the build as non-tagged | |
${{ github.event.repository.default_branch }} build | |
id: not_tagged_check | |
if: >- | |
github.event_name == 'push' && | |
github.ref == format( | |
'refs/heads/{0}', github.event.repository.default_branch | |
) | |
run: >- | |
print('::set-output name=is_untagged_devel::true') | |
- name: Mark the build as tagged | |
id: tagged_check | |
if: >- # "create" workflows run separately from "push" & "pull_request" | |
github.event_name == 'create' && | |
github.event.ref_type == 'tag' | |
run: >- | |
print('::set-output name=is_tagged::true') | |
- name: Enable profiling of the build | |
id: profiling_check | |
if: >- | |
steps.tagged_check.outputs.is_tagged != 'true' | |
run: >- | |
print('::set-output name=profiling_enabled::true') | |
- name: Check out src from Git | |
uses: actions/checkout@v2 | |
with: | |
fetch-depth: >- | |
${{ steps.tagged_check.outputs.is_tagged == 'true' && 1 || 0 }} | |
- name: >- | |
Calculate Python interpreter version hash value | |
for use in the cache key | |
id: calc_cache_key_py | |
run: | | |
from hashlib import sha512 | |
from sys import version | |
hash = sha512(version.encode()).hexdigest() | |
print(f'::set-output name=py_hash_key::{hash}') | |
- name: >- | |
Calculate dependency files' combined hash value | |
for use in the cache key | |
id: calc_cache_key_files | |
run: | | |
from hashlib import sha512 | |
hashes_combo = sha512('-'.join(( | |
"${{ hashFiles('setup.cfg') }}", | |
"${{ hashFiles('tox.ini')}}", | |
"${{ hashFiles('pyproject.toml') }}", | |
"${{ hashFiles('.pre-commit-config.yaml') }}", | |
"${{ hashFiles('pytest.ini') }}", | |
"${{ hashFiles('requirements-build.*') }}", | |
"${{ hashFiles('docs/requirements.*') }}", | |
)).encode()).hexdigest() | |
print(f'::set-output name=files_hash_key::{hashes_combo}') | |
- name: Set up pip cache | |
uses: actions/cache@v2 | |
with: | |
path: >- | |
${{ | |
runner.os == 'Linux' | |
&& '~/.cache/pip' | |
|| '~/Library/Caches/pip' | |
}} | |
key: >- | |
${{ runner.os }}-pip-${{ | |
steps.calc_cache_key_py.outputs.py_hash_key }}-${{ | |
steps.calc_cache_key_files.outputs.files_hash_key }} | |
restore-keys: | | |
${{ runner.os }}-pip-${{ steps.calc_cache_key_py.outputs.py_hash_key }}- | |
${{ runner.os }}-pip- | |
${{ runner.os }}- | |
- name: Drop Git tags from HEAD for non-tag-create events | |
if: >- | |
steps.tagged_check.outputs.is_tagged != 'true' | |
run: >- | |
git tag --points-at HEAD | |
| | |
xargs git tag --delete | |
shell: bash | |
- name: Set up versioning prerequisites | |
run: >- | |
python -m | |
pip install | |
--user | |
setuptools-scm | |
shell: bash | |
- name: Set the current dist version | |
id: scm_version | |
run: | | |
import setuptools_scm | |
ver = setuptools_scm.get_version( | |
${{ steps.not_tagged_check.outputs.is_untagged_devel == 'true' && 'local_scheme="no-local-version"' || '' }} | |
) | |
print('::set-output name=dist_version::{ver}'.format(ver=ver)) | |
build-bin-macos: | |
name: π macOS π¦ for π ${{ matrix.python-version }} | |
needs: | |
- pre-setup | |
# NOTE: I tried also making wheels for 32-bit runtime but it's | |
# NOTE: proven to be useless and hard to maintain. Also macOS | |
# NOTE: Catalina ditched support for 32-bit executables so it | |
# NOTE: doesn't really make sense to try shimming it. | |
runs-on: macos-latest | |
strategy: | |
matrix: | |
python-version: | |
# NOTE: Research on the wheel names / platform tags and how they | |
# NOTE: are matched under various macOS versions: | |
# NOTE: https://github.com/MacPython/wiki/wiki/Spinning-wheels | |
- 3.8 | |
- 2.7 | |
- 3.7 | |
- 3.6 | |
- 3.5 | |
env: | |
ANSIBLE_PYLIBSSH_TRACING: >- | |
${{ fromJSON(needs.pre-setup.outputs.profiling_enabled) && 1 || 0 }} | |
PEP517_ARGS: --binary | |
PY_COLORS: 1 | |
TOXENV: build-wheels-pip,delocate-macos-wheels,metadata-validation | |
TOX_PARALLEL_NO_SPINNER: 1 | |
steps: | |
- name: Patch env context to match docs expectations | |
run: | | |
echo "::set-env name=HOME::${HOME}" | |
- name: >- | |
Find the download URL for official | |
CPython distribution from python.org | |
id: probe-python | |
run: | | |
function probe_url() { | |
local py_ver="$1" | |
local macos_ver="$2" | |
[ $(curl -I --write-out '%{http_code}' --silent --output /dev/null "https://www.python.org/ftp/python/${py_ver}/python-${py_ver}-macosx10.${macos_ver}.pkg") == '200' ] && return 0 | |
return 1 | |
} | |
function find_last_macos_py() { | |
for macos_ver in 6 9 | |
do | |
for py_ver in $* | |
do | |
>&2 echo Probing py${py_ver} and macosx10.${macos_ver} | |
# FIXME: Can we set outputs right here? | |
if probe_url $py_ver $macos_ver | |
then | |
>&2 echo "Found pkg: py${py_ver} w/ macosx10.${macos_ver}" | |
echo "::set-output name=py_ver_long::${py_ver}" | |
echo "::set-output name=download_url::https://www.python.org/ftp/python/${py_ver}/python-${py_ver}-macosx10.${macos_ver}.pkg" | |
return 0 | |
fi | |
done | |
done | |
>&2 echo Failed looking up macOS pkg for $* | |
return 1 | |
} | |
LONG_VER_SUGGESTIONS=$(git ls-remote --sort -v:refname --tags git://github.com/python/cpython.git "${{ matrix.python-version }}*" "v${{ matrix.python-version }}*" | grep -v '\^{}$' | awk '{print$2}' | sed 's#^refs/tags/##;s#^v##' | grep -v '[abcepr]') | |
find_last_macos_py ${LONG_VER_SUGGESTIONS} | |
- name: Install Python from python.org | |
run: | | |
INSTALLERS_CACHE="${{env.HOME}}/.github/workflows/.tmp/python-installers" | |
INSTALLER_PATH="${INSTALLERS_CACHE}/python-${LONG_VER}.pkg" | |
SHORT_VER=$(echo ${LONG_VER} | awk -F. '{print$1"."$2}') | |
INSTALL_PATH="/Library/Frameworks/Python.framework/Versions/${SHORT_VER}/bin" | |
PYTHON_BIN="${INSTALL_PATH}/python${SHORT_VER}" | |
mkdir -pv "${INSTALLERS_CACHE}" | |
>&2 echo Downloading "${DOWNLOAD_URL}" into "${INSTALLER_PATH}"... | |
wget -O "${INSTALLER_PATH}" "${DOWNLOAD_URL}" | |
sudo installer -verboseR -dumplog -pkg "${INSTALLER_PATH}" -target / | |
>&2 echo Setting up '$PATH' and a binary output var for Python ${LONG_VER} | |
echo "::add-path::${INSTALL_PATH}" | |
echo "::set-output name=binary::${PYTHON_BIN}" | |
env: | |
DOWNLOAD_URL: ${{ steps.probe-python.outputs.download_url }} | |
LONG_VER: ${{ steps.probe-python.outputs.py_ver_long }} | |
id: install-python | |
- name: >- | |
Install certificates for Python ${{ matrix.python-version }} | |
from python.org, if necessary, by running | |
'Install Certificates.command' | |
if: matrix.python-version != 3.5 | |
run: >- | |
/Applications/Python\ ${{ matrix.python-version }}/Install\ Certificates.command | |
- name: >- | |
Install certificates for Python ${{ matrix.python-version }} | |
from python.org, if necessary, by installing certifi | |
if: matrix.python-version == 3.5 | |
run: >- | |
curl https://bootstrap.pypa.io/get-pip.py | |
| | |
${{ steps.install-python.outputs.binary }} - 'certifi' | |
- name: Log official Python dist version from python.org | |
run: ${{ steps.install-python.outputs.binary }} --version | |
- name: Install libssh from brew | |
run: brew install libssh # @0.9.4 # pinning the version does not work | |
# FIXME: can we pre-build libssh once in a pre-requisite job? | |
# NOTE: Currently we use a brew-installed libssh build that also | |
# NOTE: pulls-in [email protected] as well. In the future we may want to | |
# NOTE: be in control of what and how we build. This is what the | |
# NOTE: commented out code below is for. Doing own builds may help | |
# NOTE: us produce a smaller footprint by not building the server- | |
# NOTE: side APIs. Controlling the supply chain is also safer from | |
# NOTE: the security perspective. Also, it breaks when brew replaces | |
# NOTE: the versions. | |
#- name: Fetch libssh src | |
# env: | |
# LIBSSH_VERSION: 0.9.3 | |
# run: >- | |
# git clone --depth=1 | |
# -b "libssh-${{ env.LIBSSH_VERSION }}" | |
# https://git.libssh.org/projects/libssh.git | |
#- name: Make libssh build dir | |
# run: mkdir -pv build | |
# working_directory: libssh | |
#- name: Build libssh | |
# env: | |
# CFLAGS: -I/usr/local/opt/openssl/include | |
# LDFLAGS: -L/usr/local/opt/openssl/lib | |
# run: | | |
# cmake .. | |
# make | |
# make install/strip | |
# working_directory: libssh/build | |
- name: Install tox | |
run: >- | |
${{ steps.install-python.outputs.binary }} -m | |
pip install | |
--user | |
tox | |
- name: >- | |
Calculate Python interpreter version hash value | |
for use in the cache key | |
id: calc_cache_key_py | |
run: | | |
from __future__ import print_function | |
from hashlib import sha512 | |
from sys import version, version_info | |
b_version = version if version_info[0] == 2 else version.encode() | |
hash = sha512(b_version).hexdigest() | |
print('::set-output name=py_hash_key::{hash}'.format(hash=hash)) | |
shell: python | |
- name: Set up pip cache | |
uses: actions/cache@v2 | |
with: | |
path: >- | |
${{ | |
runner.os == 'Linux' | |
&& '~/.cache/pip' | |
|| '~/Library/Caches/pip' | |
}} | |
key: >- | |
${{ runner.os }}-pip-${{ | |
steps.calc_cache_key_py.outputs.py_hash_key }}-${{ | |
needs.pre-setup.outputs.cache_key_files }} | |
restore-keys: | | |
${{ runner.os }}-pip-${{ steps.calc_cache_key_py.outputs.py_hash_key }}- | |
${{ runner.os }}-pip- | |
${{ runner.os }}- | |
- name: Check out src from Git | |
uses: actions/checkout@v2 | |
with: | |
fetch-depth: >- | |
${{ fromJSON(needs.pre-setup.outputs.is_tagged) && 1 || 0 }} | |
- name: Drop Git tags from HEAD for non-tag-create events | |
if: >- | |
!fromJSON(needs.pre-setup.outputs.is_tagged) | |
run: >- | |
git tag --points-at HEAD | |
| | |
xargs git tag --delete | |
shell: bash | |
- name: Pre-populate tox env | |
run: ${{ steps.install-python.outputs.binary }} -m tox -p auto --parallel-live -vvvv --notest | |
- name: Instruct setuptools-scm not to add a local version part | |
if: fromJSON(needs.pre-setup.outputs.is_untagged_devel) | |
run: | | |
echo 'local_scheme = "no-local-version"' >> pyproject.toml | |
git update-index --assume-unchanged pyproject.toml | |
- name: Build dist | |
run: ${{ steps.install-python.outputs.binary }} -m tox -p auto --parallel-live -vvvv -e build-wheels-pip | |
- name: Bundle external shared libs | |
run: ${{ steps.install-python.outputs.binary }} -m tox -p auto --parallel-live -vvvv -e delocate-macos-wheels -- dist/*.whl | |
- name: Verify wheel metadata | |
run: ${{ steps.install-python.outputs.binary }} -m tox -p auto --parallel-live -vvvv -e metadata-validation | |
- name: Install pytest and its plugins | |
run: >- | |
${{ steps.install-python.outputs.binary }} -m | |
pip install | |
--user | |
pytest pytest-cov pytest-xdist | |
- name: Install the generated Python wheel distribution | |
run: >- | |
${{ steps.install-python.outputs.binary }} -m | |
pip install | |
--user | |
--no-index -f dist | |
--only-binary ansible-pylibssh | |
ansible-pylibssh | |
- name: Run tests using pytest | |
run: >- | |
${{ steps.install-python.outputs.binary }} | |
-m pytest | |
-m smoke | |
--no-cov | |
- name: Store the binary wheel | |
uses: actions/upload-artifact@v2 | |
with: | |
name: python-package-distributions | |
path: dist | |
build-bin-manylinux: | |
name: π manylinux π¦ for π ${{ matrix.manylinux-python-target }} | |
needs: | |
- pre-setup | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
manylinux-python-target: | |
# NOTE: Must be from this list: | |
# NOTE: $ podman run -it --rm \ | |
# NOTE: quay.io/pypa/manylinux1_x86_64 \ | |
# NOTE: ls -1 /opt/python | |
- cp38-cp38 | |
- cp37-cp37m | |
- cp36-cp36m | |
- cp35-cp35m | |
- cp27-cp27mu | |
- cp27-cp27m | |
env: | |
ANSIBLE_PYLIBSSH_TRACING: >- | |
${{ fromJSON(needs.pre-setup.outputs.profiling_enabled) && 1 || 0 }} | |
PY_COLORS: 1 | |
TOXENV: build-dists-manylinux,metadata-validation | |
TOX_PARALLEL_NO_SPINNER: 1 | |
steps: | |
- name: Switch to using Python 3.8 by default | |
uses: actions/setup-python@v2 | |
with: | |
python-version: 3.8 | |
- name: >- | |
Calculate Python interpreter version hash value | |
for use in the cache key | |
id: calc_cache_key_py | |
run: | | |
from __future__ import print_function | |
from hashlib import sha512 | |
from sys import version, version_info | |
b_version = version if version_info[0] == 2 else version.encode() | |
hash = sha512(b_version).hexdigest() | |
print('::set-output name=py_hash_key::{hash}'.format(hash=hash)) | |
shell: python | |
- name: Set up pip cache | |
uses: actions/cache@v2 | |
with: | |
path: >- | |
${{ | |
runner.os == 'Linux' | |
&& '~/.cache/pip' | |
|| '~/Library/Caches/pip' | |
}} | |
key: >- | |
${{ runner.os }}-pip-${{ | |
steps.calc_cache_key_py.outputs.py_hash_key }}-${{ | |
needs.pre-setup.outputs.cache_key_files }} | |
restore-keys: | | |
${{ runner.os }}-pip-${{ steps.calc_cache_key_py.outputs.py_hash_key }}- | |
${{ runner.os }}-pip- | |
${{ runner.os }}- | |
- name: Install tox | |
run: >- | |
python -m | |
pip install | |
--user | |
tox | |
- name: Check out src from Git | |
uses: actions/checkout@v2 | |
with: | |
fetch-depth: >- | |
${{ fromJSON(needs.pre-setup.outputs.is_tagged) && 1 || 0 }} | |
- name: Drop Git tags from HEAD for non-tag-create events | |
if: >- | |
!fromJSON(needs.pre-setup.outputs.is_tagged) | |
run: >- | |
git tag --points-at HEAD | |
| | |
xargs git tag --delete | |
shell: bash | |
- name: Pre-populate tox env | |
run: python -m tox -p auto --parallel-live -vvvv --notest | |
- name: Instruct setuptools-scm not to add a local version part | |
if: fromJSON(needs.pre-setup.outputs.is_untagged_devel) | |
run: | | |
echo 'local_scheme = "no-local-version"' >> pyproject.toml | |
git update-index --assume-unchanged pyproject.toml | |
- name: >- | |
Build ${{ matrix.manylinux-python-target }} dist | |
and verify wheel metadata | |
run: >- | |
python -m | |
tox -p auto --parallel-live -vvvv | |
-- | |
${{ matrix.manylinux-python-target }} | |
- name: Store ${{ matrix.manylinux-python-target }} binary wheel | |
uses: actions/upload-artifact@v2 | |
with: | |
name: python-package-distributions | |
path: dist | |
build-src: | |
name: π an sdist π¦ | |
needs: | |
- pre-setup | |
runs-on: ubuntu-latest | |
env: | |
ANSIBLE_PYLIBSSH_TRACING: >- | |
${{ fromJSON(needs.pre-setup.outputs.profiling_enabled) && 1 || 0 }} | |
PEP517_ARGS: --source | |
PY_COLORS: 1 | |
TOXENV: build-dists,metadata-validation | |
TOX_PARALLEL_NO_SPINNER: 1 | |
steps: | |
- name: Switch to using Python 3.8 by default | |
uses: actions/setup-python@v2 | |
with: | |
python-version: 3.8 | |
- name: >- | |
Calculate Python interpreter version hash value | |
for use in the cache key | |
id: calc_cache_key_py | |
run: | | |
from __future__ import print_function | |
from hashlib import sha512 | |
from sys import version, version_info | |
b_version = version if version_info[0] == 2 else version.encode() | |
hash = sha512(b_version).hexdigest() | |
print('::set-output name=py_hash_key::{hash}'.format(hash=hash)) | |
shell: python | |
- name: Set up pip cache | |
uses: actions/cache@v2 | |
with: | |
path: >- | |
${{ | |
runner.os == 'Linux' | |
&& '~/.cache/pip' | |
|| '~/Library/Caches/pip' | |
}} | |
key: >- | |
${{ runner.os }}-pip-${{ | |
steps.calc_cache_key_py.outputs.py_hash_key }}-${{ | |
needs.pre-setup.outputs.cache_key_files }} | |
restore-keys: | | |
${{ runner.os }}-pip-${{ steps.calc_cache_key_py.outputs.py_hash_key }}- | |
${{ runner.os }}-pip- | |
${{ runner.os }}- | |
- name: Install tox | |
run: >- | |
python -m | |
pip install | |
--user | |
tox | |
- name: Check out src from Git | |
uses: actions/checkout@v2 | |
with: | |
fetch-depth: >- | |
${{ fromJSON(needs.pre-setup.outputs.is_tagged) && 1 || 0 }} | |
- name: Drop Git tags from HEAD for non-tag-create events | |
if: >- | |
!fromJSON(needs.pre-setup.outputs.is_tagged) | |
run: >- | |
git tag --points-at HEAD | |
| | |
xargs git tag --delete | |
shell: bash | |
- name: Pre-populate tox env | |
run: python -m tox -p auto --parallel-live -vvvv --notest | |
- name: Instruct setuptools-scm not to add a local version part | |
if: fromJSON(needs.pre-setup.outputs.is_untagged_devel) | |
run: | | |
echo 'local_scheme = "no-local-version"' >> pyproject.toml | |
git update-index --assume-unchanged pyproject.toml | |
- name: Build sdist and verify metadata | |
run: python -m tox -p auto --parallel-live -vvvv | |
- name: Store the source distribution | |
uses: actions/upload-artifact@v2 | |
with: | |
name: python-package-distributions | |
path: dist | |
test-matrix: | |
name: >- | |
Test π | |
${{ matrix.python-version }} | |
${{ matrix.runner-vm-os }} | |
${{ matrix.dist-type }} dists | |
needs: | |
- build-bin-macos | |
- build-bin-manylinux | |
- build-src | |
- pre-setup # transitive, for accessing settings | |
runs-on: ${{ matrix.runner-vm-os }} | |
strategy: | |
matrix: | |
python-version: | |
- 3.8 | |
- 2.7 | |
- 3.7 | |
- 3.6 | |
- 3.5 | |
runner-vm-os: | |
- ubuntu-20.04 | |
- macos-latest | |
- ubuntu-18.04 | |
- ubuntu-16.04 | |
dist-type: | |
- binary | |
- source | |
exclude: | |
- dist-type: source | |
runner-vm-os: ubuntu-16.04 # has too old libssh in the repos | |
- dist-type: source | |
runner-vm-os: ubuntu-18.04 | |
- dist-type: source | |
runner-vm-os: ubuntu-20.04 # undefined symbol: ssh_disconnect | |
env: | |
ANSIBLE_PYLIBSSH_TRACING: >- | |
${{ fromJSON(needs.pre-setup.outputs.profiling_enabled) && 1 || 0 }} | |
PY_COLORS: 1 | |
TOXENV: test-${{ matrix.dist-type }}-dists | |
TOX_PARALLEL_NO_SPINNER: 1 | |
steps: | |
- name: Install libssh and openssl headers on Linux | |
if: >- | |
matrix.dist-type == 'source' && | |
runner.os == 'Linux' | |
run: sudo apt update && sudo apt install libssh-dev libssl-dev build-essential | |
- name: Install libssh and openssl headers on macOS | |
if: >- | |
runner.os == 'macOS' | |
run: brew install libssh | |
- name: Install libssh headers on Linux for cythonize+coverage | |
if: >- | |
runner.os == 'Linux' | |
run: sudo add-apt-repository ppa:kedazo/libssh-0.7.x && sudo apt update && sudo apt install libssh-dev | |
- name: Switch π to v${{ matrix.python-version }} | |
uses: actions/setup-python@v2 | |
with: | |
python-version: ${{ matrix.python-version }} | |
- name: >- | |
Calculate Python interpreter version hash value | |
for use in the cache key | |
id: calc_cache_key_py | |
run: | | |
from __future__ import print_function | |
from hashlib import sha512 | |
from sys import version, version_info | |
b_version = version if version_info[0] == 2 else version.encode() | |
hash = sha512(b_version).hexdigest() | |
print('::set-output name=py_hash_key::{hash}'.format(hash=hash)) | |
shell: python | |
- name: Set up pip cache | |
uses: actions/cache@v2 | |
with: | |
path: >- | |
${{ | |
runner.os == 'Linux' | |
&& '~/.cache/pip' | |
|| '~/Library/Caches/pip' | |
}} | |
key: >- | |
${{ runner.os }}-pip-${{ | |
steps.calc_cache_key_py.outputs.py_hash_key }}-${{ | |
needs.pre-setup.outputs.cache_key_files }} | |
restore-keys: | | |
${{ runner.os }}-pip-${{ steps.calc_cache_key_py.outputs.py_hash_key }}- | |
${{ runner.os }}-pip- | |
${{ runner.os }}- | |
- name: Install tox | |
run: >- | |
python -m | |
pip install | |
--user | |
tox | |
- name: Check out src from Git | |
uses: actions/checkout@v2 | |
- name: Download all the dists | |
uses: actions/download-artifact@v2 | |
with: | |
name: python-package-distributions | |
path: dist/ | |
- name: Pre-populate tox env | |
run: python -m tox -p auto --parallel-live -vvvv --notest | |
- name: Configure tox to run pytest under catchsegv | |
if: runner.os == 'Linux' | |
run: >- | |
print("::set-env name=CATCHSEGV_BINARY::catchsegv") | |
shell: python | |
- name: Run tests | |
run: python -m tox -p auto --parallel-live -vvvv | |
- name: Send coverage data to Codecov | |
uses: codecov/codecov-action@v1 | |
with: | |
file: .test-results/pytest/cov.xml | |
dist-meta: | |
name: Verify ππ¦ metadata | |
needs: | |
- build-bin-macos | |
- build-bin-manylinux | |
- build-src | |
- pre-setup # transitive, for accessing settings | |
runs-on: ubuntu-latest | |
env: | |
PY_COLORS: 1 | |
TOXENV: metadata-validation | |
TOX_PARALLEL_NO_SPINNER: 1 | |
steps: | |
- name: Switch to using Python 3.8 by default | |
uses: actions/setup-python@v2 | |
with: | |
python-version: 3.8 | |
- name: >- | |
Calculate Python interpreter version hash value | |
for use in the cache key | |
id: calc_cache_key_py | |
run: | | |
from __future__ import print_function | |
from hashlib import sha512 | |
from sys import version, version_info | |
b_version = version if version_info[0] == 2 else version.encode() | |
hash = sha512(b_version).hexdigest() | |
print('::set-output name=py_hash_key::{hash}'.format(hash=hash)) | |
shell: python | |
- name: Set up pip cache | |
uses: actions/cache@v2 | |
with: | |
path: >- | |
${{ | |
runner.os == 'Linux' | |
&& '~/.cache/pip' | |
|| '~/Library/Caches/pip' | |
}} | |
key: >- | |
${{ runner.os }}-pip-${{ | |
steps.calc_cache_key_py.outputs.py_hash_key }}-${{ | |
needs.pre-setup.outputs.cache_key_files }} | |
restore-keys: | | |
${{ runner.os }}-pip-${{ steps.calc_cache_key_py.outputs.py_hash_key }}- | |
${{ runner.os }}-pip- | |
${{ runner.os }}- | |
- name: Install tox | |
run: >- | |
python -m | |
pip install | |
--user | |
tox | |
- name: Check out src from Git | |
uses: actions/checkout@v2 | |
- name: Pre-populate tox env | |
run: python -m tox -p auto --parallel-live -vvvv --notest | |
- name: Download all the dists | |
uses: actions/download-artifact@v2 | |
with: | |
name: python-package-distributions | |
path: dist/ | |
- name: Verify metadata | |
run: python -m tox -p auto --parallel-live -vvvv | |
deploy: | |
name: Publish ππ¦ to (Test)PyPI | |
needs: | |
- dist-meta | |
- pre-setup # transitive, for accessing settings | |
- test-matrix | |
if: >- | |
fromJSON(needs.pre-setup.outputs.is_untagged_devel) || | |
fromJSON(needs.pre-setup.outputs.is_tagged) | |
runs-on: ubuntu-latest | |
steps: | |
- name: Download all the dists | |
uses: actions/download-artifact@v2 | |
with: | |
name: python-package-distributions | |
path: dist/ | |
- name: Publish ππ¦ to TestPyPI | |
if: >- | |
fromJSON(needs.pre-setup.outputs.is_untagged_devel) || | |
fromJSON(needs.pre-setup.outputs.is_tagged) | |
uses: pypa/gh-action-pypi-publish@master | |
with: | |
password: ${{ secrets.testpypi_password }} | |
repository_url: https://test.pypi.org/legacy/ | |
- name: Publish ππ¦ to PyPI | |
if: fromJSON(needs.pre-setup.outputs.is_tagged) | |
uses: pypa/gh-action-pypi-publish@master | |
with: | |
password: ${{ secrets.pypi_password }} | |
dumb-pypi: | |
name: Publish nightlies to Dumb PyPI # https://ansible.github.io/pylibssh/ | |
needs: | |
- dist-meta | |
- pre-setup # transitive, for accessing settings | |
- test-matrix | |
if: >- | |
fromJSON(needs.pre-setup.outputs.is_untagged_devel) || | |
fromJSON(needs.pre-setup.outputs.is_tagged) | |
runs-on: ubuntu-latest | |
steps: | |
- name: Download the recent published versions from TestPyPI | |
run: >- | |
python -m | |
pip download | |
--index-url https://test.pypi.org/simple/ | |
--dest dist/ | |
--no-deps | |
--pre | |
ansible-pylibssh | |
- name: Download all the dists | |
uses: actions/download-artifact@v2 | |
with: | |
name: python-package-distributions | |
path: dist/ | |
- name: Switch to Python 3.8 | |
uses: actions/setup-python@v2 | |
with: | |
python-version: 3.8 | |
- name: >- | |
Calculate Python interpreter version hash value | |
for use in the cache key | |
id: calc_cache_key_py | |
run: | | |
from __future__ import print_function | |
from hashlib import sha512 | |
from sys import version, version_info | |
b_version = version if version_info[0] == 2 else version.encode() | |
hash = sha512(b_version).hexdigest() | |
print('::set-output name=py_hash_key::{hash}'.format(hash=hash)) | |
shell: python | |
- name: Set up pip cache | |
uses: actions/cache@v2 | |
with: | |
path: >- | |
${{ | |
runner.os == 'Linux' | |
&& '~/.cache/pip' | |
|| '~/Library/Caches/pip' | |
}} | |
key: >- | |
${{ runner.os }}-pip-${{ | |
steps.calc_cache_key_py.outputs.py_hash_key }}-${{ | |
needs.pre-setup.outputs.cache_key_files }} | |
restore-keys: | | |
${{ runner.os }}-pip-${{ steps.calc_cache_key_py.outputs.py_hash_key }}- | |
${{ runner.os }}-pip- | |
${{ runner.os }}- | |
- name: Install dumb-pypi dist from PyPI | |
run: python -m pip install dumb-pypi --user | |
- name: Generate a dumb PyPI website | |
run: | | |
python -m dumb_pypi.main \ | |
--package-list <(ls dist/) \ | |
--packages-url https://raw.githubusercontent.com/${{ github.repository }}/gh-pages/dist \ | |
--output-dir gh-pages-dumb-pypi | |
shell: bash | |
- name: >- | |
Copy dists from this build and TestPyPI | |
to the generated dumb PyPI website dir | |
run: cp -av dist gh-pages-dumb-pypi/ | |
- name: Publish the dumb PyPI website to GH Pages | |
uses: peaceiris/actions-gh-pages@v3 | |
with: | |
force_orphan: true | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
publish_dir: gh-pages-dumb-pypi | |
# TODO: Test install from sdist | |
# | |
# TODO: Figure out if we can use Py_LIMITED_API / PEP 384: | |
# TODO: * https://docs.python.org/3/c-api/stable.html | |
# TODO: https://github.com/cython/cython/issues/2542 |