diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml new file mode 100644 index 0000000..cd4a170 --- /dev/null +++ b/.github/workflows/publish-pypi.yml @@ -0,0 +1,103 @@ +name: publish-pypi + +on: + release: + types: [published] + workflow_dispatch: + inputs: + upload: + description: 'Upload to PyPI' + required: false + default: 'true' + +jobs: + update-version: + runs-on: ubuntu-latest + permissions: + contents: write + if: github.event_name == 'release' + + steps: + - uses: actions/checkout@v5 + with: + ref: main + + - name: Extract version from tag + id: version + run: | + VERSION=${{ github.event.release.tag_name }} + VERSION=${VERSION#v} # Remove 'v' prefix if present + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Update pyproject.toml + run: | + sed -i 's/version = "[^"]*"/version = "${{ steps.version.outputs.version }}"/' pyproject.toml + + - name: Commit and push version update + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add pyproject.toml + git commit -m "chore: bump version to ${{ steps.version.outputs.version }}" + git push origin main + + build: + needs: update-version + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v5 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' + + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + pip install build setuptools wheel + + - name: Build distribution + run: python -m build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: distribution + path: dist/ + + publish: + needs: build + runs-on: ubuntu-latest + if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.upload == 'true') + + steps: + - uses: actions/checkout@v5 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: distribution + path: dist/ + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' + + - name: Install Twine + run: pip install twine + + - name: Publish to PyPI + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} + run: twine upload dist/* --skip-existing + + - name: Create release note + if: github.event_name == 'release' + run: | + echo "✅ Package published to PyPI successfully!" + echo "Version: ${{ github.event.release.tag_name }}" + echo "PyPI URL: https://pypi.org/project/struct/" diff --git a/.gitignore b/.gitignore index 769fc1f..5e41b32 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ __pycache__ *.log example_project/ build/* +dist/ # MkDocs generated documentation site/docs/ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5e645f2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,74 @@ +[build-system] +requires = ["setuptools>=65.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "struct" +version = "1.0.0" +description = "A structured data processing tool" +readme = "README.md" +license = {text = "MIT"} +authors = [{name = "httpdss"}] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +requires-python = ">=3.8" +keywords = ["data", "structure", "processing"] + +dependencies = [ + "PyYAML>=6.0", + "requests>=2.28.0", + "openai>=1.0.0", + "python-dotenv>=0.21.0", + "jinja2>=3.1.0", + "PyGithub>=1.58.0", + "shtab>=1.6.0", + "colorlog>=6.7.0", + "pydantic-ai>=0.1.0", + "fastmcp>=2.0.0", +] + +[project.optional-dependencies] +s3 = [ + "boto3>=1.26.0", +] +gcs = [ + "google-cloud-storage>=2.10.0", + "google-api-core>=2.11.0", +] +cloud = [ + "struct[s3]", + "struct[gcs]" +] +dev = [ + "pytest>=7.0.0", + "pytest-cov>=4.0.0", + "black>=22.0.0", + "flake8>=4.0.0", + "mypy>=0.990", +] + +[project.urls] +Homepage = "https://github.com/httpdss/struct" +Repository = "https://github.com/httpdss/struct.git" + +[project.scripts] +struct = "struct_module.main:main" + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +where = ["."] # Look for packages in root directory +include = ["struct_module*"] + +[tool.setuptools.package-data] +struct_module = ["contribs/*.yaml"] diff --git a/requirements.txt b/requirements.txt index 92cd344..9f52691 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,14 +1,23 @@ -PyYAML -requests -openai -python-dotenv -jinja2 -PyGithub -shtab -colorlog -boto3 -google-cloud -google-api-core -cachetools -pydantic-ai -fastmcp>=2.0 +# Core dependencies (always installed) +PyYAML>=6.0 +requests>=2.28.0 +openai>=1.0.0 +python-dotenv>=0.21.0 +jinja2>=3.1.0 +PyGithub>=1.58.0 +shtab>=1.6.0 +colorlog>=6.7.0 +pydantic-ai>=0.1.0 +fastmcp>=2.0.0 + +# Optional: AWS S3 support +# Install with: pip install struct[s3] +# boto3>=1.26.0 + +# Optional: Google Cloud Storage support +# Install with: pip install struct[gcs] +# google-cloud-storage>=2.10.0 +# google-api-core>=2.11.0 + +# Optional: Both cloud providers +# Install with: pip install struct[cloud] diff --git a/setup.py b/setup.py index 5996384..c2f906b 100644 --- a/setup.py +++ b/setup.py @@ -1,22 +1,5 @@ -from setuptools import setup, find_packages +# This file is maintained only for backwards compatibility. +# Configuration is now in pyproject.toml (PEP 517/518). +from setuptools import setup -def parse_requirements(filename): - with open(filename, 'r') as file: - lines = file.readlines() - return [line.strip() for line in lines if line and not line.startswith('#')] - -setup( - name='struct', - version='1.0.0', - packages=find_packages(), - install_requires=parse_requirements('requirements.txt'), - entry_points={ - 'console_scripts': [ - 'struct = struct_module.main:main', - ], - }, - include_package_data=True, - package_data={ - '': ['struct_module/contribs/*.yaml'], - }, -) +setup()