Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: CI/CD Pipeline

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Install flake8
run: pip install flake8

- name: Lint with flake8
run: |
flake8 localengine tests examples --max-line-length=100 --extend-ignore=E203,W503

- name: Format check with black
run: |
black --check localengine tests examples

- name: Import sort check with isort
run: |
isort --check-only localengine tests examples

- name: Type check with mypy
run: |
mypy localengine

- name: Test with pytest
run: |
pytest tests/ -v --cov=localengine --cov-report=xml --cov-report=term

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella

- name: Test examples
run: |
python examples/basic_usage.py
python examples/advanced_usage.py
env:
PYTHONPATH: .

package-test:
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
permissions:
id-token: write # For trusted publishing to Test PyPI
contents: read

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine

- name: Build package
run: |
python -m build
echo "📦 Built package files:"
ls -la dist/

- name: Verify package integrity
run: |
twine check dist/*
echo "✅ Package integrity verified"

- name: Test local package installation
run: |
# Test that the built package can be installed and imported
pip install dist/*.whl
python -c "import localengine; print(f'✅ Local package installation successful: {localengine.__version__}')"

- name: Publish to Test PyPI
if: github.repository == 'EnvOpen/pyLocalEngine'
continue-on-error: true # Don't fail CI if Test PyPI upload fails
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
skip-existing: true
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}

- name: Test installation from Test PyPI
if: github.repository == 'EnvOpen/pyLocalEngine'
continue-on-error: true # Don't fail CI if Test PyPI installation fails
run: |
# Wait for the package to be available on Test PyPI
sleep 30

# Create a fresh virtual environment
python -m venv test_env
source test_env/bin/activate

# Install from Test PyPI (with fallback to regular PyPI for dependencies)
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ pyLocalEngine || {
echo "⚠️ Test PyPI installation failed (this may be expected for existing versions)"
exit 0
}

# Test basic functionality if installation succeeded
python -c "
try:
import localengine
print(f'✅ Test PyPI installation verified: {localengine.__version__}')

# Quick functionality test
engine = localengine.LocalEngine(auto_detect=False)
print('✅ Basic functionality test passed')
except ImportError as e:
print(f'⚠️ Import failed: {e}')
exit(0)
"
118 changes: 118 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: Publish to PyPI

on:
release:
types: [published]

jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine

- name: Verify version consistency
run: |
# Extract version from pyproject.toml (Python 3.11+ has tomllib built-in)
PROJECT_VERSION=$(python -c "
try:
import tomllib
except ImportError:
import tomli as tomllib
with open('pyproject.toml', 'rb') as f:
data = tomllib.load(f)
print(data['project']['version'])
")

# Extract version from git tag (remove 'v' prefix if present)
TAG_VERSION=${GITHUB_REF#refs/tags/}
TAG_VERSION=${TAG_VERSION#v}

echo "Project version: $PROJECT_VERSION"
echo "Tag version: $TAG_VERSION"

if [ "$PROJECT_VERSION" != "$TAG_VERSION" ]; then
echo "❌ Version mismatch: pyproject.toml has $PROJECT_VERSION but git tag is $TAG_VERSION"
exit 1
fi
echo "✅ Version consistency verified: $PROJECT_VERSION"

- name: Build package
run: |
python -m build
echo "📦 Built package files:"
ls -la dist/

- name: Verify package integrity
run: |
twine check dist/*
echo "✅ Package integrity verified"

- name: Test package installation
run: |
# Test that the built package can be installed and imported
pip install dist/*.whl
python -c "import localengine; print(f'✅ Package import successful: {localengine.__version__}')"

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}

- name: Verify PyPI publication
run: |
# Wait for PyPI to update
sleep 60

# Create another fresh virtual environment
python -m venv verify_env
source verify_env/bin/activate

# Install from PyPI
pip install pyLocalEngine

# Verify installation
python -c "
import localengine
print(f'✅ PyPI publication verified: {localengine.__version__}')
print('🎉 Package successfully published to PyPI!')
"

- name: Create release summary
run: |
echo "## 📦 Release Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "✅ **Version**: $(python -c "
try:
import tomllib
except ImportError:
import tomli as tomllib
with open('pyproject.toml', 'rb') as f:
data = tomllib.load(f)
print(data['project']['version'])
")" >> $GITHUB_STEP_SUMMARY
echo "✅ **Built package**: $(ls dist/*.whl | head -1)" >> $GITHUB_STEP_SUMMARY
echo "✅ **PyPI**: Published successfully" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "ℹ️ **Note**: Package was pre-tested on Test PyPI during CI" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "🎉 **pyLocalEngine is now available on PyPI!**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "pip install pyLocalEngine" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,5 @@ cython_debug/
marimo/_static/
marimo/_lsp/
__marimo__/

.vscode/
38 changes: 38 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Pre-commit configuration for pyLocalEngine
# See https://pre-commit.com for more information

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
- id: check-merge-conflict
- id: check-added-large-files
- id: mixed-line-ending

- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
language_version: python3

- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: ["--profile", "black"]

- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
args: [--max-line-length=100, --extend-ignore=E203,W503]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.3.0
hooks:
- id: mypy
additional_dependencies: [types-PyYAML, types-requests]
Loading
Loading