From 354f85bec1ffe5eb5d6809edc8da3ec55e094407 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Tue, 8 Feb 2022 10:45:15 +0000 Subject: [PATCH] GitHub action to setup poetry (#1) * GitHub action to setup poetry actions/setup-python does the hard work for us, but we make use of actions/cache to avoid having to re-install poetry and the project unless the poetry version we're using has changed, or the hash of the lockfile has changed. After using this action, subsequent job steps can use `poetry run foo [...]` to run `foo [...]` in the virtual environment. Given that I've cited snok/install-poetry I've used theirs but stuck in m.org as a secondary author --- LICENSE | 22 +++++++++++++++ README.md | 13 +++++++++ action.yml | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 action.yml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dcdbab --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2020 Sondre Lillebø Gundersen +Copyright (c) 2022 The Matrix.org Foundation C.I.C. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..109e24f --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +This is an action which sets up Python and poetry for a project that uses [Poetry](https://python-poetry.org/) to manage its dependencies. +It requires a `poetry.lock` file to be present in the root of the repository. The action: + +- calls [`actions/setup-python`](https://github.com/actions/setup-python), +- `pip`-installs `poetry`, +- `poetry install`-s the current project, +- uses [`actions/cache`](https://github.com/actions/cache) to cache the poetry installation and the virtual environment it manages. + +From this point, the caller of the action can run commands within the poetry-managed environment with `poetry run`. + +The Python and Poetry versions to are configurable: see `action.yaml` for details. + +This particular action is loosely based on [`snok/install-poetry`](https://github.com/snok/install-poetry): in particular, the advice from its README on handling caching. diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..e84785b --- /dev/null +++ b/action.yml @@ -0,0 +1,78 @@ +name: Setup Python and Poetry +description: Setup Python and Poetry. Cribbed from snok/install-poetry. +inputs: + python-version: + description: Python version to pass to actions/setup-python@v2. + required: false + default: "3.x" + poetry-version: + description: Poetry version to install via pip. + required: false + default: "1.1.12" +runs: + using: composite + steps: + - name: Setup Python + id: setup-python + uses: actions/setup-python@v2 + with: + python-version: ${{ inputs.python-version }} + + - name: Check for poetry lock + run: "test -f poetry.lock || (echo No lock file! && false)" + shell: bash + + # Install poetry. It takes ~10seconds for a clean pip install, most of which is + # the installation rather than the downloading. So instead, we cache the user-base + # directory (~/.local). For this to be safe: + # - we must not write to `.local` as part of the CI + # - we must not install anything with the system `pip` other than poetry. + # Based on the writeup at: + # https://github.com/snok/install-poetry/blob/main/README.md#caching-the-poetry-installation + - name: Locate user site + id: site-user-base + run: echo "::set-output name=dir::$(python -m site --user-base)" + shell: bash + + - name: Restore/cache poetry installation + id: poetry-install-cache + uses: actions/cache@v2 + with: + path: ${{ steps.site-user-base.outputs.dir }} + key: poetry-install-cache-${{ steps.setup-python.outputs.python-version }}-${{ inputs.poetry-version }} + + - name: Install poetry from scratch + if: "${{ steps.poetry-install-cache.outputs.cache-hit != 'true' }}" + run: python -m pip install --user poetry==${{ inputs.poetry-version }} + shell: bash + + # Poetry manages a virtualenv for us. We're going to cache that too. + # Again, we're following snok/install-poetry's README. + - name: Locate poetry venv + id: poetry-venvs + run: echo "::set-output name=dir::$(python -m poetry config virtualenvs.path)" + shell: bash + + - name: Restore/cache poetry venv + id: poetry-venv-cache + uses: actions/cache@v2 + with: + path: ${{ steps.poetry-venvs.outputs.dir }} + key: poetry-venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} + + - name: Install dependencies + if: "${{ steps.poetry-venv-cache.outputs.cache-hit != 'true' }}" + run: poetry install --no-interaction --no-root + shell: bash + + # (Not sure if this is needed if there's a cache hit?) + - name: Install project + run: poetry install --no-interaction + shell: bash + + # For debugging---let's just check what we're working with. + - name: Dump virtual environment + run: | + poetry env info + poetry show + shell: bash