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

Audit fails on GH Action runners for Windows on Python 3.9 and 3.10 #365

Closed
jenstroeger opened this issue Sep 5, 2022 · 2 comments
Closed
Assignees
Labels
invalid This doesn't seem right

Comments

@jenstroeger
Copy link

Bug description

Please see these two failing Action runs:

Reproduction steps

The requirements.txt file is available as an artifact of the Linux run of that workflow: https://github.com/jenstroeger/python-package-template/actions/runs/2993510472

Expected behavior

pip-audit succeeds like for Mac and Linux runners.

Screenshots and logs

See links to Action run logs above.

Platform information

See SBOM and requirements.txt files in the artifact. Unfortunately, no artifacts were created for Windows, but they should be the same as for Linux.

Additional context

These failing runs are the consequence of removing the --require-hashes command line option from pip-audit because using that option yielded another error (run link):

pip_audit._dependency_source.requirement.RequirementSourceError: requirement alabaster does not contain a hash alabaster==0.7.12 (from RequirementLine(line_number=1, line='alabaster==0.7.12', filename=WindowsPath('requirements.txt')))

That’s unrelated to pip-audit though, I think.

@woodruffw
Copy link
Member

Thanks for the report!

This looks like the underlying error:

if ! $(python -c "import pip_audit" &> /dev/null); then \
  echo "No package pip_audit installed, upgrade your environment!" && exit 1; \
fi;
python -m pip_audit --requirement requirements.txt --skip-editable --desc on --fix --dry-run
WARNING:pip_audit._cache:Failed to read from cache directory, performance may be degraded: [Errno 22] Invalid argument: 'c:\\users\\runneradmin\\appdata\\local\\pip\\cache\r\\http\\e\\d\\4\\2\\0\\ed4206b12a5c5eaf07ac2214d1cb00783992ccd3db2bee486d936636'
WARNING:venv:Actual environment location may have moved due to redirects, links or junctions.
  Requested location: "C:\Users\RUNNER~1\AppData\Local\Temp\tmpqmup42k2\Scripts\python.exe"
  Actual location:    "C:\Users\runneradmin\AppData\Local\Temp\tmpqmup42k2\Scripts\python.exe"
Traceback (most recent call last):
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\site-packages\packaging\specifiers.py", line 634, in __init__
    parsed.add(Specifier(specifier))
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\site-packages\packaging\specifiers.py", line 98, in __init__
    raise InvalidSpecifier(f"Invalid specifier: '{spec}'")
packaging.specifiers.InvalidSpecifier: Invalid specifier: '3'

If I'm looking at your CI correctly, you might be emitting a broken requirements.txt on Windows runners:

Run make requirements sbom
makefile:29: No Python virtual environment found, proceeding anyway
echo -n "" > requirements.txt
for pkg in `python -m pip freeze --local --disable-pip-version-check --exclude-editable`; do \
  echo -n $pkg >> requirements.txt; \
  echo "Fetching package metadata for requirement '$pkg'"; \
  [[ $pkg =~ (.*)==(.*) ]] && curl -s [https://pypi.org/pypi/${BASH_REMATCH[1]}/${BASH_REMATCH[2]}/json](https://pypi.org/pypi/$%7BBASH_REMATCH[1]%7D/$%7BBASH_REMATCH[2]%7D/json) | python -c "import json, sys; print(''.join(f''' \\\\\n    --hash=sha256:{pkg['digests']['sha256']}''' for pkg in json.load(sys.stdin)['urls']));" >> requirements.txt; \
done
Fetching package metadata for requirement 'alabaster==0.7.12
'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\json\__init__.py", line 293, in load
    return loads(fp.read(),
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\json\__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Fetching package metadata for requirement 'argcomplete==1.12.3
'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\json\__init__.py", line 293, in load
    return loads(fp.read(),
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\json\__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\hostedtoolcache\windows\Python\3.10.6\x64\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Fetching package metadata for requirement 'astroid==2.11.7
'

...which makes me suspect that this isn't a bug in pip-audit, since that same step runs without JSONDecodeErrors on your non-Windows runners.

@woodruffw woodruffw self-assigned this Sep 6, 2022
@jenstroeger
Copy link
Author

Thanks @woodruffw!

I didn’t actually realize that the preceding step of the failing workflow step wasn’t successful either. After some digging around, I found the problem — the age-old DOS/UNIX newline difference. This line of code:

for pkg in `python -m pip freeze --local --disable-pip-version-check --exclude-editable`; do \

on Windows assigns alabaster==0.7.12\r to $pkg. Next, in this line:

[[ $pkg =~ (.*)==(.*) ]] && curl -s https://pypi.org/pypi/${BASH_REMATCH[1]}/${BASH_REMATCH[2]}/json | python ...

the $pkg variable matches and binds ${BASH_REMATCH[2]} to 0.7.12\r which then creates an invalid URL so that curl fetches nothing which then fails the JSON decode and that’s the exception you’ve pointed out above.

As for a fix, a possible solution would be to strip trailing newlines:

pkg=${pkg//[$'\r\n']}

I’ll look some more into this issue, but at the moment our package doesn’t generate artifacts using Windows runners anyway.

...which makes me suspect that this isn't a bug in pip-audit, since that same step runs without JSONDecodeErrors on your non-Windows runners.

Agreed. Feel free to close this issue as resolved 👍🏼

@woodruffw woodruffw added invalid This doesn't seem right and removed bug-candidate Might be a bug. labels Sep 7, 2022
jenstroeger added a commit to jenstroeger/python-package-template that referenced this issue Sep 7, 2022
This is particularly important on Windows hosts. For more background on
this change: pypa/pip-audit#365 (comment)
jenstroeger added a commit to jenstroeger/python-package-template that referenced this issue Sep 8, 2022
…ts (#316)

This is particularly important on Windows hosts. For more background on this change: pypa/pip-audit#365 (comment)
jenstroeger added a commit to jenstroeger/python-package-template that referenced this issue Sep 8, 2022
…ts (#316)

This is particularly important on Windows hosts. For more background on this change: pypa/pip-audit#365 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

2 participants