feat: added install matrix before release (#9205)

* added install matrix before release

* adds ad-hoc testing

* temp enable test

* test changes

* fix test config

* fix package install

* commonize code

* renamed files

* fix issue

* remvoe run id

* fix base build

* revert main package build change

* fix build

* fix upload

* revert ci to main

* updated release workflow naming

* add cross-platform tests to nightly build
This commit is contained in:
Eric Pinzur 2025-07-30 21:57:59 +02:00 committed by GitHub
commit e1d3e741fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 735 additions and 49 deletions

View file

@ -0,0 +1,55 @@
name: Manual Cross-Platform Test
on:
workflow_dispatch:
inputs:
test-from-pypi:
description: "Test from PyPI instead of building from source"
type: boolean
default: false
langflow-version:
description: "Langflow version to test from PyPI (leave empty for latest)"
required: false
type: string
default: ""
test-timeout:
description: "Timeout for langflow server startup test (minutes)"
required: false
type: number
default: 5
jobs:
test-pypi-installation:
if: inputs.test-from-pypi == true
name: Test PyPI Installation
uses: ./.github/workflows/cross-platform-test-shared.yml
with:
install-method: "pypi"
test-timeout: ${{ inputs.test-timeout }}
langflow-version: ${{ inputs.langflow-version }}
test-source-build:
if: inputs.test-from-pypi == false
name: Test Source Build and Install
uses: ./.github/workflows/cross-platform-test.yml
with:
base-artifact-name: ""
main-artifact-name: ""
test-timeout: ${{ inputs.test-timeout }}
test-summary:
name: Test Summary
needs: [test-pypi-installation, test-source-build]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check test results
run: |
if [ "${{ needs.test-pypi-installation.result }}" = "failure" ] || [ "${{ needs.test-source-build.result }}" = "failure" ]; then
echo "❌ Cross-platform tests failed"
exit 1
elif [ "${{ needs.test-pypi-installation.result }}" = "success" ] || [ "${{ needs.test-source-build.result }}" = "success" ]; then
echo "✅ Cross-platform tests passed"
else
echo " No tests were run"
fi

View file

@ -0,0 +1,319 @@
name: Shared Cross-Platform Test Logic
on:
workflow_call:
inputs:
test-timeout:
description: "Timeout for langflow server startup test (minutes)"
required: false
type: number
default: 5
install-method:
description: "Installation method: 'wheel' for local wheels, 'pypi' for PyPI packages"
required: true
type: string
langflow-version:
description: "Langflow version to install from PyPI (only used if install-method is 'pypi')"
required: false
type: string
default: ""
base-artifact-name:
description: "Name of the base package artifact (only used if install-method is 'wheel')"
required: false
type: string
default: ""
main-artifact-name:
description: "Name of the main package artifact (only used if install-method is 'wheel')"
required: false
type: string
default: ""
run-id:
description: "GitHub run ID to download artifacts from (leave empty for current run)"
required: false
type: string
default: ""
jobs:
test-installation:
name: Install & Run - ${{ matrix.os }} ${{ matrix.arch }} ${{ matrix.python-version }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
# Linux AMD64
- os: linux
arch: amd64
runner: ubuntu-latest
python-version: "3.10"
- os: linux
arch: amd64
runner: ubuntu-latest
python-version: "3.13"
# macOS AMD64
- os: macos
arch: amd64
runner: macos-13
python-version: "3.10"
- os: macos
arch: amd64
runner: macos-13
python-version: "3.13"
# macOS ARM64 (Apple Silicon)
- os: macos
arch: arm64
runner: macos-latest
python-version: "3.10"
- os: macos
arch: arm64
runner: macos-latest
python-version: "3.13"
# Windows AMD64
- os: windows
arch: amd64
runner: windows-latest
python-version: "3.10"
- os: windows
arch: amd64
runner: windows-latest
python-version: "3.12"
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.arch == 'amd64' && 'x64' || matrix.arch }}
- name: Setup UV
uses: astral-sh/setup-uv@v6
with:
enable-cache: false
# Download artifacts for wheel installation
- name: Download base package artifact
if: inputs.install-method == 'wheel'
uses: actions/download-artifact@v4
with:
name: ${{ inputs.base-artifact-name }}
path: ./base-dist
- name: Download main package artifact
if: inputs.install-method == 'wheel'
uses: actions/download-artifact@v4
with:
name: ${{ inputs.main-artifact-name }}
path: ./main-dist
- name: Create fresh virtual environment
run: |
uv venv test-env --seed
shell: bash
# Wheel installation steps
- name: Install base package from wheel (Windows)
if: inputs.install-method == 'wheel' && matrix.os == 'windows'
run: |
ls -la ./base-dist/
find ./base-dist -name "*.whl" -type f
WHEEL_FILE=$(find ./base-dist -name "*.whl" -type f | head -1)
if [ -n "$WHEEL_FILE" ]; then
uv pip install --python ./test-env/Scripts/python.exe "$WHEEL_FILE"
else
echo "No wheel file found in ./base-dist/"
exit 1
fi
shell: bash
- name: Install main package from wheel (Windows)
if: inputs.install-method == 'wheel' && matrix.os == 'windows'
run: |
ls -la ./main-dist/
find ./main-dist -name "*.whl" -type f
WHEEL_FILE=$(find ./main-dist -name "*.whl" -type f | head -1)
if [ -n "$WHEEL_FILE" ]; then
uv pip install --python ./test-env/Scripts/python.exe "$WHEEL_FILE"
else
echo "No wheel file found in ./main-dist/"
exit 1
fi
shell: bash
- name: Install base package from wheel (Unix)
if: inputs.install-method == 'wheel' && matrix.os != 'windows'
run: |
ls -la ./base-dist/
find ./base-dist -name "*.whl" -type f
WHEEL_FILE=$(find ./base-dist -name "*.whl" -type f | head -1)
if [ -n "$WHEEL_FILE" ]; then
uv pip install --python ./test-env/bin/python "$WHEEL_FILE"
else
echo "No wheel file found in ./base-dist/"
exit 1
fi
shell: bash
- name: Install main package from wheel (Unix)
if: inputs.install-method == 'wheel' && matrix.os != 'windows'
run: |
ls -la ./main-dist/
find ./main-dist -name "*.whl" -type f
WHEEL_FILE=$(find ./main-dist -name "*.whl" -type f | head -1)
if [ -n "$WHEEL_FILE" ]; then
uv pip install --python ./test-env/bin/python "$WHEEL_FILE"
else
echo "No wheel file found in ./main-dist/"
exit 1
fi
shell: bash
# PyPI installation steps
- name: Install langflow from PyPI (Windows)
if: inputs.install-method == 'pypi' && matrix.os == 'windows'
run: |
if [ -n "${{ inputs.langflow-version }}" ]; then
uv pip install --python ./test-env/Scripts/python.exe langflow==${{ inputs.langflow-version }}
else
uv pip install --python ./test-env/Scripts/python.exe langflow
fi
shell: bash
- name: Install langflow from PyPI (Unix)
if: inputs.install-method == 'pypi' && matrix.os != 'windows'
run: |
if [ -n "${{ inputs.langflow-version }}" ]; then
uv pip install --python ./test-env/bin/python langflow==${{ inputs.langflow-version }}
else
uv pip install --python ./test-env/bin/python langflow
fi
shell: bash
# Install additional dependencies
- name: Install additional dependencies (Windows)
if: matrix.os == 'windows'
run: |
uv pip install --python ./test-env/Scripts/python.exe openai
shell: bash
- name: Install additional dependencies (Unix)
if: matrix.os != 'windows'
run: |
uv pip install --python ./test-env/bin/python openai
shell: bash
# Test steps
- name: Test CLI help command (Windows)
if: matrix.os == 'windows'
run: |
test-env\Scripts\python.exe -m langflow --help
shell: cmd
- name: Test CLI help command (Unix)
if: matrix.os != 'windows'
run: |
./test-env/bin/python -m langflow --help
shell: bash
- name: Test server startup (Windows)
if: matrix.os == 'windows'
timeout-minutes: ${{ inputs.test-timeout }}
run: |
# Start server in background
$serverProcess = Start-Process -FilePath ".\test-env\Scripts\python.exe" -ArgumentList "-m", "langflow", "run", "--host", "localhost", "--port", "7860", "--backend-only" -PassThru -WindowStyle Hidden
# Wait for server to be ready
$timeoutSeconds = ${{ inputs.test-timeout }} * 60
$elapsed = 0
do {
try {
$response = Invoke-WebRequest -Uri "http://localhost:7860/health_check" -UseBasicParsing -TimeoutSec 5
if ($response.StatusCode -eq 200) {
Write-Host "✅ Server is ready on ${{ matrix.os }}-${{ matrix.arch }}"
break
}
} catch {
Start-Sleep -Seconds 5
$elapsed += 5
}
} while ($elapsed -lt $timeoutSeconds)
if ($elapsed -ge $timeoutSeconds) {
Write-Host "❌ Server failed to start within timeout on ${{ matrix.os }}-${{ matrix.arch }}"
exit 1
}
# Stop the server process
Stop-Process -Id $serverProcess.Id -Force -ErrorAction SilentlyContinue
shell: powershell
- name: Test server startup (Unix)
if: matrix.os != 'windows'
timeout-minutes: ${{ inputs.test-timeout }}
run: |
# Start server in background
./test-env/bin/python -m langflow run --host localhost --port 7860 --backend-only &
SERVER_PID=$!
# Wait for server to be ready (using bash loop instead of timeout command)
TIMEOUT_SECONDS=$((${{ inputs.test-timeout }} * 60))
ELAPSED=0
while [ $ELAPSED -lt $TIMEOUT_SECONDS ]; do
if curl -f http://localhost:7860/health_check >/dev/null 2>&1; then
echo "✅ Server is ready on ${{ matrix.os }}-${{ matrix.arch }}"
break
fi
sleep 5
ELAPSED=$((ELAPSED + 5))
done
if [ $ELAPSED -ge $TIMEOUT_SECONDS ]; then
echo "❌ Server failed to start within timeout on ${{ matrix.os }}-${{ matrix.arch }}"
kill $SERVER_PID 2>/dev/null || true
exit 1
fi
# Clean shutdown
kill $SERVER_PID 2>/dev/null || true
sleep 5
shell: bash
- name: Test import in Python (Windows)
if: matrix.os == 'windows'
run: |
test-env\Scripts\python.exe -c "
try:
import langflow
print('✅ langflow import successful on ${{ matrix.os }}-${{ matrix.arch }}')
except Exception as e:
print(f'❌ langflow import failed on ${{ matrix.os }}-${{ matrix.arch }}: {e}')
exit(1)
"
shell: cmd
- name: Test import in Python (Unix)
if: matrix.os != 'windows'
run: |
./test-env/bin/python -c "
try:
import langflow
print('✅ langflow import successful on ${{ matrix.os }}-${{ matrix.arch }}')
except Exception as e:
print(f'❌ langflow import failed on ${{ matrix.os }}-${{ matrix.arch }}: {e}')
exit(1)
"
shell: bash
test-summary:
name: Cross-Platform Test Summary
needs: test-installation
runs-on: ubuntu-latest
if: always()
steps:
- name: Check test results
run: |
if [ "${{ needs.test-installation.result }}" != "success" ]; then
echo "❌ Cross-platform tests failed"
exit 1
else
echo "✅ All cross-platform tests passed"
fi

105
.github/workflows/cross-platform-test.md vendored Normal file
View file

@ -0,0 +1,105 @@
# Ad-Hoc Cross-Platform Install Tests
Quick guide for running cross-platform installation tests manually.
## Available Tests
### 1. Test from PyPI
Tests published langflow packages from PyPI across all platforms.
**Via GitHub UI:**
1. Go to **Actions** → **Manual Cross-Platform Test**
2. Check **"Test from PyPI"**
3. Optionally specify a version (leave empty for latest)
4. Click **"Run workflow"**
**Via CLI:**
```bash
# Test latest version
gh workflow run manual-cross-platform-test.yml -f test-from-pypi=true
# Test specific version
gh workflow run manual-cross-platform-test.yml \
-f test-from-pypi=true \
-f langflow-version="1.0.18"
```
### 2. Test from Source
Builds and tests langflow from current branch source code.
**Via GitHub UI:**
1. Go to **Actions** → **Manual Cross-Platform Test**
2. Leave **"Test from PyPI"** unchecked
3. Click **"Run workflow"**
**Via CLI:**
```bash
# Test current branch
gh workflow run manual-cross-platform-test.yml -f test-from-pypi=false
```
## Platforms Tested
- **Linux**: AMD64
- **macOS**: Intel (AMD64), Apple Silicon (ARM64)
- **Windows**: AMD64
- **Python versions**:
- **Linux & macOS**: 3.10 and 3.13
- **Windows**: 3.10 and 3.12 (3.12 used instead of 3.13 for better stability)
## What Gets Tested
1. **Package Installation**: `uv pip install langflow` (PyPI) or local wheel installation
2. **Dependencies**: Additional packages like `openai` for full functionality
3. **CLI Help**: `langflow --help`
4. **Server Startup**: `langflow run --backend-only` with `/health_check` endpoint validation
5. **Python Import**: `import langflow`
## Common Options
```bash
# Extended timeout (10 minutes instead of default 5)
gh workflow run manual-cross-platform-test.yml \
-f test-timeout=10
# Test specific PyPI version
gh workflow run manual-cross-platform-test.yml \
-f test-from-pypi=true \
-f langflow-version="1.0.18"
```
## Use Cases
- **Before releases**: Verify current branch works on all platforms
- **After PyPI publish**: Confirm published packages install correctly
- **Debugging issues**: Test specific versions when users report problems
- **Development**: Quick cross-platform validation during feature work
## Technical Details
### Installation Methods
- **PyPI testing**: Uses `uv pip install` with official PyPI packages
- **Source testing**: Builds wheels from source, then installs locally
- **Dependencies**: Automatically installs additional packages (`openai`) for full functionality
### Health Checking
- **Endpoint**: Uses `/health_check` for reliable server readiness validation
- **Validation**: Checks database connectivity and chat service functionality
- **Timeout**: Configurable timeout with proper cross-platform handling
### Platform-Specific Optimizations
- **Windows**: Uses Python 3.12 for better package ecosystem stability
- **Unix**: Uses Python 3.13 for latest language features where stable
- **Virtual Environments**: Uses `uv venv --seed` for consistent pip availability
### Workflow Architecture
- **Shared Logic**: Common test steps defined in `shared-cross-platform-test.yml`
- **DRY principle**: No code duplication between manual and automated workflows
- **Flexible**: Supports both wheel and PyPI installation methods through single workflow
## Results
- ✅ **Success**: All platforms pass installation and basic functionality
- ❌ **Failure**: One or more platforms fail (check logs for details)
- Each platform/Python combination runs independently
- **Parallel execution**: All platforms tested simultaneously for faster feedback

View file

@ -0,0 +1,109 @@
name: Cross-Platform Installation Test
on:
workflow_dispatch:
inputs:
base-artifact-name:
description: "Name of the base package artifact (leave empty to use latest from main branch)"
required: false
type: string
default: ""
main-artifact-name:
description: "Name of the main package artifact (leave empty to use latest from main branch)"
required: false
type: string
default: ""
test-timeout:
description: "Timeout for langflow server startup test (minutes)"
required: false
type: number
default: 5
run-id:
description: "GitHub run ID to download artifacts from (leave empty for latest successful run)"
required: false
type: string
default: ""
workflow_call:
inputs:
base-artifact-name:
description: "Name of the base package artifact"
required: true
type: string
main-artifact-name:
description: "Name of the main package artifact"
required: true
type: string
test-timeout:
description: "Timeout for langflow server startup test (minutes)"
required: false
type: number
default: 5
jobs:
build-if-needed:
name: Build Packages (if no artifacts provided)
runs-on: ubuntu-latest
if: inputs.base-artifact-name == '' || inputs.main-artifact-name == ''
outputs:
base-artifact-name: ${{ steps.set-names.outputs.base-artifact-name }}
main-artifact-name: ${{ steps.set-names.outputs.main-artifact-name }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Environment
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
python-version: "3.13"
- name: Install the project
run: uv sync
- name: Install frontend dependencies
run: make install_frontendci
- name: Build frontend
run: make build_frontend
- name: Build base package
run: make build_langflow_base args="--wheel"
- name: Build main package
run: make build_langflow args="--wheel"
- name: Upload base artifact
uses: actions/upload-artifact@v4
with:
name: adhoc-dist-base
path: /home/runner/work/langflow/langflow/dist
- name: Upload main artifact
uses: actions/upload-artifact@v4
with:
name: adhoc-dist-main
path: dist
- name: Set artifact names
id: set-names
run: |
echo "base-artifact-name=adhoc-dist-base" >> $GITHUB_OUTPUT
echo "main-artifact-name=adhoc-dist-main" >> $GITHUB_OUTPUT
test-wheel-installation:
name: Test Wheel Installation
needs: [build-if-needed]
if: always() && (needs.build-if-needed.result == 'success' || needs.build-if-needed.result == 'skipped')
uses: ./.github/workflows/cross-platform-test-shared.yml
with:
install-method: "wheel"
test-timeout: ${{ inputs.test-timeout }}
base-artifact-name: ${{ inputs.base-artifact-name || needs.build-if-needed.outputs.base-artifact-name }}
main-artifact-name: ${{ inputs.main-artifact-name || needs.build-if-needed.outputs.main-artifact-name }}
test-summary:
name: Cross-Platform Test Summary
needs: test-wheel-installation
runs-on: ubuntu-latest
if: always()
steps:
- name: Check test results
run: |
if [ "${{ needs.test-wheel-installation.result }}" != "success" ]; then
echo "❌ Cross-platform tests failed - PyPI upload blocked"
exit 1
else
echo "✅ All cross-platform tests passed - PyPI upload can proceed"
fi

View file

@ -54,8 +54,8 @@ jobs:
secrets: inherit
release-base:
name: Release Langflow Base
build-base:
name: Build Langflow Base
needs: [ci]
if: inputs.release_package_base == true
runs-on: ubuntu-latest
@ -113,12 +113,9 @@ jobs:
else
echo "Server terminated successfully"
fi
- name: Publish to PyPI
if: steps.check-version.outputs.skipped == 'false'
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: |
make publish base=true
# PyPI publishing moved to after cross-platform testing
- name: Upload Artifact
if: steps.check-version.outputs.skipped == 'false'
uses: actions/upload-artifact@v4
@ -126,10 +123,10 @@ jobs:
name: dist-base
path: src/backend/base/dist
release-main:
name: Release Langflow Main
build-main:
name: Build Langflow Main
if: inputs.release_package_main == true
needs: [release-base]
needs: [build-base]
runs-on: ubuntu-latest
outputs:
version: ${{ steps.check-version.outputs.version }}
@ -172,7 +169,7 @@ jobs:
echo version=$version >> $GITHUB_OUTPUT
fi
- name: Wait for PyPI Propagation
if: needs.release-base.outputs.skipped == 'false'
if: needs.build-base.outputs.skipped == 'false'
run: sleep 300 # wait for 5 minutes to ensure PyPI propagation
- name: Build project for distribution
@ -194,25 +191,78 @@ jobs:
else
echo "Server terminated successfully"
fi
- name: Publish to PyPI
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: |
make publish main=true
# PyPI publishing moved to after cross-platform testing
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: dist-main
path: dist
test-cross-platform:
name: Test Cross-Platform Installation
if: inputs.release_package_base == true || inputs.release_package_main == true
needs: [build-base, build-main]
uses: ./.github/workflows/cross-platform-test.yml
with:
base-artifact-name: "dist-base"
main-artifact-name: "dist-main"
test-timeout: 120
publish-base:
name: Publish Langflow Base to PyPI
if: inputs.release_package_base == true
needs: [build-base, test-cross-platform]
runs-on: ubuntu-latest
steps:
- name: Download base artifact
uses: actions/download-artifact@v4
with:
name: dist-base
path: src/backend/base/dist
- name: Setup Environment
uses: astral-sh/setup-uv@v6
with:
enable-cache: false
python-version: "3.13"
- name: Publish base to PyPI
if: needs.build-base.outputs.skipped == 'false'
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: |
cd src/backend/base && uv publish dist/*.whl
publish-main:
name: Publish Langflow Main to PyPI
if: inputs.release_package_main == true
needs: [build-main, test-cross-platform, publish-base]
runs-on: ubuntu-latest
steps:
- name: Download main artifact
uses: actions/download-artifact@v4
with:
name: dist-main
path: dist
- name: Setup Environment
uses: astral-sh/setup-uv@v6
with:
enable-cache: false
python-version: "3.13"
- name: Publish main to PyPI
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: |
uv publish dist/*.whl
call_docker_build_base:
name: Call Docker Build Workflow for Langflow Base
if: inputs.build_docker_base == true
needs: [release-base, release-main]
needs: [publish-base, publish-main]
uses: ./.github/workflows/docker-build.yml
with:
base_version: ${{ needs.release-base.outputs.version }}
main_version: ${{ needs.release-main.outputs.version }}
base_version: ${{ needs.publish-base.needs.build-base.outputs.version }}
main_version: ${{ needs.publish-main.needs.build-main.outputs.version }}
release_type: base
pre_release: ${{ inputs.pre_release }}
secrets: inherit
@ -220,10 +270,10 @@ jobs:
call_docker_build_main_ep:
name: Call Docker Build Workflow for Langflow with Entrypoint
if: inputs.build_docker_ep == true
needs: [release-main, call_docker_build_base]
needs: [publish-main, call_docker_build_base]
uses: ./.github/workflows/docker-build.yml
with:
main_version: ${{ needs.release-main.outputs.version }}
main_version: ${{ needs.publish-main.needs.build-main.outputs.version }}
release_type: main-ep
pre_release: False
secrets: inherit
@ -231,10 +281,10 @@ jobs:
call_docker_build_main:
name: Call Docker Build Workflow for Langflow
if: inputs.build_docker_main == true
needs: [release-main, call_docker_build_main_ep]
needs: [publish-main, call_docker_build_main_ep]
uses: ./.github/workflows/docker-build.yml
with:
main_version: ${{ needs.release-main.outputs.version }}
main_version: ${{ needs.publish-main.needs.build-main.outputs.version }}
release_type: main
pre_release: ${{ inputs.pre_release }}
secrets: inherit
@ -242,10 +292,10 @@ jobs:
call_docker_build_main_all:
name: Call Docker Build Workflow for langflow-all
if: inputs.build_docker_main == true
needs: [release-main]
needs: [publish-main]
uses: ./.github/workflows/docker-build.yml
with:
main_version: ${{ needs.release-main.outputs.version }}
main_version: ${{ needs.publish-main.needs.build-main.outputs.version }}
release_type: main-all
pre_release: ${{ inputs.pre_release }}
secrets: inherit
@ -254,7 +304,7 @@ jobs:
create_release:
name: Create Release
runs-on: ubuntu-latest
needs: release-main
needs: publish-main
steps:
- uses: actions/download-artifact@v4
with:
@ -268,5 +318,5 @@ jobs:
draft: false
generateReleaseNotes: true
prerelease: ${{ inputs.pre_release }}
tag: ${{ needs.release-main.outputs.version }}
tag: ${{ needs.publish-main.needs.build-main.outputs.version }}
commit: ${{ github.ref }}

View file

@ -58,14 +58,15 @@ env:
PYTHON_VERSION: "3.13"
jobs:
release-nightly-base:
name: Release Langflow Nightly Base
build-nightly-base:
name: Build Langflow Nightly Base
runs-on: ubuntu-latest
defaults:
run:
shell: bash
outputs:
version: ${{ steps.verify.outputs.version }}
skipped: ${{ steps.verify.outputs.skipped }}
steps:
- name: Check out the code at a specific ref
uses: actions/checkout@v4
@ -126,22 +127,17 @@ jobs:
echo "Server terminated successfully"
fi
- name: Publish to PyPI
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: |
make publish base=true
# PyPI publishing moved to after cross-platform testing
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: dist-base
name: dist-nightly-base
path: src/backend/base/dist
release-nightly-main:
name: Release Langflow Nightly Main
needs: [release-nightly-base]
build-nightly-main:
name: Build Langflow Nightly Main
needs: [build-nightly-base]
runs-on: ubuntu-latest
outputs:
version: ${{ steps.verify.outputs.version }}
@ -181,6 +177,7 @@ jobs:
version=$(echo $version | sed 's/^v//')
echo "version=$version" >> $GITHUB_OUTPUT
- name: Wait for PyPI Propagation
if: needs.build-nightly-base.outputs.skipped == 'false'
run: sleep 300 # wait for 5 minutes to ensure PyPI propagation of base
- name: Build project for distribution
@ -202,22 +199,73 @@ jobs:
else
echo "Server terminated successfully"
fi
# PyPI publishing moved to after cross-platform testing
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: dist-nightly-main
path: dist
test-cross-platform:
name: Test Cross-Platform Installation
needs: [build-nightly-base, build-nightly-main]
uses: ./.github/workflows/cross-platform-test.yml
with:
base-artifact-name: "dist-nightly-base"
main-artifact-name: "dist-nightly-main"
test-timeout: 120
publish-nightly-base:
name: Publish Langflow Base Nightly to PyPI
needs: [build-nightly-base, test-cross-platform]
runs-on: ubuntu-latest
steps:
- name: Download base artifact
uses: actions/download-artifact@v4
with:
name: dist-nightly-base
path: src/backend/base/dist
- name: Setup Environment
uses: astral-sh/setup-uv@v6
with:
enable-cache: false
python-version: "3.13"
- name: Publish base to PyPI
if: needs.build-nightly-base.outputs.skipped == 'false'
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: |
make publish base=true
publish-nightly-main:
name: Publish Langflow Main Nightly to PyPI
needs: [build-nightly-main, test-cross-platform, publish-nightly-base]
runs-on: ubuntu-latest
steps:
- name: Download main artifact
uses: actions/download-artifact@v4
with:
name: dist-nightly-main
path: dist
- name: Setup Environment
uses: astral-sh/setup-uv@v6
with:
enable-cache: false
python-version: "3.13"
- name: Publish to PyPI
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: |
make publish main=true
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: dist-main
path: dist
call_docker_build_base:
name: Call Docker Build Workflow for Langflow Base
if: always() && ${{ inputs.build_docker_base == 'true' }}
needs: [release-nightly-base, release-nightly-main]
needs: [build-nightly-base, build-nightly-main]
uses: ./.github/workflows/docker-build.yml
with:
release_type: nightly-base
@ -228,7 +276,7 @@ jobs:
call_docker_build_main:
name: Call Docker Build Workflow for Langflow
if: always() && ${{ inputs.build_docker_main == 'true' }}
needs: [release-nightly-main, call_docker_build_base]
needs: [build-nightly-main, call_docker_build_base]
uses: ./.github/workflows/docker-build.yml
with:
release_type: nightly-main
@ -239,7 +287,7 @@ jobs:
# call_docker_build_main_all:
# name: Call Docker Build Workflow for langflow-all
# if: always() && ${{ inputs.build_docker_main == 'true' }}
# needs: [release-nightly-main]
# needs: [build-nightly-main]
# uses: ./.github/workflows/docker-build.yml
# with:
# release_type: nightly-main-all
@ -249,7 +297,7 @@ jobs:
call_docker_build_main_ep:
name: Call Docker Build Workflow for Langflow with Entrypoint
if: always() && ${{ inputs.build_docker_ep == 'true' }}
needs: [release-nightly-main, call_docker_build_main]
needs: [build-nightly-main, call_docker_build_main]
uses: ./.github/workflows/docker-build.yml
with:
release_type: main-ep