Skip to content

Conversation

@soustruh
Copy link
Contributor

@soustruh soustruh commented Jan 6, 2026

Migrate to uv build system

Summary

Migrate from setup.py + pip to pyproject.toml + uv build system, following the same pattern successfully used in keboola/python-http-client.

Testing

Changes

Commit 1: flake8 config consistent with cookiecutter template 🍪

  • Renamed flake8.cfg.flake8 (standard naming)
  • Updated config to strict standards from cookiecutter template
  • Fixed ALL flake8 errors revealed by new strict config:
    • tests/test_dao.py: Fixed star imports (F403/F405), unused variables (F841), formatting
    • tests/test_interface.py: Fixed unused variables (F841), line length (E501), normalized CRLF→LF line endings

Commit 2: migrate package configuration to pyproject.toml 📦

  • Created pyproject.toml with complete project metadata:
    • Dependencies: pygelf, pytz<2021.0, deprecated
    • Dev dependencies: flake8, pytest, ruff, pdoc3
    • Python support: 3.8-3.14
    • TestPyPI index configuration
  • Removed legacy License :: OSI Approved :: MIT License classifier (PEP 639 compliance)
  • Deleted setup.py and requirements.txt
  • Updated LICENSE copyright to 2025

Commit 3: uv 💜

  • Updated all 4 GitHub workflows to use uv:
    • .github/workflows/deploy.yml - production PyPI (triggers on tag creation)
    • .github/workflows/deploy_to_test.yml - Test PyPI (manual workflow_dispatch)
    • .github/workflows/push_dev.yml - dev branch testing
    • .github/workflows/push_main.yml - docs generation
  • Ruff checks are now blocking (removed continue-on-error)
  • Changed install commands to use uv
  • Added version replacement from git tags using uv version
  • Updated secrets: UV_PUBLISH_TOKEN, UV_PUBLISH_TOKEN_TEST_PYPI
  • Generated uv.lock with locked dependencies

Version Strategy

  • 1.7.x = Test PyPI releases (alpha testing phase) ✅ TESTED
  • 1.8.0 = Production PyPI release (this PR's target)

Workflow Strategy

  • Test PyPI: Manual trigger via workflow_dispatch - allows testing any tag
  • Production PyPI: Automatic trigger on tag creation from main branch

Breaking Changes

None - this is purely a build system migration. The published package remains functionally identical.

Migration Notes

  • Components using this library don't need any changes
  • Installation: uv add keboola.component
  • All APIs remain unchanged

Benefits

  • ✅ Modern Python packaging standards (PEP 517/518/639)
  • ✅ Faster dependency resolution with uv
  • ✅ Deterministic builds with uv.lock
  • ✅ Blocking ruff checks for code quality
  • ✅ Consistent with other Keboola Python libraries
  • ✅ Simplified CI/CD with uv tooling

Note on Large Diff in test_interface.py

The file had CRLF (Windows) line endings which were normalized to LF (Unix) during flake8 fixes. Actual code changes are minimal (5 lines: unused variables + comment formatting).

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the Python packaging infrastructure from the legacy setup.py + pip approach to the modern pyproject.toml + uv build system. This migration follows PEP 517/518/639 standards and aligns with the pattern successfully implemented in keboola/python-http-client.

Key Changes:

  • Complete migration to declarative pyproject.toml configuration
  • Adoption of uv for dependency management and publishing
  • Updated CI/CD workflows to use uv tooling with blocking ruff checks
  • Flake8 configuration improvements following cookiecutter template standards

Reviewed changes

Copilot reviewed 11 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pyproject.toml New project configuration file with metadata, dependencies, and dev dependencies
uv.lock Dependency lock file ensuring deterministic builds across Python 3.8-3.14
setup.py Removed legacy setup file
requirements.txt Removed in favor of pyproject.toml dependencies
.flake8 New standardized flake8 configuration (renamed from flake8.cfg)
flake8.cfg Removed old configuration file
LICENSE Updated copyright year to 2025
tests/test_interface.py Line ending normalization (CRLF→LF) and minor unused variable fixes
tests/test_dao.py Fixed star imports, unused variables, and formatting issues
.github/workflows/deploy.yml Updated to use uv for build and publish to PyPI
.github/workflows/deploy_to_test.yml Updated to use uv for Test PyPI publishing
.github/workflows/push_dev.yml Updated to use uv with blocking ruff checks
.github/workflows/push_main.yml Updated to use uv for documentation generation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +66
# # set env
# interface = CommonInterface(mandatory_params=[])
# `
# # tests
# try:
# interface.validate_config()
# except Exception: # noeq
# self.fail("validateConfig() fails on empty Parameters!")

def test_required_params_missing_fail(self):
return True
# set env - missing notbar
# hdlr = CommonInterface(mandatory_params=['fooBar', 'notbar'])
#
# with self.assertRaises(ValueError) as er:
# hdlr.validate_config(['fooBar', 'notbar'])
#
# self.assertEqual('Missing mandatory config parameters fields: [notbar] ', str(er.exception))
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment appears to contain commented-out code.

Suggested change
# # set env
# interface = CommonInterface(mandatory_params=[])
# `
# # tests
# try:
# interface.validate_config()
# except Exception: # noeq
# self.fail("validateConfig() fails on empty Parameters!")
def test_required_params_missing_fail(self):
return True
# set env - missing notbar
# hdlr = CommonInterface(mandatory_params=['fooBar', 'notbar'])
#
# with self.assertRaises(ValueError) as er:
# hdlr.validate_config(['fooBar', 'notbar'])
#
# self.assertEqual('Missing mandatory config parameters fields: [notbar] ', str(er.exception))
def test_required_params_missing_fail(self):
return True

Copilot uses AI. Check for mistakes.
Comment on lines +1034 to +1048
# def test_file_manifest(self):
# cfg = docker.Config()
# some_file = os.path.join(tempfile.mkdtemp('kbc-test') + 'someFile.txt')
# cfg.write_file_manifest(some_file, file_tags=['foo', 'bar'],
# is_public=True, is_permanent=False,
# notify=True)
# manifest_filename = some_file + '.manifest'
# with open(manifest_filename) as manifest_file:
# config = json.load(manifest_file)
# self.assertEqual(
# {'is_public': True, 'is_permanent': False, 'notify': True,
# 'tags': ['foo', 'bar']},
# config
# )
# os.remove(manifest_filename)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment appears to contain commented-out code.

Suggested change
# def test_file_manifest(self):
# cfg = docker.Config()
# some_file = os.path.join(tempfile.mkdtemp('kbc-test') + 'someFile.txt')
# cfg.write_file_manifest(some_file, file_tags=['foo', 'bar'],
# is_public=True, is_permanent=False,
# notify=True)
# manifest_filename = some_file + '.manifest'
# with open(manifest_filename) as manifest_file:
# config = json.load(manifest_file)
# self.assertEqual(
# {'is_public': True, 'is_permanent': False, 'notify': True,
# 'tags': ['foo', 'bar']},
# config
# )
# os.remove(manifest_filename)
# File manifest behavior is not covered by this test suite.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant