diff --git a/.github/scripts/setup-env.sh b/.github/scripts/setup-env.sh new file mode 100755 index 0000000..1b43d94 --- /dev/null +++ b/.github/scripts/setup-env.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# +# Environment setup script for the local project. Intended to be used with automation +# to create a repeatable local environment for tests to be run in. The python env +# this script creates can be accessed at the location defined by the CI_VENV variable +# below. + +set -e; + +# ##### Prereqs ##### +# +# Set global vars for usage in the script, create the cache directory so we can rely +# on that existing, then dump some diagnostic info for later reference. +# +CI_VENV=$HOME/ci; +CI_CACHE=$HOME/.cache; +CI_CACHE_GET_POETRY="$CI_CACHE/get-poetry.py"; +CI_POETRY=$HOME/.poetry/bin/poetry; +CI_VENV_PIP="$CI_VENV/bin/pip"; +CI_VENV_PIP_VERSION=19.3.1; +CI_VENV_TOX="$CI_VENV/bin/tox"; + +mkdir --parents "$CI_CACHE"; + +command -v python; +python --version; + +# ##### Install Poetry ##### +# +# Download the poetry install script to the cache directory and then install poetry. +# After dump the poetry version for later reference. +# +curl https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py \ + --output "$CI_CACHE_GET_POETRY" \ + --silent \ + --show-error \ + --location; +python "$CI_CACHE_GET_POETRY" --yes 1>/dev/null; + +python "$CI_POETRY" --version --no-ansi; + +# ##### Setup Runtime Venv ##### +# +# Create a virtual environment for poetry to use, upgrade pip in that venv to a pinned +# version, then install the current project to the venv. +# +# Note 1: Poetry, Tox, and this project plugin all use pip under the hood for package +# installation. This means that even though we are creating up to eight venvs +# during a given CI run they all share the same download cache. +# Note 2: The "VIRTUAL_ENV=$CI_VENV" prefix on the poetry commands below sets the venv +# that poetry will use for operations. There is no CLI flag for poetry that +# directs it to use a given environment, but if it finds itself in an existing +# environment it will use it and skip environment creation. +# +python -m venv "$CI_VENV"; + +$CI_VENV_PIP install "pip==$CI_VENV_PIP_VERSION" \ + --upgrade \ + --quiet; + +VIRTUAL_ENV=$CI_VENV "$CI_POETRY" install \ + --extras poetry \ + --quiet \ + --no-ansi \ + &>/dev/null; + +# ##### Print Debug Info ##### +# +# Print the pip and tox versions (which will include registered plugins) +# +$CI_VENV_PIP --version; +echo "tox $($CI_VENV_TOX --version)"; diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6fa8c21..30c31b8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,24 +20,51 @@ jobs: - version: 3.9 toxenv: py39 steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python.version }} + - name: Checkout + uses: actions/checkout@v2 + - name: Setup:python${{ matrix.python.version }} uses: actions/setup-python@v1 with: python-version: ${{ matrix.python.version }} - - name: Install project - run: pip install . - - name: Run tests via ${{ matrix.python.toxenv }} - run: tox -e ${{ matrix.python.toxenv }} + - name: Setup:cache + uses: actions/cache@v2 + with: + path: | + ~/.cache/pip + ~/.cache/pypoetry/cache + ~/.poetry + # Including the hashed poetry.lock in the cache slug ensures that the cache + # will be invalidated, and thus all packages will be redownloaded, if the + # lockfile is updated + key: ${{ runner.os }}-${{ matrix.python.toxenv }}-${{ hashFiles('**/poetry.lock') }} + - name: Setup:env + run: .github/scripts/setup-env.sh + - name: Run:${{ matrix.python.toxenv }} + run: $HOME/ci/bin/tox -e ${{ matrix.python.toxenv }} Check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up Python 3.8 + - name: Checkout + uses: actions/checkout@v2 + - name: Setup:python3.8 uses: actions/setup-python@v1 with: python-version: 3.8 - - name: Install project - run: pip install . - - name: Run meta checks - run: tox -e static -e static-tests -e security + - name: Setup:cache + uses: actions/cache@v2 + with: + path: | + ~/.cache/pip + ~/.cache/pypoetry/cache + ~/.poetry + # Hardcoded 'py38' slug here lets this cache piggyback on the 'py38' cache + # that is generated for the tests above + key: ${{ runner.os }}-py38-${{ hashFiles('**/poetry.lock') }} + - name: Setup:env + run: .github/scripts/setup-env.sh + - name: Run:static + run: $HOME/ci/bin/tox -e static + - name: Run:static-tests + run: $HOME/ci/bin/tox -e static-tests + - name: Run:security + run: $HOME/ci/bin/tox -e security