Repository: tox-dev/tox

Issue:
Tox 4 breaks in CI/CD pipelines where user does not exist
## Issue

Starting with Tox 4, tox is failing to run unittests due to an exception in code trying to determiner HOME directory.

## Environment

Our environment is using Jenkins with Docker based declarative pipelines but for the sake of the bug report, I'll demonstrate the problem with a direct Docker setup.

```console
$ git clone https://github.com/psf/requests
$ docker run --rm -it -u $UID -v $PWD:/src -w /src -e HOME=/src python:3.7 bash
I have no name!@ffa04e72c39f:~$ pip freeze
cachetools==5.2.0
chardet==5.1.0
colorama==0.4.6
distlib==0.3.6
filelock==3.8.2
importlib-metadata==5.1.0
packaging==22.0
platformdirs==2.6.0
pluggy==1.0.0
py==1.11.0
pyproject_api==1.2.1
six==1.16.0
tomli==2.0.1
tox==3.27.1
typing_extensions==4.4.0
virtualenv==20.17.1
zipp==3.11.0

## Output of running tox

Provide the output of `tox -rvv`:

Moved the first comment as it makes the report exceed maximum size.

## Minimal example

If possible, provide a minimal reproducer for the issue:

```console
$ git clone https://github.com/psf/requests
$ docker run --rm -it -u $UID -v $PWD:/src -w /src -e HOME=/src python:3.7 bash
I have no name!@ffa04e72c39f:~$ pip install "tox<4"
I have no name!@ffa04e72c39f:~$ .local/bin/tox -e py37
---> works
I have no name!@ffa04e72c39f:~$ pip install -U "tox"
I have no name!@ffa04e72c39f:~$ .local/bin/tox -e py37
---> fails
```

Blocking Tox to <4 does not seem to work for all our packages but I could reproduce our issue with requests at least so you can get an early report of the problem. You can see HOME environment variable is set on the Docker command line which we are doing in our Jenkins pipelines as well. We've had a similar issue in the past with running Spark based unittests as JVM is very picky about its environment but we would really like to avoid apply the same hack to get it to work with tox 4+.


Discussion:

Patch:
diff --git a/docs/changelog/2702.bugfix.rst b/docs/changelog/2702.bugfix.rst
new file mode 100644
index 00000000..7f3e64ee
--- /dev/null
+++ b/docs/changelog/2702.bugfix.rst
@@ -0,0 +1,1 @@
+Forward ``HOME`` by default - by :user:`gschaffner`.
diff --git a/src/tox/tox_env/api.py b/src/tox/tox_env/api.py
index 1542a8fc..fcfc9e4b 100644
--- a/src/tox/tox_env/api.py
+++ b/src/tox/tox_env/api.py
@@ -218,6 +218,7 @@ class ToxEnv(ABC):
             "CPPFLAGS",  # C++ compiler flags
             "LD_LIBRARY_PATH",  # location of libs
             "LDFLAGS",  # linker flags
+            "HOME",  # needed for `os.path.expanduser()` on non-Windows systems
         ]
         if sys.stdout.isatty():  # if we're on a interactive shell pass on the TERM
             env.append("TERM")


Test patch:
diff --git a/tests/session/cmd/test_show_config.py b/tests/session/cmd/test_show_config.py
index 9ef9f300..46a04246 100644
--- a/tests/session/cmd/test_show_config.py
+++ b/tests/session/cmd/test_show_config.py
@@ -117,7 +117,7 @@ def test_pass_env_config_default(tox_project: ToxProjectCreator, stdout_is_atty:
     expected = (
         ["CC", "CCSHARED", "CFLAGS"]
         + (["COMSPEC"] if is_win else [])
-        + ["CPPFLAGS", "CURL_CA_BUNDLE", "CXX", "LANG", "LANGUAGE", "LDFLAGS", "LD_LIBRARY_PATH"]
+        + ["CPPFLAGS", "CURL_CA_BUNDLE", "CXX", "HOME", "LANG", "LANGUAGE", "LDFLAGS", "LD_LIBRARY_PATH"]
         + (["MSYSTEM", "NUMBER_OF_PROCESSORS", "PATHEXT"] if is_win else [])
         + ["PIP_*", "PKG_CONFIG", "PKG_CONFIG_PATH", "PKG_CONFIG_SYSROOT_DIR"]
         + (["PROCESSOR_ARCHITECTURE"] if is_win else [])