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 pytest-cov -r requirements.txt
- 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() }}
run: scripts/build_directory_md.py 2>&1 | tee DIRECTORY.md

View File

@ -1,12 +1,14 @@
on:
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:
- 'project_euler/**'
- '.github/workflows/project_euler.yml'
- 'scripts/validate_solutions.py'
- "project_euler/**"
- ".github/workflows/project_euler.yml"
- "scripts/validate_solutions.py"
schedule:
- cron: "0 0 * * *" # Run everyday
name: 'Project Euler'
name: "Project Euler"
jobs:
project-euler:
@ -24,8 +26,10 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- name: Install pytest
- name: Install pytest and requests
run: |
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
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,11 +1,13 @@
#!/usr/bin/env python3
import importlib.util
import json
import os
import pathlib
from types import ModuleType
from typing import Dict, List
import pytest
import requests
PROJECT_EULER_DIR_PATH = pathlib.Path.cwd().joinpath("project_euler")
PROJECT_EULER_ANSWERS_PATH = pathlib.Path.cwd().joinpath(
@ -24,7 +26,7 @@ def convert_path_to_module(file_path: pathlib.Path) -> ModuleType:
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"""
solution_file_paths = []
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
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(
"solution_path",
collect_solution_file_paths(),
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"""
# problem_[extract this part] and pad it with zeroes for width 3
problem_number: str = solution_path.parent.name[8:].zfill(3)