Skip to content

Commit 873d558

Browse files
authored
fix(ci): align nightly workflows with langflow-base (#14352)
1 parent 48aac68 commit 873d558

7 files changed

Lines changed: 122 additions & 265 deletions

File tree

.github/workflows/cross-platform-test.yml

Lines changed: 62 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ on:
1414
description: "Name of the base package artifact"
1515
required: true
1616
type: string
17-
core-artifact-name:
18-
description: "Name of the langflow-core package artifact"
19-
required: false
20-
type: string
2117
main-artifact-name:
2218
description: "Name of the main package artifact"
2319
required: true
@@ -262,13 +258,6 @@ jobs:
262258
name: ${{ inputs.base-artifact-name || needs.build-if-needed.outputs.base-artifact-name || 'adhoc-dist-base' }}
263259
path: ./base-dist
264260

265-
- name: Download langflow-core package artifact
266-
if: steps.install-method.outputs.method == 'wheel' && inputs.core-artifact-name != ''
267-
uses: actions/download-artifact@v7
268-
with:
269-
name: ${{ inputs.core-artifact-name }}
270-
path: ./core-dist
271-
272261
- name: Download main package artifact
273262
if: steps.install-method.outputs.method == 'wheel'
274263
uses: actions/download-artifact@v7
@@ -302,7 +291,7 @@ jobs:
302291
303292
refresh_find_links() {
304293
FIND_LINKS=()
305-
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./core-dist ./bundles-dist; do
294+
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./bundles-dist; do
306295
if [ -d "$wheel_dir" ]; then
307296
FIND_LINKS+=(--find-links "$wheel_dir")
308297
fi
@@ -336,11 +325,6 @@ jobs:
336325
BASE_WHEELS=(./base-dist/*.whl)
337326
install_wheels "base" "${BASE_WHEELS[@]}"
338327
339-
CORE_WHEELS=(./core-dist/*.whl)
340-
if [ ${#CORE_WHEELS[@]} -gt 0 ]; then
341-
install_wheels "core" "${CORE_WHEELS[@]}"
342-
fi
343-
344328
if [ -d ./bundles-dist ]; then
345329
BUNDLE_WHEELS=(./bundles-dist/*.whl)
346330
install_wheels "bundle" "${BUNDLE_WHEELS[@]}"
@@ -576,13 +560,6 @@ jobs:
576560
name: ${{ inputs.base-artifact-name || needs.build-if-needed.outputs.base-artifact-name || 'adhoc-dist-base' }}
577561
path: ./base-dist
578562

579-
- name: Download langflow-core package artifact
580-
if: steps.install-method.outputs.method == 'wheel' && inputs.core-artifact-name != ''
581-
uses: actions/download-artifact@v7
582-
with:
583-
name: ${{ inputs.core-artifact-name }}
584-
path: ./core-dist
585-
586563
- name: Download main package artifact
587564
if: steps.install-method.outputs.method == 'wheel'
588565
uses: actions/download-artifact@v7
@@ -616,7 +593,7 @@ jobs:
616593
617594
refresh_find_links() {
618595
FIND_LINKS=()
619-
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./core-dist ./bundles-dist; do
596+
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./bundles-dist; do
620597
if [ -d "$wheel_dir" ]; then
621598
FIND_LINKS+=(--find-links "$wheel_dir")
622599
fi
@@ -646,11 +623,6 @@ jobs:
646623
BASE_WHEELS=(./base-dist/*.whl)
647624
install_wheels "base" "${BASE_WHEELS[@]}"
648625
649-
CORE_WHEELS=(./core-dist/*.whl)
650-
if [ ${#CORE_WHEELS[@]} -gt 0 ]; then
651-
install_wheels "core" "${CORE_WHEELS[@]}"
652-
fi
653-
654626
if [ -d ./bundles-dist ]; then
655627
BUNDLE_WHEELS=(./bundles-dist/*.whl)
656628
install_wheels "bundle" "${BUNDLE_WHEELS[@]}"
@@ -673,12 +645,12 @@ jobs:
673645
run: |
674646
# Expose the local wheel dirs so dependency re-resolution (the
675647
# pre-release path below drops --no-deps) can find the local
676-
# pre-release lfx/base/core wheels. Without these, uv re-resolves
648+
# pre-release SDK/LFX/base wheels. Without these, uv re-resolves
677649
# langflow-base's `lfx>=X.Y.Zrc0` constraint against PyPI only, where
678650
# the matching rc/dev wheel is not published yet, and fails with
679651
# "No solution found when resolving dependencies".
680652
FIND_LINKS=()
681-
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./core-dist ./bundles-dist; do
653+
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./bundles-dist; do
682654
if [ -d "$wheel_dir" ]; then
683655
FIND_LINKS+=(--find-links "$wheel_dir")
684656
fi
@@ -734,24 +706,19 @@ jobs:
734706
fi
735707
uv pip install --force-reinstall $NO_DEPS --prerelease=if-necessary-or-explicit "${FIND_LINKS[@]}" --python ./test-env/Scripts/python.exe "${INSTALL_WHEELS[@]}"
736708
fi
737-
738-
CORE_WHEEL=$(find ./core-dist -name "*.whl" -type f 2>/dev/null | head -1 || true)
739-
if [ -n "$CORE_WHEEL" ]; then
740-
uv pip install --force-reinstall --no-deps --python ./test-env/Scripts/python.exe "$CORE_WHEEL"
741-
fi
742709
shell: bash
743710

744711
- name: Force reinstall local wheels to prevent downgrades (Unix)
745712
if: steps.install-method.outputs.method == 'wheel' && matrix.os != 'windows'
746713
run: |
747714
# Expose the local wheel dirs so dependency re-resolution (the
748715
# pre-release path below drops --no-deps) can find the local
749-
# pre-release lfx/base/core wheels. Without these, uv re-resolves
716+
# pre-release SDK/LFX/base wheels. Without these, uv re-resolves
750717
# langflow-base's `lfx>=X.Y.Zrc0` constraint against PyPI only, where
751718
# the matching rc/dev wheel is not published yet, and fails with
752719
# "No solution found when resolving dependencies".
753720
FIND_LINKS=()
754-
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./core-dist ./bundles-dist; do
721+
for wheel_dir in ./sdk-dist ./lfx-dist ./base-dist ./bundles-dist; do
755722
if [ -d "$wheel_dir" ]; then
756723
FIND_LINKS+=(--find-links "$wheel_dir")
757724
fi
@@ -807,11 +774,6 @@ jobs:
807774
fi
808775
uv pip install --force-reinstall $NO_DEPS --prerelease=if-necessary-or-explicit "${FIND_LINKS[@]}" --python ./test-env/bin/python "${INSTALL_WHEELS[@]}"
809776
fi
810-
811-
CORE_WHEEL=$(find ./core-dist -name "*.whl" -type f 2>/dev/null | head -1 || true)
812-
if [ -n "$CORE_WHEEL" ]; then
813-
uv pip install --force-reinstall --no-deps --python ./test-env/bin/python "$CORE_WHEEL"
814-
fi
815777
shell: bash
816778

817779
# PyPI installation steps
@@ -939,14 +901,17 @@ jobs:
939901
"
940902
shell: bash
941903

942-
test-core-runtime:
943-
name: Core Runtime Wheel - Linux Python 3.14
904+
test-base-runtime:
905+
name: Base Distribution Wheel - Linux Python 3.14
944906
needs: [build-if-needed]
945907
if: |
946908
always() &&
947909
inputs.langflow-version == '' &&
948-
(needs.build-if-needed.result == 'success' || needs.build-if-needed.result == 'skipped')
910+
(needs.build-if-needed.result == 'success' || needs.build-if-needed.result == 'skipped') &&
911+
(inputs.base-artifact-name != '' || needs.build-if-needed.outputs.base-artifact-name != '')
949912
runs-on: ubuntu-latest
913+
permissions:
914+
contents: read
950915
steps:
951916
- name: Setup UV
952917
uses: astral-sh/setup-uv@v6
@@ -973,7 +938,7 @@ jobs:
973938
name: ${{ inputs.base-artifact-name || needs.build-if-needed.outputs.base-artifact-name || 'adhoc-dist-base' }}
974939
path: ./base-dist
975940

976-
- name: Install only core wheels
941+
- name: Install only the base dependency chain
977942
shell: bash
978943
run: |
979944
set -euo pipefail
@@ -982,49 +947,56 @@ jobs:
982947
SDK_WHEELS=(./sdk-dist/*.whl)
983948
LFX_WHEELS=(./lfx-dist/*.whl)
984949
BASE_WHEELS=(./base-dist/*.whl)
985-
[ ${#LFX_WHEELS[@]} -eq 1 ] || { echo "Expected one LFX wheel, found ${#LFX_WHEELS[@]}"; exit 1; }
986-
[ ${#BASE_WHEELS[@]} -eq 1 ] || { echo "Expected one base wheel, found ${#BASE_WHEELS[@]}"; exit 1; }
987-
[ ${#SDK_WHEELS[@]} -le 1 ] || { echo "Expected at most one SDK wheel, found ${#SDK_WHEELS[@]}"; exit 1; }
950+
[ ${#SDK_WHEELS[@]} -le 1 ] || { echo "Expected at most one SDK wheel"; exit 1; }
951+
[ ${#LFX_WHEELS[@]} -le 1 ] || { echo "Expected at most one LFX wheel"; exit 1; }
952+
[ ${#BASE_WHEELS[@]} -eq 1 ] || { echo "Expected one base wheel"; exit 1; }
988953
989-
FIND_LINKS=(--find-links ./lfx-dist --find-links ./base-dist)
990-
if [ ${#SDK_WHEELS[@]} -eq 1 ]; then
991-
FIND_LINKS+=(--find-links ./sdk-dist)
992-
fi
993-
994-
uv venv core-test-env --seed --python 3.14
995-
uv pip install --python core-test-env/bin/python \
954+
FIND_LINKS=()
955+
for directory in sdk-dist lfx-dist base-dist; do
956+
if [ -d "$directory" ]; then
957+
FIND_LINKS+=(--find-links "./$directory")
958+
fi
959+
done
960+
uv venv base-test-env --seed --python 3.14
961+
uv pip install --python base-test-env/bin/python \
996962
--prerelease=if-necessary-or-explicit \
997963
"${FIND_LINKS[@]}" "${SDK_WHEELS[@]}" "${LFX_WHEELS[@]}" "${BASE_WHEELS[0]}"
998-
uv pip check --python core-test-env/bin/python
964+
uv pip check --python base-test-env/bin/python
999965
1000-
- name: Verify core boundary and indexed imports
966+
- name: Verify base boundary and indexed imports
1001967
shell: bash
1002968
run: |
1003-
core-test-env/bin/python - <<'PY'
969+
base-test-env/bin/python - <<'PY'
1004970
import importlib
1005971
import re
1006-
from importlib.metadata import distributions, entry_points
972+
import sys
973+
from importlib.metadata import distributions, entry_points, metadata, requires
974+
from pathlib import Path
1007975
1008976
from lfx.interface.components import _read_component_index
1009977
1010978
normalize = lambda value: re.sub(r"[-_.]+", "-", value).lower()
1011979
installed = {normalize(dist.metadata["Name"]) for dist in distributions() if dist.metadata["Name"]}
1012980
assert {"langflow-base", "langflow-sdk", "lfx"} <= installed, installed
1013-
assert "langflow" not in installed, installed
1014-
extensions = sorted(name for name in installed if name.startswith("lfx-"))
1015-
assert not extensions, f"Extension distributions installed: {extensions}"
981+
forbidden = installed & {"langflow", "langflow-core", "torch", "torchvision"}
982+
forbidden |= {name for name in installed if name.startswith("lfx-")}
983+
assert not forbidden, f"Forbidden base distributions: {sorted(forbidden)}"
1016984
for group in ("lfx.bundles", "langflow.extensions", "langflow.plugins"):
1017985
assert not entry_points(group=group), f"Extension entry points registered in {group}"
1018986
987+
scripts = Path(sys.executable).parent
988+
assert (scripts / "langflow").is_file()
989+
assert not (scripts / "langflow-base").exists()
990+
provided_extras = set(metadata("langflow-base").get_all("Provides-Extra", []))
991+
assert {"complete", "all"} <= provided_extras
992+
compatibility_requirements = [
993+
requirement for requirement in (requires("langflow-base") or [])
994+
if 'extra == "complete"' in requirement or 'extra == "all"' in requirement
995+
]
996+
assert not compatibility_requirements, compatibility_requirements
997+
1019998
index = _read_component_index()
1020999
assert index is not None, "Installed LFX rejected its bundled component index"
1021-
expected_metadata = {
1022-
"num_modules": len(index["entries"]),
1023-
"num_components": sum(len(components) for _, components in index["entries"]),
1024-
}
1025-
assert index["metadata"] == expected_metadata, (
1026-
f"Unexpected component index metadata: {index['metadata']} != {expected_metadata}"
1027-
)
10281000
for category, components in index["entries"]:
10291001
for component_name, component in components.items():
10301002
module_path = component.get("metadata", {}).get("module")
@@ -1033,7 +1005,7 @@ jobs:
10331005
getattr(importlib.import_module(module_name), class_name)
10341006
PY
10351007
1036-
- name: Boot installed core server
1008+
- name: Boot installed base server
10371009
shell: bash
10381010
timeout-minutes: 5
10391011
run: |
@@ -1045,7 +1017,7 @@ jobs:
10451017
export DO_NOT_TRACK=true
10461018
LOG_FILE="$RUNTIME_DIR/server.log"
10471019
1048-
core-test-env/bin/langflow-base run \
1020+
base-test-env/bin/langflow run \
10491021
--host 127.0.0.1 --port 7861 --backend-only --workers 1 >"$LOG_FILE" 2>&1 &
10501022
SERVER_PID=$!
10511023
cleanup() {
@@ -1071,52 +1043,40 @@ jobs:
10711043
exit 1
10721044
fi
10731045
1074-
curl -fsS -c "$RUNTIME_DIR/cookies" http://127.0.0.1:7861/api/v1/auto_login >/dev/null
1075-
curl -fsS --compressed -b "$RUNTIME_DIR/cookies" \
1076-
http://127.0.0.1:7861/api/v1/all >"$RUNTIME_DIR/catalog.json"
1077-
core-test-env/bin/python - "$RUNTIME_DIR/catalog.json" <<'PY'
1078-
import json
1079-
import sys
1080-
from pathlib import Path
1081-
1082-
from lfx.interface.components import _read_component_index
1083-
1084-
catalog = json.loads(Path(sys.argv[1]).read_text())
1085-
catalog.pop("component_display_names", None)
1086-
index = _read_component_index()
1087-
assert index is not None, "Installed LFX rejected its bundled component index"
1088-
actual_metadata = {
1089-
"num_modules": len(catalog),
1090-
"num_components": sum(len(components) for components in catalog.values()),
1091-
}
1092-
assert actual_metadata == index["metadata"], (
1093-
f"Unexpected API catalog metadata: {actual_metadata} != {index['metadata']}"
1094-
)
1095-
PY
1096-
10971046
test-summary:
10981047
name: Cross-Platform Test Summary
1099-
needs: [test-installation-stable, test-installation-experimental, test-core-runtime]
1048+
needs: [build-if-needed, test-installation-stable, test-installation-experimental, test-base-runtime]
11001049
runs-on: ubuntu-latest
11011050
if: always()
11021051
steps:
11031052
- name: Check test results
11041053
env:
11051054
LANGFLOW_VERSION: ${{ inputs.langflow-version }}
1055+
EXPECT_BASE_RUNTIME: ${{ inputs.base-artifact-name != '' || needs.build-if-needed.outputs.base-artifact-name != '' }}
11061056
run: |
11071057
stable_result="${{ needs.test-installation-stable.result }}"
11081058
experimental_result="${{ needs.test-installation-experimental.result }}"
1109-
core_result="${{ needs.test-core-runtime.result }}"
1059+
base_result="${{ needs.test-base-runtime.result }}"
11101060
11111061
echo "Stable platforms result: $stable_result"
11121062
echo "Experimental platforms result: $experimental_result"
1113-
echo "Core runtime result: $core_result"
1063+
echo "Base runtime result: $base_result"
1064+
1065+
if [ "$stable_result" = "skipped" ] && [ "$base_result" = "skipped" ]; then
1066+
echo "✅ No Langflow application distribution was selected; package build tests passed"
1067+
exit 0
1068+
fi
11141069
1115-
if [ "${{ inputs.langflow-version }}" = "" ] && [ "$core_result" != "success" ]; then
1116-
echo "❌ Core runtime wheel test failed: $core_result"
1070+
if [ "$EXPECT_BASE_RUNTIME" = "true" ] && [ -z "$LANGFLOW_VERSION" ] && [ "$base_result" != "success" ]; then
1071+
echo "❌ Base runtime wheel test failed: $base_result"
11171072
exit 1
11181073
fi
11191074
1075+
if [ "$stable_result" = "skipped" ] && [ "$base_result" = "success" ]; then
1076+
echo "✅ Base-only wheel installation tests passed"
1077+
exit 0
1078+
fi
1079+
11201080
# Stable platforms must succeed, experimental can fail
11211081
if [ "$stable_result" = "success" ]; then
11221082
if [ "$experimental_result" = "success" ]; then

.github/workflows/docker-nightly-build.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ jobs:
122122
context: .
123123
push: ${{ inputs.push_to_registry }}
124124
pull: true
125-
file: ./docker/build_and_push_base.Dockerfile
125+
file: ./docker/build_and_push.Dockerfile
126+
target: base
126127
tags: ${{ steps.tags.outputs.docker_tags }}
127128
platforms: linux/${{ matrix.arch }}
128129
provenance: false
@@ -135,7 +136,8 @@ jobs:
135136
context: .
136137
push: ${{ inputs.push_to_registry }}
137138
pull: true
138-
file: ./docker/build_and_push_base.Dockerfile
139+
file: ./docker/build_and_push.Dockerfile
140+
target: base
139141
tags: ${{ steps.tags.outputs.ghcr_tags }}
140142
platforms: linux/${{ matrix.arch }}
141143
provenance: false
@@ -218,6 +220,7 @@ jobs:
218220
push: ${{ inputs.push_to_registry }}
219221
pull: true
220222
file: ./docker/build_and_push.Dockerfile
223+
target: full
221224
tags: ${{ steps.tags.outputs.docker_tags }}
222225
platforms: linux/${{ matrix.arch }}
223226
provenance: false
@@ -231,6 +234,7 @@ jobs:
231234
push: ${{ inputs.push_to_registry }}
232235
pull: true
233236
file: ./docker/build_and_push.Dockerfile
237+
target: full
234238
tags: ${{ steps.tags.outputs.ghcr_tags }}
235239
platforms: linux/${{ matrix.arch }}
236240
provenance: false
@@ -312,7 +316,8 @@ jobs:
312316
context: .
313317
push: ${{ inputs.push_to_registry }}
314318
pull: true
315-
file: ./docker/build_and_push_with_extras.Dockerfile
319+
file: ./docker/build_and_push.Dockerfile
320+
target: full-bundles
316321
tags: ${{ steps.tags.outputs.docker_tags }}
317322
platforms: linux/${{ matrix.arch }}
318323
provenance: false
@@ -325,7 +330,8 @@ jobs:
325330
context: .
326331
push: ${{ inputs.push_to_registry }}
327332
pull: true
328-
file: ./docker/build_and_push_with_extras.Dockerfile
333+
file: ./docker/build_and_push.Dockerfile
334+
target: full-bundles
329335
tags: ${{ steps.tags.outputs.ghcr_tags }}
330336
platforms: linux/${{ matrix.arch }}
331337
provenance: false

0 commit comments

Comments
 (0)