mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-23 15:43:25 +08:00
ci(lfx): add coverage generation and Codecov reporting (#10266)
* chore: update dependency markers and add pytest-cov for coverage reporting - Refined dependency markers for several packages to improve compatibility with Python 3.12 and specific platforms. - Added pytest-cov to development dependencies for enhanced test coverage reporting. - Updated dependencies for pyobjc frameworks to include platform-specific markers for better compatibility. * chore: enhance lfx_tests command with coverage reporting - Updated the lfx_tests target in the Makefile to include coverage reporting options for pytest. - Added coverage metrics output in XML, HTML, and terminal formats to improve test visibility and analysis. * chore: update codecov configuration for LFX coverage tracking - Added LFX coverage target and threshold to the codecov.yml file. - Defined separate coverage flags for frontend, backend, and LFX components. - Updated ignore patterns to exclude LFX test and component directories from coverage reports. * chore: add coverage upload steps to Python CI workflow - Implemented steps to upload coverage reports to Codecov for Python 3.10. - Added artifact upload for coverage reports, retaining them for 30 days. * chore: update LFX coverage target in codecov configuration - Increased the LFX coverage target from 40% to 60% to encourage aspirational improvement. - Clarified the allowable drop in coverage threshold from 44% to 39% without failing the status check. * chore: update coverage configuration in pyproject.toml - Enabled branch coverage in the coverage run configuration. - Fixed a typo in the main module check to ensure proper execution.
This commit is contained in:
committed by
GitHub
parent
c6a3bdbbab
commit
2a6461560d
21
.github/workflows/python_test.yml
vendored
21
.github/workflows/python_test.yml
vendored
@ -168,6 +168,27 @@ jobs:
|
||||
env:
|
||||
DO_NOT_TRACK: true # disable telemetry reporting
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v5
|
||||
if: matrix.python-version == '3.10'
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./src/lfx/coverage.xml
|
||||
flags: lfx
|
||||
name: lfx-coverage
|
||||
fail_ci_if_error: false
|
||||
directory: ./src/lfx/
|
||||
|
||||
- name: Upload coverage artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
if: matrix.python-version == '3.10'
|
||||
with:
|
||||
name: lfx-coverage-report
|
||||
path: |
|
||||
src/lfx/coverage.xml
|
||||
src/lfx/htmlcov/
|
||||
retention-days: 30
|
||||
|
||||
test-cli:
|
||||
name: Test CLI - Python ${{ matrix.python-version }}
|
||||
runs-on: ${{ (inputs['runs-on'] && startsWith(format('{0}', inputs['runs-on']), '[') && fromJSON(inputs['runs-on'])) || inputs['runs-on'] || github.event.inputs['runs-on'] || 'ubuntu-latest' }}
|
||||
|
||||
2
Makefile
2
Makefile
@ -171,7 +171,7 @@ lfx_tests: ## run lfx package unit tests
|
||||
@echo 'Running LFX Package Tests...'
|
||||
@cd src/lfx && \
|
||||
uv sync && \
|
||||
uv run pytest tests/unit -v $(args)
|
||||
uv run pytest tests/unit -v --cov=src/lfx --cov-report=xml --cov-report=html --cov-report=term-missing $(args)
|
||||
|
||||
integration_tests:
|
||||
uv run pytest src/backend/tests/integration \
|
||||
|
||||
22
codecov.yml
22
codecov.yml
@ -36,6 +36,17 @@ coverage:
|
||||
flags:
|
||||
- frontend
|
||||
|
||||
# LFX coverage: Target for core package (excludes components)
|
||||
# Components (third-party integrations) tracked separately
|
||||
# Current core coverage: ~44%, Target: 60% (aspirational improvement)
|
||||
lfx:
|
||||
target: 60%
|
||||
# Threshold: Allowable drop in coverage before failing the check
|
||||
# 5% = coverage can drop from 44% to 39% without failing status
|
||||
threshold: 5%
|
||||
flags:
|
||||
- lfx
|
||||
|
||||
# New code coverage requirements - realistic target for current state
|
||||
# Encourages testing new features without blocking development
|
||||
patch:
|
||||
@ -51,7 +62,7 @@ comment:
|
||||
require_base: false # Don't require base branch comparison
|
||||
require_head: true # Require current branch coverage
|
||||
|
||||
# Define separate coverage tracking for frontend and backend
|
||||
# Define separate coverage tracking for frontend, backend, and lfx
|
||||
flags:
|
||||
backend:
|
||||
paths:
|
||||
@ -61,6 +72,10 @@ flags:
|
||||
paths:
|
||||
- src/frontend/
|
||||
carryforward: true # Preserve coverage data across builds if missing
|
||||
lfx:
|
||||
paths:
|
||||
- src/lfx/
|
||||
carryforward: true # Preserve coverage data across builds if missing
|
||||
|
||||
# Define coverage components for granular reporting
|
||||
component_management:
|
||||
@ -86,6 +101,7 @@ ignore:
|
||||
- "src/backend/tests/**"
|
||||
- "src/frontend/tests/**"
|
||||
- "src/frontend/test-results/**"
|
||||
- "src/lfx/tests/**"
|
||||
# Build artifacts and dependencies
|
||||
- "**/__pycache__/**"
|
||||
- "**/*.pyc"
|
||||
@ -94,4 +110,6 @@ ignore:
|
||||
# Python package init files - typically just imports
|
||||
- "**/__init__.py"
|
||||
# Database migrations
|
||||
- "**/migrations/**"
|
||||
- "**/migrations/**"
|
||||
# LFX components - third-party integrations tracked separately
|
||||
- "src/lfx/components/**"
|
||||
@ -125,5 +125,25 @@ dev = [
|
||||
"hypothesis>=6.136.3",
|
||||
"pytest>=8.4.1",
|
||||
"pytest-asyncio>=0.26.0",
|
||||
"pytest-cov>=7.0.0",
|
||||
"ruff>=0.9.10",
|
||||
]
|
||||
|
||||
[tool.coverage.run]
|
||||
branch = true
|
||||
omit = [
|
||||
"*/tests/*",
|
||||
"*/__init__.py",
|
||||
"*/components/*", # Third-party integrations tracked separately
|
||||
]
|
||||
|
||||
[tool.coverage.report]
|
||||
exclude_lines = [
|
||||
"pragma: no cover",
|
||||
"def __repr__",
|
||||
"raise AssertionError",
|
||||
"raise NotImplementedError",
|
||||
"if __name__ == '__main__':",
|
||||
"if TYPE_CHECKING:",
|
||||
"@abstractmethod",
|
||||
]
|
||||
|
||||
34
uv.lock
generated
34
uv.lock
generated
@ -2824,10 +2824,10 @@ name = "gassist"
|
||||
version = "0.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "python_full_version < '3.12' or platform_machine != 'arm64' or sys_platform != 'darwin'" },
|
||||
{ name = "flask", marker = "python_full_version < '3.12' or platform_machine != 'arm64' or sys_platform != 'darwin'" },
|
||||
{ name = "flask-cors", marker = "python_full_version < '3.12' or platform_machine != 'arm64' or sys_platform != 'darwin'" },
|
||||
{ name = "tqdm", marker = "python_full_version < '3.12' or platform_machine != 'arm64' or sys_platform != 'darwin'" },
|
||||
{ name = "colorama", marker = "(python_full_version >= '3.12' and platform_machine != 'arm64' and sys_platform == 'darwin') or (python_full_version >= '3.12' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" },
|
||||
{ name = "flask", marker = "(python_full_version >= '3.12' and platform_machine != 'arm64' and sys_platform == 'darwin') or (python_full_version >= '3.12' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" },
|
||||
{ name = "flask-cors", marker = "(python_full_version >= '3.12' and platform_machine != 'arm64' and sys_platform == 'darwin') or (python_full_version >= '3.12' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" },
|
||||
{ name = "tqdm", marker = "(python_full_version >= '3.12' and platform_machine != 'arm64' and sys_platform == 'darwin') or (python_full_version >= '3.12' and sys_platform == 'linux') or (platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" },
|
||||
]
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/2e/f79632d7300874f7f0e60b61a6ab22455a245e1556116a1729542a77b0da/gassist-0.0.1-py3-none-any.whl", hash = "sha256:bb0fac74b453153a6c74b2db40a14fdde7879cbc10ec692ed170e576c8e2b6aa", size = 23819, upload-time = "2025-05-09T18:22:23.609Z" },
|
||||
@ -5864,6 +5864,7 @@ dev = [
|
||||
{ name = "hypothesis" },
|
||||
{ name = "pytest" },
|
||||
{ name = "pytest-asyncio" },
|
||||
{ name = "pytest-cov" },
|
||||
{ name = "ruff" },
|
||||
]
|
||||
|
||||
@ -5910,6 +5911,7 @@ dev = [
|
||||
{ name = "hypothesis", specifier = ">=6.136.3" },
|
||||
{ name = "pytest", specifier = ">=8.4.1" },
|
||||
{ name = "pytest-asyncio", specifier = ">=0.26.0" },
|
||||
{ name = "pytest-cov", specifier = ">=7.0.0" },
|
||||
{ name = "ruff", specifier = ">=0.9.10" },
|
||||
]
|
||||
|
||||
@ -7388,9 +7390,9 @@ name = "ocrmac"
|
||||
version = "1.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
{ name = "pillow" },
|
||||
{ name = "pyobjc-framework-vision" },
|
||||
{ name = "click", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
{ name = "pillow", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
{ name = "pyobjc-framework-vision", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/dd/dc/de3e9635774b97d9766f6815bbb3f5ec9bce347115f10d9abbf2733a9316/ocrmac-1.0.0.tar.gz", hash = "sha256:5b299e9030c973d1f60f82db000d6c2e5ff271601878c7db0885e850597d1d2e", size = 1463997, upload-time = "2024-11-07T12:00:00.197Z" }
|
||||
wheels = [
|
||||
@ -9826,7 +9828,7 @@ name = "pyobjc-framework-cocoa"
|
||||
version = "11.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyobjc-core" },
|
||||
{ name = "pyobjc-core", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4b/c5/7a866d24bc026f79239b74d05e2cf3088b03263da66d53d1b4cf5207f5ae/pyobjc_framework_cocoa-11.1.tar.gz", hash = "sha256:87df76b9b73e7ca699a828ff112564b59251bb9bbe72e610e670a4dc9940d038", size = 5565335, upload-time = "2025-06-14T20:56:59.683Z" }
|
||||
wheels = [
|
||||
@ -9842,8 +9844,8 @@ name = "pyobjc-framework-coreml"
|
||||
version = "11.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyobjc-core" },
|
||||
{ name = "pyobjc-framework-cocoa" },
|
||||
{ name = "pyobjc-core", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
{ name = "pyobjc-framework-cocoa", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0d/5d/4309f220981d769b1a2f0dcb2c5c104490d31389a8ebea67e5595ce1cb74/pyobjc_framework_coreml-11.1.tar.gz", hash = "sha256:775923eefb9eac2e389c0821b10564372de8057cea89f1ea1cdaf04996c970a7", size = 82005, upload-time = "2025-06-14T20:57:12.004Z" }
|
||||
wheels = [
|
||||
@ -9859,8 +9861,8 @@ name = "pyobjc-framework-quartz"
|
||||
version = "11.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyobjc-core" },
|
||||
{ name = "pyobjc-framework-cocoa" },
|
||||
{ name = "pyobjc-core", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
{ name = "pyobjc-framework-cocoa", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/ac/6308fec6c9ffeda9942fef72724f4094c6df4933560f512e63eac37ebd30/pyobjc_framework_quartz-11.1.tar.gz", hash = "sha256:a57f35ccfc22ad48c87c5932818e583777ff7276605fef6afad0ac0741169f75", size = 3953275, upload-time = "2025-06-14T20:58:17.924Z" }
|
||||
wheels = [
|
||||
@ -9876,10 +9878,10 @@ name = "pyobjc-framework-vision"
|
||||
version = "11.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pyobjc-core" },
|
||||
{ name = "pyobjc-framework-cocoa" },
|
||||
{ name = "pyobjc-framework-coreml" },
|
||||
{ name = "pyobjc-framework-quartz" },
|
||||
{ name = "pyobjc-core", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
{ name = "pyobjc-framework-cocoa", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
{ name = "pyobjc-framework-coreml", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
{ name = "pyobjc-framework-quartz", marker = "python_full_version >= '3.12' or sys_platform == 'darwin'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/40/a8/7128da4d0a0103cabe58910a7233e2f98d18c590b1d36d4b3efaaedba6b9/pyobjc_framework_vision-11.1.tar.gz", hash = "sha256:26590512ee7758da3056499062a344b8a351b178be66d4b719327884dde4216b", size = 133721, upload-time = "2025-06-14T20:58:46.095Z" }
|
||||
wheels = [
|
||||
|
||||
Reference in New Issue
Block a user