mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-27 00:44:21 +08:00
fix: Build and install the langflow-sdk for lfx (fixes nightly) (#12481)
* fix: Build and install the langflow-sdk for lfx * Publish sdk as a nightly * Update ci.yml * Update python_test.yml * Update ci.yml
This commit is contained in:
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -426,7 +426,7 @@ jobs:
|
||||
DOCS_ONLY: ${{ needs.path-filter.outputs.docs-only }}
|
||||
EXIT_CODE: ${{ (contains(needs.*.result, 'failure') ||
|
||||
contains(needs.*.result, 'cancelled') ||
|
||||
(needs.check-nightly-status.outputs.should-proceed != 'true' && github.event_name != 'workflow_dispatch' && needs.path-filter.outputs.docs-only != 'true'))
|
||||
(needs.check-nightly-status.outputs.should-proceed != 'true' && github.event_name != 'workflow_dispatch' && github.event_name != 'merge_group' && needs.path-filter.outputs.docs-only != 'true' && !contains(github.event.pull_request.labels.*.name, 'skip-nightly-check')))
|
||||
&& '1' || '0' }}
|
||||
steps:
|
||||
- name: "CI Success"
|
||||
|
||||
108
.github/workflows/cross-platform-test.yml
vendored
108
.github/workflows/cross-platform-test.yml
vendored
@ -22,6 +22,10 @@ on:
|
||||
description: "Name of the LFX package artifact"
|
||||
required: false
|
||||
type: string
|
||||
sdk-artifact-name:
|
||||
description: "Name of the langflow-sdk package artifact"
|
||||
required: false
|
||||
type: string
|
||||
pre_release:
|
||||
description: "Whether this is a pre-release build"
|
||||
required: false
|
||||
@ -161,6 +165,13 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
# Download artifacts for wheel installation
|
||||
- name: Download langflow-sdk package artifact
|
||||
if: steps.install-method.outputs.method == 'wheel' && inputs.sdk-artifact-name != ''
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: ${{ inputs.sdk-artifact-name }}
|
||||
path: ./sdk-dist
|
||||
|
||||
- name: Download LFX package artifact
|
||||
if: steps.install-method.outputs.method == 'wheel' && inputs.lfx-artifact-name != ''
|
||||
uses: actions/download-artifact@v7
|
||||
@ -187,9 +198,38 @@ jobs:
|
||||
uv venv test-env --seed
|
||||
shell: bash
|
||||
|
||||
# Wheel installation steps
|
||||
# Wheel installation steps — install SDK and LFX together when both are present.
|
||||
- name: Install SDK and LFX packages from wheel (Windows)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os == 'windows' && inputs.sdk-artifact-name != '' && inputs.lfx-artifact-name != ''
|
||||
run: |
|
||||
ls -la ./sdk-dist/
|
||||
find ./sdk-dist -name "*.whl" -type f
|
||||
ls -la ./lfx-dist/
|
||||
find ./lfx-dist -name "*.whl" -type f
|
||||
SDK_WHEEL_FILE=$(find ./sdk-dist -name "*.whl" -type f | head -1)
|
||||
LFX_WHEEL_FILE=$(find ./lfx-dist -name "*.whl" -type f | head -1)
|
||||
if [ -n "$SDK_WHEEL_FILE" ] && [ -n "$LFX_WHEEL_FILE" ]; then
|
||||
uv pip install --prerelease=allow --python ./test-env/Scripts/python.exe "$SDK_WHEEL_FILE" "$LFX_WHEEL_FILE"
|
||||
else
|
||||
echo "Missing wheel file in ./sdk-dist/ or ./lfx-dist/"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Install SDK package from wheel (Windows)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os == 'windows' && inputs.sdk-artifact-name != '' && inputs.lfx-artifact-name == ''
|
||||
run: |
|
||||
WHEEL_FILE=$(find ./sdk-dist -name "*.whl" -type f | head -1)
|
||||
if [ -n "$WHEEL_FILE" ]; then
|
||||
uv pip install --prerelease=allow --python ./test-env/Scripts/python.exe "$WHEEL_FILE"
|
||||
else
|
||||
echo "No wheel file found in ./sdk-dist/"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Install LFX package from wheel (Windows)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os == 'windows' && inputs.lfx-artifact-name != ''
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os == 'windows' && inputs.lfx-artifact-name != '' && inputs.sdk-artifact-name == ''
|
||||
run: |
|
||||
ls -la ./lfx-dist/
|
||||
find ./lfx-dist -name "*.whl" -type f
|
||||
@ -230,8 +270,37 @@ jobs:
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Install SDK and LFX packages from wheel (Unix)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os != 'windows' && inputs.sdk-artifact-name != '' && inputs.lfx-artifact-name != ''
|
||||
run: |
|
||||
ls -la ./sdk-dist/
|
||||
find ./sdk-dist -name "*.whl" -type f
|
||||
ls -la ./lfx-dist/
|
||||
find ./lfx-dist -name "*.whl" -type f
|
||||
SDK_WHEEL_FILE=$(find ./sdk-dist -name "*.whl" -type f | head -1)
|
||||
LFX_WHEEL_FILE=$(find ./lfx-dist -name "*.whl" -type f | head -1)
|
||||
if [ -n "$SDK_WHEEL_FILE" ] && [ -n "$LFX_WHEEL_FILE" ]; then
|
||||
uv pip install --prerelease=allow --python ./test-env/bin/python "$SDK_WHEEL_FILE" "$LFX_WHEEL_FILE"
|
||||
else
|
||||
echo "Missing wheel file in ./sdk-dist/ or ./lfx-dist/"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Install SDK package from wheel (Unix)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os != 'windows' && inputs.sdk-artifact-name != '' && inputs.lfx-artifact-name == ''
|
||||
run: |
|
||||
WHEEL_FILE=$(find ./sdk-dist -name "*.whl" -type f | head -1)
|
||||
if [ -n "$WHEEL_FILE" ]; then
|
||||
uv pip install --prerelease=allow --python ./test-env/bin/python "$WHEEL_FILE"
|
||||
else
|
||||
echo "No wheel file found in ./sdk-dist/"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Install LFX package from wheel (Unix)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os != 'windows' && inputs.lfx-artifact-name != ''
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os != 'windows' && inputs.lfx-artifact-name != '' && inputs.sdk-artifact-name == ''
|
||||
run: |
|
||||
ls -la ./lfx-dist/
|
||||
find ./lfx-dist -name "*.whl" -type f
|
||||
@ -460,6 +529,13 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
# Download artifacts for wheel installation
|
||||
- name: Download langflow-sdk package artifact
|
||||
if: steps.install-method.outputs.method == 'wheel' && inputs.sdk-artifact-name != ''
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: ${{ inputs.sdk-artifact-name }}
|
||||
path: ./sdk-dist
|
||||
|
||||
- name: Download LFX package artifact
|
||||
if: steps.install-method.outputs.method == 'wheel' && inputs.lfx-artifact-name != ''
|
||||
uses: actions/download-artifact@v7
|
||||
@ -486,7 +562,31 @@ jobs:
|
||||
uv venv test-env --seed
|
||||
shell: bash
|
||||
|
||||
# Wheel installation steps
|
||||
# Wheel installation steps — install langflow-sdk before LFX (sdk is not yet on PyPI)
|
||||
- name: Install langflow-sdk from wheel (Windows)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os == 'windows' && inputs.sdk-artifact-name != ''
|
||||
run: |
|
||||
WHEEL_FILE=$(find ./sdk-dist -name "*.whl" -type f | head -1)
|
||||
if [ -n "$WHEEL_FILE" ]; then
|
||||
uv pip install --prerelease=allow --python ./test-env/Scripts/python.exe "$WHEEL_FILE"
|
||||
else
|
||||
echo "No wheel file found in ./sdk-dist/"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Install langflow-sdk from wheel (Unix)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os != 'windows' && inputs.sdk-artifact-name != ''
|
||||
run: |
|
||||
WHEEL_FILE=$(find ./sdk-dist -name "*.whl" -type f | head -1)
|
||||
if [ -n "$WHEEL_FILE" ]; then
|
||||
uv pip install --prerelease=allow --python ./test-env/bin/python "$WHEEL_FILE"
|
||||
else
|
||||
echo "No wheel file found in ./sdk-dist/"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Install LFX package from wheel (Windows)
|
||||
if: steps.install-method.outputs.method == 'wheel' && matrix.os == 'windows' && inputs.lfx-artifact-name != ''
|
||||
run: |
|
||||
|
||||
17
.github/workflows/nightly_build.yml
vendored
17
.github/workflows/nightly_build.yml
vendored
@ -85,6 +85,7 @@ jobs:
|
||||
release_tag: ${{ steps.generate_release_tag.outputs.release_tag }}
|
||||
base_tag: ${{ steps.set_base_tag.outputs.base_tag }}
|
||||
lfx_tag: ${{ steps.generate_lfx_tag.outputs.lfx_tag }}
|
||||
sdk_tag: ${{ steps.generate_sdk_tag.outputs.sdk_tag }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
@ -138,6 +139,14 @@ jobs:
|
||||
echo "lfx_tag=$LFX_TAG" >> $GITHUB_OUTPUT
|
||||
echo "lfx_tag=$LFX_TAG"
|
||||
|
||||
- name: Generate SDK nightly tag
|
||||
id: generate_sdk_tag
|
||||
run: |
|
||||
# NOTE: This outputs the tag with the `v` prefix.
|
||||
SDK_TAG="$(uv run ./scripts/ci/sdk_nightly_tag.py)"
|
||||
echo "sdk_tag=$SDK_TAG" >> $GITHUB_OUTPUT
|
||||
echo "sdk_tag=$SDK_TAG"
|
||||
|
||||
- name: Commit tag
|
||||
id: commit_tag
|
||||
run: |
|
||||
@ -149,8 +158,11 @@ jobs:
|
||||
RELEASE_TAG="${{ steps.generate_release_tag.outputs.release_tag }}"
|
||||
BASE_TAG="${{ steps.generate_base_tag.outputs.base_tag }}"
|
||||
LFX_TAG="${{ steps.generate_lfx_tag.outputs.lfx_tag }}"
|
||||
SDK_TAG="${{ steps.generate_sdk_tag.outputs.sdk_tag }}"
|
||||
echo "Updating SDK project version to $SDK_TAG"
|
||||
uv run --no-sync ./scripts/ci/update_sdk_version.py $SDK_TAG
|
||||
echo "Updating LFX project version to $LFX_TAG"
|
||||
uv run ./scripts/ci/update_lfx_version.py $LFX_TAG
|
||||
uv run --no-sync ./scripts/ci/update_lfx_version.py $LFX_TAG $SDK_TAG
|
||||
echo "Updating base project version to $BASE_TAG and updating main project version to $RELEASE_TAG"
|
||||
uv run --no-sync ./scripts/ci/update_pyproject_combined.py main $RELEASE_TAG $BASE_TAG $LFX_TAG
|
||||
|
||||
@ -158,7 +170,7 @@ jobs:
|
||||
cd src/backend/base && uv lock && cd ../../..
|
||||
cd src/lfx && uv lock && cd ../..
|
||||
|
||||
git add pyproject.toml src/backend/base/pyproject.toml src/lfx/pyproject.toml uv.lock src/backend/base/uv.lock
|
||||
git add pyproject.toml src/backend/base/pyproject.toml src/lfx/pyproject.toml src/sdk/pyproject.toml uv.lock src/backend/base/uv.lock
|
||||
git commit -m "Update version and project name"
|
||||
|
||||
echo "Tagging main with $RELEASE_TAG"
|
||||
@ -278,6 +290,7 @@ jobs:
|
||||
nightly_tag_release: ${{ needs.create-nightly-tag.outputs.release_tag }}
|
||||
nightly_tag_base: ${{ needs.create-nightly-tag.outputs.base_tag }}
|
||||
nightly_tag_lfx: ${{ needs.create-nightly-tag.outputs.lfx_tag }}
|
||||
nightly_tag_sdk: ${{ needs.create-nightly-tag.outputs.sdk_tag }}
|
||||
# When triggered by schedule, inputs.push_to_registry is not set, so default to true
|
||||
# When triggered manually, use the provided value (default is also true)
|
||||
push_to_registry: ${{ github.event_name == 'schedule' || inputs.push_to_registry != false }}
|
||||
|
||||
2
.github/workflows/python_test.yml
vendored
2
.github/workflows/python_test.yml
vendored
@ -93,7 +93,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 12
|
||||
timeout_minutes: 15
|
||||
max_attempts: 2
|
||||
command: make unit_tests args="-x -vv --splits ${{ matrix.splitCount }} --group ${{ matrix.group }} --reruns 5 --cov --cov-config=src/backend/.coveragerc --cov-report=xml --cov-report=html"
|
||||
|
||||
|
||||
66
.github/workflows/release_nightly.yml
vendored
66
.github/workflows/release_nightly.yml
vendored
@ -36,6 +36,10 @@ on:
|
||||
description: "Tag for the nightly LFX build"
|
||||
required: false
|
||||
type: string
|
||||
nightly_tag_sdk:
|
||||
description: "Tag for the nightly SDK build"
|
||||
required: false
|
||||
type: string
|
||||
push_to_registry:
|
||||
description: "Whether to push images to registries. Set to false for testing builds without publishing."
|
||||
required: true
|
||||
@ -72,6 +76,20 @@ jobs:
|
||||
- name: Install LFX dependencies
|
||||
run: cd src/lfx && uv sync
|
||||
|
||||
- name: Verify SDK Nightly Name and Version
|
||||
if: ${{ inputs.build_lfx }}
|
||||
run: |
|
||||
name=$(grep '^name = "' src/sdk/pyproject.toml | head -n 1 | sed 's/.*"\(.*\)".*/\1/')
|
||||
version=$(grep '^version = "' src/sdk/pyproject.toml | head -n 1 | sed 's/.*"\(.*\)".*/\1/')
|
||||
if [ "$name" != "langflow-sdk-nightly" ]; then
|
||||
echo "Name $name does not match langflow-sdk-nightly. Exiting the workflow."
|
||||
exit 1
|
||||
fi
|
||||
if [ "v$version" != "${{ inputs.nightly_tag_sdk }}" ]; then
|
||||
echo "Version v$version does not match nightly tag ${{ inputs.nightly_tag_sdk }}. Exiting the workflow."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Verify Nightly Name and Version
|
||||
id: verify
|
||||
run: |
|
||||
@ -90,6 +108,10 @@ jobs:
|
||||
version=$(echo $version | sed 's/^v//')
|
||||
echo "version=$version" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build langflow-sdk for distribution
|
||||
run: |
|
||||
make sdk_build args="--wheel"
|
||||
|
||||
- name: Build LFX for distribution
|
||||
run: |
|
||||
cd src/lfx
|
||||
@ -99,12 +121,21 @@ jobs:
|
||||
- name: Test LFX CLI
|
||||
run: |
|
||||
cd src/lfx
|
||||
uv pip install dist/*.whl --force-reinstall
|
||||
uv run lfx --help
|
||||
# Use a clean venv and install both wheels together so uv can resolve
|
||||
# the local SDK dependency without falling back to PyPI.
|
||||
uv venv test-env --seed
|
||||
uv pip install --python ./test-env/bin/python --force-reinstall ../sdk/dist/*.whl dist/*.whl
|
||||
./test-env/bin/lfx --help
|
||||
echo "LFX CLI test completed successfully"
|
||||
|
||||
# PyPI publishing moved to after cross-platform testing
|
||||
|
||||
- name: Upload langflow-sdk Artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: dist-nightly-sdk
|
||||
path: src/sdk/dist
|
||||
|
||||
- name: Upload LFX Artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
@ -316,10 +347,11 @@ jobs:
|
||||
base-artifact-name: "dist-nightly-base"
|
||||
main-artifact-name: "dist-nightly-main"
|
||||
lfx-artifact-name: "dist-nightly-lfx"
|
||||
sdk-artifact-name: "dist-nightly-sdk"
|
||||
|
||||
publish-nightly-lfx:
|
||||
name: Publish LFX Nightly to PyPI
|
||||
needs: [build-nightly-lfx, test-cross-platform]
|
||||
needs: [build-nightly-lfx, test-cross-platform, publish-nightly-sdk]
|
||||
if: ${{ inputs.build_lfx }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@ -345,6 +377,34 @@ jobs:
|
||||
run: |
|
||||
make lfx_publish
|
||||
|
||||
publish-nightly-sdk:
|
||||
name: Publish SDK Nightly to PyPI
|
||||
needs: [build-nightly-lfx, test-cross-platform]
|
||||
if: ${{ inputs.build_lfx }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.nightly_tag_release }}
|
||||
persist-credentials: true
|
||||
- name: Download langflow-sdk artifact
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: dist-nightly-sdk
|
||||
path: src/sdk/dist
|
||||
- name: Setup Environment
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
enable-cache: false
|
||||
python-version: "3.13"
|
||||
- name: Publish SDK to PyPI
|
||||
env:
|
||||
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
|
||||
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
||||
run: |
|
||||
make sdk_publish
|
||||
|
||||
publish-nightly-base:
|
||||
name: Publish Langflow Base Nightly to PyPI
|
||||
needs: [build-nightly-base, test-cross-platform, publish-nightly-lfx]
|
||||
|
||||
@ -187,7 +187,7 @@
|
||||
"filename": ".github/workflows/nightly_build.yml",
|
||||
"hashed_secret": "3e26d6750975d678acb8fa35a0f69237881576b0",
|
||||
"is_verified": false,
|
||||
"line_number": 284,
|
||||
"line_number": 297,
|
||||
"is_secret": false
|
||||
}
|
||||
],
|
||||
@ -207,7 +207,7 @@
|
||||
"filename": ".github/workflows/release_nightly.yml",
|
||||
"hashed_secret": "3e26d6750975d678acb8fa35a0f69237881576b0",
|
||||
"is_verified": false,
|
||||
"line_number": 413,
|
||||
"line_number": 473,
|
||||
"is_secret": false
|
||||
}
|
||||
],
|
||||
@ -7315,5 +7315,5 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"generated_at": "2026-04-02T17:27:24Z"
|
||||
"generated_at": "2026-04-03T04:00:10Z"
|
||||
}
|
||||
|
||||
42
Makefile
42
Makefile
@ -490,6 +490,38 @@ lfx_docker_test: ## run LFX tests in Docker
|
||||
@echo 'Running LFX tests in Docker'
|
||||
@cd src/lfx && make docker_test
|
||||
|
||||
######################
|
||||
# SDK PACKAGE
|
||||
######################
|
||||
|
||||
sdk_build: ## build the SDK package
|
||||
@echo 'Building SDK package'
|
||||
@cd src/sdk && make build
|
||||
|
||||
sdk_publish: ## publish SDK package to PyPI
|
||||
@echo 'Publishing SDK package'
|
||||
@cd src/sdk && make publish
|
||||
|
||||
sdk_publish_testpypi: ## publish SDK package to test PyPI
|
||||
@echo 'Publishing SDK package to test PyPI'
|
||||
@cd src/sdk && make publish_test
|
||||
|
||||
sdk_test: ## run SDK tests
|
||||
@echo 'Running SDK tests'
|
||||
@cd src/sdk && make test
|
||||
|
||||
sdk_format: ## format SDK code
|
||||
@echo 'Formatting SDK code'
|
||||
@cd src/sdk && make format
|
||||
|
||||
sdk_lint: ## lint SDK code
|
||||
@echo 'Linting SDK code'
|
||||
@cd src/sdk && make lint
|
||||
|
||||
sdk_clean: ## clean SDK build artifacts
|
||||
@echo 'Cleaning SDK build artifacts'
|
||||
@cd src/sdk && make clean
|
||||
|
||||
# example make alembic-revision message="Add user table"
|
||||
alembic-revision: ## generate a new migration
|
||||
@echo 'Generating a new Alembic revision'
|
||||
@ -877,6 +909,14 @@ help_backend: ## show backend-specific commands
|
||||
@echo " $(GREEN)make lfx_docker_dev$(NC) - Start LFX development environment"
|
||||
@echo " $(GREEN)make lfx_docker_test$(NC) - Run LFX tests in Docker"
|
||||
@echo ''
|
||||
@echo "$(GREEN)SDK Package Commands:$(NC)"
|
||||
@echo " $(GREEN)make sdk_build$(NC) - Build SDK package"
|
||||
@echo " $(GREEN)make sdk_test$(NC) - Run SDK tests"
|
||||
@echo " $(GREEN)make sdk_format$(NC) - Format SDK code"
|
||||
@echo " $(GREEN)make sdk_lint$(NC) - Lint SDK code"
|
||||
@echo " $(GREEN)make sdk_clean$(NC) - Clean SDK build artifacts"
|
||||
@echo " $(GREEN)make sdk_publish$(NC) - Publish SDK to PyPI"
|
||||
@echo ''
|
||||
@echo "$(GREEN)═══════════════════════════════════════════════════════════════════$(NC)"
|
||||
@echo ''
|
||||
|
||||
@ -983,6 +1023,8 @@ help_advanced: ## show advanced and miscellaneous commands
|
||||
@echo " $(GREEN)make publish_langflow$(NC) - Publish langflow to PyPI"
|
||||
@echo " $(GREEN)make lfx_publish$(NC) - Publish LFX package to PyPI"
|
||||
@echo " $(GREEN)make lfx_publish_testpypi$(NC) - Publish LFX to test PyPI"
|
||||
@echo " $(GREEN)make sdk_publish$(NC) - Publish SDK package to PyPI"
|
||||
@echo " $(GREEN)make sdk_publish_testpypi$(NC) - Publish SDK to test PyPI"
|
||||
@echo ''
|
||||
@echo "$(GREEN)Lock Files:$(NC)"
|
||||
@echo " $(GREEN)make lock$(NC) - Lock all dependencies"
|
||||
|
||||
63
scripts/ci/sdk_nightly_tag.py
Normal file
63
scripts/ci/sdk_nightly_tag.py
Normal file
@ -0,0 +1,63 @@
|
||||
"""Script to generate nightly tags for the SDK package."""
|
||||
|
||||
import packaging.version
|
||||
import requests
|
||||
from packaging.version import Version
|
||||
|
||||
PYPI_SDK_URL = "https://pypi.org/pypi/langflow-sdk/json"
|
||||
PYPI_SDK_NIGHTLY_URL = "https://pypi.org/pypi/langflow-sdk-nightly/json"
|
||||
|
||||
|
||||
def get_latest_published_version(*, is_nightly: bool) -> Version:
|
||||
url = PYPI_SDK_NIGHTLY_URL if is_nightly else PYPI_SDK_URL
|
||||
|
||||
res = requests.get(url, timeout=10)
|
||||
if res.status_code == requests.codes.not_found:
|
||||
msg = "Package not found on PyPI"
|
||||
raise requests.RequestException(msg)
|
||||
|
||||
try:
|
||||
version_str = res.json()["info"]["version"]
|
||||
except (KeyError, ValueError) as e:
|
||||
msg = "Got unexpected response from PyPI"
|
||||
raise requests.RequestException(msg) from e
|
||||
return Version(version_str)
|
||||
|
||||
|
||||
def create_sdk_tag():
|
||||
from pathlib import Path
|
||||
|
||||
import tomllib
|
||||
|
||||
sdk_pyproject_path = Path(__file__).parent.parent.parent / "src" / "sdk" / "pyproject.toml"
|
||||
pyproject_data = tomllib.loads(sdk_pyproject_path.read_text())
|
||||
|
||||
current_version_str = pyproject_data["project"]["version"]
|
||||
current_version = Version(current_version_str)
|
||||
|
||||
try:
|
||||
current_nightly_version = get_latest_published_version(is_nightly=True)
|
||||
nightly_base_version = current_nightly_version.base_version
|
||||
except (requests.RequestException, KeyError, ValueError):
|
||||
current_nightly_version = None
|
||||
nightly_base_version = None
|
||||
|
||||
build_number = "0"
|
||||
latest_base_version = current_version.base_version
|
||||
|
||||
if current_nightly_version and latest_base_version == nightly_base_version:
|
||||
build_number = str(current_nightly_version.dev + 1)
|
||||
|
||||
new_nightly_version = latest_base_version + ".dev" + build_number
|
||||
|
||||
if not new_nightly_version.startswith("v"):
|
||||
new_nightly_version = "v" + new_nightly_version
|
||||
|
||||
packaging.version.Version(new_nightly_version)
|
||||
|
||||
return new_nightly_version
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tag = create_sdk_tag()
|
||||
print(tag)
|
||||
@ -34,11 +34,28 @@ def update_lfx_workspace_dep(pyproject_path: str, new_project_name: str) -> None
|
||||
filepath.write_text(content, encoding="utf-8")
|
||||
|
||||
|
||||
def update_lfx_for_nightly(lfx_tag: str):
|
||||
def update_sdk_dependency_in_lfx(pyproject_path: str, sdk_version: str) -> None:
|
||||
"""Update the SDK dependency in the LFX pyproject for nightly builds."""
|
||||
filepath = BASE_DIR / pyproject_path
|
||||
content = filepath.read_text(encoding="utf-8")
|
||||
|
||||
pattern = re.compile(r'"langflow-sdk(?:-nightly)?(?:==|~=|>=)[\d.]+(?:\.(?:post|dev|a|b|rc)\d+)*"')
|
||||
replacement = f'"langflow-sdk-nightly=={sdk_version}"'
|
||||
|
||||
if not pattern.search(content):
|
||||
msg = f"SDK dependency not found in {filepath}"
|
||||
raise ValueError(msg)
|
||||
|
||||
content = pattern.sub(replacement, content)
|
||||
filepath.write_text(content, encoding="utf-8")
|
||||
|
||||
|
||||
def update_lfx_for_nightly(lfx_tag: str, sdk_tag: str):
|
||||
"""Update LFX package for nightly build.
|
||||
|
||||
Args:
|
||||
lfx_tag: The nightly tag for LFX (e.g., "v0.1.0.dev0")
|
||||
sdk_tag: The nightly tag for the SDK (e.g., "v0.1.0.dev0")
|
||||
"""
|
||||
lfx_pyproject_path = "src/lfx/pyproject.toml"
|
||||
|
||||
@ -52,6 +69,9 @@ def update_lfx_for_nightly(lfx_tag: str):
|
||||
# Update workspace dependency in root pyproject.toml
|
||||
update_lfx_workspace_dep("pyproject.toml", "lfx-nightly")
|
||||
|
||||
sdk_version = sdk_tag.lstrip("v")
|
||||
update_sdk_dependency_in_lfx(lfx_pyproject_path, sdk_version)
|
||||
|
||||
print(f"Updated LFX package to lfx-nightly version {version}")
|
||||
|
||||
|
||||
@ -59,15 +79,16 @@ def main():
|
||||
"""Update LFX for nightly builds.
|
||||
|
||||
Usage:
|
||||
update_lfx_version.py <lfx_tag>
|
||||
update_lfx_version.py <lfx_tag> <sdk_tag>
|
||||
"""
|
||||
expected_args = 2
|
||||
expected_args = 3
|
||||
if len(sys.argv) != expected_args:
|
||||
print("Usage: update_lfx_version.py <lfx_tag>")
|
||||
print("Usage: update_lfx_version.py <lfx_tag> <sdk_tag>")
|
||||
sys.exit(1)
|
||||
|
||||
lfx_tag = sys.argv[1]
|
||||
update_lfx_for_nightly(lfx_tag)
|
||||
sdk_tag = sys.argv[2]
|
||||
update_lfx_for_nightly(lfx_tag, sdk_tag)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -45,6 +45,9 @@ def update_uv_dep(pyproject_path: str, new_project_name: str) -> None:
|
||||
elif new_project_name == "langflow-base-nightly":
|
||||
pattern = re.compile(r"langflow-base = \{ workspace = true \}")
|
||||
replacement = "langflow-base-nightly = { workspace = true }"
|
||||
elif new_project_name == "langflow-sdk-nightly":
|
||||
pattern = re.compile(r"langflow-sdk = \{ workspace = true \}")
|
||||
replacement = "langflow-sdk-nightly = { workspace = true }"
|
||||
else:
|
||||
msg = f"Invalid project name: {new_project_name}"
|
||||
raise ValueError(msg)
|
||||
|
||||
40
scripts/ci/update_sdk_version.py
Normal file
40
scripts/ci/update_sdk_version.py
Normal file
@ -0,0 +1,40 @@
|
||||
"""Script to update SDK version for nightly builds."""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from update_pyproject_name import update_pyproject_name
|
||||
from update_pyproject_name import update_uv_dep as update_workspace_dep
|
||||
from update_pyproject_version import update_pyproject_version
|
||||
|
||||
# Add the current directory to the path so we can import the other scripts
|
||||
current_dir = Path(__file__).resolve().parent
|
||||
sys.path.append(str(current_dir))
|
||||
|
||||
|
||||
def update_sdk_for_nightly(sdk_tag: str):
|
||||
"""Update SDK package for nightly build."""
|
||||
sdk_pyproject_path = "src/sdk/pyproject.toml"
|
||||
|
||||
update_pyproject_name(sdk_pyproject_path, "langflow-sdk-nightly")
|
||||
|
||||
version = sdk_tag.lstrip("v")
|
||||
update_pyproject_version(sdk_pyproject_path, version)
|
||||
|
||||
update_workspace_dep("pyproject.toml", "langflow-sdk-nightly")
|
||||
|
||||
print(f"Updated SDK package to langflow-sdk-nightly version {version}")
|
||||
|
||||
|
||||
def main():
|
||||
expected_args = 2
|
||||
if len(sys.argv) != expected_args:
|
||||
print("Usage: update_sdk_version.py <sdk_tag>")
|
||||
sys.exit(1)
|
||||
|
||||
sdk_tag = sys.argv[1]
|
||||
update_sdk_for_nightly(sdk_tag)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
68
src/sdk/Makefile
Normal file
68
src/sdk/Makefile
Normal file
@ -0,0 +1,68 @@
|
||||
.PHONY: all help init install dev format lint test build build_wheel build_sdist publish publish_test clean
|
||||
|
||||
# Configurations
|
||||
VERSION=$(shell grep "^version" pyproject.toml | sed 's/.*\"\(.*\)\"$$/\1/')
|
||||
GREEN=\033[0;32m
|
||||
NC=\033[0m # No Color
|
||||
|
||||
all: help
|
||||
|
||||
help: ## show this help message
|
||||
@echo '----'
|
||||
@grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | \
|
||||
awk -F ':.*##' '{printf "\033[36mmake %s\033[0m: %s\n", $$1, $$2}' | \
|
||||
column -c2 -t -s :
|
||||
@echo '----'
|
||||
|
||||
init: ## initialize the project
|
||||
@echo "$(GREEN)Installing SDK dependencies...$(NC)"
|
||||
@uv sync --dev
|
||||
@echo "$(GREEN)SDK project initialized.$(NC)"
|
||||
|
||||
install: ## install the project dependencies
|
||||
@echo "$(GREEN)Installing SDK dependencies...$(NC)"
|
||||
@uv sync
|
||||
|
||||
dev: ## install development dependencies
|
||||
@echo "$(GREEN)Installing SDK development dependencies...$(NC)"
|
||||
@uv sync --dev
|
||||
|
||||
format: dev ## format the code
|
||||
@echo "$(GREEN)Formatting SDK code...$(NC)"
|
||||
@uv run ruff check . --fix
|
||||
@uv run ruff format .
|
||||
|
||||
lint: dev ## run linters
|
||||
@echo "$(GREEN)Running SDK linters...$(NC)"
|
||||
@uv run ruff check .
|
||||
|
||||
test: dev ## run tests
|
||||
@echo "$(GREEN)Running SDK tests...$(NC)"
|
||||
@uv run pytest tests -v $(args)
|
||||
|
||||
build: ## build the project
|
||||
@echo "$(GREEN)Building SDK...$(NC)"
|
||||
@rm -rf dist/
|
||||
@uv build --out-dir dist $(args)
|
||||
@echo "$(GREEN)SDK build completed. Artifacts in dist/$(NC)"
|
||||
|
||||
build_wheel: ## build wheel only
|
||||
@make build args="--wheel"
|
||||
|
||||
build_sdist: ## build source distribution only
|
||||
@make build args="--sdist"
|
||||
|
||||
publish: ## publish to PyPI
|
||||
@echo "$(GREEN)Publishing SDK to PyPI...$(NC)"
|
||||
@uv publish
|
||||
|
||||
publish_test: ## publish to test PyPI
|
||||
@echo "$(GREEN)Publishing SDK to test PyPI...$(NC)"
|
||||
@uv publish --repository testpypi
|
||||
|
||||
clean: ## clean build artifacts
|
||||
@echo "$(GREEN)Cleaning SDK build artifacts...$(NC)"
|
||||
@rm -rf dist/
|
||||
@find . -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null || true
|
||||
@find . -type f -name '*.pyc' -delete
|
||||
@echo "$(GREEN)Cleanup completed.$(NC)"
|
||||
Reference in New Issue
Block a user