Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
dd3ac6a
refactor(types): Rename Data to JSON and DataFrame to Table …
Cristhianzl Mar 11, 2026
911bc9d
fix: update openai api key prefix in fe (#12122)
jordanrfrazier Mar 11, 2026
9012a54
feat: revise deployment schemas (#12150)
HzaRashid Mar 11, 2026
abf0fb9
feat(deployment): add list operations for configs and snapshots (#12162)
HzaRashid Mar 12, 2026
329ae37
chore: fix safe biome issues (#12169)
Adam-Aghili Mar 12, 2026
170c986
docs: square up inline icons CSS (#12159)
mendonk Mar 12, 2026
bc2da11
fix: gate PyPI publish jobs on CI completion in release workflow (#12…
vjgit96 Mar 12, 2026
c4adc7d
fix: filter Docker Hub tag queries to prevent rc0 overwrite (LE-515) …
vjgit96 Mar 12, 2026
4334e0b
fix: Cascading deletes to files when deleting users (#12155)
erichare Mar 12, 2026
a2e1660
docs: OpenAPI spec content updated without version change (#12113)
github-actions[bot] Mar 12, 2026
1fdbbfa
docs: uv included in 1.8.1 images (#12135)
mendonk Mar 13, 2026
73b6612
fix: prevent RCE via data parameter in build_public_tmp endpoint (#12…
Jkavia Mar 13, 2026
7838d0d
fix: Postgres JSON column fails with "Token NaN is invalid" when Agen…
AryamanSi17 Mar 13, 2026
4511419
docs: replace the file upload utility (#12153)
mendonk Mar 13, 2026
ba8dab1
ci: allow docs-only pull requests to skip tests (#12174)
mendonk Mar 13, 2026
e6d6d2e
fix: use timezone=true on flow_version created_at field (#12180)
jordanrfrazier Mar 13, 2026
aea0796
fix: Proper refresh of Groq models (#12158)
erichare Mar 13, 2026
f553896
chore: merge branch release-1.8.1 into main (#12185)
Adam-Aghili Mar 13, 2026
1dafc75
fix: make LANGFUSE_BASE_URL the preferred URL variable (#12154)
mendonk Mar 13, 2026
67d5694
chore: remove hash history (#12183)
jordanrfrazier Mar 16, 2026
8dbcbb0
chore: release nightlies from of release branch (#12181)
Adam-Aghili Mar 16, 2026
37cf0a1
test: add upgrade migration check to ci (#12061)
jordanrfrazier Mar 16, 2026
3811db4
feat(deployments): unify payload passthrough from api to adapter (#12…
HzaRashid Mar 16, 2026
2d3be10
fix: allow clearing Max Tokens field with Backspace/Delete (#12198)
viktoravelino Mar 16, 2026
94c94ad
fix: Resolve CodeQL false positives for path injection and URL substr…
Cristhianzl Mar 16, 2026
68edb4a
fix: Add explicit left/right DataFrame inputs for merge operations (#…
Cristhianzl Mar 16, 2026
7c5bda4
fix: add dict to allowlist preventing TableInput data loss (#12074)
AntonioABLima Mar 16, 2026
facd0b1
chore: update pyproject versions 1.9.0
Adam-Aghili Mar 17, 2026
13908b2
fix: 1.9.0 nightly
Adam-Aghili Mar 17, 2026
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
  •  
  •  
  •  
21 changes: 18 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,12 @@ jobs:
if: |
always() &&
!cancelled() &&
needs.set-ci-condition.outputs.should-run-tests == 'true'
needs.set-ci-condition.outputs.should-run-tests == 'true' &&
(
inputs.run-all-tests ||
(needs.path-filter.result != 'skipped' &&
needs.path-filter.outputs.docs-only != 'true')
)
uses: ./.github/workflows/python_test.yml
with:
python-versions: ${{ inputs.python-versions || '["3.10"]' }}
Expand All @@ -253,7 +258,12 @@ jobs:
if: |
always() &&
!cancelled() &&
needs.set-ci-condition.outputs.should-run-tests == 'true'
needs.set-ci-condition.outputs.should-run-tests == 'true' &&
(
inputs.run-all-tests ||
(needs.path-filter.result != 'skipped' &&
needs.path-filter.outputs.docs-only != 'true')
)
uses: ./.github/workflows/jest_test.yml
with:
ref: ${{ inputs.ref || github.ref }}
Expand All @@ -266,7 +276,12 @@ jobs:
if: |
always() &&
!cancelled() &&
needs.set-ci-condition.outputs.should-run-tests == 'true'
needs.set-ci-condition.outputs.should-run-tests == 'true' &&
(
inputs.run-all-tests ||
(needs.path-filter.result != 'skipped' &&
needs.path-filter.outputs.docs-only != 'true')
)
uses: ./.github/workflows/typescript_test.yml
with:
tests_folder: ${{ inputs.frontend-tests-folder }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/docker-build-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ jobs:
echo "Base version from pyproject.toml: $version"

if [ ${{inputs.pre_release}} == "true" ]; then
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/langflowai/langflow/tags?page_size=100" | jq -r '.results[].name' | grep -E '\.rc[0-9]+' | sort -V | tail -n 1)
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/langflowai/langflow/tags?page_size=100" | jq -r '.results[].name' | grep -E '^base-.*\.rc[0-9]+' | grep -vE '\-(amd64|arm64)$' | sed 's/^base-//' | sort -V | tail -n 1)
version="$(uv run ./scripts/ci/langflow_pre_release_tag.py "$version" "$last_released_version")"
echo "Latest base pre-release version: $last_released_version"
echo "Base pre-release version to be released: $version"
else
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/langflowai/langflow/tags?page_size=100" | jq -r '.results[].name' | grep -v 'latest' | sort -V | tail -n 1)
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/langflowai/langflow/tags?page_size=100" | jq -r '.results[].name' | grep -E '^base-' | grep -vE '\-(amd64|arm64)$' | grep -v 'latest' | sed 's/^base-//' | sort -V | tail -n 1)
echo "Latest base release version: $last_released_version"
fi

Expand Down Expand Up @@ -128,12 +128,12 @@ jobs:
echo "Main version from pyproject.toml: $version"

if [ ${{inputs.pre_release}} == "true" ]; then
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/langflowai/langflow/tags?page_size=100" | jq -r '.results[].name' | grep -E '\.rc[0-9]+' | sort -V | tail -n 1)
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/langflowai/langflow/tags?page_size=100" | jq -r '.results[].name' | grep -E '\.rc[0-9]+' | grep -v '^base-' | grep -vE '\-(amd64|arm64)$' | sort -V | tail -n 1)
version="$(uv run ./scripts/ci/langflow_pre_release_tag.py "$version" "$last_released_version")"
echo "Latest main pre-release version: $last_released_version"
echo "Main pre-release version to be released: $version"
else
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/langflowai/langflow/tags?page_size=100" | jq -r '.results[].name' | grep -v 'latest' | sort -V | tail -n 1)
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/langflowai/langflow/tags?page_size=100" | jq -r '.results[].name' | grep -v '^base-' | grep -vE '\-(amd64|arm64)$' | grep -v 'latest' | sort -V | tail -n 1)
echo "Latest main release version: $last_released_version"
fi

Expand Down
120 changes: 75 additions & 45 deletions .github/workflows/migration-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ on:
pull_request:
paths:
- 'src/backend/base/langflow/alembic/versions/*.py'
- 'alembic/versions/*.py'
- 'src/backend/base/langflow/services/database/models/**/*.py'
- 'src/backend/tests/unit/alembic/test_migration_execution.py'
- '.github/workflows/migration-validation.yml'

jobs:
validate-migration:
model-migration-consistency:
name: Model/Migration Consistency
runs-on: ubuntu-latest

steps:
Expand All @@ -16,50 +19,72 @@ jobs:
with:
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v6

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
python-version: '3.12'

- name: Install dependencies
run: |
pip install sqlalchemy alembic
uv sync

- name: Get changed migration files
id: changed-files
- name: Check model/migration consistency
env:
MIGRATION_VALIDATION_CI: "true"
run: |
# Get all changed Python files in alembic/versions directories
uv run pytest src/backend/tests/unit/alembic/test_migration_execution.py -x -v

# CHANGED_FILES=$(git diff --name-only origin/main...HEAD | grep -E '(alembic|migrations)/versions/.*\.py$' || echo "")
validate-migration:
name: Migration Pattern Validation
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0

# Exclude test migrations, as they are not part of the main codebase
CHANGED_FILES=$(git diff --name-only origin/main...HEAD | grep -E '(alembic|migrations)/versions/.*\.py$' | grep -v 'test_migrations/' || echo "")
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: Get changed migration files
id: changed-files
run: |
set -euo pipefail
CHANGED_FILES=$(git diff --name-only origin/main...HEAD | grep -E 'src/backend/base/langflow/alembic/versions/.*\.py$' | grep -v 'test_migrations/' || echo "")

if [ -z "$CHANGED_FILES" ]; then
echo "No migration files changed"
echo "files=" >> $GITHUB_OUTPUT
echo "files=" >> "$GITHUB_OUTPUT"
else
echo "Changed migration files:"
echo "$CHANGED_FILES"
# Convert newlines to spaces for passing as arguments
echo "files=$(echo $CHANGED_FILES | tr '\n' ' ')" >> $GITHUB_OUTPUT
echo "files=$(printf '%s' "$CHANGED_FILES" | tr '\n' ' ')" >> "$GITHUB_OUTPUT"
fi

- name: Validate migrations
- name: Validate migration patterns
if: steps.changed-files.outputs.files != ''
env:
MIGRATION_FILES: ${{ steps.changed-files.outputs.files }}
run: |
python src/backend/base/langflow/alembic/migration_validator.py ${{ steps.changed-files.outputs.files }}

# - name: Check migration phase sequence
# if: steps.changed-files.outputs.files != ''
# run: |
# python scripts/check_phase_sequence.py ${{ steps.changed-files.outputs.files }}
python src/backend/base/langflow/alembic/migration_validator.py $MIGRATION_FILES

- name: Generate validation report
if: always() && steps.changed-files.outputs.files != ''
env:
MIGRATION_FILES: ${{ steps.changed-files.outputs.files }}
run: |
python src/backend/base/langflow/alembic/migration_validator.py \
--json ${{ steps.changed-files.outputs.files }} > validation-report.json || true
--json $MIGRATION_FILES > validation-report.json 2> validation-stderr.txt || true
if [ ! -s validation-report.json ]; then
echo "::error::Validator produced no output. Stderr:"
cat validation-stderr.txt
fi

- name: Post PR comment with results
if: always() && steps.changed-files.outputs.files != ''
Expand Down Expand Up @@ -110,7 +135,7 @@ jobs:
}
}

message += `### 📚 Resources\n`;
message += `### Resources\n`;
message += `- Review the [DB Migration Guide](./src/backend/base/langflow/alembic/DB-MIGRATION-GUIDE.MD)\n`;
message += `- Use \`python scripts/generate_migration.py --help\` to generate compliant migrations\n\n`;

Expand All @@ -123,37 +148,42 @@ jobs:
} catch (error) {
message = `⚠️ **Migration validation check failed to run properly**\n`;
message += `Error: ${error.message}\n`;
validationPassed = false;
}

// Post or update comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});

const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Migration Validation')
);

if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: message
});
} else {
await github.rest.issues.createComment({
// Post or update comment (non-critical — don't let API errors mask validation results)
try {
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: message
});

const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Migration Validation')
);

if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: message
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: message
});
}
} catch (apiError) {
core.warning(`Failed to post PR comment: ${apiError.message}`);
}

// Fail the workflow if validation didn't pass
if (!validationPassed) {
core.setFailed('Migration validation failed');
}
}
Loading