1919 type : boolean
2020 default : false
2121 release_lfx :
22- description : " WARNING: Not implemented yet. "
23- required : true
22+ description : " Release LFX package (manually triggered) "
23+ required : false
2424 type : boolean
2525 default : false
2626 build_docker_base :
@@ -106,12 +106,6 @@ jobs:
106106 exit 1
107107 fi
108108
109- if [ "${{ inputs.release_lfx }}" = "true" ]; then
110- echo "Error: Release LFX is not implemented yet."
111- echo "Please disable 'release_lfx' or wait for it to be implemented."
112- exit 1
113- fi
114-
115109 echo "✅ Release dependencies validated successfully."
116110
117111 ci :
@@ -127,9 +121,119 @@ jobs:
127121 runs-on : ubuntu-latest
128122 secrets : inherit
129123
124+ # Automatically ensure lfx is published before building langflow-base
125+ # This job checks if the required lfx version exists on PyPI and publishes it if not
126+ ensure-lfx-published :
127+ name : Ensure LFX Dependency is Published
128+ needs : [ci]
129+ if : ${{ inputs.release_package_base }}
130+ runs-on : ubuntu-latest
131+ outputs :
132+ lfx-version : ${{ steps.check-lfx.outputs.lfx_version }}
133+ lfx-published : ${{ steps.check-lfx.outputs.already_published }}
134+ lfx-published-now : ${{ steps.publish-lfx.outputs.published }}
135+ steps :
136+ - name : Checkout code
137+ uses : actions/checkout@v6
138+ with :
139+ ref : ${{ inputs.release_tag }}
140+
141+ - name : Setup Environment
142+ uses : astral-sh/setup-uv@v6
143+ with :
144+ enable-cache : true
145+ cache-dependency-glob : " uv.lock"
146+ python-version : " 3.13"
147+ prune-cache : false
148+
149+ - name : Check LFX version requirement
150+ id : check-lfx
151+ run : |
152+ # Get the lfx version required by langflow-base from pyproject.toml
153+ cd src/backend/base
154+ LFX_REQUIREMENT=$(grep -E "^\s*\"lfx" pyproject.toml | head -1 | sed 's/.*lfx[~>=<]*//' | sed 's/[",].*//')
155+ echo "LFX requirement from langflow-base: $LFX_REQUIREMENT"
156+
157+ # Get the actual lfx version from source
158+ cd ../../lfx
159+ LFX_SOURCE_VERSION=$(grep -E "^version\s*=" pyproject.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
160+ echo "LFX source version: $LFX_SOURCE_VERSION"
161+ echo "lfx_version=$LFX_SOURCE_VERSION" >> $GITHUB_OUTPUT
162+
163+ # Check if this version exists on PyPI
164+ HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://pypi.org/pypi/lfx/$LFX_SOURCE_VERSION/json")
165+
166+ if [ "$HTTP_STATUS" = "200" ]; then
167+ echo "✅ LFX version $LFX_SOURCE_VERSION already exists on PyPI"
168+ echo "already_published=true" >> $GITHUB_OUTPUT
169+ else
170+ echo "⚠️ LFX version $LFX_SOURCE_VERSION NOT found on PyPI (HTTP: $HTTP_STATUS)"
171+ echo "Will build and publish LFX first..."
172+ echo "already_published=false" >> $GITHUB_OUTPUT
173+ fi
174+
175+ - name : Install LFX dependencies
176+ if : steps.check-lfx.outputs.already_published == 'false'
177+ run : uv sync --dev --package lfx
178+
179+ - name : Build LFX
180+ if : steps.check-lfx.outputs.already_published == 'false'
181+ run : |
182+ cd src/lfx
183+ rm -rf dist/
184+ uv build --wheel --out-dir dist
185+ echo "Built LFX wheel:"
186+ ls -la dist/
187+
188+ - name : Test LFX CLI
189+ if : steps.check-lfx.outputs.already_published == 'false'
190+ run : |
191+ cd src/lfx
192+ uv pip install dist/*.whl --force-reinstall
193+ uv run lfx --help
194+ echo "✅ LFX CLI test passed"
195+
196+ - name : Publish LFX to PyPI
197+ id : publish-lfx
198+ if : steps.check-lfx.outputs.already_published == 'false' && !inputs.dry_run
199+ env :
200+ UV_PUBLISH_TOKEN : ${{ secrets.PYPI_API_TOKEN }}
201+ run : |
202+ cd src/lfx
203+ echo "Publishing LFX ${{ steps.check-lfx.outputs.lfx_version }} to PyPI..."
204+ uv publish dist/*.whl
205+ echo "published=true" >> $GITHUB_OUTPUT
206+ echo "✅ LFX published successfully"
207+
208+ - name : Wait for PyPI propagation
209+ if : steps.publish-lfx.outputs.published == 'true'
210+ run : |
211+ echo "Waiting 60 seconds for PyPI propagation..."
212+ sleep 60
213+
214+ # Verify the package is available
215+ LFX_VERSION="${{ steps.check-lfx.outputs.lfx_version }}"
216+ for i in {1..5}; do
217+ HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://pypi.org/pypi/lfx/$LFX_VERSION/json")
218+ if [ "$HTTP_STATUS" = "200" ]; then
219+ echo "✅ LFX $LFX_VERSION is now available on PyPI"
220+ exit 0
221+ fi
222+ echo "Attempt $i: LFX not yet available (HTTP: $HTTP_STATUS), waiting 30s..."
223+ sleep 30
224+ done
225+ echo "❌ LFX $LFX_VERSION still not available on PyPI after waiting"
226+ exit 1
227+
228+ - name : Skip publishing (dry run)
229+ if : steps.check-lfx.outputs.already_published == 'false' && inputs.dry_run
230+ run : |
231+ echo "⚠️ DRY RUN: Would have published LFX ${{ steps.check-lfx.outputs.lfx_version }} to PyPI"
232+ echo "In actual release, this step will publish the package"
233+
130234 build-base :
131235 name : Build Langflow Base
132- needs : [ci]
236+ needs : [ci, ensure-lfx-published ]
133237 if : ${{ inputs.release_package_base }}
134238 runs-on : ubuntu-latest
135239 outputs :
@@ -279,9 +383,58 @@ jobs:
279383 name : dist-main
280384 path : dist
281385
386+ build-lfx :
387+ name : Build LFX
388+ needs : [build-base]
389+ if : ${{ inputs.release_lfx }}
390+ runs-on : ubuntu-latest
391+ outputs :
392+ version : ${{ steps.check-version.outputs.version }}
393+ steps :
394+ - name : Checkout code
395+ uses : actions/checkout@v6
396+ with :
397+ ref : ${{ inputs.release_tag }}
398+ - name : Setup Environment
399+ uses : astral-sh/setup-uv@v6
400+ with :
401+ enable-cache : true
402+ cache-dependency-glob : " uv.lock"
403+ python-version : " 3.13"
404+ prune-cache : false
405+ - name : Install LFX dependencies
406+ run : uv sync --dev --package lfx
407+ - name : Check Version
408+ id : check-version
409+ run : |
410+ cd src/lfx
411+ version=$(uv tree | grep 'lfx' | head -n 1 | awk '{print $2}' | sed 's/^v//')
412+ last_released_version=$(curl -s "https://pypi.org/pypi/lfx/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
413+ if [ "$version" = "$last_released_version" ]; then
414+ echo "Version $version is already released. Skipping release."
415+ exit 1
416+ else
417+ echo version=$version >> $GITHUB_OUTPUT
418+ fi
419+ - name : Build project for distribution
420+ run : |
421+ cd src/lfx
422+ rm -rf dist/
423+ uv build --wheel --out-dir dist
424+ - name : Test CLI
425+ run : |
426+ cd src/lfx
427+ uv pip install dist/*.whl --force-reinstall
428+ uv run lfx --help
429+ - name : Upload Artifact
430+ uses : actions/upload-artifact@v4
431+ with :
432+ name : dist-lfx
433+ path : src/lfx/dist
434+
282435 test-cross-platform :
283436 name : Test Cross-Platform Installation
284- needs : [build-base, build-main]
437+ needs : [build-base, build-main, build-lfx ]
285438 if : |
286439 always() &&
287440 !cancelled() &&
@@ -338,84 +491,10 @@ jobs:
338491 run : |
339492 uv publish dist/*.whl
340493
341- build-lfx :
342- name : Build LFX
343- needs : [ci]
344- if : ${{ inputs.release_lfx }}
345- runs-on : ubuntu-latest
346- outputs :
347- version : ${{ steps.check-version.outputs.version }}
348- steps :
349- - name : Checkout code
350- uses : actions/checkout@v6
351- with :
352- ref : ${{ inputs.release_tag }}
353- - name : Setup Environment
354- uses : astral-sh/setup-uv@v6
355- with :
356- enable-cache : true
357- cache-dependency-glob : " uv.lock"
358- python-version : " 3.13"
359- prune-cache : false
360- - name : Install LFX dependencies
361- run : uv sync --dev --package lfx
362- - name : Check Version
363- id : check-version
364- run : |
365- cd src/lfx
366- version=$(uv tree | grep 'lfx' | head -n 1 | awk '{print $2}' | sed 's/^v//')
367- last_released_version=$(curl -s "https://pypi.org/pypi/lfx/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
368- if [ "$version" = "$last_released_version" ]; then
369- echo "Version $version is already released. Skipping release."
370- exit 1
371- else
372- echo version=$version >> $GITHUB_OUTPUT
373- fi
374- - name : Build project for distribution
375- run : |
376- cd src/lfx
377- rm -rf dist/
378- uv build --wheel --out-dir dist
379- - name : Test CLI
380- run : |
381- cd src/lfx
382- uv pip install dist/*.whl --force-reinstall
383- uv run lfx --help
384- - name : Upload Artifact
385- uses : actions/upload-artifact@v4
386- with :
387- name : dist-lfx
388- path : src/lfx/dist
389-
390- test-lfx-cross-platform :
391- name : Test LFX Cross-Platform Installation
392- if : ${{ inputs.release_lfx }}
393- needs : [build-lfx]
394- runs-on : ${{ matrix.os }}
395- strategy :
396- matrix :
397- os : [ubuntu-latest, windows-latest, macos-latest]
398- python-version : ["3.10", "3.11", "3.12", "3.13"]
399- steps :
400- - name : Download LFX artifact
401- uses : actions/download-artifact@v5
402- with :
403- name : dist-lfx
404- path : dist-lfx
405- - name : Setup Environment
406- uses : astral-sh/setup-uv@v6
407- with :
408- enable-cache : false
409- python-version : ${{ matrix.python-version }}
410- - name : Test LFX installation
411- run : |
412- uv pip install dist-lfx/*.whl
413- uv run lfx --help
414-
415494 publish-lfx :
416495 name : Publish LFX to PyPI
417496 if : ${{ inputs.release_lfx }}
418- needs : [build-lfx, test-lfx- cross-platform]
497+ needs : [build-lfx, test-cross-platform]
419498 runs-on : ubuntu-latest
420499 steps :
421500 - name : Download LFX artifact
@@ -435,6 +514,31 @@ jobs:
435514 run : |
436515 cd src/lfx && uv publish dist/*.whl
437516
517+ # test-lfx-cross-platform:
518+ # name: Test LFX Cross-Platform Installation
519+ # if: ${{ inputs.release_lfx }}
520+ # needs: [build-lfx]
521+ # runs-on: ${{ matrix.os }}
522+ # strategy:
523+ # matrix:
524+ # os: [ubuntu-latest, windows-latest, macos-latest]
525+ # python-version: ["3.10", "3.11", "3.12", "3.13"]
526+ # steps:
527+ # - name: Download LFX artifact
528+ # uses: actions/download-artifact@v5
529+ # with:
530+ # name: dist-lfx
531+ # path: dist-lfx
532+ # - name: Setup Environment
533+ # uses: astral-sh/setup-uv@v6
534+ # with:
535+ # enable-cache: false
536+ # python-version: ${{ matrix.python-version }}
537+ # - name: Test LFX installation
538+ # run: |
539+ # uv pip install dist-lfx/*.whl
540+ # uv run lfx --help
541+
438542 call_docker_build_base :
439543 name : Call Docker Build Workflow for Langflow Base
440544 if : ${{ inputs.build_docker_base }}
0 commit comments