# Generated from: # https://github.com/zopefoundation/meta/tree/master/config/c-code ### # Initially copied from # https://github.com/actions/starter-workflows/blob/main/ci/python-package.yml # And later based on the version jamadden updated at # gevent/gevent, and then at zodb/relstorage and zodb/perfmetrics # # Original comment follows. ### ### # This workflow will install Python dependencies, run tests and lint with a variety of Python versions # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions ### ### # Important notes on GitHub actions: # # - We only get 2,000 free minutes a month (private repos) # - We only get 500MB of artifact storage # - Cache storage is limited to 7 days and 5GB. # - macOS minutes are 10x as expensive as Linux minutes # - windows minutes are twice as expensive. # # So keep those workflows light. Note: Currently, they seem to be free # and unlimited for open source projects. But for how long... # # In December 2020, github only supports x86/64. If we wanted to test # on other architectures, we can use docker emulation, but there's no # native support. It works, but is slow. # # Another major downside: You can't just re-run the job for one part # of the matrix. So if there's a transient test failure that hit, say, 3.8, # to get a clean run every version of Python runs again. That's bad. # https://github.community/t/ability-to-rerun-just-a-single-job-in-a-workflow/17234/65 name: tests # Triggers the workflow on push or pull request events and periodically on: push: pull_request: schedule: - cron: '0 12 * * 0' # run once a week on Sunday # Allow to run this workflow manually from the Actions tab workflow_dispatch: env: # Weirdly, this has to be a top-level key, not ``defaults.env`` PYTHONHASHSEED: 8675309 PYTHONUNBUFFERED: 1 PYTHONDONTWRITEBYTECODE: 1 PYTHONDEVMODE: 1 PYTHONFAULTHANDLER: 1 ZOPE_INTERFACE_STRICT_IRO: 1 PIP_UPGRADE_STRATEGY: eager # Don't get warnings about Python 2 support being deprecated. We # know. The env var works for pip 20. PIP_NO_PYTHON_VERSION_WARNING: 1 PIP_NO_WARN_SCRIPT_LOCATION: 1 CFLAGS: -O3 -pipe CXXFLAGS: -O3 -pipe # Uploading built wheels for releases. # TWINE_PASSWORD is encrypted and stored directly in the # github repo settings. TWINE_USERNAME: __token__ ### # caching # This is where we'd set up ccache, but this compiles so fast its not worth it. ### jobs: # Because sharing code/steps is so hard, and because it can be # extremely valuable to be able to get binary wheels without # uploading to PyPI and even if there is some failure, (e.g., for # other people to test/debug), the strategy is to divide the process # into several different jobs. The first builds and saves the binary # wheels. It has dependent jobs that download and install the wheel # to run tests, build docs, and perform linting. Building the # manylinux wheels is an independent set of jobs. # # This division is time-saving for projects that take awhile to # build, but somewhat less of a clear-cut win given how quick this # is to compile (at least at this writing). build-package: # Sigh. Note that the matrix must be kept in sync # with `test`, and `docs` must use a subset. runs-on: ${{ matrix.os }} if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name strategy: fail-fast: false matrix: python-version: - "2.7" - "3.5" - "pypy-2.7" - "pypy-3.7" - "3.6" - "3.7" - "3.8" - "3.9" - "3.10" - "3.11" os: [ubuntu-20.04, macos-latest] exclude: - os: macos-latest python-version: "pypy-2.7" - os: macos-latest python-version: "pypy-3.7" - os: macos-latest python-version: "3.5" steps: - name: checkout uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} ### # Caching. # This actually *restores* a cache and schedules a cleanup action # to save the cache. So it must come before the thing we want to use # the cache. ### - name: Get pip cache dir id: pip-cache run: | echo "dir=$(pip cache dir)" >>$GITHUB_OUTPUT - name: pip cache uses: actions/cache@v2 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ matrix.python-version }} restore-keys: | ${{ runner.os }}-pip- - name: Install Build Dependencies (PyPy2) if: > startsWith(matrix.python-version, 'pypy-2.7') run: | pip install -U pip pip install -U setuptools wheel twine "cffi != 1.15.1" - name: Install Build Dependencies (other Python versions) if: > !startsWith(matrix.python-version, 'pypy-2.7') run: | pip install -U pip pip install -U setuptools wheel twine cffi - name: Build zope.i18nmessageid (Python 3.10 on MacOS) if: > startsWith(runner.os, 'Mac') && startsWith(matrix.python-version, '3.10') env: _PYTHON_HOST_PLATFORM: macosx-11-x86_64 run: | # Next, build the wheel *in place*. This helps ccache, and also lets us cache the configure # output (pip install uses a random temporary directory, making this difficult). python setup.py build_ext -i python setup.py bdist_wheel # Also install it, so that we get dependencies in the (pip) cache. pip install -U 'faulthandler; python_version == "2.7" and platform_python_implementation == "CPython"' pip install .[test] - name: Build zope.i18nmessageid (all other versions) if: > !startsWith(runner.os, 'Mac') || !startsWith(matrix.python-version, '3.10') run: | # Next, build the wheel *in place*. This helps ccache, and also lets us cache the configure # output (pip install uses a random temporary directory, making this difficult). python setup.py build_ext -i python setup.py bdist_wheel # Also install it, so that we get dependencies in the (pip) cache. pip install -U 'faulthandler; python_version == "2.7" and platform_python_implementation == "CPython"' pip install .[test] - name: Check zope.i18nmessageid build run: | ls -l dist twine check dist/* - name: Upload zope.i18nmessageid wheel uses: actions/upload-artifact@v2 with: name: zope.i18nmessageid-${{ runner.os }}-${{ matrix.python-version }}.whl path: dist/*whl - name: Publish package to PyPI (mac) # We cannot 'uses: pypa/gh-action-pypi-publish@v1.4.1' because # that's apparently a container action, and those don't run on # the Mac. if: > github.event_name == 'push' && startsWith(github.ref, 'refs/tags') && startsWith(runner.os, 'Mac') && !startsWith(matrix.python-version, 'pypy') env: TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} run: | twine upload --skip-existing dist/* test: needs: build-package runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: python-version: - "2.7" - "3.5" - "pypy-2.7" - "pypy-3.7" - "3.6" - "3.7" - "3.8" - "3.9" - "3.10" - "3.11" os: [ubuntu-20.04, macos-latest] exclude: - os: macos-latest python-version: "pypy-2.7" - os: macos-latest python-version: "pypy-3.7" - os: macos-latest python-version: "3.5" steps: - name: checkout uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} ### # Caching. # This actually *restores* a cache and schedules a cleanup action # to save the cache. So it must come before the thing we want to use # the cache. ### - name: Get pip cache dir id: pip-cache run: | echo "dir=$(pip cache dir)" >>$GITHUB_OUTPUT - name: pip cache uses: actions/cache@v2 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ matrix.python-version }} restore-keys: | ${{ runner.os }}-pip- - name: Download zope.i18nmessageid wheel uses: actions/download-artifact@v2 with: name: zope.i18nmessageid-${{ runner.os }}-${{ matrix.python-version }}.whl path: dist/ - name: Install zope.i18nmessageid run: | pip install -U wheel setuptools pip install -U coverage pip install -U 'faulthandler; python_version == "2.7" and platform_python_implementation == "CPython"' # Unzip into src/ so that testrunner can find the .so files # when we ask it to load tests from that directory. This # might also save some build time? unzip -n dist/zope.i18nmessageid-*whl -d src pip install -U -e .[test] - name: Run tests with C extensions if: ${{ !startsWith(matrix.python-version, 'pypy') }} run: | python -m coverage run -p -m zope.testrunner --test-path=src --auto-color --auto-progress - name: Run tests without C extensions run: # coverage makes PyPy run about 3x slower! PURE_PYTHON=1 python -m coverage run -p -m zope.testrunner --test-path=src --auto-color --auto-progress - name: Report Coverage run: | coverage combine coverage report -i - name: Submit to Coveralls # This is a container action, which only runs on Linux. if: ${{ startsWith(runner.os, 'Linux') }} uses: AndreMiras/coveralls-python-action@develop with: parallel: true coveralls_finish: needs: test runs-on: ubuntu-20.04 steps: - name: Coveralls Finished uses: AndreMiras/coveralls-python-action@develop with: parallel-finished: true docs: needs: build-package runs-on: ${{ matrix.os }} strategy: matrix: python-version: ["3.9"] os: [ubuntu-20.04] steps: - name: checkout uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} ### # Caching. # This actually *restores* a cache and schedules a cleanup action # to save the cache. So it must come before the thing we want to use # the cache. ### - name: Get pip cache dir id: pip-cache run: | echo "dir=$(pip cache dir)" >>$GITHUB_OUTPUT - name: pip cache uses: actions/cache@v2 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ matrix.python-version }} restore-keys: | ${{ runner.os }}-pip- - name: Download zope.i18nmessageid wheel uses: actions/download-artifact@v2 with: name: zope.i18nmessageid-${{ runner.os }}-${{ matrix.python-version }}.whl path: dist/ - name: Install zope.i18nmessageid run: | pip install -U wheel pip install -U coverage pip install -U "`ls dist/zope.i18nmessageid-*.whl`[docs]" - name: Build docs env: ZOPE_INTERFACE_STRICT_IRO: 1 run: | sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest lint: needs: build-package runs-on: ${{ matrix.os }} strategy: matrix: python-version: ["3.9"] os: [ubuntu-20.04] steps: - name: checkout uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} ### # Caching. # This actually *restores* a cache and schedules a cleanup action # to save the cache. So it must come before the thing we want to use # the cache. ### - name: Get pip cache dir id: pip-cache run: | echo "dir=$(pip cache dir)" >>$GITHUB_OUTPUT - name: pip cache uses: actions/cache@v2 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ matrix.python-version }} restore-keys: | ${{ runner.os }}-pip- - name: Download zope.i18nmessageid wheel uses: actions/download-artifact@v2 with: name: zope.i18nmessageid-${{ runner.os }}-${{ matrix.python-version }}.whl path: dist/ - name: Install zope.i18nmessageid run: | pip install -U pip pip install -U wheel pip install -U `ls dist/zope.i18nmessageid-*`[test] - name: Lint # We only need to do this on one version, and it should be Python 3, because # pylint has stopped updating for Python 2. # TODO: Pick a linter and configuration and make this step right. run: | pip install -U pylint # python -m pylint --limit-inference-results=1 --rcfile=.pylintrc zope.i18nmessageid -f parseable -r n manylinux: runs-on: ubuntu-20.04 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name # We use a regular Python matrix entry to share as much code as possible. strategy: matrix: python-version: ["3.9"] image: [manylinux2010_x86_64, manylinux2010_i686, manylinux2014_aarch64] steps: - name: checkout uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} ### # Caching. # This actually *restores* a cache and schedules a cleanup action # to save the cache. So it must come before the thing we want to use # the cache. ### - name: Get pip cache dir id: pip-cache run: | echo "dir=$(pip cache dir)" >>$GITHUB_OUTPUT - name: pip cache uses: actions/cache@v2 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip_manylinux-${{ matrix.image }}-${{ matrix.python-version }} restore-keys: | ${{ runner.os }}-pip- - name: Update pip run: pip install -U pip - name: Build zope.i18nmessageid (x86_64) if: matrix.image == 'manylinux2010_x86_64' # An alternate way to do this is to run the container directly with a uses: # and then the script runs inside it. That may work better with caching. # See https://github.com/pyca/bcrypt/blob/f6b5ee2eda76d077c531362ac65e16f045cf1f29/.github/workflows/wheel-builder.yml # The 2010 image is the most recent spec that comes with Python 2.7, # and only up through the tag 2021-02-06-3d322a5 env: DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }} run: | bash .manylinux.sh - name: Build zope.i18nmessageid (i686) if: matrix.image == 'manylinux2010_i686' env: DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }} PRE_CMD: linux32 run: | bash .manylinux.sh - name: Build zope.i18nmessageid (aarch64) if: matrix.image == 'manylinux2014_aarch64' env: DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }} run: | # First we must enable emulation docker run --rm --privileged hypriot/qemu-register bash .manylinux.sh - name: Upload zope.i18nmessageid wheels uses: actions/upload-artifact@v2 with: path: wheelhouse/*whl name: manylinux_${{ matrix.image }}_wheels.zip - name: Restore pip cache permissions run: sudo chown -R $(whoami) ${{ steps.pip-cache.outputs.dir }} - name: Publish package to PyPI uses: pypa/gh-action-pypi-publish@v1.4.1 if: > github.event_name == 'push' && startsWith(github.ref, 'refs/tags') with: user: __token__ password: ${{ secrets.TWINE_PASSWORD }} skip_existing: true packages_dir: wheelhouse/