From e5cb3ce286c5aec8126b04d657c38d53b4e54034 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Fri, 27 Sep 2024 16:16:42 -0700 Subject: [PATCH 1/3] Removes comment --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7ec75c94..524bc9f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ fuzzywuzzy~=0.18.0 netaddr~=1.3.0 numpy>=2.0.1 Jinja2 -pycryptodome # Crypto +pycryptodome PyYAML~=6.0.1 pytest python-Levenshtein From 79d64240f9817f160b2051f14e5dd895070d07c1 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Fri, 27 Sep 2024 16:16:56 -0700 Subject: [PATCH 2/3] Adds circle workflow files (wip) --- .circleci/check_compatibility.py | 128 +++++++++++++++++++++++++++++++ .circleci/check_pr_status.sh | 26 +++++++ .circleci/check_requirements.sh | 10 +++ .circleci/config.yml | 102 ++++++++++++++++++++++++ 4 files changed, 266 insertions(+) create mode 100644 .circleci/check_compatibility.py create mode 100644 .circleci/check_pr_status.sh create mode 100644 .circleci/check_requirements.sh create mode 100644 .circleci/config.yml diff --git a/.circleci/check_compatibility.py b/.circleci/check_compatibility.py new file mode 100644 index 00000000..650f24dd --- /dev/null +++ b/.circleci/check_compatibility.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 + +import sys +import requests +from packaging.specifiers import SpecifierSet +from packaging.version import Version, InvalidVersion, parse +import re + + +def main(): + if len(sys.argv) != 2: + print("Usage: python check_compatibility.py ") + sys.exit(1) + + python_version = sys.argv[1] + all_passed = True + + GREEN = "\033[0;32m" + RED = "\033[0;31m" + NC = "\033[0m" # No Color + + def check_compatibility(): + nonlocal all_passed + try: + with open("/Users/ibraheem/Desktop/btcli/btcli/requirements.txt", "r") as f: + requirements = f.readlines() + except FileNotFoundError: + print(f"{RED}requirements.txt file not found.{NC}") + sys.exit(1) + + for line in requirements: + line = line.strip() + # Skip empty lines and comments + if not line or line.startswith("#"): + continue + # Skip lines starting with git+ + if line.startswith("git+"): + continue + + # Extract package name and version specifier + package_name_and_specifier = re.split("[;]", line)[0].strip() + package_name = re.split("[!=<>~]", package_name_and_specifier)[0] + package_name = package_name.split("[")[0] # Remove extras + version_specifier = package_name_and_specifier[len(package_name) :].strip() + + # Request PyPi for package details + print(f"Checking {package_name}... ", end="") + url = f"https://pypi.org/pypi/{package_name}/json" + response = requests.get(url) + if response.status_code != 200: + print( + f"{RED}Information not available for {package_name}. Failure.{NC}" + ) + all_passed = False + continue + + # Parse the data + data = response.json() + requires_python = data["info"]["requires_python"] + + # Parse the version specifier from requirements.txt + requirement_specifier = ( + SpecifierSet(version_specifier) if version_specifier else None + ) + + # Get all available versions of the package + available_versions = [parse(v) for v in data["releases"].keys()] + available_versions.sort(reverse=True) + + # Filter versions that satisfy the requirement specifier + if requirement_specifier: + matching_versions = [ + v for v in available_versions if requirement_specifier.contains(v) + ] + else: + matching_versions = available_versions + + # Check for versions compatible with the specified Python version + compatible_versions = [] + for version in matching_versions: + releases = data["releases"].get(str(version), []) + for release in releases: + # Check if the release has a 'requires_python' field + release_requires_python = ( + release.get("requires_python") or requires_python + ) + if release_requires_python: + try: + specifier = SpecifierSet(release_requires_python) + if specifier.contains(Version(python_version)): + compatible_versions.append(version) + break # No need to check other files for this version + except InvalidVersion as e: + print(f"{RED}Invalid version in requires_python: {e}{NC}") + all_passed = False + break + else: + # If no requires_python, assume compatible + compatible_versions.append(version) + break + if compatible_versions: + break # Found the highest compatible version + + if compatible_versions: + print( + f"{GREEN}Supported (compatible version: {compatible_versions[0]}){NC}" + ) + else: + print(f"{RED}Not compatible with Python {python_version}.{NC}") + all_passed = False + + check_compatibility() + + if all_passed: + print( + f"{GREEN}All requirements are compatible with Python {python_version}.{NC}" + ) + print(f"{GREEN}All tests passed.{NC}") + else: + print( + f"{RED}Some requirements are NOT compatible with Python {python_version}.{NC}" + ) + print(f"{RED}Some tests did not pass.{NC}") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/.circleci/check_pr_status.sh b/.circleci/check_pr_status.sh new file mode 100644 index 00000000..4b31a296 --- /dev/null +++ b/.circleci/check_pr_status.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Extract the repository owner +REPO_OWNER=$(echo $CIRCLE_PULL_REQUEST | awk -F'/' '{print $(NF-3)}') + +# Extract the repository name +REPO_NAME=$(echo $CIRCLE_PULL_REQUEST | awk -F'/' '{print $(NF-2)}') + +# Extract the pull request number +PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | awk -F'/' '{print $NF}') + + +PR_DETAILS=$(curl -s \ + "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/pulls/$PR_NUMBER") + + +IS_DRAFT=$(echo "$PR_DETAILS" | jq -r .draft) +echo $IS_DRAFT + +if [ "$IS_DRAFT" == "true" ]; then + echo "This PR is a draft. Skipping the workflow." + exit 1 +else + echo "This PR is not a draft. Proceeding with the workflow." + exit 0 +fi diff --git a/.circleci/check_requirements.sh b/.circleci/check_requirements.sh new file mode 100644 index 00000000..5fcd27ea --- /dev/null +++ b/.circleci/check_requirements.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Check if requirements files have changed in the last commit +if git diff --name-only HEAD~1 | grep -E 'requirements/prod.txt|requirements/dev.txt'; then + echo "Requirements files have changed. Running compatibility checks..." + echo 'export REQUIREMENTS_CHANGED="true"' >> $BASH_ENV +else + echo "Requirements files have not changed. Skipping compatibility checks..." + echo 'export REQUIREMENTS_CHANGED="false"' >> $BASH_ENV +fi diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..7d38f2f6 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,102 @@ +version: 2.1 + +orbs: + python: circleci/python@2.1.1 + python-lib: dialogue/python-lib@0.1.55 + +jobs: + # Check if the PR is a draft + check-if-pr-is-draft: + docker: + - image: cimg/python:3.10 + steps: + - checkout + - run: + name: Install jq and curl + command: sudo apt-get update && sudo apt-get install -y jq curl + - run: + name: Check if PR is a draft + command: ./check_pr_status.sh + + # Compatibility check across all supported versions + check_compatibility: + parameters: + python_version: + type: string + docker: + - image: cimg/python:<< parameters.python_version >> + steps: + - checkout + - run: + name: Install dependencies + command: | + sudo apt-get update + sudo apt-get install -y jq curl + python -m pip install --upgrade pip + pip install requests packaging + - run: + name: Check compatibility for Python << parameters.python_version >> + command: | + python .circleci/check_compatibility.py << parameters.python_version >> + + # Linting with Ruff (Run once on the latest Python version) + ruff: + resource_class: small + docker: + - image: cimg/python:3.12.0 + steps: + - checkout + - restore_cache: + name: Restore cached Ruff venv + keys: + - v2-pypi-py-ruff-3.12.0 + - run: + name: Update & Activate Ruff venv + command: | + python -m venv .venv + . .venv/bin/activate + python -m pip install --upgrade pip + pip install ruff + - save_cache: + name: Save cached Ruff venv + paths: + - ".venv/" + key: v2-pypi-py-ruff-3.12.0 + - run: + name: Ruff linting + command: | + . .venv/bin/activate + ruff check . + +workflows: + version: 2 + main_workflow: + jobs: + - check-if-pr-is-draft + + # Compatibility checks for multiple Python versions + - check_compatibility: + requires: + - check-if-pr-is-draft + python_version: "3.9.0" + name: check-compatibility-3.9.0 + - check_compatibility: + requires: + - check-if-pr-is-draft + python_version: "3.10.0" + name: check-compatibility-3.10.0 + - check_compatibility: + requires: + - check-if-pr-is-draft + python_version: "3.11.0" + name: check-compatibility-3.11.0 + - check_compatibility: + requires: + - check-if-pr-is-draft + python_version: "3.12.0" + name: check-compatibility-3.12.0 + + # Linting workflow using Ruff + - ruff: + requires: + - check-if-pr-is-draft From 9f55fe26733a04ee148946f565bf83ed59257d28 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Fri, 27 Sep 2024 16:18:12 -0700 Subject: [PATCH 3/3] WIP --- .circleci/check_compatibility.py | 0 .circleci/check_pr_status.sh | 0 .circleci/check_requirements.sh | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .circleci/check_compatibility.py mode change 100644 => 100755 .circleci/check_pr_status.sh mode change 100644 => 100755 .circleci/check_requirements.sh diff --git a/.circleci/check_compatibility.py b/.circleci/check_compatibility.py old mode 100644 new mode 100755 diff --git a/.circleci/check_pr_status.sh b/.circleci/check_pr_status.sh old mode 100644 new mode 100755 diff --git a/.circleci/check_requirements.sh b/.circleci/check_requirements.sh old mode 100644 new mode 100755