From ca8689bebecc0b79d9acda8481e2b523be8dcfbe Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Sat, 28 Nov 2020 10:57:22 +0530 Subject: [PATCH 1/7] Update validate solution script to fetch one solution --- scripts/validate_solutions.py | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/scripts/validate_solutions.py b/scripts/validate_solutions.py index e1f68ff843bb..a4caa08eab6a 100755 --- a/scripts/validate_solutions.py +++ b/scripts/validate_solutions.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 import importlib.util import json +import os import pathlib from types import ModuleType from typing import Dict, List +import github import pytest PROJECT_EULER_DIR_PATH = pathlib.Path.cwd().joinpath("project_euler") @@ -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,6 +39,40 @@ def collect_solution_file_paths() -> List[pathlib.Path]: return solution_file_paths +def get_pull_number() -> int: + """Return the pull request number which triggered this action.""" + GITHUB_REF = os.environ["GITHUB_REF"] + return int(GITHUB_REF.split("/")[2]) + + +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 = [] + # Direct fetching so that the error propagates, if any. + login = github.Github(os.environ["GITHUB_TOKEN"]) + repo = login.get_repo(os.environ["GITHUB_REPOSITORY"]) + if pull_number := get_pull_number(): + pull = repo.get_pull(pull_number) + for file in pull.get_files(): + file_path = pathlib.Path.cwd().joinpath(file.filename) + if file_path.suffix != ".py" or file_path.name.startswith(("_", "test")): + continue + solution_file_paths.append(file_path) + 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(), From ec1af0f18031e7c2c1e6b20fc96e05103c519731 Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Sat, 28 Nov 2020 10:57:49 +0530 Subject: [PATCH 2/7] Update workflow file with the updated PE script --- .github/workflows/project_euler.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/project_euler.yml b/.github/workflows/project_euler.yml index e8b011af20a6..432011fe9c8c 100644 --- a/.github/workflows/project_euler.yml +++ b/.github/workflows/project_euler.yml @@ -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: @@ -27,5 +29,7 @@ jobs: - name: Install pytest run: | python -m pip install --upgrade pip - python -m pip install --upgrade pytest + python -m pip install --upgrade pytest pygithub - run: pytest scripts/validate_solutions.py + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 9be644a1a734d0f2104ae2881c0cdedd706e8f5b Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Sat, 28 Nov 2020 11:02:43 +0530 Subject: [PATCH 3/7] Fix: do not fetch validate solution script --- scripts/validate_solutions.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/validate_solutions.py b/scripts/validate_solutions.py index a4caa08eab6a..34e49b181947 100755 --- a/scripts/validate_solutions.py +++ b/scripts/validate_solutions.py @@ -59,7 +59,11 @@ def added_solution_file_path() -> List[pathlib.Path]: pull = repo.get_pull(pull_number) for file in pull.get_files(): file_path = pathlib.Path.cwd().joinpath(file.filename) - if file_path.suffix != ".py" or file_path.name.startswith(("_", "test")): + if ( + file_path.suffix != ".py" + or file_path.name.startswith(("_", "test")) + or not file_path.name.startswith("sol") + ): continue solution_file_paths.append(file_path) return solution_file_paths From f3ceac22f9ce3d55920401a7b7031d9b155eee92 Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Sat, 28 Nov 2020 11:07:25 +0530 Subject: [PATCH 4/7] Fix: import error on build run --- scripts/validate_solutions.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/validate_solutions.py b/scripts/validate_solutions.py index 34e49b181947..8f3588f07e96 100755 --- a/scripts/validate_solutions.py +++ b/scripts/validate_solutions.py @@ -6,9 +6,13 @@ from types import ModuleType from typing import Dict, List -import github import pytest +try: + import github +except ImportError: + pass + PROJECT_EULER_DIR_PATH = pathlib.Path.cwd().joinpath("project_euler") PROJECT_EULER_ANSWERS_PATH = pathlib.Path.cwd().joinpath( "scripts", "project_euler_answers.json" @@ -82,7 +86,7 @@ def collect_solution_file_paths() -> List[pathlib.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) From 21db7cf8dd157572b5bbc37d29089d11a86cd7e3 Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Sun, 29 Nov 2020 22:36:27 +0530 Subject: [PATCH 5/7] Update script to use the requests for API call --- .github/workflows/project_euler.yml | 2 +- scripts/validate_solutions.py | 41 +++++++++++++---------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/.github/workflows/project_euler.yml b/.github/workflows/project_euler.yml index 432011fe9c8c..18d07c9a67f4 100644 --- a/.github/workflows/project_euler.yml +++ b/.github/workflows/project_euler.yml @@ -29,7 +29,7 @@ jobs: - name: Install pytest run: | python -m pip install --upgrade pip - python -m pip install --upgrade pytest pygithub + python -m pip install --upgrade pytest - run: pytest scripts/validate_solutions.py env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/scripts/validate_solutions.py b/scripts/validate_solutions.py index 8f3588f07e96..fd804ea5aa31 100755 --- a/scripts/validate_solutions.py +++ b/scripts/validate_solutions.py @@ -7,11 +7,7 @@ from typing import Dict, List import pytest - -try: - import github -except ImportError: - pass +import requests PROJECT_EULER_DIR_PATH = pathlib.Path.cwd().joinpath("project_euler") PROJECT_EULER_ANSWERS_PATH = pathlib.Path.cwd().joinpath( @@ -43,10 +39,11 @@ def all_solution_file_paths() -> List[pathlib.Path]: return solution_file_paths -def get_pull_number() -> int: +def get_files_url() -> str: """Return the pull request number which triggered this action.""" - GITHUB_REF = os.environ["GITHUB_REF"] - return int(GITHUB_REF.split("/")[2]) + 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]: @@ -56,20 +53,20 @@ def added_solution_file_path() -> List[pathlib.Path]: This will only be triggered if the script is ran from GitHub Actions. """ solution_file_paths = [] - # Direct fetching so that the error propagates, if any. - login = github.Github(os.environ["GITHUB_TOKEN"]) - repo = login.get_repo(os.environ["GITHUB_REPOSITORY"]) - if pull_number := get_pull_number(): - pull = repo.get_pull(pull_number) - for file in pull.get_files(): - file_path = pathlib.Path.cwd().joinpath(file.filename) - if ( - file_path.suffix != ".py" - or file_path.name.startswith(("_", "test")) - or not file_path.name.startswith("sol") - ): - continue - solution_file_paths.append(file_path) + 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 From 501140719ac518d120aa9a262bdcf7d972a62d8c Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Sun, 29 Nov 2020 22:39:14 +0530 Subject: [PATCH 6/7] Fix: install requests module --- .github/workflows/project_euler.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/project_euler.yml b/.github/workflows/project_euler.yml index 18d07c9a67f4..995295fcaa9a 100644 --- a/.github/workflows/project_euler.yml +++ b/.github/workflows/project_euler.yml @@ -26,10 +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 }} From fbe7cd6a9600cc7f02227333ffa4e23b59b82c9f Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Sun, 29 Nov 2020 22:46:40 +0530 Subject: [PATCH 7/7] Pytest ignore scripts/ directory --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ae9b4e36b1ce..9e15d18ade8e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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