Validate only submitted Project Euler solution (#3977)

* Update validate solution script to fetch only submitted solution
* Update workflow file with the updated PE script
* Fix: do not fetch `validate_solutions.py` script
* Update script to use the requests package for API calls
* Fix: install requests module
* Pytest ignore scripts/ directory
This commit is contained in:
Dhruv Manilawala 2020-11-29 23:11:09 +05:30 committed by GitHub
parent 25164bb638
commit ba6310b647
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 10 deletions

View File

@ -22,6 +22,6 @@ jobs:
python -m pip install --upgrade pip setuptools six wheel python -m pip install --upgrade pip setuptools six wheel
python -m pip install pytest-cov -r requirements.txt python -m pip install pytest-cov -r requirements.txt
- name: Run tests - name: Run tests
run: pytest --doctest-modules --ignore=project_euler/ --cov-report=term-missing:skip-covered --cov=. . run: pytest --doctest-modules --ignore=project_euler/ --ignore=scripts/ --cov-report=term-missing:skip-covered --cov=. .
- if: ${{ success() }} - if: ${{ success() }}
run: scripts/build_directory_md.py 2>&1 | tee DIRECTORY.md run: scripts/build_directory_md.py 2>&1 | tee DIRECTORY.md

View File

@ -1,12 +1,14 @@
on: on:
pull_request: pull_request:
# only check if a file is changed within the project_euler directory and related files # Run only if a file is changed within the project_euler directory and related files
paths: paths:
- 'project_euler/**' - "project_euler/**"
- '.github/workflows/project_euler.yml' - ".github/workflows/project_euler.yml"
- 'scripts/validate_solutions.py' - "scripts/validate_solutions.py"
schedule:
- cron: "0 0 * * *" # Run everyday
name: 'Project Euler' name: "Project Euler"
jobs: jobs:
project-euler: project-euler:
@ -24,8 +26,10 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-python@v2 - uses: actions/setup-python@v2
- name: Install pytest - name: Install pytest and requests
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
python -m pip install --upgrade pytest python -m pip install --upgrade pytest requests
- run: pytest scripts/validate_solutions.py - run: pytest scripts/validate_solutions.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,11 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import importlib.util import importlib.util
import json import json
import os
import pathlib import pathlib
from types import ModuleType from types import ModuleType
from typing import Dict, List from typing import Dict, List
import pytest import pytest
import requests
PROJECT_EULER_DIR_PATH = pathlib.Path.cwd().joinpath("project_euler") PROJECT_EULER_DIR_PATH = pathlib.Path.cwd().joinpath("project_euler")
PROJECT_EULER_ANSWERS_PATH = pathlib.Path.cwd().joinpath( PROJECT_EULER_ANSWERS_PATH = pathlib.Path.cwd().joinpath(
@ -24,7 +26,7 @@ def convert_path_to_module(file_path: pathlib.Path) -> ModuleType:
return module return module
def collect_solution_file_paths() -> List[pathlib.Path]: def all_solution_file_paths() -> List[pathlib.Path]:
"""Collects all the solution file path in the Project Euler directory""" """Collects all the solution file path in the Project Euler directory"""
solution_file_paths = [] solution_file_paths = []
for problem_dir_path in PROJECT_EULER_DIR_PATH.iterdir(): for problem_dir_path in PROJECT_EULER_DIR_PATH.iterdir():
@ -37,12 +39,51 @@ def collect_solution_file_paths() -> List[pathlib.Path]:
return solution_file_paths return solution_file_paths
def get_files_url() -> str:
"""Return the pull request number which triggered this action."""
with open(os.environ["GITHUB_EVENT_PATH"]) as file:
event = json.load(file)
return event["pull_request"]["url"] + "/files"
def added_solution_file_path() -> List[pathlib.Path]:
"""Collects only the solution file path which got added in the current
pull request.
This will only be triggered if the script is ran from GitHub Actions.
"""
solution_file_paths = []
headers = {
"Accept": "application/vnd.github.v3+json",
"Authorization": "token " + os.environ["GITHUB_TOKEN"],
}
files = requests.get(get_files_url(), headers=headers).json()
for file in files:
filepath = pathlib.Path.cwd().joinpath(file["filename"])
if (
filepath.suffix != ".py"
or filepath.name.startswith(("_", "test"))
or not filepath.name.startswith("sol")
):
continue
solution_file_paths.append(filepath)
return solution_file_paths
def collect_solution_file_paths() -> List[pathlib.Path]:
if os.environ.get("CI") and os.environ.get("GITHUB_EVENT_NAME") == "pull_request":
# Return only if there are any, otherwise default to all solutions
if filepaths := added_solution_file_path():
return filepaths
return all_solution_file_paths()
@pytest.mark.parametrize( @pytest.mark.parametrize(
"solution_path", "solution_path",
collect_solution_file_paths(), collect_solution_file_paths(),
ids=lambda path: f"{path.parent.name}/{path.name}", ids=lambda path: f"{path.parent.name}/{path.name}",
) )
def test_project_euler(solution_path: pathlib.Path): def test_project_euler(solution_path: pathlib.Path) -> None:
"""Testing for all Project Euler solutions""" """Testing for all Project Euler solutions"""
# problem_[extract this part] and pad it with zeroes for width 3 # problem_[extract this part] and pad it with zeroes for width 3
problem_number: str = solution_path.parent.name[8:].zfill(3) problem_number: str = solution_path.parent.name[8:].zfill(3)