From d9f284d682c9d02456445638becc121a0282780f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Gince?= <50332514+JeremieGince@users.noreply.github.com> Date: Mon, 2 Jun 2025 22:10:55 -0400 Subject: [PATCH 1/5] Update build_dist.yml --- .github/workflows/build_dist.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build_dist.yml b/.github/workflows/build_dist.yml index c34b047..9610d07 100644 --- a/.github/workflows/build_dist.yml +++ b/.github/workflows/build_dist.yml @@ -6,6 +6,12 @@ on: permissions: contents: write + pull-requests: write + actions: write + checks: write + statuses: write + issues: write + discussions: write jobs: Build-Dist: From c5c6d4cd84ae7037c8eafa4c1d0b56a1f022c018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Gince?= <50332514+JeremieGince@users.noreply.github.com> Date: Mon, 2 Jun 2025 23:59:42 -0400 Subject: [PATCH 2/5] Update build_dist.yml --- .github/workflows/build_dist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_dist.yml b/.github/workflows/build_dist.yml index 9610d07..ecd718a 100644 --- a/.github/workflows/build_dist.yml +++ b/.github/workflows/build_dist.yml @@ -59,7 +59,7 @@ jobs: git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git add pyproject.toml - git commit -m "Updating version of pyproject.toml" + git diff-index --quiet HEAD || git commit -m "Updating version of pyproject.toml" - name: Push the new pyproject.toml uses: ad-m/github-push-action@master From 6909bb226f9570a1a589f18b60c5a4596f3f98f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Gince?= <50332514+JeremieGince@users.noreply.github.com> Date: Tue, 3 Jun 2025 19:35:15 -0400 Subject: [PATCH 3/5] update pyproject --- pyproject.toml | 3 +++ run_pytests.py | 4 +--- tests/conftest.py | 4 +--- tests/test_dummy.py | 16 ++++------------ 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4d15813..ab1155f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -96,3 +96,6 @@ module = [ "pythonbasictools", ] ignore_missing_imports = true + +[tool.black] +line-length = 120 diff --git a/run_pytests.py b/run_pytests.py index d3bb4bc..dbc62c0 100644 --- a/run_pytests.py +++ b/run_pytests.py @@ -1,14 +1,12 @@ +import argparse import json import os import pytest -import pythonbasictools as pbt from pytest_jsonreport.plugin import JSONReport -from pytest_cov.plugin import CovPlugin from tests import configs from tests.conftest import RUN_SLOW_ARG_NAME -import argparse def get_args_parser(): diff --git a/tests/conftest.py b/tests/conftest.py index 7149b9d..d3672af 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -39,9 +39,7 @@ def pytest_collection_modifyitems(config, items): pass else: # print("Skipping slow tests") - skipper = pytest.mark.skip( - reason=f"Only run when '--{RUN_SLOW_ARG_NAME}=True' is given" - ) + skipper = pytest.mark.skip(reason=f"Only run when '--{RUN_SLOW_ARG_NAME}=True' is given") for item in items: if "slow" in item.keywords: item.add_marker(skipper) diff --git a/tests/test_dummy.py b/tests/test_dummy.py index d664e8e..f7c2a96 100644 --- a/tests/test_dummy.py +++ b/tests/test_dummy.py @@ -26,9 +26,7 @@ def test_dummy(dummy): def test_attributes(attr): assert hasattr(python_template, attr), f"Module does not have attribute {attr}" assert getattr(python_template, attr) is not None, f"Attribute {attr} is None" - assert isinstance( - getattr(python_template, attr), str - ), f"Attribute {attr} is not a string" + assert isinstance(getattr(python_template, attr), str), f"Attribute {attr} is not a string" def test_main(): @@ -39,13 +37,7 @@ def test_main(): def test_get_args_parser(): parser = get_args_parser() assert parser is not None, "get_args_parser returned None" - assert isinstance( - parser, argparse.ArgumentParser - ), "get_args_parser did not return an ArgumentParser instance" + assert isinstance(parser, argparse.ArgumentParser), "get_args_parser did not return an ArgumentParser instance" # Check if the parser has the expected attributes - assert hasattr( - parser, "description" - ), "ArgumentParser does not have a description attribute" - assert ( - parser.description == "Python Template" - ), "ArgumentParser description does not match expected value" + assert hasattr(parser, "description"), "ArgumentParser does not have a description attribute" + assert parser.description == "Python Template", "ArgumentParser description does not match expected value" From debbe347c0b4a2e381cb279dae9715d0a55fb17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Gince?= <50332514+JeremieGince@users.noreply.github.com> Date: Fri, 6 Jun 2025 16:53:39 -0400 Subject: [PATCH 4/5] Update Dockerfile --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8b86107..a30caa9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,7 +38,6 @@ FROM base_stage AS main_stage # Files WORKDIR $ROOT_DIR COPY --from=build_stage $ROOT_DIR ./ -VOLUME data # Entrypoint ENV PATH="venv/bin:$PATH" From 8520f3018c6bc52a283cd78fcc956f15871e7965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Gince?= <50332514+JeremieGince@users.noreply.github.com> Date: Sat, 7 Jun 2025 17:26:20 -0400 Subject: [PATCH 5/5] update workflow --- .github/ISSUE_TEMPLATE/bug_report.yml | 64 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.yml | 44 +++++++++++++++ .github/pull_request_template.md | 22 ++++++++ .github/workflows/tests.yml | 6 +- docker_files/build_image_and_run.py | 28 +++++++++- 5 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..41cfeeb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,64 @@ +name: Bug report +description: File a bug report +title: '[BUG]' +labels: "bug :bug:" + +body: + - type: markdown + id: description + attributes: + value: | + ## Before posting a bug report + Search existing GitHub issues to make sure the issue does not already exist. + + # Issue description + Description of the issue - include code snippets in the Source code section below and screenshots if relevant. + - type: textarea + id: expected + attributes: + label: Expected behavior + description: | + What do you expect to happen? + validations: + required: true + - type: textarea + id: actual + attributes: + label: Actual behavior + description: | + What actually happens? + validations: + required: true + - type: textarea + id: info + attributes: + label: Additional information + description: | + Please provide any additional information here that might be necessary to reproduce the issue. + - type: textarea + id: sourcecode + attributes: + label: Source code + description: Please include a minimal non-working example, or any other code related to the issue. + render: shell + - type: textarea + id: tracebacks + attributes: + label: Tracebacks + description: Please include the error tracebacks related to the issue here. + render: shell + - type: textarea + id: system + attributes: + label: System information + description: Please provide informations about you python version and os. The command `python -c "import sys; print(sys.version, sys.platform)"` can be used to get this information. Provide also the output of `pip list` command. + render: shell + validations: + required: true + - type: checkboxes + id: terms + attributes: + label: Existing GitHub issues + options: + - label: I have searched existing GitHub issues to make sure the issue does not already exist. + required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..34051e4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,44 @@ +name: Feature request +description: Suggest a new feature +labels: "enhancement :sparkles:" + +body: + - type: markdown + id: description + attributes: + value: | + ## Before posting a feature request + Search existing GitHub issues to make sure the issue does not already exist. + + # Feature description + Description of the feature request - include code snippets and screenshots here if relevant. + - type: textarea + id: details + attributes: + label: Feature details + description: | + What feature would you like to have? + validations: + required: true + - type: textarea + id: implementation + attributes: + label: Implementation + description: | + Do you have an idea for how this could be implemented? Please include those details here. + - type: dropdown + id: urgency + attributes: + label: How important would you say this feature is? + options: + - "1: Not important. Would be nice to have." + - "2: Somewhat important. Needed this quarter." + - "3: Very important! Blocking work." + validations: + required: true + - type: textarea + id: info + attributes: + label: Additional information + description: | + Please provide any additional information here. Include potential alternative solutions, or workarounds, as well as references, if any. \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ee67225 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,22 @@ +# Description + +Please provide a brief description of the changes you are making in this pull request. + +------------------------------------------------------------------------------------------------------------ + +# Checklist + +Please complete the following checklist when submitting a PR. The PR will not be reviewed until all items are checked. + +- [ ] All new features include a unit test. + Make sure that the tests passed and the coverage is + sufficient by running `python run_pytests.py --tests_folder=tests` or + `pytest tests --cov=src --cov-report=term-missing`. + +- [ ] All new functions and code are clearly documented. + +- [ ] The code is formatted using Black. + You can do this by running `black src tests`. + +- [ ] The code is type-checked using Mypy. + You can do this by running `mypy src tests`. diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5e4f0ac..eee80f0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -37,13 +37,11 @@ jobs: - name: Test Linting run: | . ./venv/bin/activate - black src --check --diff - black tests --check --diff + black src tests --check --diff - name: Test Typing run: | . ./venv/bin/activate - mypy src - mypy tests + mypy src tests - name: Test Notebooks run: | . ./venv/bin/activate diff --git a/docker_files/build_image_and_run.py b/docker_files/build_image_and_run.py index 68548e6..7161f3b 100644 --- a/docker_files/build_image_and_run.py +++ b/docker_files/build_image_and_run.py @@ -44,6 +44,12 @@ def get_args_parser(): default=False, help="If set, only runs the container without building the image.", ) + parser.add_argument( + "--only_build", + action=argparse.BooleanOptionalAction, + default=False, + help="If set, only build the container without running the image.", + ) return parser @@ -73,6 +79,15 @@ def build_images( print(f"{cmd = }") subprocess.run(cmd, shell=True, check=True) print(f"Pruned old images") + + save_images_folder = os.path.join(os.path.dirname(__file__), "..", "data", "dockerfiles") + os.makedirs(save_images_folder, exist_ok=True) + for image in images: + savefile = os.path.abspath(os.path.join(save_images_folder, image.replace(":", "-") + ".tar")) + print(f"Saving {image} to {savefile}") + save_cmd = f"docker save -o {savefile} {image}" + subprocess.run(save_cmd, shell=True, check=True) + print(f"{image} saved to {savefile}.") return images def run_container( @@ -100,6 +115,7 @@ def run_container( print(f"Running container {container_name} from image {image_name}:{tag}") container_args = [ "--name", container_name, + "--gpus all", "--detach", f"--volume=" f"{os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'data'))}" @@ -116,8 +132,6 @@ def run_container( def main(): args = get_args_parser().parse_args() - if not args.image_name: - args.image_name = os.path.basename(os.path.dirname(os.path.dirname(__file__))) print(f"Running with args: {json.dumps(vars(args), indent=4)}") if args.only_run: images = [f"{args.image_name}:{args.tag}"] @@ -127,12 +141,20 @@ def main(): tag=args.tag, image_name=args.image_name, ) + if args.only_build: + return 0 for image in images: + container_img_part = ( + image + .replace("/", "-") + .replace(":", "-") + .replace(".", "-") + ) run_container( image_name=image, tag=args.tag, args=json.loads(args.args) if args.args else None, - container_name=f"{args.image_name}-{args.mode}", + container_name=f"{container_img_part}-{args.mode}", run_args=["-e", f"MODE={args.mode}"], ) return 0