Skip to content
Draft
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .github/changes-filter.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# https://github.com/dorny/paths-filter
python:
- "src/backend/**"
- "src/langflow-services/**"
- "src/backend/**.py"
- "src/lfx/**"
- "pyproject.toml"
Expand Down Expand Up @@ -32,6 +33,7 @@ docker:
- "uv.lock"
- "pyproject.toml"
- "src/backend/**"
- "src/langflow-services/**"
- "src/frontend/**"
- "src/lfx/**"
- ".dockerignore"
Expand Down Expand Up @@ -103,6 +105,7 @@ api:

database:
- "src/backend/base/langflow/services/database/**"
- "src/langflow-services/src/langflow_services/database/**"
- "src/backend/base/langflow/alembic/**"
- "src/frontend/src/controllers/**"
- "src/frontend/tests/core/features/**"
Expand Down
63 changes: 52 additions & 11 deletions .github/workflows/cross-platform-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ on:
description: "Name of the LFX package artifact"
required: false
type: string
services-artifact-name:
description: "Name of the langflow-services package artifact"
required: false
type: string
sdk-artifact-name:
description: "Name of the langflow-sdk package artifact"
required: false
Expand All @@ -45,6 +49,7 @@ jobs:
base-artifact-name: ${{ steps.set-names.outputs.base-artifact-name }}
main-artifact-name: ${{ steps.set-names.outputs.main-artifact-name }}
lfx-artifact-name: ${{ steps.set-names.outputs.lfx-artifact-name }}
services-artifact-name: ${{ steps.set-names.outputs.services-artifact-name }}
sdk-artifact-name: ${{ steps.set-names.outputs.sdk-artifact-name }}
bundles-artifact-name: ${{ steps.set-names.outputs.bundles-artifact-name }}
steps:
Expand All @@ -62,13 +67,6 @@ jobs:
run: make install_frontendci
- name: Build frontend
run: make build_frontend
- name: Build base package
run: make build_langflow_base args="--wheel"
- name: Move base package to correct directory
run: |
# Base package builds to dist/ but should be in src/backend/base/dist/
mkdir -p src/backend/base/dist
mv dist/langflow_base*.whl src/backend/base/dist/
- name: Build LFX package
run: |
cd src/lfx
Expand All @@ -77,6 +75,17 @@ jobs:
run: |
cd src/sdk
uv build --wheel --out-dir dist
- name: Build services package
run: |
cd src/langflow-services
uv build --wheel --out-dir dist
- name: Build base package
run: make build_langflow_base args="--wheel"
- name: Move base package to correct directory
run: |
# Base package builds to dist/ but should be in src/backend/base/dist/
mkdir -p src/backend/base/dist
mv dist/langflow_base*.whl src/backend/base/dist/
- name: Build main package
run: make build_langflow args="--wheel"
- name: Build bundle wheels
Expand Down Expand Up @@ -108,6 +117,11 @@ jobs:
with:
name: adhoc-dist-sdk
path: src/sdk/dist
- name: Upload services artifact
uses: actions/upload-artifact@v6
with:
name: adhoc-dist-services
path: src/langflow-services/dist
- name: Upload base artifact
uses: actions/upload-artifact@v6
with:
Expand All @@ -130,6 +144,7 @@ jobs:
echo "base-artifact-name=adhoc-dist-base" >> $GITHUB_OUTPUT
echo "main-artifact-name=adhoc-dist-main" >> $GITHUB_OUTPUT
echo "lfx-artifact-name=adhoc-dist-lfx" >> $GITHUB_OUTPUT
echo "services-artifact-name=adhoc-dist-services" >> $GITHUB_OUTPUT
echo "sdk-artifact-name=adhoc-dist-sdk" >> $GITHUB_OUTPUT
if [ "${{ steps.build-bundles.outputs.bundles-found }}" = "1" ]; then
echo "bundles-artifact-name=adhoc-dist-bundles" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -249,6 +264,13 @@ jobs:
name: ${{ inputs.lfx-artifact-name || needs.build-if-needed.outputs.lfx-artifact-name || 'adhoc-dist-lfx' }}
path: ./lfx-dist

- name: Download services package artifact
if: steps.install-method.outputs.method == 'wheel' && (inputs.services-artifact-name != '' || needs.build-if-needed.outputs.services-artifact-name != '')
uses: actions/download-artifact@v7
with:
name: ${{ inputs.services-artifact-name || needs.build-if-needed.outputs.services-artifact-name || 'adhoc-dist-services' }}
path: ./services-dist

- name: Download base package artifact
if: steps.install-method.outputs.method == 'wheel'
uses: actions/download-artifact@v7
Expand Down Expand Up @@ -289,7 +311,7 @@ jobs:

refresh_find_links() {
FIND_LINKS=()
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./bundles-dist; do
for wheel_dir in ./sdk-dist ./lfx-dist ./services-dist ./base-dist ./bundles-dist; do
if [ -d "$wheel_dir" ]; then
FIND_LINKS+=(--find-links "$wheel_dir")
fi
Expand Down Expand Up @@ -545,6 +567,13 @@ jobs:
name: ${{ inputs.lfx-artifact-name || needs.build-if-needed.outputs.lfx-artifact-name || 'adhoc-dist-lfx' }}
path: ./lfx-dist

- name: Download services package artifact
if: steps.install-method.outputs.method == 'wheel' && (inputs.services-artifact-name != '' || needs.build-if-needed.outputs.services-artifact-name != '')
uses: actions/download-artifact@v7
with:
name: ${{ inputs.services-artifact-name || needs.build-if-needed.outputs.services-artifact-name || 'adhoc-dist-services' }}
path: ./services-dist

- name: Download base package artifact
if: steps.install-method.outputs.method == 'wheel'
uses: actions/download-artifact@v7
Expand Down Expand Up @@ -585,7 +614,7 @@ jobs:

refresh_find_links() {
FIND_LINKS=()
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./bundles-dist; do
for wheel_dir in ./sdk-dist ./lfx-dist ./services-dist ./base-dist ./bundles-dist; do
if [ -d "$wheel_dir" ]; then
FIND_LINKS+=(--find-links "$wheel_dir")
fi
Expand Down Expand Up @@ -642,7 +671,7 @@ jobs:
# the matching rc/dev wheel is not published yet, and fails with
# "No solution found when resolving dependencies".
FIND_LINKS=()
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./bundles-dist; do
for wheel_dir in ./sdk-dist ./lfx-dist ./services-dist ./base-dist ./bundles-dist; do
if [ -d "$wheel_dir" ]; then
FIND_LINKS+=(--find-links "$wheel_dir")
fi
Expand Down Expand Up @@ -694,6 +723,12 @@ jobs:
LOCAL_WHEELS+=("$LFX_WHEEL")
fi
fi
if [ -d ./services-dist ]; then
SERVICES_WHEEL=$(find ./services-dist -name "*.whl" -type f | head -1)
if [ -n "$SERVICES_WHEEL" ]; then
LOCAL_WHEELS+=("$SERVICES_WHEEL")
fi
fi
INSTALL_WHEELS=("${LOCAL_WHEELS[@]}" "$BASE_WHEEL")
fi
uv pip install --force-reinstall $NO_DEPS --prerelease=if-necessary-or-explicit "${FIND_LINKS[@]}" --python ./test-env/Scripts/python.exe "${INSTALL_WHEELS[@]}"
Expand All @@ -710,7 +745,7 @@ jobs:
# the matching rc/dev wheel is not published yet, and fails with
# "No solution found when resolving dependencies".
FIND_LINKS=()
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./bundles-dist; do
for wheel_dir in ./sdk-dist ./lfx-dist ./services-dist ./base-dist ./bundles-dist; do
if [ -d "$wheel_dir" ]; then
FIND_LINKS+=(--find-links "$wheel_dir")
fi
Expand Down Expand Up @@ -762,6 +797,12 @@ jobs:
LOCAL_WHEELS+=("$LFX_WHEEL")
fi
fi
if [ -d ./services-dist ]; then
SERVICES_WHEEL=$(find ./services-dist -name "*.whl" -type f | head -1)
if [ -n "$SERVICES_WHEEL" ]; then
LOCAL_WHEELS+=("$SERVICES_WHEEL")
fi
fi
INSTALL_WHEELS=("${LOCAL_WHEELS[@]}" "$BASE_WHEEL")
fi
uv pip install --force-reinstall $NO_DEPS --prerelease=if-necessary-or-explicit "${FIND_LINKS[@]}" --python ./test-env/bin/python "${INSTALL_WHEELS[@]}"
Expand Down
21 changes: 12 additions & 9 deletions .github/workflows/db-migration-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ jobs:
# `python -m langflow` could keep running the stable version and no real nightly migration
# is exercised (false-positive test).
echo "Removing stable langflow to force a clean install of the nightly dev version..."
uv pip uninstall -y langflow langflow-base || true
uv pip uninstall -y langflow langflow-base langflow-services || true

# Extract version from Docker tag (format: langflowai/langflow:v1.10.0.dev20260522)
if [[ "$NIGHTLY_TAG" == *":"* ]]; then
Expand All @@ -182,24 +182,27 @@ jobs:

# Scope pre-release resolution to the langflow stack only. uv accepts a
# pre-release for a package when its own requirement carries a pre-release
# marker, but NOT via transitive pins (langflow -> langflow-base -> lfx ->
# langflow-sdk are exact ==devN pins on nightlies), so each lockstep package
# must be requested directly. A global --prerelease=allow is NOT safe here:
# it lets unrelated dependencies resolve to alphas (pydantic 2.14.0a1 broke
# langchain-core imports on the first canonical-prerelease nightly).
# marker, but NOT via transitive pins (langflow -> langflow-base ->
# langflow-services -> lfx -> langflow-sdk are exact ==devN pins on nightlies),
# so each lockstep package must be requested directly. A global
# --prerelease=allow is NOT safe here: it lets unrelated dependencies resolve
# to alphas (pydantic 2.14.0a1 broke langchain-core imports on the first
# canonical-prerelease nightly).
# langflow-sdk has its own version line, so an explicit .dev0 floor marks it
# pre-release-eligible while the lfx pin selects the exact version.
# Nightlies publish langflow / langflow-base / langflow-services / lfx
# at the same root-axis .devN (base is remapped off its stable 0.x line).
if [[ "$VERSION" == "latest" ]]; then
# Install latest nightly (canonical pre-release) from PyPI
uv pip install --upgrade 'langflow[postgresql]>=0.0.0.dev0' 'langflow-base>=0.0.0.dev0' 'lfx>=0.0.0.dev0' 'langflow-sdk>=0.0.0.dev0'
uv pip install --upgrade 'langflow[postgresql]>=0.0.0.dev0' 'langflow-base>=0.0.0.dev0' 'langflow-services>=0.0.0.dev0' 'lfx>=0.0.0.dev0' 'langflow-sdk>=0.0.0.dev0'
else
# Install specific version
uv pip install --upgrade "langflow[postgresql]==$VERSION" "langflow-base==$VERSION" "lfx==$VERSION" 'langflow-sdk>=0.0.0.dev0'
uv pip install --upgrade "langflow[postgresql]==$VERSION" "langflow-base==$VERSION" "langflow-services==$VERSION" "lfx==$VERSION" 'langflow-sdk>=0.0.0.dev0'
fi
else
# Direct version string (strip 'v' prefix if present)
VERSION="${NIGHTLY_TAG#v}"
uv pip install --upgrade "langflow[postgresql]==$VERSION" "langflow-base==$VERSION" "lfx==$VERSION" 'langflow-sdk>=0.0.0.dev0'
uv pip install --upgrade "langflow[postgresql]==$VERSION" "langflow-base==$VERSION" "langflow-services==$VERSION" "lfx==$VERSION" 'langflow-sdk>=0.0.0.dev0'
fi

# Verify upgrade
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/migration-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
- 'src/backend/base/langflow/alembic/**'
- 'src/backend/base/langflow/services/database/models/**'
- 'src/backend/base/langflow/services/database/service.py'
- 'src/langflow-services/src/langflow_services/database/service.py'
- 'src/langflow-services/src/langflow_services/database/factory.py'
- 'src/langflow-services/src/langflow_services/database/models.py'
- 'src/backend/tests/unit/alembic/**'
- '.github/workflows/migration-validation.yml'

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ jobs:
uv lock
cd src/lfx && uv lock && cd ../..

git add pyproject.toml src/backend/base/pyproject.toml src/lfx/pyproject.toml src/sdk/pyproject.toml uv.lock
git add pyproject.toml src/backend/base/pyproject.toml src/langflow-services/pyproject.toml src/lfx/pyproject.toml src/sdk/pyproject.toml uv.lock
# The nightly keeps canonical package names and the stable `lfx-*` bundles
# are not modified (see src/bundles/NIGHTLY.md), so no bundle pyprojects ride this commit.
git commit -m "Update version for nightly"
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/python_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,26 @@ jobs:
src/lfx/htmlcov/
retention-days: 30

isolated-services-wheel:
name: Isolated services wheel - 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' }}
strategy:
matrix:
python-version: ${{ fromJson(inputs.python-versions || '["3.12"]') }}
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.ref || github.ref }}
- name: "Setup Environment"
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
python-version: ${{ matrix.python-version }}
prune-cache: false
- name: Prove services wheel imports without langflow-base
run: make check_services_isolated_wheel

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' }}
Expand Down
Loading
Loading