From 12b288226ee9939c3d00b915ca68676bc2a62694 Mon Sep 17 00:00:00 2001 From: Jasper Date: Tue, 8 Aug 2023 19:07:37 +0200 Subject: [PATCH 01/19] Linter, formatter and added docs. Mypy fixes (wherever reasonable) --- config/__init__.py | 29 ++++++++-------- libretro_finder/main.py | 8 ++--- libretro_finder/utils.py | 23 ++++++------ poetry.lock | 42 +++++++++++++++++++++- pyproject.toml | 8 +++-- tests/fixtures.py | 9 +++-- tests/test_main.py | 75 ++++++++++++++++++++++++++++++---------- tests/test_utils.py | 67 ++++++++++++++++++++++++++--------- 8 files changed, 187 insertions(+), 74 deletions(-) diff --git a/config/__init__.py b/config/__init__.py index cef5678..db3f6c2 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -20,7 +20,8 @@ # Parsing Libretro's system.dat and formatting as pandas dataframe index = 0 # pylint: disable=invalid-name -SYSTEMS = [] + +system_series = [] with open(FILE_PATH, "r", encoding="utf-8") as file: for line in file: line = line.strip() @@ -31,27 +32,27 @@ r"name (\S+)(?: size (\S+))?(?: crc (\S+))?(?: md5 (\S+))?(?: sha1 (\S+))?", line, ) - data = { - "system": current_system, - "name": match.group(1).replace('"', "").replace("'", ""), - "size": match.group(2) if match.group(2) else None, - "crc": match.group(3) if match.group(3) else None, - "md5": match.group(4) if match.group(4) else None, - "sha1": match.group(5) if match.group(5) else None, - } - SYSTEMS.append(pd.DataFrame(data, index=[index])) - index += 1 + if match: + data = { + "system": current_system, + "name": match.group(1).replace('"', "").replace("'", ""), + "size": match.group(2) if match.group(2) else None, + "crc": match.group(3) if match.group(3) else None, + "md5": match.group(4) if match.group(4) else None, + "sha1": match.group(5) if match.group(5) else None, + } + system_series.append(pd.DataFrame(data, index=[index])) + index += 1 # join dfs and drop features without checksums -SYSTEMS = pd.concat(SYSTEMS) +SYSTEMS = pd.concat(system_series) SYSTEMS = SYSTEMS[~SYSTEMS["md5"].isnull()].reset_index(drop=True) # path to retroarch/system (if found) RETROARCH_PATH = find_retroarch() - # 'cli' if user passes arguments else 'start gui' # Needs to be present before the @Gooey decorator (https://github.com/chriskiehl/Gooey/issues/449) if len(sys.argv) >= 2: - if not "--ignore-gooey" in sys.argv: + if "--ignore-gooey" not in sys.argv: sys.argv.append("--ignore-gooey") diff --git a/libretro_finder/main.py b/libretro_finder/main.py index 0e8bed8..531f843 100644 --- a/libretro_finder/main.py +++ b/libretro_finder/main.py @@ -1,11 +1,10 @@ import shutil import pathlib +from typing import List, Optional import numpy as np -from gooey import Gooey, GooeyParser - +from gooey import Gooey, GooeyParser # type: ignore from config import SYSTEMS as system_df from config import RETROARCH_PATH -from typing import List, Optional from libretro_finder.utils import match_arrays, recursive_hash @@ -17,7 +16,6 @@ def organize(search_dir: pathlib.Path, output_dir: pathlib.Path) -> None: :param search_dir: starting location of recursive search :param output_dir: path to output directory (will be created if it doesn't exist) - :return: """ # Indexing files to be checked for matching MD5 checksums @@ -100,7 +98,7 @@ def main(argv: Optional[List[str]] = None) -> None: if not search_directory.exists(): raise FileNotFoundError("Search directory does not exist..") - elif not search_directory.is_dir(): + if not search_directory.is_dir(): raise NotADirectoryError("Search directory needs to be a directory..") organize(search_dir=search_directory, output_dir=output_directory) diff --git a/libretro_finder/utils.py b/libretro_finder/utils.py index 6bfee9a..29963aa 100644 --- a/libretro_finder/utils.py +++ b/libretro_finder/utils.py @@ -2,12 +2,13 @@ import concurrent.futures import hashlib import pathlib -from typing import Tuple, Optional, List, Union -from tqdm import tqdm -import numpy as np -import vdf +from typing import Tuple, Optional, List import platform from string import ascii_uppercase +from tqdm import tqdm +import numpy as np +import vdf # type: ignore + # not expecting BIOS files over 15mb MAX_BIOS_BYTES = 15728640 @@ -34,7 +35,7 @@ def recursive_hash( :param directory: Starting directory for the glob pattern matching :param glob: The glob pattern to match files. Defaults to "*". - :return: An array with the file_paths to selected files and an array with the corresponding MD5 hashes + :return: array with file_paths to selected files and an array with corresponding MD5 hashes """ file_paths = list(directory.rglob(pattern=glob)) @@ -65,8 +66,8 @@ def match_arrays( :param array_a: The first array to compare. :param array_b: The second array to compare. - :return: A tuple of three numpy arrays: unique matching values, indices of the matching values in - array_a and indices of the matching values in array_b. + :return: A tuple of three numpy arrays: unique matching values, indices of the matching values + in array_a and indices of the matching values in array_b. """ # expecting 1D arrays @@ -123,10 +124,10 @@ def find_retroarch() -> Optional[pathlib.Path]: env_vars = ["PROGRAMFILES(X86)", "PROGRAMFILES"] for env_var in env_vars: - env_var = os.environ.get(env_var) - if not env_var: + env_value = os.environ.get(env_var) + if not env_value: continue - env_path = pathlib.Path(env_var) + env_path = pathlib.Path(env_value) if env_path.exists(): paths_to_check.append(env_path) @@ -166,7 +167,7 @@ def find_retroarch() -> Optional[pathlib.Path]: # checking for retroarch/system (one level down) for path_to_check in paths_to_check: - # glob is needed for inconsistent parent naming (e.g. RetroArch-Win32, RetroArch-Win64, retroarch) + # glob is needed for inconsistent parent naming (e.g. RetroArch-Win32, retroarch) for path in path_to_check.glob(system_glob): return path return None diff --git a/poetry.lock b/poetry.lock index 425cdce..fae7830 100644 --- a/poetry.lock +++ b/poetry.lock @@ -446,6 +446,22 @@ sql-other = ["SQLAlchemy (>=1.4.16)"] test = ["hypothesis (>=6.34.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.6.3)"] +[[package]] +name = "pandas-stubs" +version = "2.0.2.230605" +description = "Type annotations for pandas" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pandas_stubs-2.0.2.230605-py3-none-any.whl", hash = "sha256:39106b602f3cb6dc5f728b84e1b32bde6ecf41ee34ee714c66228009609fbada"}, + {file = "pandas_stubs-2.0.2.230605.tar.gz", hash = "sha256:624c7bb06d38145a44b61be459ccd19b038e0bf20364a025ecaab78fea65e858"}, +] + +[package.dependencies] +numpy = ">=1.24.3" +types-pytz = ">=2022.1.1" + [[package]] name = "pathspec" version = "0.11.1" @@ -841,6 +857,30 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] +[[package]] +name = "types-pytz" +version = "2023.3.0.0" +description = "Typing stubs for pytz" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "types-pytz-2023.3.0.0.tar.gz", hash = "sha256:ecdc70d543aaf3616a7e48631543a884f74205f284cefd6649ddf44c6a820aac"}, + {file = "types_pytz-2023.3.0.0-py3-none-any.whl", hash = "sha256:4fc2a7fbbc315f0b6630e0b899fd6c743705abe1094d007b0e612d10da15e0f3"}, +] + +[[package]] +name = "types-tqdm" +version = "4.65.0.2" +description = "Typing stubs for tqdm" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "types-tqdm-4.65.0.2.tar.gz", hash = "sha256:ad07ee08e758cad04299543b2586ef1d3fd5a10c54271457de13e0cba009cc5d"}, + {file = "types_tqdm-4.65.0.2-py3-none-any.whl", hash = "sha256:956d92e921651309ffe36a783cc10d41d753f107c84e82d84373c84d68737246"}, +] + [[package]] name = "typing-extensions" version = "4.7.1" @@ -996,4 +1036,4 @@ six = "*" [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.13" -content-hash = "d32e3cc909ccd2fc2758726be5fba2cc9988663ff7b9fe7287c2ae1fd90c9eb8" +content-hash = "4477a64438c7401c2f2a678dcf4cdebe36371aac2291fe42066c0d154692cdca" diff --git a/pyproject.toml b/pyproject.toml index 934165e..38ebfcc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "libretro-finder" -version = "0.2.1" -description = "Command line utility that looks for specific BIOS files for libretro cores and, if found, refactors them to the expected format (i.e. name and directory structure)." +version = "0.2.2" +description = "Simple tool that finds and prepares your BIOS files for usage with Libretro (or its RetroArch frontend)." authors = ["Jasper Siebring "] license = "GNU General Public License v3.0" homepage = "https://github.com/jaspersiebring/libretro_finder" @@ -29,10 +29,12 @@ black = "^23.7.0" mypy = "^1.4.1" pyinstaller = "^5.13.0" pytest-mock = "^3.11.1" +pandas-stubs = "^2.0.2.230605" +types-tqdm = "^4.65.0.2" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.pylint.'MESSAGES CONTROL'] -disable = "C0114" \ No newline at end of file +disable = "C0114, R0912, R0914" \ No newline at end of file diff --git a/tests/fixtures.py b/tests/fixtures.py index 5e4a446..dd06009 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -3,7 +3,6 @@ import os import pathlib from typing import Tuple -import tempfile import pandas as pd import pytest @@ -17,10 +16,10 @@ @pytest.fixture(scope="function") def setup_files(tmp_path_factory: TempPathFactory) -> Tuple[pathlib.Path, pd.DataFrame]: """ - Pytest fixture that creates a temporary directory, populates it with fake BIOS files and - returns the path to said directory to be used in tests that expect BIOS files. The function - also updates the reference pandas dataFrame with the CRC32, MD5, and SHA1 hashes of the - dummy files (needed since hashes for the dummy files won't match the checksums for the actual + Pytest fixture that creates a temporary directory, populates it with fake BIOS files and + returns the path to said directory to be used in tests that expect BIOS files. The function + also updates the reference pandas dataFrame with the CRC32, MD5, and SHA1 hashes of the + dummy files (needed since hashes for the dummy files won't match the checksums for the actual BIOS files) :param tmp_path_factory: A pytest fixture for creating temporary directories. diff --git a/tests/test_main.py b/tests/test_main.py index 556b486..7433b98 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,22 +1,29 @@ -import os +# pylint: disable=redefined-outer-name import pathlib -import stat import pytest import numpy as np -from pytest import MonkeyPatch, TempdirFactory, TempPathFactory -from pytest_mock import MockerFixture -from pytest_mock import mocker +from pytest import MonkeyPatch +from pytest_mock import MockerFixture, mocker # pylint: disable=unused-import from libretro_finder.main import organize, main from libretro_finder.utils import hash_file from tests import TEST_SAMPLE_SIZE -from tests.fixtures import setup_files +from tests.fixtures import setup_files # pylint: disable=unused-import -class Test_organize: +class TestOrganize: + """Bundle of pytest asserts for main.organize""" + def test_matching( self, setup_files, tmp_path: pathlib.Path, monkeypatch: MonkeyPatch ) -> None: + """main.organize with (only) matching files + + :param setup_files: A pytest fixture that generates fake BIOS files and reference dataframe + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + :param monkeypatch: A pytest fixture that allows us to set certain testing conditions + """ + bios_dir, bios_lut = setup_files assert bios_dir.exists() @@ -55,7 +62,12 @@ def test_matching( assert np.all(np.isin(bios_lut["name"].values, output_names)) def test_non_matching(self, setup_files, tmp_path: pathlib.Path) -> None: - # pretty much matching but we don't monkeypatch so we're comparing different hashes + """main.organize without matching files + + :param setup_files: A pytest fixture that generates fake BIOS files and reference dataframe + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + """ + # same as 'matching' test but without monkeypatching (i.e. different hashes so no matches) bios_dir, _ = setup_files assert bios_dir.exists() @@ -80,6 +92,11 @@ def test_non_matching(self, setup_files, tmp_path: pathlib.Path) -> None: assert len(list(output_dir.rglob("*"))) == 0 def test_empty(self, tmp_path: pathlib.Path) -> None: + """main.organize with empty search_dir + + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + """ + input_dir = tmp_path / "input" output_dir = tmp_path / "output" input_dir.mkdir() @@ -95,12 +112,14 @@ def test_empty(self, tmp_path: pathlib.Path) -> None: organize(search_dir=input_dir, output_dir=output_dir) assert len(list(output_dir.rglob("*"))) == 0 - def test_same_input( - self, setup_files, monkeypatch: MonkeyPatch - ) -> None: - # organize but with (prepopulated) bios_dir as input and output - # verifies if non-additive + def test_same_input(self, setup_files, monkeypatch: MonkeyPatch) -> None: + """main.organize with shared input for search_dir and output_dir (verifies if non-additive) + + :param setup_files: A pytest fixture that generates fake BIOS files and reference dataframe + :param monkeypatch: A pytest fixture that allows us to set certain testing conditions + """ + # organize but with (prepopulated) bios_dir as input and output bios_dir, bios_lut = setup_files assert bios_dir.exists() @@ -131,10 +150,18 @@ def test_same_input( assert np.all(np.isin(bios_lut["name"].values, output_names)) -class Test_main: +class TestMain: + """Bundle of pytest asserts for main.main""" + def test_main(self, tmp_path: pathlib.Path, mocker: MockerFixture): + """main.main with valid input + + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + :param mocker: A pytest fixture that mocks specific objects for testing purposes + """ + # Mocking the organize function to prevent actual file operations - mock_organize = mocker.patch('libretro_finder.main.organize') + mock_organize = mocker.patch("libretro_finder.main.organize") search_dir = tmp_path / "search" output_dir = tmp_path / "output" @@ -143,17 +170,29 @@ def test_main(self, tmp_path: pathlib.Path, mocker: MockerFixture): argv = [str(search_dir), str(output_dir)] main(argv) - mock_organize.assert_called_once_with(search_dir=search_dir, output_dir=output_dir) + mock_organize.assert_called_once_with( + search_dir=search_dir, output_dir=output_dir + ) def test_main_search_directory_not_exists(self, tmp_path: pathlib.Path): + """main.main with non-existent search_dir + + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + """ + output_dir = tmp_path / "output" output_dir.mkdir() - argv = ['/path/to/nonexistent/search', str(output_dir)] + argv = ["/path/to/nonexistent/search", str(output_dir)] with pytest.raises(FileNotFoundError): main(argv) def test_main_search_directory_not_directory(self, tmp_path: pathlib.Path): + """main.main with file as search_dir + + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + """ + file_path = tmp_path / "search.txt" output_dir = tmp_path / "output" file_path.touch() @@ -161,4 +200,4 @@ def test_main_search_directory_not_directory(self, tmp_path: pathlib.Path): argv = [str(file_path), str(output_dir)] with pytest.raises(NotADirectoryError): - main(argv) \ No newline at end of file + main(argv) diff --git a/tests/test_utils.py b/tests/test_utils.py index bc47c44..939910a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,3 +1,4 @@ +# pylint: disable=redefined-outer-name import hashlib import os import pathlib @@ -6,19 +7,26 @@ import numpy as np import pandas as pd import pytest -from pytest import TempdirFactory, TempPathFactory from libretro_finder.utils import hash_file, match_arrays, recursive_hash from tests import TEST_BYTES, TEST_SAMPLE_SIZE -from tests.fixtures import setup_files +from tests.fixtures import setup_files # pylint: disable=unused-import def test_libretro_meta_import(): - from config import SYSTEMS + """verifies that (remote) libretro-database can pulled, parsed and dumped to pandas DataFrame""" + from config import SYSTEMS # pylint: disable=W0611,C0415 -class Test_hash_file: +class TestHashFile: + """Bundle of pytest asserts for utils.hash_file""" + def test_existing(self, tmp_path: pathlib.Path) -> None: + """utils.hash_file with existing input + + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + """ + file_path = tmp_path / "some_file" random_bytes = os.urandom(TEST_BYTES) @@ -27,14 +35,25 @@ def test_existing(self, tmp_path: pathlib.Path) -> None: _ = hash_file(file_path) def test_nonexistent(self, tmp_path: pathlib.Path) -> None: + """utils.hash_file with non-existing input + + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + """ + file_path = tmp_path / "some_file" with pytest.raises(FileNotFoundError): hash_file(file_path) -class Test_recursive_hash: +class TestRecursiveHash: + """Bundle of pytest asserts for utils.recursive_hash""" + def test_with_fixture(self, setup_files: Tuple[pathlib.Path, pd.DataFrame]) -> None: - """populate tempdir exclusievly with matching files""" + """utils.recursive_hash with (exclusively) matching files + + :param setup_files: A pytest fixture that generates fake BIOS files and reference dataframe + """ + bios_dir, bios_lut = setup_files file_paths, file_hashes = recursive_hash(directory=bios_dir, glob="*") @@ -47,12 +66,17 @@ def test_with_fixture(self, setup_files: Tuple[pathlib.Path, pd.DataFrame]) -> N assert np.all(np.isin(file_names, bios_lut["name"].values)) # type: ignore index_a, index_b = np.where( - file_names.reshape(1, -1) == bios_lut["name"].values.reshape(-1, 1) + file_names.reshape(1, -1) == bios_lut["name"].values.reshape(-1, 1) # type: ignore ) assert np.array_equal(file_names[index_b], bios_lut["name"].values[index_a]) assert np.array_equal(file_hashes[index_b], bios_lut["md5"].values[index_a]) def test_without_fixture(self, tmp_path: pathlib.Path) -> None: + """utils.recursive_hash without matching files + + :param tmp_path: A pytest fixture that creates a temporary directory unique to this test + """ + temp_output_dir = tmp_path / "rhash" temp_output_dir.mkdir() @@ -61,8 +85,9 @@ def test_without_fixture(self, tmp_path: pathlib.Path) -> None: input_paths = [] input_hashes = [] - for i in range(len(file_names)): - temp_path = temp_output_dir / file_names[i] + + for i, file_name in enumerate(file_names): + temp_path = temp_output_dir / file_name md5 = hashlib.md5(file_bytes[i]).hexdigest() input_hashes.append(md5) input_paths.append(temp_path) @@ -77,12 +102,16 @@ def test_without_fixture(self, tmp_path: pathlib.Path) -> None: assert np.unique(output_hashes).size == output_hashes.size assert len(input_paths) == len(output_paths) - assert np.all(np.isin(input_paths, output_paths)) + assert np.all(np.isin(input_paths, output_paths)) # type: ignore assert np.all(np.isin(input_hashes, output_hashes)) -class Test_match_arrays: +class TestMatchArrays: + """Bundle of pytest asserts for utils.match_arrays""" + def test_overlap(self): + """utils.match_arrays with partial overlap""" + array_a = np.array([0, 1, 2, 3, 4, 5]) array_b = np.array([5, 2, 5, 16]) @@ -95,6 +124,8 @@ def test_overlap(self): assert np.array_equal(array_a[indices_a], array_b[indices_b]) def test_no_overlap(self): + """utils.match_arrays with no overlap""" + array_a = np.array([0, 1, 2, 3, 4, 5]) array_b = np.array([9, 9, 7, 16]) @@ -107,24 +138,26 @@ def test_no_overlap(self): assert not np.any(indices_b) def test_type(self): + """utils.match_arrays with invalid input type""" + array_a = [0, 1, 2, 3, 4, 5] array_b = np.array([5, 2, 5, 16]) with pytest.raises(AttributeError): - matching_values, indices_a, indices_b = match_arrays( - array_a=array_a, array_b=array_b - ) + _ = match_arrays(array_a=array_a, array_b=array_b) def test_shape(self): + """utils.match_arrays with input arrays of invalid shape""" + array_a = np.array([[0, 1, 2, 3, 4, 5]]) array_b = np.array([[5, 2, 5, 16]]) with pytest.raises(ValueError): - matching_values, indices_a, indices_b = match_arrays( - array_a=array_a, array_b=array_b - ) + _ = match_arrays(array_a=array_a, array_b=array_b) def test_nptype(self): + """utils.match_arrays with valid non-numerical arrays as input""" + array_a = np.array(["a", "b"]) array_b = np.array(["c", "a", "a", "x", "b"]) From 7697bbcfd1ae742b7133c77bdf149c5c7f13337c Mon Sep 17 00:00:00 2001 From: Jasper Date: Tue, 8 Aug 2023 20:21:57 +0200 Subject: [PATCH 02/19] Added initial workflow files for Github Actions --- .github/workflows/github-actions-demo.yaml | 18 ++++++++ .github/workflows/poetry_build.yaml | 51 ++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 .github/workflows/github-actions-demo.yaml create mode 100644 .github/workflows/poetry_build.yaml diff --git a/.github/workflows/github-actions-demo.yaml b/.github/workflows/github-actions-demo.yaml new file mode 100644 index 0000000..e007988 --- /dev/null +++ b/.github/workflows/github-actions-demo.yaml @@ -0,0 +1,18 @@ +name: GitHub Actions Demo +run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 +on: [push] +jobs: + Explore-GitHub-Actions: + runs-on: ubuntu-latest + steps: + - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" + - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + - name: Check out repository code + uses: actions/checkout@v3 + - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." + - run: echo "🖥️ The workflow is now ready to test your code on the runner." + - name: List files in the repository + run: | + ls ${{ github.workspace }} + - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/.github/workflows/poetry_build.yaml b/.github/workflows/poetry_build.yaml new file mode 100644 index 0000000..d0a059c --- /dev/null +++ b/.github/workflows/poetry_build.yaml @@ -0,0 +1,51 @@ +name: Poetry testing +on: [push] +jobs: + Poetry-Build: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: List files in the repository + run: | + ls ${{ github.workspace }} + - name: Echo current working directory + run: | + pwd + - name: Installing Python + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y \ + dpkg-dev \ + build-essential \ + freeglut3-dev \ + libgl1-mesa-dev \ + libglu1-mesa-dev \ + libgstreamer-plugins-base1.0-dev \ + libgtk-3-dev \ + libjpeg-dev \ + libnotify-dev \ + libpng-dev \ + libsdl2-dev \ + libsm-dev \ + libunwind-dev \ + libtiff-dev \ + libwebkit2gtk-4.0-dev \ + libxtst-dev \ + libgtk2.0-dev + - name: Installing Poetry + uses: abatilo/actions-poetry@v2 + with: + poetry-version: 1.4 + - name: Installing Poetry environment + run: poetry install + - name: Running pytest + run: poetry run pytest -v + - name: Running mypy + run: poetry run mypy libretro_finder/ config/ tests/ + - name: Running pylint + run: poetry run pylint libretro_finder/ config/ tests/ From 6e91b8fd23a5e6ed21587e70c25c9a033d485f32 Mon Sep 17 00:00:00 2001 From: Jasper Date: Tue, 8 Aug 2023 23:11:17 +0200 Subject: [PATCH 03/19] Added build caching --- .github/workflows/poetry_build.yaml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/poetry_build.yaml b/.github/workflows/poetry_build.yaml index d0a059c..1279a1e 100644 --- a/.github/workflows/poetry_build.yaml +++ b/.github/workflows/poetry_build.yaml @@ -6,16 +6,16 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@v3 - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - name: Echo current working directory - run: | - pwd + - name: Installing Poetry + uses: abatilo/actions-poetry@v2 + with: + poetry-version: 1.4 - name: Installing Python uses: actions/setup-python@v4 with: python-version: 3.8 + cache: poetry + cache-dependency-path: poetry.lock - name: Install dependencies run: | sudo apt update @@ -36,11 +36,7 @@ jobs: libtiff-dev \ libwebkit2gtk-4.0-dev \ libxtst-dev \ - libgtk2.0-dev - - name: Installing Poetry - uses: abatilo/actions-poetry@v2 - with: - poetry-version: 1.4 + libgtk2.0-dev - name: Installing Poetry environment run: poetry install - name: Running pytest From 4fb791d7c523ef2f14d2c05ef6febfadeaae2a33 Mon Sep 17 00:00:00 2001 From: Jasper Date: Tue, 8 Aug 2023 23:21:51 +0200 Subject: [PATCH 04/19] Dropped abatilo/actions-poetry@v2 for poetry install, now just pipx install poetry --- .github/workflows/poetry_build.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/poetry_build.yaml b/.github/workflows/poetry_build.yaml index 1279a1e..a3a0d95 100644 --- a/.github/workflows/poetry_build.yaml +++ b/.github/workflows/poetry_build.yaml @@ -7,9 +7,7 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Installing Poetry - uses: abatilo/actions-poetry@v2 - with: - poetry-version: 1.4 + run: pipx install poetry - name: Installing Python uses: actions/setup-python@v4 with: From 3b913e2fc8bb67ef6d60719a877cb4948b4101f4 Mon Sep 17 00:00:00 2001 From: Jasper Date: Tue, 8 Aug 2023 23:34:46 +0200 Subject: [PATCH 05/19] Dropped dependency path This reverts commit 364e06c11f4be9408e808fb6849baaff4cff6920. --- .github/workflows/poetry_build.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/poetry_build.yaml b/.github/workflows/poetry_build.yaml index a3a0d95..f12f6ea 100644 --- a/.github/workflows/poetry_build.yaml +++ b/.github/workflows/poetry_build.yaml @@ -6,14 +6,13 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@v3 - - name: Installing Poetry + - name: Installing Poetry globally run: pipx install poetry - name: Installing Python uses: actions/setup-python@v4 with: python-version: 3.8 cache: poetry - cache-dependency-path: poetry.lock - name: Install dependencies run: | sudo apt update From f24462845efff31202a0e245028f29cf099e0210 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 00:41:08 +0200 Subject: [PATCH 06/19] Revert dummy test and added conditional poetry build step --- .github/workflows/poetry_build.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/poetry_build.yaml b/.github/workflows/poetry_build.yaml index f12f6ea..b95ebcb 100644 --- a/.github/workflows/poetry_build.yaml +++ b/.github/workflows/poetry_build.yaml @@ -37,8 +37,17 @@ jobs: - name: Installing Poetry environment run: poetry install - name: Running pytest + id: pytest run: poetry run pytest -v - name: Running mypy + id: mypy run: poetry run mypy libretro_finder/ config/ tests/ - name: Running pylint + id: pylint run: poetry run pylint libretro_finder/ config/ tests/ + - name: Poetry Build + id: build + run: poetry build + if: steps.pytest.outcome == 'success' && steps.mpy.outcome == 'success' && steps.pylint.outcome == 'success' + - name: Show artifacts + run: ls dist/ \ No newline at end of file From f9744c892e640f2bef228815ebe85de3a0790182 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 00:45:26 +0200 Subject: [PATCH 07/19] Changed conditional --- .github/workflows/poetry_build.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/poetry_build.yaml b/.github/workflows/poetry_build.yaml index b95ebcb..72bdaa7 100644 --- a/.github/workflows/poetry_build.yaml +++ b/.github/workflows/poetry_build.yaml @@ -48,6 +48,7 @@ jobs: - name: Poetry Build id: build run: poetry build - if: steps.pytest.outcome == 'success' && steps.mpy.outcome == 'success' && steps.pylint.outcome == 'success' + if: steps.pytest.outcome == 'success' - name: Show artifacts - run: ls dist/ \ No newline at end of file + run: ls dist/ + if: steps.build.outcome == 'success' \ No newline at end of file From 771e21c3ad8a367a8197ada0dd093fc3289527e1 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 00:53:26 +0200 Subject: [PATCH 08/19] Added code coverage check, stage and dep --- .github/workflows/poetry_build.yaml | 3 + poetry.lock | 97 ++++++++++++++++++++++++++++- pyproject.toml | 1 + 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/.github/workflows/poetry_build.yaml b/.github/workflows/poetry_build.yaml index 72bdaa7..3c1753b 100644 --- a/.github/workflows/poetry_build.yaml +++ b/.github/workflows/poetry_build.yaml @@ -45,6 +45,9 @@ jobs: - name: Running pylint id: pylint run: poetry run pylint libretro_finder/ config/ tests/ + - name: Checking code coverage + id: coverage + run: poetry run pytest --cov=config --cov=libretro_finder - name: Poetry Build id: build run: poetry build diff --git a/poetry.lock b/poetry.lock index fae7830..9cc48a2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -117,6 +117,82 @@ files = [ {file = "colored-1.4.4.tar.gz", hash = "sha256:04ff4d4dd514274fe3b99a21bb52fb96f2688c01e93fba7bef37221e7cb56ce0"}, ] +[[package]] +name = "coverage" +version = "7.2.7" +description = "Code coverage measurement for Python" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, + {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, + {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, + {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, + {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, + {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, + {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, + {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, + {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, + {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, + {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, + {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, + {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, + {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, + {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, + {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, + {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, + {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, + {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, + {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, + {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, + {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, + {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, + {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + [[package]] name = "dill" version = "0.3.7" @@ -726,6 +802,25 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-cov" +version = "4.1.0" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + [[package]] name = "pytest-mock" version = "3.11.1" @@ -1036,4 +1131,4 @@ six = "*" [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.13" -content-hash = "4477a64438c7401c2f2a678dcf4cdebe36371aac2291fe42066c0d154692cdca" +content-hash = "c85aecbb131d55e7e08808afd66c161ab98f2ad62a1686bbb3f664bb76479462" diff --git a/pyproject.toml b/pyproject.toml index 38ebfcc..b97365b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ pyinstaller = "^5.13.0" pytest-mock = "^3.11.1" pandas-stubs = "^2.0.2.230605" types-tqdm = "^4.65.0.2" +pytest-cov = "^4.1.0" [build-system] requires = ["poetry-core"] From 917b881f0d629a482f8f7fbdaccddda90caa9ec7 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 01:18:52 +0200 Subject: [PATCH 09/19] Dropped dummy workflow and added workflow with alternative caching (partial key matching) --- .github/workflows/github-actions-demo.yaml | 18 ------ .github/workflows/poetry_caching.yaml | 64 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 18 deletions(-) delete mode 100644 .github/workflows/github-actions-demo.yaml create mode 100644 .github/workflows/poetry_caching.yaml diff --git a/.github/workflows/github-actions-demo.yaml b/.github/workflows/github-actions-demo.yaml deleted file mode 100644 index e007988..0000000 --- a/.github/workflows/github-actions-demo.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: GitHub Actions Demo -run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 -on: [push] -jobs: - Explore-GitHub-Actions: - runs-on: ubuntu-latest - steps: - - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - name: Check out repository code - uses: actions/checkout@v3 - - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/.github/workflows/poetry_caching.yaml b/.github/workflows/poetry_caching.yaml new file mode 100644 index 0000000..9a019bb --- /dev/null +++ b/.github/workflows/poetry_caching.yaml @@ -0,0 +1,64 @@ +name: Poetry caching +on: [push] +jobs: + Poetry-Build: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Installing Poetry globally + run: pipx install poetry + - name: Installing Python + id: setup-python + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - uses: actions/cache@v3 + with: + path: /home/runner/.cache/pypoetry/virtualenvs + key: poetry-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} + restore-keys: | + poetry-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} + poetry-${{ steps.setup-python.outputs.python-version }}- + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y \ + dpkg-dev \ + build-essential \ + freeglut3-dev \ + libgl1-mesa-dev \ + libglu1-mesa-dev \ + libgstreamer-plugins-base1.0-dev \ + libgtk-3-dev \ + libjpeg-dev \ + libnotify-dev \ + libpng-dev \ + libsdl2-dev \ + libsm-dev \ + libunwind-dev \ + libtiff-dev \ + libwebkit2gtk-4.0-dev \ + libxtst-dev \ + libgtk2.0-dev + - name: Installing Poetry environment + run: poetry install + - name: Running pytest + id: pytest + run: poetry run pytest -v + - name: Running mypy + id: mypy + run: poetry run mypy libretro_finder/ config/ tests/ + - name: Running pylint + id: pylint + run: poetry run pylint libretro_finder/ config/ tests/ + - name: Checking code coverage + id: coverage + run: poetry run pytest --cov=config --cov=libretro_finder + - name: Poetry Build + id: build + run: poetry build + if: steps.pytest.outcome == 'success' + - name: Show artifacts + run: ls dist/ + if: steps.build.outcome == 'success' \ No newline at end of file From 13a4cc0e48366f9a4fb4b9a17b1e6205945c6939 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 02:20:28 +0200 Subject: [PATCH 10/19] Added release workflow with PYPI auth --- .github/workflows/poetry_release.yaml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/poetry_release.yaml diff --git a/.github/workflows/poetry_release.yaml b/.github/workflows/poetry_release.yaml new file mode 100644 index 0000000..0067ab9 --- /dev/null +++ b/.github/workflows/poetry_release.yaml @@ -0,0 +1,67 @@ +name: Publish package +on: + push: + branches: + - main + +jobs: + Poetry-Build: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Installing Poetry globally + run: pipx install poetry + - name: Installing Python + uses: actions/setup-python@v4 + with: + python-version: 3.8 + cache: poetry + - name: Getting release version + run: echo "VERSION=$(poetry version | awk '{print $2}')" >> $GITHUB_ENV + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y \ + dpkg-dev \ + build-essential \ + freeglut3-dev \ + libgl1-mesa-dev \ + libglu1-mesa-dev \ + libgstreamer-plugins-base1.0-dev \ + libgtk-3-dev \ + libjpeg-dev \ + libnotify-dev \ + libpng-dev \ + libsdl2-dev \ + libsm-dev \ + libunwind-dev \ + libtiff-dev \ + libwebkit2gtk-4.0-dev \ + libxtst-dev \ + libgtk2.0-dev + - name: Installing Poetry environment + run: poetry install + - name: Running pytest + id: pytest + run: poetry run pytest -v + - name: Running mypy + id: mypy + run: poetry run mypy libretro_finder/ config/ tests/ + - name: Running pylint + id: pylint + run: poetry run pylint libretro_finder/ config/ tests/ + - name: Checking code coverage + id: coverage + run: poetry run pytest --cov=config --cov=libretro_finder + - name: Poetry Build + id: build + run: poetry build + if: steps.pytest.outcome == 'success' + - name: Authorize GitHub Actions to publish on PYPIPublish build + run: poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }} + if: steps.build.outcome == 'success' + - name: Publish build + run: poetry publish + if: steps.build.outcome == 'success' + \ No newline at end of file From 0f8b116ca17fd49ed8495c3016411883b8d30e4f Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 02:26:28 +0200 Subject: [PATCH 11/19] Checking partial restore_key matching with dummy dep --- poetry.lock | 110 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 9cc48a2..3ce3c76 100644 --- a/poetry.lock +++ b/poetry.lock @@ -79,6 +79,30 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "build" +version = "0.10.0" +description = "A simple, correct Python build frontend" +category = "dev" +optional = false +python-versions = ">= 3.7" +files = [ + {file = "build-0.10.0-py3-none-any.whl", hash = "sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171"}, + {file = "build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "os_name == \"nt\""} +packaging = ">=19.0" +pyproject_hooks = "*" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[package.extras] +docs = ["furo (>=2021.08.31)", "sphinx (>=4.0,<5.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)"] +test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "toml (>=0.10.0)", "wheel (>=0.36.0)"] +typing = ["importlib-metadata (>=5.1)", "mypy (==0.991)", "tomli", "typing-extensions (>=3.7.4.3)"] +virtualenv = ["virtualenv (>=20.0.35)"] + [[package]] name = "click" version = "8.1.6" @@ -208,6 +232,18 @@ files = [ [package.extras] graph = ["objgraph (>=1.7.2)"] +[[package]] +name = "docutils" +version = "0.20.1" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] + [[package]] name = "exceptiongroup" version = "1.1.2" @@ -242,6 +278,26 @@ psutil = ">=5.4.2" pygtrie = ">=2.3.3" wxpython = ">=4.1.0" +[[package]] +name = "importlib-metadata" +version = "6.8.0" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -779,6 +835,21 @@ typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\"" spelling = ["pyenchant (>=3.2,<4.0)"] testutils = ["gitpython (>3)"] +[[package]] +name = "pyproject-hooks" +version = "1.0.0" +description = "Wrappers to call pyproject.toml-based build backend hooks." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"}, + {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"}, +] + +[package.dependencies] +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + [[package]] name = "pytest" version = "7.4.0" @@ -802,6 +873,27 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-checkdocs" +version = "2.10.1" +description = "check the README when running tests" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-checkdocs-2.10.1.tar.gz", hash = "sha256:393868583f2d0314f8c5828fd94f7d28699543f6a0a925356d7e274e2952297e"}, + {file = "pytest_checkdocs-2.10.1-py3-none-any.whl", hash = "sha256:f069d6408633697023298ebf66c9bb1cb915c3ae5f047457b507229a4784e153"}, +] + +[package.dependencies] +build = "*" +docutils = ">=0.15" +importlib-metadata = {version = ">=4", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "types-docutils"] + [[package]] name = "pytest-cov" version = "4.1.0" @@ -1128,7 +1220,23 @@ numpy = {version = "*", markers = "python_version >= \"3.0\" and python_version pillow = "*" six = "*" +[[package]] +name = "zipp" +version = "3.16.2" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, + {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.13" -content-hash = "c85aecbb131d55e7e08808afd66c161ab98f2ad62a1686bbb3f664bb76479462" +content-hash = "61c96d4c569072063bbd65e965dedb214919ab7455e8e6aa77d277795025cf46" diff --git a/pyproject.toml b/pyproject.toml index b97365b..2b0b04a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,7 @@ pytest-mock = "^3.11.1" pandas-stubs = "^2.0.2.230605" types-tqdm = "^4.65.0.2" pytest-cov = "^4.1.0" +pytest-checkdocs = "^2.10.1" [build-system] requires = ["poetry-core"] From 18453ab2d0a903a77d9ed862b7bb6824c7604a20 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 02:53:51 +0200 Subject: [PATCH 12/19] Github Actions refactor (now QC is triggered by PR activity and publish only on pushes to protected main) --- .../{poetry_build.yaml => manual_build.yaml} | 5 +++-- .github/workflows/poetry_release.yaml | 5 ++--- ...{poetry_caching.yaml => quality_control.yaml} | 16 +++++----------- 3 files changed, 10 insertions(+), 16 deletions(-) rename .github/workflows/{poetry_build.yaml => manual_build.yaml} (97%) rename .github/workflows/{poetry_caching.yaml => quality_control.yaml} (87%) diff --git a/.github/workflows/poetry_build.yaml b/.github/workflows/manual_build.yaml similarity index 97% rename from .github/workflows/poetry_build.yaml rename to .github/workflows/manual_build.yaml index 3c1753b..845c0fe 100644 --- a/.github/workflows/poetry_build.yaml +++ b/.github/workflows/manual_build.yaml @@ -1,5 +1,6 @@ -name: Poetry testing -on: [push] +name: Manual build +on: + workflow_dispatch: jobs: Poetry-Build: runs-on: ubuntu-latest diff --git a/.github/workflows/poetry_release.yaml b/.github/workflows/poetry_release.yaml index 0067ab9..a9c1d34 100644 --- a/.github/workflows/poetry_release.yaml +++ b/.github/workflows/poetry_release.yaml @@ -1,11 +1,10 @@ -name: Publish package +name: Publish to PYPI on: push: branches: - main - jobs: - Poetry-Build: + Poetry-Release: runs-on: ubuntu-latest steps: - name: Check out repository code diff --git a/.github/workflows/poetry_caching.yaml b/.github/workflows/quality_control.yaml similarity index 87% rename from .github/workflows/poetry_caching.yaml rename to .github/workflows/quality_control.yaml index 9a019bb..ce33ba3 100644 --- a/.github/workflows/poetry_caching.yaml +++ b/.github/workflows/quality_control.yaml @@ -1,7 +1,8 @@ -name: Poetry caching -on: [push] +name: Quality control (pytest, mpy, pylint and cov) +on: + pull_request: # Pull request events (default: open, synchronized, reopened) in any branch triggers the workflow. jobs: - Poetry-Build: + Quality-Control: runs-on: ubuntu-latest steps: - name: Check out repository code @@ -54,11 +55,4 @@ jobs: run: poetry run pylint libretro_finder/ config/ tests/ - name: Checking code coverage id: coverage - run: poetry run pytest --cov=config --cov=libretro_finder - - name: Poetry Build - id: build - run: poetry build - if: steps.pytest.outcome == 'success' - - name: Show artifacts - run: ls dist/ - if: steps.build.outcome == 'success' \ No newline at end of file + run: poetry run pytest --cov=config --cov=libretro_finder \ No newline at end of file From 672f8b66202e75cb73b0a577f5be43be822e0e32 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 12:42:51 +0200 Subject: [PATCH 13/19] Added cov fail and step echoes (temp) --- .github/workflows/quality_control.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality_control.yaml b/.github/workflows/quality_control.yaml index ce33ba3..b1f4114 100644 --- a/.github/workflows/quality_control.yaml +++ b/.github/workflows/quality_control.yaml @@ -55,4 +55,10 @@ jobs: run: poetry run pylint libretro_finder/ config/ tests/ - name: Checking code coverage id: coverage - run: poetry run pytest --cov=config --cov=libretro_finder \ No newline at end of file + run: poetry run pytest --cov=config --cov=libretro_finder --cov-fail-under=75 + - name: echo step status + run: | + echo ${{ steps.pytest.outcome }} + echo ${{ steps.mypy.outcome }} + echo ${{ steps.pylint.outcome }} + echo ${{ steps.coverage.outcome }} \ No newline at end of file From 9842f83a8631b7f28bb8a3326580111c3efb3736 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 12:57:01 +0200 Subject: [PATCH 14/19] Added publication conditional (testpypi) --- .github/workflows/quality_control.yaml | 27 +++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/.github/workflows/quality_control.yaml b/.github/workflows/quality_control.yaml index b1f4114..0c27390 100644 --- a/.github/workflows/quality_control.yaml +++ b/.github/workflows/quality_control.yaml @@ -21,6 +21,7 @@ jobs: restore-keys: | poetry-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} poetry-${{ steps.setup-python.outputs.python-version }}- + - name: Install dependencies run: | sudo apt update @@ -42,6 +43,7 @@ jobs: libwebkit2gtk-4.0-dev \ libxtst-dev \ libgtk2.0-dev + - name: Installing Poetry environment run: poetry install - name: Running pytest @@ -52,13 +54,24 @@ jobs: run: poetry run mypy libretro_finder/ config/ tests/ - name: Running pylint id: pylint - run: poetry run pylint libretro_finder/ config/ tests/ + run: poetry run pylint libretro_finder/ config/ tests/ --fail-under=8 - name: Checking code coverage id: coverage run: poetry run pytest --cov=config --cov=libretro_finder --cov-fail-under=75 - - name: echo step status - run: | - echo ${{ steps.pytest.outcome }} - echo ${{ steps.mypy.outcome }} - echo ${{ steps.pylint.outcome }} - echo ${{ steps.coverage.outcome }} \ No newline at end of file + + - name: Build source and .whl archives with Poetry + id: build + run: poetry build + if: steps.pytest.outcome == 'success' && steps.mypy.outcome == 'success' && steps.pylint.outcome == 'success' && steps.coverage.outcome == 'success' + + - name: Authorize GitHub Actions to publish on PYPI + #run: poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }} + run: | + poetry config repositories.test-pypi https://test.pypi.org/legacy/ + poetry config pypi-token.test-pypi ${{ secrets.TESTPYPI_API_TOKEN }} + if: steps.build.outcome == 'success' + - name: Publish on PYPI + #run: poetry publish + run: poetry publish -r test-pypi + if: steps.build.outcome == 'success' + \ No newline at end of file From b22d82447a977553775f3d2726a02d80e130d52f Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 13:49:37 +0200 Subject: [PATCH 15/19] Bundled workflow files in main.yml (with conditional releases). --- .../{quality_control.yaml => main.yml} | 12 ++-- .github/workflows/manual_build.yaml | 58 ---------------- .github/workflows/poetry_release.yaml | 66 ------------------- 3 files changed, 7 insertions(+), 129 deletions(-) rename .github/workflows/{quality_control.yaml => main.yml} (89%) delete mode 100644 .github/workflows/manual_build.yaml delete mode 100644 .github/workflows/poetry_release.yaml diff --git a/.github/workflows/quality_control.yaml b/.github/workflows/main.yml similarity index 89% rename from .github/workflows/quality_control.yaml rename to .github/workflows/main.yml index 0c27390..5aee762 100644 --- a/.github/workflows/quality_control.yaml +++ b/.github/workflows/main.yml @@ -1,8 +1,11 @@ -name: Quality control (pytest, mpy, pylint and cov) +name: Quality control and automated release on: pull_request: # Pull request events (default: open, synchronized, reopened) in any branch triggers the workflow. + push: + branches: + - main # Pushes to main (i.e. after a merged PR) jobs: - Quality-Control: + checks_and_release: runs-on: ubuntu-latest steps: - name: Check out repository code @@ -69,9 +72,8 @@ jobs: run: | poetry config repositories.test-pypi https://test.pypi.org/legacy/ poetry config pypi-token.test-pypi ${{ secrets.TESTPYPI_API_TOKEN }} - if: steps.build.outcome == 'success' + if: steps.build.outcome == 'success' && github.event_name == 'push' - name: Publish on PYPI #run: poetry publish run: poetry publish -r test-pypi - if: steps.build.outcome == 'success' - \ No newline at end of file + if: steps.build.outcome == 'success' && github.event_name == 'push' diff --git a/.github/workflows/manual_build.yaml b/.github/workflows/manual_build.yaml deleted file mode 100644 index 845c0fe..0000000 --- a/.github/workflows/manual_build.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: Manual build -on: - workflow_dispatch: -jobs: - Poetry-Build: - runs-on: ubuntu-latest - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - name: Installing Poetry globally - run: pipx install poetry - - name: Installing Python - uses: actions/setup-python@v4 - with: - python-version: 3.8 - cache: poetry - - name: Install dependencies - run: | - sudo apt update - sudo apt install -y \ - dpkg-dev \ - build-essential \ - freeglut3-dev \ - libgl1-mesa-dev \ - libglu1-mesa-dev \ - libgstreamer-plugins-base1.0-dev \ - libgtk-3-dev \ - libjpeg-dev \ - libnotify-dev \ - libpng-dev \ - libsdl2-dev \ - libsm-dev \ - libunwind-dev \ - libtiff-dev \ - libwebkit2gtk-4.0-dev \ - libxtst-dev \ - libgtk2.0-dev - - name: Installing Poetry environment - run: poetry install - - name: Running pytest - id: pytest - run: poetry run pytest -v - - name: Running mypy - id: mypy - run: poetry run mypy libretro_finder/ config/ tests/ - - name: Running pylint - id: pylint - run: poetry run pylint libretro_finder/ config/ tests/ - - name: Checking code coverage - id: coverage - run: poetry run pytest --cov=config --cov=libretro_finder - - name: Poetry Build - id: build - run: poetry build - if: steps.pytest.outcome == 'success' - - name: Show artifacts - run: ls dist/ - if: steps.build.outcome == 'success' \ No newline at end of file diff --git a/.github/workflows/poetry_release.yaml b/.github/workflows/poetry_release.yaml deleted file mode 100644 index a9c1d34..0000000 --- a/.github/workflows/poetry_release.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: Publish to PYPI -on: - push: - branches: - - main -jobs: - Poetry-Release: - runs-on: ubuntu-latest - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - name: Installing Poetry globally - run: pipx install poetry - - name: Installing Python - uses: actions/setup-python@v4 - with: - python-version: 3.8 - cache: poetry - - name: Getting release version - run: echo "VERSION=$(poetry version | awk '{print $2}')" >> $GITHUB_ENV - - name: Install dependencies - run: | - sudo apt update - sudo apt install -y \ - dpkg-dev \ - build-essential \ - freeglut3-dev \ - libgl1-mesa-dev \ - libglu1-mesa-dev \ - libgstreamer-plugins-base1.0-dev \ - libgtk-3-dev \ - libjpeg-dev \ - libnotify-dev \ - libpng-dev \ - libsdl2-dev \ - libsm-dev \ - libunwind-dev \ - libtiff-dev \ - libwebkit2gtk-4.0-dev \ - libxtst-dev \ - libgtk2.0-dev - - name: Installing Poetry environment - run: poetry install - - name: Running pytest - id: pytest - run: poetry run pytest -v - - name: Running mypy - id: mypy - run: poetry run mypy libretro_finder/ config/ tests/ - - name: Running pylint - id: pylint - run: poetry run pylint libretro_finder/ config/ tests/ - - name: Checking code coverage - id: coverage - run: poetry run pytest --cov=config --cov=libretro_finder - - name: Poetry Build - id: build - run: poetry build - if: steps.pytest.outcome == 'success' - - name: Authorize GitHub Actions to publish on PYPIPublish build - run: poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }} - if: steps.build.outcome == 'success' - - name: Publish build - run: poetry publish - if: steps.build.outcome == 'success' - \ No newline at end of file From 0381b973cc4b097ea8552c9a149abb585ca347e6 Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 13:58:15 +0200 Subject: [PATCH 16/19] Pushes to main now trigger a release on PyPi. Also added a workflow for manually releasing on TestPyPi. --- .github/workflows/main.yml | 8 +--- .github/workflows/test_release.yml | 74 ++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/test_release.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5aee762..5cda024 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -68,12 +68,8 @@ jobs: if: steps.pytest.outcome == 'success' && steps.mypy.outcome == 'success' && steps.pylint.outcome == 'success' && steps.coverage.outcome == 'success' - name: Authorize GitHub Actions to publish on PYPI - #run: poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }} - run: | - poetry config repositories.test-pypi https://test.pypi.org/legacy/ - poetry config pypi-token.test-pypi ${{ secrets.TESTPYPI_API_TOKEN }} + run: poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }} if: steps.build.outcome == 'success' && github.event_name == 'push' - name: Publish on PYPI - #run: poetry publish - run: poetry publish -r test-pypi + run: poetry publish if: steps.build.outcome == 'success' && github.event_name == 'push' diff --git a/.github/workflows/test_release.yml b/.github/workflows/test_release.yml new file mode 100644 index 0000000..02949da --- /dev/null +++ b/.github/workflows/test_release.yml @@ -0,0 +1,74 @@ +name: Build and release on TestPyPi +on: + workflow_dispatch: # Manual trigger (dev) +jobs: + checks_and_release: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Installing Poetry globally + run: pipx install poetry + - name: Installing Python + id: setup-python + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - uses: actions/cache@v3 + with: + path: /home/runner/.cache/pypoetry/virtualenvs + key: poetry-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} + restore-keys: | + poetry-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} + poetry-${{ steps.setup-python.outputs.python-version }}- + + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y \ + dpkg-dev \ + build-essential \ + freeglut3-dev \ + libgl1-mesa-dev \ + libglu1-mesa-dev \ + libgstreamer-plugins-base1.0-dev \ + libgtk-3-dev \ + libjpeg-dev \ + libnotify-dev \ + libpng-dev \ + libsdl2-dev \ + libsm-dev \ + libunwind-dev \ + libtiff-dev \ + libwebkit2gtk-4.0-dev \ + libxtst-dev \ + libgtk2.0-dev + + - name: Installing Poetry environment + run: poetry install + - name: Running pytest + id: pytest + run: poetry run pytest -v + - name: Running mypy + id: mypy + run: poetry run mypy libretro_finder/ config/ tests/ + - name: Running pylint + id: pylint + run: poetry run pylint libretro_finder/ config/ tests/ --fail-under=8 + - name: Checking code coverage + id: coverage + run: poetry run pytest --cov=config --cov=libretro_finder --cov-fail-under=75 + + - name: Build source and .whl archives with Poetry + id: build + run: poetry build + if: steps.pytest.outcome == 'success' && steps.mypy.outcome == 'success' && steps.pylint.outcome == 'success' && steps.coverage.outcome == 'success' + + - name: Authorize GitHub Actions to publish on PYPI + run: | + poetry config repositories.test-pypi https://test.pypi.org/legacy/ + poetry config pypi-token.test-pypi ${{ secrets.TESTPYPI_API_TOKEN }} + if: steps.build.outcome == 'success' + - name: Publish on PYPI + run: poetry publish -r test-pypi + if: steps.build.outcome == 'success' From a338603c388cdb6a8485de2ba6b87cd67bafa85b Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 15:12:35 +0200 Subject: [PATCH 17/19] Dropped pytest-checksdocs dep --- poetry.lock | 110 +------------------------------------------------ pyproject.toml | 1 - 2 files changed, 1 insertion(+), 110 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3ce3c76..9cc48a2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -79,30 +79,6 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] -[[package]] -name = "build" -version = "0.10.0" -description = "A simple, correct Python build frontend" -category = "dev" -optional = false -python-versions = ">= 3.7" -files = [ - {file = "build-0.10.0-py3-none-any.whl", hash = "sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171"}, - {file = "build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "os_name == \"nt\""} -packaging = ">=19.0" -pyproject_hooks = "*" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} - -[package.extras] -docs = ["furo (>=2021.08.31)", "sphinx (>=4.0,<5.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)"] -test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "toml (>=0.10.0)", "wheel (>=0.36.0)"] -typing = ["importlib-metadata (>=5.1)", "mypy (==0.991)", "tomli", "typing-extensions (>=3.7.4.3)"] -virtualenv = ["virtualenv (>=20.0.35)"] - [[package]] name = "click" version = "8.1.6" @@ -232,18 +208,6 @@ files = [ [package.extras] graph = ["objgraph (>=1.7.2)"] -[[package]] -name = "docutils" -version = "0.20.1" -description = "Docutils -- Python Documentation Utilities" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, - {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, -] - [[package]] name = "exceptiongroup" version = "1.1.2" @@ -278,26 +242,6 @@ psutil = ">=5.4.2" pygtrie = ">=2.3.3" wxpython = ">=4.1.0" -[[package]] -name = "importlib-metadata" -version = "6.8.0" -description = "Read metadata from Python packages" -category = "dev" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, - {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -835,21 +779,6 @@ typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\"" spelling = ["pyenchant (>=3.2,<4.0)"] testutils = ["gitpython (>3)"] -[[package]] -name = "pyproject-hooks" -version = "1.0.0" -description = "Wrappers to call pyproject.toml-based build backend hooks." -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"}, - {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"}, -] - -[package.dependencies] -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} - [[package]] name = "pytest" version = "7.4.0" @@ -873,27 +802,6 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] -[[package]] -name = "pytest-checkdocs" -version = "2.10.1" -description = "check the README when running tests" -category = "dev" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-checkdocs-2.10.1.tar.gz", hash = "sha256:393868583f2d0314f8c5828fd94f7d28699543f6a0a925356d7e274e2952297e"}, - {file = "pytest_checkdocs-2.10.1-py3-none-any.whl", hash = "sha256:f069d6408633697023298ebf66c9bb1cb915c3ae5f047457b507229a4784e153"}, -] - -[package.dependencies] -build = "*" -docutils = ">=0.15" -importlib-metadata = {version = ">=4", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "types-docutils"] - [[package]] name = "pytest-cov" version = "4.1.0" @@ -1220,23 +1128,7 @@ numpy = {version = "*", markers = "python_version >= \"3.0\" and python_version pillow = "*" six = "*" -[[package]] -name = "zipp" -version = "3.16.2" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "dev" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, - {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.13" -content-hash = "61c96d4c569072063bbd65e965dedb214919ab7455e8e6aa77d277795025cf46" +content-hash = "c85aecbb131d55e7e08808afd66c161ab98f2ad62a1686bbb3f664bb76479462" diff --git a/pyproject.toml b/pyproject.toml index 2b0b04a..b97365b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,6 @@ pytest-mock = "^3.11.1" pandas-stubs = "^2.0.2.230605" types-tqdm = "^4.65.0.2" pytest-cov = "^4.1.0" -pytest-checkdocs = "^2.10.1" [build-system] requires = ["poetry-core"] From b24423ecba37fbb042449ea8466e74f360caf06b Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 15:23:20 +0200 Subject: [PATCH 18/19] Initial poetry cache --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5cda024..f59bd99 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,7 +66,6 @@ jobs: id: build run: poetry build if: steps.pytest.outcome == 'success' && steps.mypy.outcome == 'success' && steps.pylint.outcome == 'success' && steps.coverage.outcome == 'success' - - name: Authorize GitHub Actions to publish on PYPI run: poetry config pypi-token.pypi ${{ secrets.PYPI_API_TOKEN }} if: steps.build.outcome == 'success' && github.event_name == 'push' From 353c6b229fdde79634e3e8255087f14da1933c2f Mon Sep 17 00:00:00 2001 From: Jasper Date: Wed, 9 Aug 2023 16:13:41 +0200 Subject: [PATCH 19/19] Added Github Actions badge and pylint line limit (100) --- README.md | 6 ++++-- pyproject.toml | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bd776a6..e6ae314 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ [![PyPI](https://img.shields.io/pypi/v/libretro-finder)](https://pypi.org/project/libretro-finder/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/libretro-finder) ![PyPI - License](https://img.shields.io/pypi/l/libretro-finder) +[![Build passing (main)](https://github.com/jaspersiebring/libretro_finder/actions/workflows/main.yml/badge.svg?branch=main&event=push)](https://github.com/jaspersiebring/libretro_finder/actions/workflows/main.yml) + Simple tool that finds and prepares your BIOS files for usage with Libretro (or its RetroArch frontend). @@ -89,5 +91,5 @@ If `libretro_finder` is called without any additional arguments, LibretroFinder ### Missing features? Have some feedback? Let me know! -- [My Reddit account](https://www.reddit.com/user/qtieb/) -- [My Github account](https://github.com/jaspersiebring) \ No newline at end of file +- [Open a Github issue](https://github.com/jaspersiebring) +- [Message me on Reddit ](https://www.reddit.com/user/qtieb/) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index b97365b..c2e8e42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,4 +38,5 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.pylint.'MESSAGES CONTROL'] -disable = "C0114, R0912, R0914" \ No newline at end of file +disable = "C0114, R0912, R0914" +max-line-length = 100 \ No newline at end of file