Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2 of 5 tasks
lazka opened this issue Mar 12, 2025 · 13 comments
Open
2 of 5 tasks

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

lazka opened this issue Mar 12, 2025 · 13 comments
Labels
bug Something isn't working

Comments

@lazka
Copy link

lazka commented Mar 12, 2025

Description:

Downstream issue: msys2/msys2-autobuild@fe4bcd0#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:

({stdout: stdout, stderr: stderr} = await execPromisify('pip cache dir'));
} else {
({
stdout: stdout,
stderr: stderr,
exitCode: exitCode
} = await exec.getExecOutput('pip cache dir'));
. 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:

const pythonBinary = path.join(pythonLocation, 'python');
await exec.exec(`${pythonBinary} -m ensurepip`);
await exec.exec(
`${pythonLocation}/python -m pip install --ignore-installed pip`
);

Action version:
actions/setup-python@v5

Platform:

  • Ubuntu
  • macOS
  • Windows

Runner type:

  • Hosted
  • 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 lazka added bug Something isn't working needs triage labels Mar 12, 2025
lazka referenced this issue in msys2/msys2-autobuild Mar 12, 2025
setup-python, by default, sets various cmake and pkg-config env
vars, so that packages using cmake can be built. Since this might
interfere with out package builds disable it.

We only care about the Python executable itself, so use the action
output to create the venv.
lazka added a commit to msys2/msys2-autobuild that referenced this issue Mar 12, 2025
@mahabaleshwars
Copy link
Contributor

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

@lazka
Copy link
Author

lazka commented Mar 14, 2025

A workaround is to use "actions/cache" for caching instead, see msys2/msys2-autobuild@e9e823c

@gowridurgad
Copy link
Contributor

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!

@lazka
Copy link
Author

lazka commented Mar 21, 2025

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.

@gowridurgad
Copy link
Contributor

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

@lazka
Copy link
Author

lazka commented Mar 28, 2025

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.

@gowridurgad
Copy link
Contributor

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.

@lazka
Copy link
Author

lazka commented Apr 2, 2025

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.

@ewancg
Copy link

ewancg commented Apr 2, 2025

@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 😀

@jeremyd2019
Copy link

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.

@gowridurgad
Copy link
Contributor

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.

@lazka
Copy link
Author

lazka commented Apr 7, 2025

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

@jeremyd2019
Copy link

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

@gowridurgad gowridurgad removed their assignment Apr 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants