Skip to content

Commit 8b0f727

Browse files
fix: release workflow (#11089)
* chore(release.yml): update release_lfx input description and make it optional to improve clarity feat(release.yml): add ensure-lfx-published job to automate LFX version check and publishing process to PyPI * chore: clean up release workflow comment out unneeded cross platform test and move steps around to match the already existing pattern * chore: remove test-lfx-cross-platform remove test-lfx-cross-platform * chore: address some of co-pilots comments address some of co-pilots comments --------- Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
1 parent b6a5fb0 commit 8b0f727

File tree

2 files changed

+190
-86
lines changed

2 files changed

+190
-86
lines changed

.github/workflows/release.yml

Lines changed: 189 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ on:
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 }}

.secrets.baseline

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
"filename": ".github/workflows/release.yml",
164164
"hashed_secret": "3e26d6750975d678acb8fa35a0f69237881576b0",
165165
"is_verified": false,
166-
"line_number": 128,
166+
"line_number": 122,
167167
"is_secret": false
168168
}
169169
],

0 commit comments

Comments
 (0)