This page describes the structure and behavior of the primary CI workflow at .github/workflows/ci.yml including how jobs are conditionally triggered, how path-based filtering decides what to run, the nightly status gate, and the final ci_success aggregation job.
For the overall testing strategy (what kinds of tests exist and how they're structured), see 8.1. For the release workflow that calls ci.yml as a dependency, see 8.3. For nightly build specifics, see 8.4. For linting tools, see 8.5.
ci.yml is a reusable workflow (workflow_call) as well as a directly triggerable one (pull_request, merge_group, workflow_dispatch). It orchestrates all automated quality checks: backend tests, frontend unit tests, frontend end-to-end tests, backend linting, docs build verification, starter template tests, and Docker image tests. A final aggregation job (ci_success) produces a single pass/fail signal consumed by branch protection rules.
The workflow is called directly from:
pull_request: [opened, synchronize, labeled])merge_group)release.yml via workflow_callnightly_build.yml indirectly via sub-workflowsSources: .github/workflows/ci.yml1-68
The concurrency block cancels any in-progress run on the same branch when a new commit is pushed, preventing redundant work.
Sources: .github/workflows/ci.yml63-68
The following diagram maps every job in ci.yml to its dependencies and the sub-workflows it calls.
CI Job Dependency Graph
Sources: .github/workflows/ci.yml76-456
set-ci-condition.github/workflows/ci.yml156-169
Evaluates two Boolean outputs that downstream jobs read:
| Output | Value |
|---|---|
should-run-ci | true when PR is not a draft, or when triggered via workflow_dispatch, workflow_call, or merge_group |
should-run-tests | true unless the PR carries the fast-track label (and even then, true when called programmatically) |
Draft PRs suppress most CI. Adding the fast-track label to a PR skips test jobs but still runs the CI condition evaluation.
check-nightly-status.github/workflows/ci.yml91-154
Queries the PyPI API for langflow-nightly to verify its latest release was published today. The result feeds the ci_success job.
If should-proceed is false and the workflow was triggered by a PR (not workflow_dispatch), ci_success fails — except when the PR only changes documentation files.
Sources: .github/workflows/ci.yml91-154 .github/workflows/ci.yml366-369
The path-filter job runs dorny/paths-filter against .github/changes-filter.yaml. It produces a set of Boolean outputs consumed by downstream jobs.
Path Filter Output to Job Mapping
| Filter key | Triggers |
|---|---|
python | test-backend, lint-backend, test-templates |
frontend | test-frontend-unit, test-frontend, test-templates |
docs | test-docs-build |
docker | test-docker |
components-changes | (used in typescript_test.yml suite detection) |
starter-projects-changes | (used in typescript_test.yml suite detection) |
workspace, api, database, mainpage | (used in typescript_test.yml suite detection) |
A composite output docs-only is true when docs == true and all other flags are false. When docs-only is set, the nightly status check is bypassed in ci_success.
If run-all-tests input is true (used in release builds), path filtering is skipped entirely and all jobs run unconditionally.
Sources: .github/workflows/ci.yml171-231 .github/changes-filter.yaml1-104
Changes filter categories
Sources: .github/changes-filter.yaml1-104
Each test job in ci.yml delegates to a reusable sub-workflow via uses:.
Sub-workflow Delegation
ci.yml Job | Sub-workflow | Runner |
|---|---|---|
test-backend | .github/workflows/python_test.yml | configurable (runs-on input) |
test-frontend-unit | .github/workflows/jest_test.yml | configurable |
test-frontend | .github/workflows/typescript_test.yml | configurable |
lint-backend | .github/workflows/lint-py.yml | ubuntu-latest |
test-docs-build | .github/workflows/docs_test.yml | ubuntu-latest |
test-docker | .github/workflows/docker_test.yml | ubuntu-latest |
test-templates | inline steps in ci.yml | ubuntu-latest |
Sources: .github/workflows/ci.yml233-338
test-backend → python_test.ymlRuns three parallel job groups:
build (unit tests): Matrix of Python versions × 5 split groups. Uses pytest-split to distribute the test suite across groups. Runs with make unit_tests targeting src/backend/tests. Coverage is uploaded to Codecov for Python 3.10.integration-tests: Matrix of Python versions, runs make integration_tests_no_api_keys.lfx-tests: Matrix of Python versions, runs uv run make lfx_tests in the src/lfx package.test-cli: Matrix of Python versions. Builds a wheel, installs it into a fresh venv, starts the server with --backend-only, polls /api/v1/auto_login until ready, then terminates.Sources: .github/workflows/python_test.yml55-255
test-frontend → typescript_test.yml.github/workflows/typescript_test.yml74-420
This sub-workflow performs dynamic test sharding:
determine-test-suite: Reads path-filter outputs (passed via suites input or detected from dorny/paths-filter) and maps them to Playwright --grep tag patterns. Counts total matching tests, then computes the optimal shard count (1 shard per 5 tests, capped at 70).
setup-and-test: Runs one job per shard in parallel (fail-fast: false). Each shard runs npx playwright test ... --shard N/Total --workers 2 --retries=3. Playwright browsers are cached by version and OS.
merge-reports: Runs unconditionally after setup-and-test. If any shard failed, downloads all blob-report-* artifacts and merges them into a single HTML report via npx playwright merge-reports.
Test Suite to Tag Mapping
| Suite name | --grep pattern |
|---|---|
components | @components |
starter-projects | @starter-projects |
workspace | @workspace |
api | @api |
database | @database |
development | @development |
release (default/fallback) | @release |
When triggered with release: true, all suites collapse to ["release"] and --grep="@release" is used.
Sources: .github/workflows/typescript_test.yml74-266
Frontend test sharding flow
Sources: .github/workflows/typescript_test.yml234-266 .github/workflows/typescript_test.yml266-420
test-templates (inline).github/workflows/ci.yml300-331
Runs directly in ci.yml without delegating to a sub-workflow. Installs the project with uv sync --dev and runs:
uv run pytest src/backend/tests/unit/template/test_starter_projects.py -v -n auto
Condition: Python or frontend changes detected, or run-all-tests is true.
ci_success Aggregation Job.github/workflows/ci.yml343-456
This job always runs (if: always()), collects the results of every other job, and exits with code 0 or 1.
Exit conditions:
The EXIT_CODE environment variable is computed as:
EXIT_CODE = (
contains(results, 'failure') ||
contains(results, 'cancelled') ||
(nightly-check failed AND event != workflow_dispatch AND NOT docs-only)
) ? '1' : '0'
On failure, the job prints a description of which job failed and guidance on how to fix it (e.g., "Run make format_backend then make lint to fix code style issues").
The docs-only bypass means PRs that touch only docs/** files never fail due to a broken nightly build.
Sources: .github/workflows/ci.yml343-456
When ci.yml is called via workflow_call (e.g., from release.yml), it accepts these inputs:
| Input | Type | Default | Purpose |
|---|---|---|---|
ref | string | — | Git ref to check out |
python-versions | string | ["3.10"] | Python version matrix for backend tests |
frontend-tests-folder | string | "tests/core" | Playwright test folder |
release | boolean | false | If true, runs all FE tests with @release tag |
run-all-tests | boolean | false | Bypasses path filtering |
runs-on | string | "ubuntu-latest" | Runner label |
Secrets inherited: OPENAI_API_KEY, ANTHROPIC_API_KEY, STORE_API_KEY, TAVILY_API_KEY, CODECOV_TOKEN.
Sources: .github/workflows/ci.yml3-68
Two supplementary workflows run on PRs and automatically commit fixes back to the branch using the autofix.ci service:
| Workflow | Trigger | Action |
|---|---|---|
py_autofix.yml | pull_request on **/*.py | Runs ruff check --fix-only + ruff format, updates starter projects via scripts/ci/update_starter_projects.py, rebuilds component_index.json |
js_autofix.yml | pull_request on src/frontend/** | Runs npm run format (Biome) |
These run in parallel with CI and do not block the ci_success gate.
Sources: .github/workflows/py_autofix.yml1-79 .github/workflows/js_autofix.yml1-47
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.