Poetry dependencies can fail to build in niche case #8547
Labels
manager:poetry
Poetry package manager
priority-2-high
Bugs impacting wide number of users or very important features
status:requirements
Full requirements are not yet known, so implementation should not be started
type:bug
Bug fix of existing functionality
Summary
Poetry dependencies which include distutils-based sub-dependencies which in turn have no dependencies of their own can cause Artifact Update Problems for the parent projects. This is due to the
PIP_USER
flag, which is erroneously set when runningpoetry update
in some of the renovate base images. Though debugging was carried out via self-hosted Renovate, this should affect both hosted and self-hosted and in any case where therenovate
app runs in arenovate
docker image, in addition to cases where users provide their own images but havePIP_USER
set for other reasons.There are several possible solutions which might solve this, but as they could have far-reaching impacts I would defer to @rarkins at the team to point me in the right direction. Please find the potential solutions at the bottom of this report, as they really don't make much sense without the full context.
Full Explanation
We've been getting a bunch of "⚠️ Artifact update problem" in most of our Renovate bot runs. Re-running with DEBUG logs shows a whole bunch of errors along the lines of (note: some irrelevant details relating to our repo have been replaces with fake env vars, otherwise error message unchanged):
DEBUG logs
Note as well that
h5py
is just one of many examples, but all follow the same message as above.This can be replicated by using the
renovate/python:latest
image (digest:renovate/python@sha256:f4841e0bc49c2aa6e2ad900456f99fceebc1a36afb5c0f94c7bf57f3b50f9c26
) as follows:Docker debugging commands and error log
(Note that I also ran
poetry config http-basic.fury $GEMFURY_TOKEN NOPASS
as this package includes dependencies on a private PyPI server. This does not seem to be relevant to the bug report as we've seen the same issue on repos without private dependencies).(At this point I looked into version issues, as there are several GH Issues and SO posts showing that the above error may have to do with out of date
setuptools
versions, etc, but all turned out to be red herrings. It may be worth noting, though, that therenovate/python
image usessetuptools
version49.2.1
despite53.0.0
being latest; it may be worth upgrading!)Please note from the above output that the specific package which is failing is distance -- though it is not the only package to throw here, it did turn out that all instances of our projects failing eventually included either
distance
or another package like it in their dependency tree.The relevant points of note for
distance
(anddistance
-like packages causing the same error) is that distance usersdistutils
rather thansetuptools
(it's quite old) and has no dependencies. This, in turn, leads Poetry to execute this code: it needs to fall back to actually installing the package to verify there are no dependencies.The interesting point here -- running the
poetry update
command locally (eg. without renovate) works just fine; the problem isn't that Poetry needs to fall back, but rather that it falls back incorrectly within Renovate. Debug logging through Poetry eventually leads to the point of divergence where Renovate is breaking: this method is the source of failure, as it errors when run via Renovate but not locally. Printing that stack trace gives us the crux of the issue:But... why are we trying to do a
--user
install within a virtualenv anyway? In my understanding, the entire point of using virtualenvs is inorder to avoid needing to write to global-vs-user site packages, so this flag is pretty much nonsensical in our case.Turns out the reason pip is attempting a user install here is because we have
PIP_USER=true
set in the environment. It looks like the reason for that is therenovate-buildpack
config forinstall-tool python
which sets this at build time.This makes sense for the use-case where we expect to be installing packages via
pip
directly in the image, but will break use-cases like this where we are installing within a virtual environment.Possible Fixes
I haven't done a full audit of everything renovate does within python images, so at this point I'll defer to @rarkins and the team for thoughts on how best to solve this. I think the following options would be potentially reasonable:
avoid setting
PIP_USER
in the build pack, set it only for the subset of commands we know should be user installs -- if most of our usecases are within virtual environments, this might make the most sense! Note that it seems you've already run into cases which require you to unset this.unset
PIP_USER
within therenovate/python:latest
docker image, after theinstall-tool
commands have completed -- if renovate itself runs commands within venvs, but theinstall-tool
commands are all global, this might make sense.update only the
manager/poetry/artifacts.ts
commands to includePIP_USER=false
as an override in the env var options here (eg. by addingenv: {"PIP_USER": "false"}
to that map). This would solve my specific use-case without impacting other renovate features, but may not solve all instances of this issue if venvs are used anywhere else by renovate.PIP_USER=true
set, for whatever reason. It might be worth havingPIP_USER=false
be a default somewhere in thisutil/exec
level.The text was updated successfully, but these errors were encountered: