setup-python icon indicating copy to clipboard operation
setup-python copied to clipboard

Fails to run on self hosted Windows runner if pip is not in PATH

Open lazka opened this issue 9 months ago • 4 comments

Description:

Downstream issue: https://github.com/msys2/msys2-autobuild/commit/fe4bcd08a9fbdd4a2874a67b4491991a76d784a7#commitcomment-153600091

Running the following on a self-hosted Windows runner leads to:

    - uses: actions/setup-python@v5
      id: python
      with:
        python-version: '3.13'
        cache: 'pip'
        cache-dependency-path: 'requirements.txt'
        architecture: 'x64'
        update-environment: false

error:

[error]Command failed: pip cache dir
'pip' is not recognized as an internal or external command,
operable program or batch file.

The problematic thing being "update-environment" (which we need to set, so it doesn't set cmake and pkg-config variables interfering with our builds. I don't mind the PATH, but setup-python only does all or nothing)

It looks like the cache code depends on pip being globally available, while it might not be: https://github.com/actions/setup-python/blob/9e62be81b28222addecf85e47571213eb7680449/src/cache-distributions/pip-cache.ts#L35-L41. This likely just works on the hosted runners since there pip is installed already.

In other places this is handled correctly by explicitly going through the just installed python/pip, for example: https://github.com/actions/setup-python/blob/9e62be81b28222addecf85e47571213eb7680449/src/install-pypy.ts#L177-L182

Action version: actions/setup-python@v5

Platform:

  • [ ] Ubuntu
  • [ ] macOS
  • [x] Windows

Runner type:

  • [ ] Hosted
  • [x] Self-hosted

Tools version:

3.13, but any really

Repro steps:
See above

Expected behavior: The action to run

Actual behavior: It errors out

lazka avatar Mar 12 '25 05:03 lazka

Hi @lazka, Thank you for creating this issue. We will investigate it and provide feedback as soon as we have some updates.

mahabaleshwars avatar Mar 12 '25 10:03 mahabaleshwars

A workaround is to use "actions/cache" for caching instead, see https://github.com/msys2/msys2-autobuild/commit/e9e823c2e730ab4f96df32ad0a4d4a2d75d30a7a

lazka avatar Mar 14 '25 12:03 lazka

Hi @lazka, Thank you for bringing up this issue! As outlined in the documentation, when the update-environment: false flag is set, the action intentionally does not modify environment variables such as PATH. This behavior is useful in scenarios where you need to avoid altering existing environment variables, like CMAKE or pkg-config, to maintain a specific configuration. However, it’s important to recognise that by choosing this option, you are opting out of having Python and pip automatically added to the PATH. As a result, this can lead to certain side effects, such as the issue you’ve encountered with the pip cache dir command not being able to find pip. In essence, if you decide to keep update-environment: false, you will need to ensure that pip is explicitly available in the environment for commands like pip to work correctly. To resolve this issue, we recommend reconsidering the use of update-environment: false, as the default behaviour of updating environment variables ensures that pip is included in the PATH, which should resolve the issue you're facing. If you need to maintain a specific environment configuration, you can explore alternative solutions, such as: Use actions/cache: If you are already utilising actions/cache in your workflow, you can continue to manage your dependencies via that action, which may help mitigate the need for modifying the environment variables. I hope this clarifies the situation. Please let me know if you have any further questions or if there's anything else we can assist you with!

gowridurgad avatar Mar 21 '25 10:03 gowridurgad

The action is failing internally and not my code, so I don't see how that is not a bug. I'm not using pip, the action is.

lazka avatar Mar 21 '25 10:03 lazka

Hi @lazka, As discussed earlier, the issue you are encountering is due to the update-environment: false flag. This option prevents the action from modifying environment variables such as PATH, which means that Python and pip are not automatically added to the PATH. As a result, commands like pip cannot run if they are not manually installed and configured in the self-hosted runner's environment. This is different from GitHub-hosted runners, where Python and pip are pre-installed, which is why this issue doesn’t occur there.

To make this clearer, we have updated the error message in the action. The new error message is as follows:

core.error(
 `'update-environment' is set to false, so the environment will not be updated. Please ensure that all required tools, including 'pip', are pre-installed and available in the PATH of the runner.`
);

This change aims to provide more clarity on the cause of the issue. If you decide to keep update-environment: false, you will need to ensure that pip and other necessary tools are explicitly available in the environment. In this case, even if we attempted to install pip, it wouldn’t work because Python is also not available in the environment. Pre-installing Python in the self-hosted runner is the better approach, as it ensures both Python and pip are available without conflicting with the update-environment: false flag, which prevents modifying the environment. Attached is a screenshot of the updated error message for your reference.

We hope this clarifies the situation. Please let us know if you have any further questions or if there's anything else we can assist you with!

Image

gowridurgad avatar Mar 28 '25 10:03 gowridurgad

Again, the error happens in the action itself and has nothing to do with my use of python or pip after the action. What you are suggesting is outside of my control as I can't control how the action is using pip/python.

lazka avatar Mar 28 '25 10:03 lazka

Hi @lazka, As mentioned earlier, we provide Python and pip as part of the action through setup-python. However, when update-environment: false is set, it prevents the action from modifying environment variables such as PATH. This means that pip and Python won’t be automatically added to the PATH, which is causing the issue you're encountering. To resolve this please choose one of the below options: Remove the update-environment: false configuration – This will allow the action to modify the PATH and ensure that Python and pip are available automatically during the action. Pre-install Python and pip on your self-hosted runner – If you need to keep the update-environment: false flag to preserve your custom environment, you will need to make sure that Python and pip are installed and added to the PATH before running the action. Unfortunately, there are no other alternatives beyond these two options, as the update-environment: false configuration is specifically designed to prevent the action from modifying environment variables like PATH. With this configuration in place, the action is unable to automatically add Python and pip to the PATH, so without either removing the configuration or ensuring Python and pip are pre-installed, the action will not be able to locate and use these tools and in this scenario, the behaviour is not a bug, but rather a result of the deliberate choice to preserve custom environment settings on your self-hosted runner.

gowridurgad avatar Apr 02 '25 10:04 gowridurgad

As I pointed out in the initial post the action is already capable of finding its installed python/pip in other places of the code, so what you are saying is not correct.

lazka avatar Apr 02 '25 16:04 lazka

@gowridurgad Situations like these usually warrant that you put the LLM away in order to come up with a real response. Saves everybody’s time 😀

ewancg avatar Apr 02 '25 19:04 ewancg

I'd suggest making a pull request to fix it, but past experience shows even those tend to languish for issues only affecting self-hosted runners.

jeremyd2019 avatar Apr 03 '25 00:04 jeremyd2019

Hi @lazka, We understand your concern, and we’d like to clarify the issue based on how the setup-python action works, particularly in relation to pip installation.

To give some context, the update-environment flag was introduced in PR #411 to provide users more control over whether or not the action should modify the system environment variables, like updating the PATH to include Python and pip. This was added because there were use cases where users didn't want the action to alter the global environment—particularly in scenarios where Python and pip are already managed externally. By setting update-environment: false, the action avoids modifying the system PATH, which explains why pip is not found in some cases

As you correctly mentioned, the setup-python action is capable of finding its installed python and pip in some parts of the code, like in the install-pypy.ts file. The reason it works in install-pypy.ts is that the action explicitly installs pip through python -m ensurepip and then uses python -m pip to run commands. This is possible because it’s done in a controlled manner, and the Python executable is available at that point.

However, in the case of pip-cache.ts, the action fails to find pip when update-environment: false is set. This is because, when update-environment: false is used, the action does not modify the system PATH. Therefore, both python and pip might not be available in the environment, and running something like pip cache dir will fail because pip is not in the PATH. The difference here is that pip-cache.ts tries to invoke pip directly from the shell, which requires pip to be globally available in the PATH. In other parts of the code, like in install-pypy.ts, the action works around this by explicitly invoking python -m pip (using the Python binary) instead of relying on the pip command being in the PATH. This works because it uses Python’s built-in pip module, which doesn't require pip to be globally installed or available in the PATH. I hope this clears things up! Let me know if you need further clarification.

gowridurgad avatar Apr 07 '25 10:04 gowridurgad

Yes, this is exactly what I wrote in the initial description of this issue.

lazka avatar Apr 07 '25 10:04 lazka

that's a very verbose description of the problem.

the action works around this by explicitly invoking python -m pip (using the Python binary) instead of relying on the pip command being in the PATH. This works because it uses Python’s built-in pip module, which doesn't require pip to be globally installed or available in the PATH.

and that's a good description of the proposed fix for pip-cache.ts

jeremyd2019 avatar Apr 07 '25 17:04 jeremyd2019