-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial, read-only support for GitHub Actions
See #22.
- Loading branch information
Showing
7 changed files
with
214 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
""" | ||
Support for GitHub Actions. | ||
GitHub Actions are very flexible, so this code is going to make some | ||
simplifying assumptions: | ||
- your workflow is in .github/workflows/tests.yml | ||
- you use a matrix strategy | ||
- on 'python-version' that contains python versions, or | ||
- on 'config' that contains lists of [python_version, tox_env] | ||
""" | ||
|
||
from typing import List, Union | ||
|
||
import yaml | ||
|
||
from .base import Source | ||
from ..utils import FileOrFilename, open_file | ||
from ..versions import SortedVersionList, Version | ||
|
||
|
||
GHA_WORKFLOW_FILE = '.github/workflows/tests.yml' | ||
|
||
|
||
def get_gha_python_versions( | ||
filename: FileOrFilename = GHA_WORKFLOW_FILE, | ||
) -> SortedVersionList: | ||
"""Extract supported Python versions from a GitHub workflow.""" | ||
with open_file(filename) as fp: | ||
conf = yaml.safe_load(fp) | ||
|
||
versions: List[Version] = [] | ||
for job_name, job in conf.get('jobs', {}).items(): | ||
matrix = job.get('strategy', {}).get('matrix', {}) | ||
if 'python-version' in matrix: | ||
versions.extend( | ||
e for e in map(parse_gh_ver, matrix['python-version']) if e) | ||
if 'config' in matrix: | ||
versions.extend( | ||
parse_gh_ver(c[0]) | ||
for c in matrix['config'] | ||
if isinstance(c, list) | ||
) | ||
|
||
return sorted(set(versions)) | ||
|
||
|
||
def parse_gh_ver(v: Union[str, float]) -> Version: | ||
"""Parse Python versions used for actions/setup-python@v2. | ||
This format is not fully well documented. There's support for | ||
specifying things like | ||
- "3.x" (latest minor in Python 3.x; currently 3.9) | ||
- "3.7" (latest bugfix in Python 3.7) | ||
- "3.7.2" (specific version to be downloaded and installed) | ||
- "pypy2"/"pypy3" | ||
https://github.com/actions/python-versions/blob/main/versions-manifest.json | ||
contains a list of supported CPython versions that can be downloaded | ||
and installed; this includes prereleases, but doesn't include PyPy. | ||
""" | ||
v = str(v) | ||
if v.startswith('pypy3'): | ||
return Version.from_string('PyPy3') | ||
elif v.startswith('pypy2'): | ||
return Version.from_string('PyPy') | ||
else: | ||
return Version.from_string(v) | ||
|
||
|
||
GitHubActions = Source( | ||
title=GHA_WORKFLOW_FILE, | ||
filename=GHA_WORKFLOW_FILE, | ||
extract=get_gha_python_versions, | ||
update=None, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import textwrap | ||
from io import StringIO | ||
from typing import List | ||
|
||
import pytest | ||
|
||
from check_python_versions.sources.github import ( | ||
get_gha_python_versions, | ||
parse_gh_ver, | ||
) | ||
from check_python_versions.versions import Version | ||
|
||
|
||
def v(versions: List[str]) -> List[Version]: | ||
return [Version.from_string(v) for v in versions] | ||
|
||
|
||
def test_get_gha_python_versions(): | ||
tests_yml = StringIO(textwrap.dedent("""\ | ||
name: Python package | ||
on: [push] | ||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: [2.7, 3.5, 3.6, 3.7, 3.8] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install pytest | ||
pip install -r requirements.txt | ||
- name: Test with pytest | ||
run: | | ||
pytest | ||
""")) | ||
tests_yml.name = '.github/workflows/tests.yml' | ||
assert get_gha_python_versions(tests_yml) == v([ | ||
'2.7', '3.5', '3.6', '3.7', '3.8', | ||
]) | ||
|
||
|
||
def test_get_gha_python_versions_zopefoundation(): | ||
tests_yml = StringIO(textwrap.dedent("""\ | ||
name: tests | ||
on: | ||
push: | ||
branches: [ master ] | ||
pull_request: | ||
schedule: | ||
- cron: '0 12 * * 0' # run once a week on Sunday | ||
jobs: | ||
build: | ||
strategy: | ||
matrix: | ||
config: | ||
# [Python version, tox env] | ||
- ["3.8", "lint"] | ||
- ["2.7", "py27"] | ||
- ["3.5", "py35"] | ||
- ["3.6", "py36"] | ||
- ["3.7", "py37"] | ||
- ["3.8", "py38"] | ||
- ["3.9", "py39"] | ||
- ["pypy2", "pypy"] | ||
- ["pypy3", "pypy3"] | ||
- ["3.8", "coverage"] | ||
runs-on: ubuntu-latest | ||
name: ${{ matrix.config[1] }} | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.config[0] }} | ||
- ... | ||
""")) | ||
tests_yml.name = '.github/workflows/tests.yml' | ||
assert get_gha_python_versions(tests_yml) == v([ | ||
'2.7', '3.5', '3.6', '3.7', '3.8', '3.9', 'PyPy', 'PyPy3', | ||
]) | ||
|
||
|
||
def test_get_gha_python_versions_no_version_matrix(): | ||
tests_yml = StringIO(textwrap.dedent("""\ | ||
name: Python package | ||
on: [push] | ||
jobs: | ||
build: | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
matrix: | ||
os: [ubuntu-latest, macos-latest, windows-latest] | ||
steps: | ||
- ... | ||
""")) | ||
tests_yml.name = '.github/workflows/tests.yml' | ||
assert get_gha_python_versions(tests_yml) == [] | ||
|
||
|
||
@pytest.mark.parametrize('s, expected', [ | ||
(3.6, '3.6'), | ||
('3.7', '3.7'), | ||
('pypy2', 'PyPy'), | ||
('pypy3', 'PyPy3'), | ||
]) | ||
def test_parse_gh_ver(s, expected): | ||
assert parse_gh_ver(s) == Version.from_string(expected) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters