Package Manager Comparison Test #4324
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: "Package Manager Comparison Test" | |
| on: | |
| schedule: | |
| - cron: '0 */3 * * *' # Run every 3 hours (Save servers & prevent conflicts) | |
| workflow_dispatch: # Allow manual trigger if you really want to check stats | |
| jobs: | |
| package-manager-comparison: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| services: | |
| redis: | |
| image: redis:7 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 6379:6379 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| ref: main # Always check out main to update the "official" README | |
| fetch-depth: 0 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . redis uv | |
| - name: Configure omnipkg | |
| run: | | |
| python - << 'EOF' | |
| import sys, site, json, os, sysconfig | |
| from pathlib import Path | |
| site_packages_path = site.getsitepackages()[0] if site.getsitepackages() else sysconfig.get_paths()['purelib'] | |
| project_root = Path(os.environ['GITHUB_WORKSPACE']) | |
| builder_script = project_root / 'omnipkg' / 'package_meta_builder.py' | |
| config_data = { | |
| 'site_packages_path': site_packages_path, | |
| 'multiversion_base': str(Path(site_packages_path) / '.omnipkg_versions'), | |
| 'python_executable': sys.executable, | |
| 'builder_script_path': str(builder_script), | |
| 'redis_host': 'localhost', | |
| 'redis_port': 6379, | |
| 'redis_key_prefix': 'omnipkg:pkg:', | |
| 'paths_to_index': [str(Path(sys.executable).parent), '/usr/local/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin'], | |
| 'auto_cleanup': True, | |
| 'cleanup_threshold_days': 30 | |
| } | |
| config_dir = Path.home() / '.config' / 'omnipkg' | |
| config_dir.mkdir(parents=True, exist_ok=True) | |
| with open(config_dir / 'config.json', 'w') as f: | |
| json.dump(config_data, f, indent=2) | |
| EOF | |
| - name: Test omnipkg multi-version coexistence | |
| id: omnipkg_test | |
| run: | | |
| echo "Testing omnipkg ability to maintain multiple package versions simultaneously" | |
| if omnipkg install pip==24.0 pip==23.2.1; then | |
| echo "OMNIPKG_COEXIST_RESULT=PASS" >> $GITHUB_ENV | |
| echo "✓ omnipkg: Multiple pip versions coexist in same environment" | |
| omnipkg list | grep pip || true | |
| else | |
| echo "OMNIPKG_COEXIST_RESULT=FAIL" >> $GITHUB_ENV | |
| echo "✗ omnipkg: Failed to maintain multiple versions" | |
| fi | |
| - name: Test pip single-version limitation | |
| id: pip_test | |
| run: | | |
| echo "Testing pip's single-version replacement behavior" | |
| pip install pip==24.0 > pip_test.log 2>&1 | |
| pip install pip==23.2.1 >> pip_test.log 2>&1 | |
| echo "PIP_COEXIST_RESULT=FAIL" >> $GITHUB_ENV | |
| echo "✗ pip: Replaces existing version (standard behavior)" | |
| - name: Test uv single-version limitation | |
| id: uv_test | |
| run: | | |
| echo "Testing uv's single-version replacement behavior" | |
| uv pip install uv==0.5.0 --system > uv_test.log 2>&1 || true | |
| uv pip install uv==0.4.0 --system >> uv_test.log 2>&1 || true | |
| echo "UV_COEXIST_RESULT=FAIL" >> $GITHUB_ENV | |
| echo "✗ uv: Replaces existing version (standard behavior)" | |
| - name: Test omnipkg environment restoration | |
| id: omnipkg_restoration_test | |
| run: | | |
| echo "Testing omnipkg environment state restoration" | |
| omnipkg install uv | |
| baseline_version=$(uv --version | awk '{print $2}') | |
| echo "Baseline uv version: $baseline_version" | |
| uv pip install uv==0.7.1 --system > restore_test.log 2>&1 | |
| echo "After standard tool modification: $(uv --version | awk '{print $2}')" | |
| if omnipkg revert -y >> restore_test.log 2>&1; then | |
| echo "OMNIPKG_RESTORE_RESULT=PASS" >> $GITHUB_ENV | |
| echo "✓ omnipkg: Restored environment to baseline state" | |
| else | |
| echo "OMNIPKG_RESTORE_RESULT=FAIL" >> $GITHUB_ENV | |
| echo "✗ omnipkg: Environment restoration failed" | |
| fi | |
| - name: Extract current statistics | |
| run: | | |
| cat > extract_stats.py << 'EOF' | |
| import re, os | |
| from pathlib import Path | |
| README_FILE = Path("README.md") | |
| # Initialize counters | |
| omnipkg_wins = 0 | |
| pip_failures = 0 | |
| uv_failures = 0 | |
| if README_FILE.exists(): | |
| try: | |
| content = README_FILE.read_text(encoding='utf-8') | |
| # Extract omnipkg wins from badge | |
| omnipkg_match = re.search(r'omnipkg-(\d+)%20Wins-brightgreen', content) | |
| if omnipkg_match: | |
| omnipkg_wins = int(omnipkg_match.group(1)) | |
| print(f"Found omnipkg wins: {omnipkg_wins}") | |
| # Extract pip failures from badge | |
| pip_match = re.search(r'pip-(\d+)%20Failures-red', content) | |
| if pip_match: | |
| pip_failures = int(pip_match.group(1)) | |
| print(f"Found pip failures: {pip_failures}") | |
| # Extract uv failures from badge | |
| uv_match = re.search(r'uv-(\d+)%20Failures-red', content) | |
| if uv_match: | |
| uv_failures = int(uv_match.group(1)) | |
| print(f"Found uv failures: {uv_failures}") | |
| if not (omnipkg_match or pip_match or uv_match): | |
| print("No existing badges found, starting fresh") | |
| except Exception as e: | |
| print(f"Statistics extraction error: {e}") | |
| print("Starting with fresh counters") | |
| else: | |
| print("README.md not found, starting with fresh counters") | |
| print(f"Current stats: omnipkg={omnipkg_wins} wins, pip={pip_failures} failures, uv={uv_failures} failures") | |
| with open(os.environ['GITHUB_ENV'], 'a') as f: | |
| f.write(f"EXISTING_OMNIPKG_WINS={omnipkg_wins}\n") | |
| f.write(f"EXISTING_PIP_FAILURES={pip_failures}\n") | |
| f.write(f"EXISTING_UV_FAILURES={uv_failures}\n") | |
| EOF | |
| python extract_stats.py | |
| - name: Update documentation with test results | |
| run: | | |
| cat > update_documentation.py << 'EOF' | |
| import os | |
| from pathlib import Path | |
| from datetime import datetime | |
| README_FILE = Path("README.md") | |
| # Get test results | |
| omnipkg_coexist = os.environ.get('OMNIPKG_COEXIST_RESULT', 'FAIL') | |
| pip_coexist = os.environ.get('PIP_COEXIST_RESULT', 'FAIL') | |
| uv_coexist = os.environ.get('UV_COEXIST_RESULT', 'FAIL') | |
| # Get existing counts | |
| existing_omnipkg_wins = int(os.environ.get('EXISTING_OMNIPKG_WINS', '0')) | |
| existing_pip_failures = int(os.environ.get('EXISTING_PIP_FAILURES', '0')) | |
| existing_uv_failures = int(os.environ.get('EXISTING_UV_FAILURES', '0')) | |
| # Update counts based on this test run | |
| omnipkg_wins = existing_omnipkg_wins + (1 if omnipkg_coexist == 'PASS' else 0) | |
| pip_failures = existing_pip_failures + (1 if pip_coexist == 'FAIL' else 0) | |
| uv_failures = existing_uv_failures + (1 if uv_coexist == 'FAIL' else 0) | |
| print(f"Test results: omnipkg={omnipkg_coexist}, pip={pip_coexist}, uv={uv_coexist}") | |
| print(f"Updated stats: omnipkg={omnipkg_wins} wins, pip={pip_failures} failures, uv={uv_failures} failures") | |
| # Create the competitive badge section | |
| compact_section = ( | |
| f"## ⚖️ Multi-Version Support\n\n" | |
| f"[![omnipkg]" | |
| f"(https://img.shields.io/badge/omnipkg-{omnipkg_wins}%20Wins-brightgreen" | |
| f"?logo=python&logoColor=white)]" | |
| f"(https://github.com/1minds3t/omnipkg/actions/workflows/omnipkg_vs_the_world.yml) " | |
| f"[![pip]" | |
| f"(https://img.shields.io/badge/pip-{pip_failures}%20Failures-red" | |
| f"?logo=pypi&logoColor=white)]" | |
| f"(https://github.com/1minds3t/omnipkg/actions/workflows/omnipkg_vs_the_world.yml) " | |
| f"[![uv]" | |
| f"(https://img.shields.io/badge/uv-{uv_failures}%20Failures-red" | |
| f"?logo=python&logoColor=white)]" | |
| f"(https://github.com/1minds3t/omnipkg/actions/workflows/omnipkg_vs_the_world.yml)\n\n" | |
| f"*Multi-version installation tests run every 3 hours. [Live results here.]" | |
| f"(https://github.com/1minds3t/omnipkg/actions/workflows/omnipkg_vs_the_world.yml)*\n\n" | |
| f"---\n" | |
| ) | |
| try: | |
| content = README_FILE.read_text(encoding='utf-8') if README_FILE.exists() else "# omnipkg\n\n" | |
| start_marker, end_marker = "<!-- COMPARISON_STATS_START -->", "<!-- COMPARISON_STATS_END -->" | |
| if start_marker in content and end_marker in content: | |
| before_section = content.split(start_marker)[0] | |
| after_section = content.split(end_marker)[1] | |
| updated_content = before_section + start_marker + "\n" + compact_section + "\n" + end_marker + after_section | |
| else: | |
| updated_content = content.rstrip() + "\n\n" + start_marker + "\n" + compact_section + "\n" + end_marker | |
| with open(README_FILE, 'w', encoding='utf-8') as f: | |
| f.write(updated_content) | |
| print("✓ Documentation updated successfully") | |
| except Exception as e: | |
| print(f"Documentation update failed: {e}") | |
| exit(1) | |
| EOF | |
| python update_documentation.py | |
| - name: Commit and push documentation updates | |
| continue-on-error: true | |
| run: | | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "Package Manager Test Bot" | |
| git clean -f -X -- extract_stats.py update_documentation.py *.log || true | |
| git add README.md || true | |
| if git diff --staged --quiet; then | |
| echo "No documentation changes to commit" | |
| exit 0 | |
| fi | |
| TIMESTAMP=$(date -u '+%Y-%m-%d %H:%M UTC') | |
| # Pull latest main to avoid conflict | |
| git pull origin main --rebase || true | |
| # [skip ci] is CRITICAL here | |
| git commit -m "docs: update package manager comparison results - $TIMESTAMP [skip ci]" || exit 0 | |
| # Push strictly to main | |
| git push origin main |