From fdda7760d44bfefe6de83c87a8c1caa1229a99b4 Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 13 Jun 2024 17:46:26 -0700 Subject: [PATCH 1/2] Install Poetry in dependent tasks The project's Python package dependencies are managed by the Poetry tool. In addition to the packages used by the action script, project development tools from Python packages are also managed by Poetry. For this reason, Poetry is a dependency of several of the tasks in the taskfile. Previously, there was an undocumented requirement that the contributor have Poetry installed and in their system path. The reason for that approach was that, at the time, the practice was to make a global system installation of Poetry, which might cause problems for some contributors. Since that time, the project has migrated to using pipx to install Poetry. This tool installs Poetry in an virtual environment. Of course, even though this means manual installation of Poetry is no longer the responsibility of the contributor, installation of pipx is. However, the officially recommended mechanism for installing Poetry is now pipx so the contributor would have likely ended up manually installing pipx anyway as a prerequisite for the Poetry installation procedure. --- .github/workflows/check-python-task.yml | 12 ----------- .github/workflows/check-yaml-task.yml | 6 ------ .github/workflows/spell-check-task.yml | 6 ------ .github/workflows/test-python-poetry-task.yml | 6 ------ Taskfile.yml | 20 +++++++++++++++++++ 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/.github/workflows/check-python-task.yml b/.github/workflows/check-python-task.yml index 27e7ed2..3fb4b4b 100644 --- a/.github/workflows/check-python-task.yml +++ b/.github/workflows/check-python-task.yml @@ -71,12 +71,6 @@ jobs: with: python-version-file: pyproject.toml - - name: Install Poetry - run: | - pipx install \ - --python "$(which python)" \ - poetry - - name: Install Task uses: arduino/setup-task@v2 with: @@ -105,12 +99,6 @@ jobs: with: python-version-file: pyproject.toml - - name: Install Poetry - run: | - pipx install \ - --python "$(which python)" \ - poetry - - name: Install Task uses: arduino/setup-task@v2 with: diff --git a/.github/workflows/check-yaml-task.yml b/.github/workflows/check-yaml-task.yml index 7c7ecd1..c72a19e 100644 --- a/.github/workflows/check-yaml-task.yml +++ b/.github/workflows/check-yaml-task.yml @@ -99,12 +99,6 @@ jobs: with: python-version-file: pyproject.toml - - name: Install Poetry - run: | - pipx install \ - --python "$(which python)" \ - poetry - - name: Install Task uses: arduino/setup-task@v2 with: diff --git a/.github/workflows/spell-check-task.yml b/.github/workflows/spell-check-task.yml index e5c24ce..f52596c 100644 --- a/.github/workflows/spell-check-task.yml +++ b/.github/workflows/spell-check-task.yml @@ -53,12 +53,6 @@ jobs: with: python-version-file: pyproject.toml - - name: Install Poetry - run: | - pipx install \ - --python "$(which python)" \ - poetry - - name: Install Task uses: arduino/setup-task@v2 with: diff --git a/.github/workflows/test-python-poetry-task.yml b/.github/workflows/test-python-poetry-task.yml index 028e495..bca5a59 100644 --- a/.github/workflows/test-python-poetry-task.yml +++ b/.github/workflows/test-python-poetry-task.yml @@ -75,12 +75,6 @@ jobs: with: python-version-file: pyproject.toml - - name: Install Poetry - run: | - pipx install \ - --python "$(which python)" \ - poetry - - name: Install Task uses: arduino/setup-task@v2 with: diff --git a/Taskfile.yml b/Taskfile.yml index 733078d..dc8ed83 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -381,10 +381,30 @@ tasks: -r "{{.STYLELINTRC_SCHEMA_PATH}}" \ -d "{{.PROJECT_FOLDER}}/{{.INSTANCE_PATH}}" + poetry:install: + desc: Install Poetry + run: once + vars: + PYTHON_PATH: + sh: task utility:normalize-path RAW_PATH="$(which python)" + cmds: + - | + if ! which pipx &>/dev/null; then + echo "pipx not found or not in PATH." + echo "Please install: https://pipx.pypa.io/stable/installation/#installing-pipx" + exit 1 + fi + - | + pipx install \ + --python "{{.PYTHON_PATH}}" \ + poetry + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml poetry:install-deps: desc: Install dependencies managed by Poetry run: when_changed + deps: + - task: poetry:install cmds: - | poetry install \ From e5f98c35be0888acfe289ef12f8f31cd7b2a4e7e Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 13 Jun 2024 17:47:08 -0700 Subject: [PATCH 2/2] Use Dependabot to manage Poetry version The project's Python package dependencies are managed by the Poetry tool. Previously, the version of Poetry was managed in two inconsistent and sub-ideal ways: * The version used during execution of the action was hardcoded in the action metadata file. * The version used locally by contributors and by the GitHub Actions workflows was not managed at all. The first is problematic because there is no mechanism to facilitate updates, which means it will never be updated. The second is problematic because some versions might be incompatible, or produce different results than the version used by the action. The better solution is to take the same approach for managing the Poetry dependency as done for the project's other dependencies: * Install a specific version of Poetry according to a single source of versioning data. * Use the Dependabot service to get automated update pull requests. The logical place to define the Poetry package dependency version is in pyproject.toml, as is done for all direct Python package dependencies. Dependabot recognizes two forms of dependency data in the pyproject.toml file: * Poetry * PEP 621 Since Poetry can't be used to manage itself, the obvious approach would be to define the Poetry dependency in a PEP 621 field in the file. However, this is not possible because if Dependabot finds Poetry data in pyproject.toml, it ignores the PEP 621 fields. So it is necessary to define the Poetry dependency in the Poetry fields of the file. A special dependencies group is created for this purpose. That group is configured as "optional" so that it won't be installed redundantly by `poetry install` commands. Unfortunately pipx doesn't support using pyproject.toml as a dependency configuration file so it is necessary to generate the dependency argument in the pipx command by parsing the project.toml file. --- Taskfile.yml | 14 +++++++++++++- action.yml | 8 +++++++- pyproject.toml | 8 ++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index dc8ed83..feab92c 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -394,10 +394,22 @@ tasks: echo "Please install: https://pipx.pypa.io/stable/installation/#installing-pipx" exit 1 fi + - | + if ! which yq &>/dev/null; then + echo "yq not found or not in PATH." + echo "Please install: https://github.com/mikefarah/yq/#install" + exit 1 + fi - | pipx install \ --python "{{.PYTHON_PATH}}" \ - poetry + "poetry==$( \ + yq \ + --input-format toml \ + --output-format yaml \ + '.tool.poetry.group.pipx.dependencies.poetry' \ + < pyproject.toml + )" # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml poetry:install-deps: diff --git a/action.yml b/action.yml index 26fba2e..17c1e8a 100644 --- a/action.yml +++ b/action.yml @@ -87,7 +87,13 @@ runs: # Install Poetry. pipx install \ --python "$(which python)" \ - poetry==1.4.0 + "poetry==$( \ + yq \ + --input-format toml \ + --output-format yaml \ + '.tool.poetry.group.pipx.dependencies.poetry' \ + < pyproject.toml + )" # Install Python dependencies. poetry install \ diff --git a/pyproject.toml b/pyproject.toml index 50c5c29..5ea9ab3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,14 @@ optional = true [tool.poetry.group.external.dependencies] pyserial = "3.5" +# The dependencies in this group are installed using pipx; NOT Poetry. The use of a `poetry` section is a hack required +# in order to be able to manage updates of these dependencies via Dependabot, as used for all other dependencies. +[tool.poetry.group.pipx] +optional = true + +[tool.poetry.group.pipx.dependencies] +poetry = "1.4.0" + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"