Skip to content

Commit 039073d

Browse files
committed
add Github actions for lint, test, and release
1 parent 0df2e22 commit 039073d

File tree

10 files changed

+349
-25
lines changed

10 files changed

+349
-25
lines changed

.github/workflows/release.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: release
2+
on:
3+
release:
4+
types: [published]
5+
tags:
6+
- v*
7+
8+
env:
9+
LIBZIM_RELEASE: libzim_linux-x86_64-6.1.1
10+
LIBZIM_LIBRARY_PATH: lib/x86_64-linux-gnu/libzim.so.6.1.1
11+
LIBZIM_INCLUDE_PATH: include/zim
12+
CYTHON_VERSION: 0.29.6
13+
14+
jobs:
15+
release:
16+
runs-on: ${{ matrix.os }}
17+
strategy:
18+
matrix:
19+
os: [ubuntu-latest]
20+
# TODO: expand this to cross-platform builds (see V2 approach below)
21+
# os: [ubuntu-latest, windows-latest, macos-latest]
22+
python-version: [3.6, 3.7, 3.8]
23+
24+
steps:
25+
- uses: actions/checkout@v2
26+
27+
- name: Set up Python ${{ matrix.python-version }}
28+
uses: actions/setup-python@v1
29+
with:
30+
python-version: ${{ matrix.python-version }}
31+
architecture: x64
32+
33+
- name: Cache libzim dylib & headers
34+
uses: actions/cache@master
35+
id: cache-libzim
36+
with:
37+
path: libzim_linux
38+
key: $LIBZIM_RELEASE-libzim-cache
39+
40+
- name: Download libzim dylib & headers from OpenZIM.org releases
41+
if: steps.cache-libzim.outputs.cache-hit != 'true'
42+
run: |
43+
wget -q https://download.openzim.org/release/libzim/$LIBZIM_RELEASE.tar.gz
44+
tar --gunzip --extract --file=$LIBZIM_RELEASE.tar.gz
45+
mv $LIBZIM_RELEASE libzim_linux
46+
47+
- name: Link libzim dylib & headers into workspace lib and include folders
48+
run: |
49+
ln -s $GITHUB_WORKSPACE/libzim_linux/$LIBZIM_LIBRARY_PATH lib/libzim.so
50+
ln -s $GITHUB_WORKSPACE/libzim_linux/$LIBZIM_INCLUDE_PATH include/zim
51+
52+
- name: Build cython, sdist, and bdist_wheels
53+
run: |
54+
pip install --upgrade cython==$CYTHON_VERSION setuptools pip
55+
python3 setup.py build_ext --inplace
56+
python3 setup.py sdist bdist_wheel
57+
python -m cibuildwheel --output-dir wheelhouse
58+
59+
- uses: actions/upload-artifact@v1
60+
with:
61+
name: wheels
62+
path: ./wheelhouse
63+
64+
- name: Push release to PyPI
65+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
66+
uses: pypa/gh-action-pypi-publish@master
67+
with:
68+
user: __token__
69+
password: ${{ secrets.PYPI_API_TOKEN }}
70+
# TODO: remove this line to upload to the real PyPI when ready
71+
repository_url: https://test.pypi.org/legacy/

.github/workflows/test.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: test
2+
on: [push]
3+
4+
env:
5+
LIBZIM_RELEASE: libzim_linux-x86_64-6.1.1
6+
LIBZIM_LIBRARY_PATH: lib/x86_64-linux-gnu/libzim.so.6.1.1
7+
LIBZIM_INCLUDE_PATH: include/zim
8+
CYTHON_VERSION: 0.29.6
9+
MAX_LINE_LENGTH: 110
10+
11+
jobs:
12+
lint:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v2
16+
17+
- name: Set up Python ${{ matrix.python }}
18+
uses: actions/setup-python@v1
19+
with:
20+
python-version: 3.6
21+
architecture: x64
22+
23+
- name: Autoformat with black
24+
run: |
25+
pip install black
26+
black --check --exclude=setup.py .
27+
28+
- name: Lint with flake8
29+
run: |
30+
pip install flake8
31+
# one pass for show-stopper syntax errors or undefined names
32+
flake8 . --count --select=E9,F63,F7,F82 --exclude=setup.py --show-source --statistics
33+
# one pass for small stylistic things
34+
flake8 . --count --exclude=setup.py --max-line-length=$MAX_LINE_LENGTH --statistics
35+
36+
test:
37+
runs-on: ${{ matrix.os }}
38+
strategy:
39+
matrix:
40+
os: [ubuntu-latest]
41+
# TODO: expand this once macos and windows libzim releases become available
42+
# os: [ubuntu-latest, windows-latest, macos-latest]
43+
# alternatively we can compile libzim in docker and use the container as an action
44+
python: [3.6, 3.7, 3.8]
45+
46+
steps:
47+
- uses: actions/checkout@v2
48+
49+
- name: Set up Python ${{ matrix.python }}
50+
uses: actions/setup-python@v1
51+
with:
52+
python-version: ${{ matrix.python }}
53+
architecture: x64
54+
55+
- name: Cache libzim dylib & headers
56+
uses: actions/cache@master
57+
id: cache-libzim
58+
with:
59+
path: libzim_linux
60+
key: ${{ env.LIBZIM_RELEASE }}-libzim-cache
61+
62+
- name: Download libzim dylib & headers from OpenZIM.org releases
63+
if: steps.cache-libzim.outputs.cache-hit != 'true'
64+
run: |
65+
wget -q https://download.openzim.org/release/libzim/$LIBZIM_RELEASE.tar.gz
66+
tar --gunzip --extract --file=$LIBZIM_RELEASE.tar.gz
67+
mv $LIBZIM_RELEASE libzim_linux
68+
69+
- name: Link libzim dylib & headers into workspace lib and include folders
70+
run: |
71+
cp -p $GITHUB_WORKSPACE/libzim_linux/$LIBZIM_LIBRARY_PATH lib/libzim.so
72+
cp -p $GITHUB_WORKSPACE/libzim_linux/$LIBZIM_LIBRARY_PATH lib/
73+
sudo ldconfig $GITHUB_WORKSPACE/lib
74+
ln -s $GITHUB_WORKSPACE/libzim_linux/$LIBZIM_INCLUDE_PATH include/zim
75+
76+
- name: Build cython, sdist, and bdist_wheel
77+
run: |
78+
pip install --upgrade cython==$CYTHON_VERSION setuptools pip wheel
79+
python3 setup.py build_ext
80+
python3 setup.py sdist bdist_wheel
81+
82+
- name: Test built package with pytest
83+
run: |
84+
export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH
85+
sudo ldconfig
86+
pip install pytest
87+
pip install -e .
88+
pytest .

.gitignore

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1+
# General cruft
2+
.DS_Store
3+
.venv
4+
.venv-docker
5+
.mypy_cache
16
__pycache__
2-
build
7+
*.pyc
8+
.tox
9+
10+
# Compiled binaries and package builds
11+
*.so
12+
build/
13+
dist/
14+
*.egg-info/
15+
16+
# Dylibs and headers
17+
lib/*
18+
include/*
19+
libzim_linux-*/
20+
21+
# Autogenerated files
322
libzim_wrapper.*.so
423
libzim/libzim_wrapper.cpp
524
libzim/libzim_wrapper.h
625
libzim/libzim_wrapper_api.h
7-
*.egg-info

MANIFEST.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
include LICENSE
2+
include README.md
3+
include tests/*.py
4+
include pyproject.toml
5+
6+
recursive-include lib *
7+
recursive-include include *
8+
recursive-include libzim *

Pipfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[[source]]
2+
name = "pypi"
3+
url = "https://pypi.org/simple"
4+
verify_ssl = true
5+
6+
[dev-packages]
7+
pytest = "*"
8+
cython = "==0.29.6"
9+
e1839a8 = {editable = true, path = "."}
10+
11+
[packages]
File renamed without changes.

include/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Put your zim/*.h folder in here.

lib/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Put your libzim.so file in here.

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[build-system]
2+
requires = [ "setuptools >= 35.0.2", "wheel >= 0.29.0", "twine", "cython == 0.29.6" ]
3+
build-backend = "setuptools.build_meta"
4+
5+
[tool.black]
6+
line-length = 110
7+
target-version = ['py36', 'py37', 'py38']

setup.py

Lines changed: 142 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,149 @@
1-
import os
2-
from distutils.core import setup
3-
from distutils.extension import Extension
1+
#!/usr/bin/env python3
2+
"""
3+
python-libzim (the openzim/libzim bindings for Python)
4+
5+
The project is compiled in two steps:
6+
7+
1. Cython: compile the cython format files (.pyx, .pyd) to C++ (.cpp and .h)
8+
2. Cythonize: compile the generated C++ to a python-importable binary extension .so
9+
10+
The Cython and Cythonize compilation is done automatically during packaging with setup.py:
11+
12+
$ python3 setup.py build_ext
13+
$ python3 setup.py sdist bdist_wheel
14+
15+
16+
To compile or run this project, you must first get the libzim headers & binary:
17+
18+
- You can get the headers here and build and install the binary from source:
19+
https://github.com/openzim/libzim
20+
21+
- Or you can download a full prebuilt release (if one exists for your platform):
22+
https://download.openzim.org/release/libzim/
23+
24+
Either place the `libzim.so` and `zim/*.h` files in `./lib/` and `./include/`,
25+
or set these environment variables to use custom libzim header and dylib paths:
26+
27+
$ export CFLAGS="-I/tmp/libzim_linux-x86_64-6.1.1/include"
28+
$ export LDFLAGS="-L/tmp/libzim_linux-x86_64-6.1.1/lib/x86_64-linux-gnu"
29+
$ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/tmp/libzim_linux-x86_64-6.1.1/lib/x86_64-linux-gnu"
30+
"""
31+
from pathlib import Path
32+
from ctypes.util import find_library
33+
34+
from setuptools import setup, Extension
435
from Cython.Build import cythonize
536

6-
# Utility function to read the README file.
7-
# Used for the long_description. It's nice, because now 1) we have a top levegit checkout masterl
8-
# README file and 2) it's easier to type in the README file than to put a raw
9-
# string in below ...
10-
def read(fname):
11-
return open(os.path.join(os.path.dirname(__file__), fname)).read()
37+
38+
PACKAGE_NAME = "libzim_wrapper"
39+
VERSION = "0.0.1" # pegged to be the same version as libzim since they are always released together
40+
LICENSE = "GPLv3+"
41+
DESCRIPTION = "A python-facing API for creating and interacting with ZIM files"
42+
AUTHOR = "Monadical Inc."
43+
AUTHOR_EMAIL = "[email protected]"
44+
GITHUB_URL = "https://github.com/openzim/python-libzim"
45+
46+
BASE_DIR = Path(__file__).parent
47+
BINDINGS_CYTHON_DIR = 'libzim' # the cython binding source dir (containing .pyx, .pyd, etc.)
48+
LIBZIM_INCLUDE_DIR = 'include' # the libzim C++ header src dir (containing zim/*.h)
49+
LIBZIM_LIBRARY_DIR = 'lib' # the libzim .so binary lib dir (containing libzim.so)
50+
51+
52+
# Check for the CPP Libzim library headers in expected directory
53+
if not (BASE_DIR / LIBZIM_INCLUDE_DIR / 'zim/zim.h').exists():
54+
print(
55+
f"[!] Warning: Couldn't find zim/*.h in ./{LIBZIM_INCLUDE_DIR}!\n"
56+
f" Hint: You can install them from source from https://github.com/openzim/libzim\n"
57+
f" or download a prebuilt release's headers into ./include/zim/*.h\n"
58+
f" (or set CFLAGS='-I/tmp/libzim_linux-x86_64-{VERSION}/include')"
59+
)
60+
61+
# Check for the CPP Libzim shared library in expected directory or system paths
62+
if not ((BASE_DIR / LIBZIM_LIBRARY_DIR / 'libzim.so').exists() or find_library('zim')):
63+
print(
64+
f"[!] Warning: Couldn't find libzim.so in ./{LIBZIM_LIBRARY_DIR} or system library paths!"
65+
f" Hint: You can install it from source from https://github.com/openzim/libzim\n"
66+
f" or download a prebuilt zimlib.so release into ./lib.\n"
67+
f" (or set LDFLAGS='-L/tmp/libzim_linux-x86_64-{VERSION}/lib/x86_64-linux-gnu')"
68+
)
1269

1370
setup(
14-
name = "python-libzim",
15-
version = "0.0.1",
16-
author = "Monadical SAS",
17-
author_email = "[email protected]",
18-
description = ("A python-facing API for creating and interacting with ZIM files"),
19-
license = "GPLv3+",
20-
long_description=read('README.md'),
21-
ext_modules = cythonize([
22-
Extension("libzim_wrapper", ["libzim/*.pyx", "libzim/lib.cxx"],
23-
include_dirs=["libzim"],
24-
libraries=["zim"],
25-
extra_compile_args=["-std=c++11"],
26-
language="c++"),
71+
name=PACKAGE_NAME,
72+
version=VERSION,
73+
url=GITHUB_URL,
74+
project_urls={
75+
'Source': GITHUB_URL,
76+
'Bug Tracker': f'{GITHUB_URL}/issues',
77+
'Changelog': f'{GITHUB_URL}/releases',
78+
'Documentation': f'{GITHUB_URL}/blob/master/README.md',
79+
'Donate': 'https://www.kiwix.org/en/support-us/',
80+
},
81+
author=AUTHOR,
82+
author_email=AUTHOR_EMAIL,
83+
license=LICENSE,
84+
description=DESCRIPTION,
85+
long_description=(BASE_DIR / 'README.md').read_text(),
86+
long_description_content_type="text/markdown",
87+
python_requires='>=3.6',
88+
include_package_data=True,
89+
ext_modules=cythonize(
90+
[
91+
Extension(
92+
"libzim_wrapper",
93+
sources=[
94+
f"{BINDINGS_CYTHON_DIR}/*.pyx",
95+
f"{BINDINGS_CYTHON_DIR}/lib.cxx",
96+
],
97+
include_dirs=[
98+
BINDINGS_CYTHON_DIR,
99+
LIBZIM_INCLUDE_DIR,
100+
],
101+
libraries=[
102+
'zim',
103+
],
104+
library_dirs=[
105+
LIBZIM_LIBRARY_DIR,
106+
],
107+
extra_compile_args=[
108+
"-std=c++11",
109+
"-Wall",
110+
"-Wextra",
111+
],
112+
language="c++",
113+
)
27114
],
28-
compiler_directives={'language_level' : "3"}
115+
compiler_directives={"language_level" : "3"},
29116
),
117+
zip_safe=False,
118+
classifiers=[
119+
"Development Status :: 3 - Alpha",
120+
121+
"Topic :: Utilities",
122+
"Topic :: Software Development :: Libraries",
123+
"Topic :: Software Development :: Libraries :: Python Modules",
124+
"Topic :: System :: Archiving",
125+
"Topic :: System :: Archiving :: Compression",
126+
"Topic :: System :: Archiving :: Mirroring",
127+
"Topic :: System :: Archiving :: Backup",
128+
"Topic :: Internet :: WWW/HTTP",
129+
"Topic :: Internet :: WWW/HTTP :: Indexing/Search",
130+
"Topic :: Sociology :: History",
131+
132+
"Intended Audience :: Developers",
133+
"Intended Audience :: Education",
134+
"Intended Audience :: End Users/Desktop",
135+
"Intended Audience :: Information Technology",
136+
"Intended Audience :: System Administrators",
137+
138+
"Programming Language :: Cython",
139+
"Programming Language :: Python :: 3",
140+
"Programming Language :: Python :: 3.6",
141+
"Programming Language :: Python :: 3.7",
142+
"Programming Language :: Python :: 3.8",
143+
# "Typing :: Typed",
144+
145+
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
146+
"Natural Language :: English",
147+
"Operating System :: OS Independent",
148+
],
30149
)

0 commit comments

Comments
 (0)