Skip to content
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

Port python deps setup to windows #257

Merged
merged 15 commits into from
Oct 15, 2020
Merged

Port python deps setup to windows #257

merged 15 commits into from
Oct 15, 2020

Conversation

Daverlo
Copy link
Contributor

@Daverlo Daverlo commented Oct 6, 2020

Closes https://github.com/github/code-scanning/issues/2108

This PR ports the auto install python deps functionality so it also works on windows workers.

I tested this branch with the django example and it worked as expected, providing two alerts:
https://github.com/dsp-testing/daverlo-djanjo-test/actions/runs/291392369
https://github.com/dsp-testing/daverlo-djanjo-test/security/code-scanning

@RasmusWL would you mind taking a look at the python scripts? I created a copy of auto-install-packages and modified it so it works on windows.

Merge / deployment checklist

  • Confirm this change is backwards compatible with existing workflows.
  • Confirm the readme has been updated if necessary.

Copy link
Member

@RasmusWL RasmusWL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather have seen auto_install_packages.py being adapted to work on both Windows and Linux instead of duplicating the script and making adjustments (using sys.platform or os.name). I really think that is the right approach.

As an example of why this is important, the version of the linux script you ported is not the most up to date (compare with https://github.com/github/codeql-action/blob/main/python-setup/auto_install_packages.py)

I also don't understand the need to strip out the first 3 characters when using pipenv and poetry, can you explain?

@Daverlo Daverlo force-pushed the daverlo/python-windows branch from 4cb342f to e97bdbd Compare October 7, 2020 10:55
@Daverlo
Copy link
Contributor Author

Daverlo commented Oct 7, 2020

I also don't understand the need to strip out the first 3 characters when using pipenv and poetry, can you explain?

They were producing a path like
/d/a/codeql-python-autobuild-playground/virtualenvs/autoinstall-test-FP1YIZRL-py2.7/Scripts/python

and windows didn't like the /d prefix, it complained about the file not existing. 🤷

Copy link
Member

@RasmusWL RasmusWL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this version looks much better, good job 🥇

There is an issue with hardcoding version of python, but otherwise this looks good to me!

@@ -137,7 +162,10 @@ def install_packages(codeql_base_dir) -> Optional[str]:

# The binaries for packages installed with `pip install --user` are not available on
# PATH by default, so we need to manually add them.
os.environ['PATH'] = os.path.expanduser('~/.local/bin') + os.pathsep + os.environ['PATH']
if sys.platform.startswith('win32'):
os.environ['PATH'] = os.path.expandvars('%APPDATA%\Python\\Python38\\scripts') + os.pathsep + os.environ['PATH']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hardcoded Python version (3.8) looks a bit scary to me. Is there a way to not hardcode the version? 😬

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the default version of Python in Windows workers and it's always there, no matter if you add the setup-python action with like 2.7 or 3.5 or whatever, in fact, that action is not needed at all. I

prefer to leave it like this if you don't mind, right now it is working for all the cases and I don't think its the best use of my time at this moment.

https://github.com/dsp-testing/codeql-python-autobuild-playground/runs/1213872774?check_suite_focus=true
https://github.com/dsp-testing/codeql-python-autobuild-playground/runs/1221157769?check_suite_focus=true
https://github.com/dsp-testing/codeql-python-autobuild-playground/runs/1221281906?check_suite_focus=true

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3.8 is "always" there until someone updates the virtual machine image. 3.9 was just released, so it may change sooner than you think. You should be able to get the USER_BASE directory from the site module. See also https://docs.python.org/3/library/site.html#site.USER_BASE

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly you should also be able to set PYTHONUSERBASE to have full control over the install location. You could consider stuffing things in the RUNNER_TEMP folder to avoid interfering with future other jobs on self_hosted workers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good idea @aibaars is pointing out, and I'm probably to blame for not thinking about this in the first place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @aibaars added this comment to the wrong thread:

Perhaps you should invoke poetry like py -3 -m poetry or similar or even use sys.executable like [sys.executable like , '-m', 'poetry', 'run', 'which', 'python']

For solving this problem, I think using sys.executable instead of hardcoding the 3.8 path is a very good trade-off.

We just need to make sure that we only invoke this script with Python 3, since we only install pipenv/poetry for Python 3. (but I guess the JS code already does ensures this, right?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to make it work with the sys.executable

    _check_call([sys.executable like , '-m', 'poetry', 'install', '--no-root'])
                                ^
SyntaxError: invalid syntax

But I managed to make it work with the py -3!!

We just need to make sure that we only invoke this script with Python 3, since we only install pipenv/poetry for Python 3. (but I guess the JS code already does ensures this, right?)

Yep, it is always called with py -3

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Real code without syntax error would be

_check_call([sys.executable, '-m', 'poetry', 'install', '--no-root'])

python-setup/auto_install_packages.py Outdated Show resolved Hide resolved
@@ -36,10 +38,14 @@ def install_packages_with_poetry():
poetry_out = _check_output(['poetry', 'run', 'which', 'python'])
python_executable_path = poetry_out.decode('utf-8').splitlines()[-1]

if sys.platform.startswith('win32'):
python_executable_path = python_executable_path[2:]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain the purpose of chopping off the start of the python_executable_path? If it is to get rid off the drive letter (eg C: ) then this code is likely wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Poetry and pipenv display the path wrongly. They produce /d/a/codeql-python-autobuild-playground/virtualenvs/requests-2-z_EHYAbo/Scripts/python instead of D:\a\codeql-python-autobuild-playground\codeql-action-python-autoinstall\Scripts\python. Windows doesn't like that way of specifying the drive letter. I completely removed because it is not needed as everything is in the same drive (We are installing the dependencies in the RUNNER_WORKSPACE)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since I also asked about this, can we maybe just add that comment to the code? 😊

Copy link
Collaborator

@aibaars aibaars Oct 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The /d silly paths are likely due to cygwin or msys. You might want to check whether the paths are bad before chopping off letters. You never know when they'll replace pipenv and poetry with more windows-like versions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why poetry or pipenv would behave this way. These are python programs. Are you accidentally running them with a non-windows (ie. cygwin/msys) python binary?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you should invoke poetry like py -3 -m poetry or similar or even use sys.executable like [sys.executable like , '-m', 'poetry', 'run', 'which', 'python']

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm now calling it with py -3 -m poetry and is still producing the same output, so I still need to chop off the start of the string

python-setup/auto_install_packages.py Outdated Show resolved Hide resolved
@@ -48,29 +54,43 @@ def install_packages_with_pipenv():
pipenv_out = _check_output(['pipenv', 'run', 'which', 'python'])
python_executable_path = pipenv_out.decode('utf-8').splitlines()[-1]

if sys.platform.startswith('win32'):
python_executable_path = python_executable_path[2:]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks strange to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the other comment

python-setup/auto_install_packages.py Outdated Show resolved Hide resolved
@@ -137,7 +162,10 @@ def install_packages(codeql_base_dir) -> Optional[str]:

# The binaries for packages installed with `pip install --user` are not available on
# PATH by default, so we need to manually add them.
os.environ['PATH'] = os.path.expanduser('~/.local/bin') + os.pathsep + os.environ['PATH']
if sys.platform.startswith('win32'):
os.environ['PATH'] = os.path.expandvars('%APPDATA%\Python\\Python38\\scripts') + os.pathsep + os.environ['PATH']
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3.8 is "always" there until someone updates the virtual machine image. 3.9 was just released, so it may change sooner than you think. You should be able to get the USER_BASE directory from the site module. See also https://docs.python.org/3/library/site.html#site.USER_BASE

src/init.ts Outdated Show resolved Hide resolved
@@ -137,7 +162,10 @@ def install_packages(codeql_base_dir) -> Optional[str]:

# The binaries for packages installed with `pip install --user` are not available on
# PATH by default, so we need to manually add them.
os.environ['PATH'] = os.path.expanduser('~/.local/bin') + os.pathsep + os.environ['PATH']
if sys.platform.startswith('win32'):
os.environ['PATH'] = os.path.expandvars('%APPDATA%\Python\\Python38\\scripts') + os.pathsep + os.environ['PATH']
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly you should also be able to set PYTHONUSERBASE to have full control over the install location. You could consider stuffing things in the RUNNER_TEMP folder to avoid interfering with future other jobs on self_hosted workers.

@Daverlo
Copy link
Contributor Author

Daverlo commented Oct 13, 2020

@aibaars @RasmusWL I got this working using the py -3 -m poetry/py -3 -m pipenv calls, so no more hardcoded python version. Could you re-review the PR please?

Copy link
Member

@RasmusWL RasmusWL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor nitpicks, but generally I won't be against merging it now 😊

python-setup/auto_install_packages.py Outdated Show resolved Hide resolved
python-setup/auto_install_packages.py Show resolved Hide resolved
python-setup/auto_install_packages.py Show resolved Hide resolved
Copy link
Member

@RasmusWL RasmusWL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, looks good to me now 👍

Thanks for working through all the things 💪

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants