Spaces:
Running
Running
Tai Truong
commited on
Commit
·
d202ada
1
Parent(s):
40131fc
fix readme
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .devcontainer/Dockerfile +29 -0
- .devcontainer/demo/README.md +15 -0
- .devcontainer/demo/devcontainer.json +33 -0
- .devcontainer/devcontainer.json +51 -0
- .env.example +104 -0
- .eslintrc.json +90 -0
- .gitattributes +32 -35
- .github/ISSUE_TEMPLATE/bug-report.yaml +120 -0
- .github/ISSUE_TEMPLATE/feature-request.yaml +28 -0
- .github/ISSUE_TEMPLATE/work-in-progress.yaml +58 -0
- .github/actions/install-playwright/action.yml +76 -0
- .github/actions/poetry_caching/action.yml +99 -0
- .github/actions/setup-uv/action.yml +25 -0
- .github/changes-filter.yaml +71 -0
- .github/dependabot.yml +11 -0
- .github/release.yml +35 -0
- .github/semantic.yml +2 -0
- .github/workflows/auto-update.yml +13 -0
- .github/workflows/ci.yml +140 -0
- .github/workflows/codeql.yml +66 -0
- .github/workflows/codspeed.yml +45 -0
- .github/workflows/conventional-labels.yml +28 -0
- .github/workflows/create-release.yml +36 -0
- .github/workflows/deploy_gh-pages.yml +41 -0
- .github/workflows/docker-build.yml +323 -0
- .github/workflows/docker_test.yml +64 -0
- .github/workflows/docs_test.yml +49 -0
- .github/workflows/fetch_docs_notion.yml +61 -0
- .github/workflows/integration_tests.yml +50 -0
- .github/workflows/js_autofix.yml +45 -0
- .github/workflows/lint-js.yml +53 -0
- .github/workflows/lint-py.yml +41 -0
- .github/workflows/matchers/ruff.json +14 -0
- .github/workflows/nightly_build.yml +204 -0
- .github/workflows/py_autofix.yml +21 -0
- .github/workflows/python_test.yml +175 -0
- .github/workflows/release.yml +243 -0
- .github/workflows/release_nightly.yml +233 -0
- .github/workflows/store_pytest_durations.yml +65 -0
- .github/workflows/style-check-py.yml +31 -0
- .github/workflows/typescript_test.yml +348 -0
- .gitignore +279 -0
- .pre-commit-config.yaml +25 -0
- .vscode/launch.json +80 -0
- .vscode/tasks.json +54 -0
- CODE_OF_CONDUCT.md +128 -0
- CONTRIBUTING.md +102 -0
- LICENSE +21 -0
- Makefile +446 -0
- README.md +0 -11
.devcontainer/Dockerfile
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Source: https://github.com/a5chin/python-uv
|
2 |
+
FROM debian:bookworm-slim AS builder
|
3 |
+
|
4 |
+
ENV CARGO_HOME="/opt/.cargo"
|
5 |
+
|
6 |
+
SHELL [ "/bin/bash", "-o", "pipefail", "-c" ]
|
7 |
+
|
8 |
+
WORKDIR /opt
|
9 |
+
|
10 |
+
# The installer requires curl (and certificates) to download the release archive
|
11 |
+
# hadolint ignore=DL3008
|
12 |
+
RUN apt-get update && \
|
13 |
+
apt-get install -y --no-install-recommends ca-certificates curl
|
14 |
+
|
15 |
+
# Run uv installer
|
16 |
+
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
|
17 |
+
|
18 |
+
|
19 |
+
FROM mcr.microsoft.com/vscode/devcontainers/base:bookworm
|
20 |
+
|
21 |
+
|
22 |
+
ENV CARGO_HOME="/opt/.cargo"
|
23 |
+
ENV PATH="$CARGO_HOME/bin/:$PATH"
|
24 |
+
ENV PYTHONUNBUFFERED=True
|
25 |
+
ENV UV_LINK_MODE=copy
|
26 |
+
|
27 |
+
WORKDIR /opt
|
28 |
+
|
29 |
+
COPY --from=builder --chown=vscode: $CARGO_HOME $CARGO_HOME
|
.devcontainer/demo/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Langflow Demo Codespace Readme
|
2 |
+
|
3 |
+
These instructions will walk you through the process of running a Langflow demo via GitHub Codespaces.
|
4 |
+
|
5 |
+
## Setup
|
6 |
+
|
7 |
+
### Create a Codespace in GitHub
|
8 |
+
|
9 |
+
To setup the demo, simply navigate to the Langflow repo, click the "+" button, and select "Create new Codespace". This will automatically create a new codespace in your browser, which you can use for the demo.
|
10 |
+
|
11 |
+
### Wait for everything to install
|
12 |
+
|
13 |
+
After the codespace is opened, you should see a new Terminal window in VS Code where langflow is installed. Once the install completes, `langflow` will launch the webserver and your application will be available via devcontainer port.
|
14 |
+
|
15 |
+
Note: VS Code should prompt you with a button to push once the port is available.
|
.devcontainer/demo/devcontainer.json
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
2 |
+
// README at: https://github.com/devcontainers/templates/tree/main/src/universal
|
3 |
+
{
|
4 |
+
"name": "Langflow Demo Container",
|
5 |
+
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
6 |
+
"image": "mcr.microsoft.com/devcontainers/python:3.10",
|
7 |
+
"features": {
|
8 |
+
"ghcr.io/devcontainers/features/aws-cli:1": {},
|
9 |
+
"ghcr.io/devcontainers/features/docker-in-docker": {},
|
10 |
+
"ghcr.io/devcontainers/features/node": {}
|
11 |
+
},
|
12 |
+
"customizations": {
|
13 |
+
"vscode": {
|
14 |
+
"extensions": [
|
15 |
+
"actboy168.tasks",
|
16 |
+
"GitHub.copilot",
|
17 |
+
"ms-python.python",
|
18 |
+
"eamodio.gitlens",
|
19 |
+
"GitHub.vscode-pull-request-github"
|
20 |
+
]
|
21 |
+
}
|
22 |
+
},
|
23 |
+
// Features to add to the dev container. More info: https://containers.dev/features.
|
24 |
+
// "features": {},
|
25 |
+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
26 |
+
// "forwardPorts": [],
|
27 |
+
// Use 'postCreateCommand' to run commands after the container is created.
|
28 |
+
"postCreateCommand": "pipx install 'langflow>=0.0.33' && langflow --host 0.0.0.0"
|
29 |
+
// Configure tool-specific properties.
|
30 |
+
// "customizations": {},
|
31 |
+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
32 |
+
// "remoteUser": "root"
|
33 |
+
}
|
.devcontainer/devcontainer.json
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
2 |
+
// README at: https://github.com/devcontainers/templates/tree/main/src/universal
|
3 |
+
{
|
4 |
+
"name": "Langflow Dev Container",
|
5 |
+
"build": {
|
6 |
+
"context": "..",
|
7 |
+
"dockerfile": "Dockerfile"
|
8 |
+
},
|
9 |
+
// Features to add to the dev container. More info: https://containers.dev/features.
|
10 |
+
"features": {
|
11 |
+
"ghcr.io/devcontainers/features/node": {},
|
12 |
+
"ghcr.io/dhoeric/features/hadolint:1": {}
|
13 |
+
},
|
14 |
+
|
15 |
+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
16 |
+
// "forwardPorts": [],
|
17 |
+
|
18 |
+
// Use 'postCreateCommand' to run commands after the container is created.
|
19 |
+
"postCreateCommand": "make install_frontend && make install_backend",
|
20 |
+
"postStartCommand": "make init",
|
21 |
+
|
22 |
+
// Configure tool-specific properties.
|
23 |
+
"customizations": {
|
24 |
+
"vscode": {
|
25 |
+
"extensions": [
|
26 |
+
"charliermarsh.ruff",
|
27 |
+
"njpwerner.autodocstring",
|
28 |
+
"oderwat.indent-rainbow",
|
29 |
+
"exiasr.hadolint",
|
30 |
+
"actboy168.tasks",
|
31 |
+
"GitHub.copilot",
|
32 |
+
"ms-python.python",
|
33 |
+
"eamodio.gitlens",
|
34 |
+
"ms-vscode.makefile-tools",
|
35 |
+
"GitHub.vscode-pull-request-github"
|
36 |
+
],
|
37 |
+
"settings": {
|
38 |
+
"terminal.integrated.defaultProfile.linux": "zsh",
|
39 |
+
"terminal.integrated.profiles.linux": {
|
40 |
+
"zsh": {
|
41 |
+
"path": "/bin/zsh"
|
42 |
+
}
|
43 |
+
}
|
44 |
+
}
|
45 |
+
}
|
46 |
+
},
|
47 |
+
|
48 |
+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
49 |
+
// "remoteUser": "root"
|
50 |
+
"remoteUser": "vscode"
|
51 |
+
}
|
.env.example
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Description: Example of .env file
|
2 |
+
# Usage: Copy this file to .env and change the values
|
3 |
+
# according to your needs
|
4 |
+
# Do not commit .env file to git
|
5 |
+
# Do not change .env.example file
|
6 |
+
|
7 |
+
# Config directory
|
8 |
+
# Directory where files, logs and database will be stored
|
9 |
+
# Example: LANGFLOW_CONFIG_DIR=~/.langflow
|
10 |
+
LANGFLOW_CONFIG_DIR=
|
11 |
+
|
12 |
+
# Save database in the config directory
|
13 |
+
# Values: true, false
|
14 |
+
# If false, the database will be saved in Langflow's root directory
|
15 |
+
# This means that the database will be deleted when Langflow is uninstalled
|
16 |
+
# and that the database will not be shared between different virtual environments
|
17 |
+
# Example: LANGFLOW_SAVE_DB_IN_CONFIG_DIR=true
|
18 |
+
LANGFLOW_SAVE_DB_IN_CONFIG_DIR=
|
19 |
+
|
20 |
+
# Database URL
|
21 |
+
# Postgres example: LANGFLOW_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/langflow
|
22 |
+
# SQLite example:
|
23 |
+
LANGFLOW_DATABASE_URL=sqlite:///./langflow.db
|
24 |
+
|
25 |
+
# Cache type
|
26 |
+
LANGFLOW_LANGCHAIN_CACHE=SQLiteCache
|
27 |
+
|
28 |
+
# Server host
|
29 |
+
# Example: LANGFLOW_HOST=127.0.0.1
|
30 |
+
LANGFLOW_HOST=
|
31 |
+
|
32 |
+
# Worker processes
|
33 |
+
# Example: LANGFLOW_WORKERS=1
|
34 |
+
LANGFLOW_WORKERS=
|
35 |
+
|
36 |
+
# Server port
|
37 |
+
# Example: LANGFLOW_PORT=7860
|
38 |
+
LANGFLOW_PORT=
|
39 |
+
|
40 |
+
# Logging level
|
41 |
+
# Example: LANGFLOW_LOG_LEVEL=critical
|
42 |
+
LANGFLOW_LOG_LEVEL=
|
43 |
+
|
44 |
+
# Path to the log file
|
45 |
+
# Example: LANGFLOW_LOG_FILE=logs/langflow.log
|
46 |
+
LANGFLOW_LOG_FILE=
|
47 |
+
|
48 |
+
# Path to the frontend directory containing build files
|
49 |
+
# Example: LANGFLOW_FRONTEND_PATH=/path/to/frontend/build/files
|
50 |
+
LANGFLOW_FRONTEND_PATH=
|
51 |
+
|
52 |
+
# Whether to open the browser after starting the server
|
53 |
+
# Values: true, false
|
54 |
+
# Example: LANGFLOW_OPEN_BROWSER=true
|
55 |
+
LANGFLOW_OPEN_BROWSER=
|
56 |
+
|
57 |
+
# Whether to remove API keys from the projects saved in the database
|
58 |
+
# Values: true, false
|
59 |
+
# Example: LANGFLOW_REMOVE_API_KEYS=false
|
60 |
+
LANGFLOW_REMOVE_API_KEYS=
|
61 |
+
|
62 |
+
# Whether to use RedisCache or ThreadingInMemoryCache or AsyncInMemoryCache
|
63 |
+
# Values: async, memory, redis
|
64 |
+
# Example: LANGFLOW_CACHE_TYPE=memory
|
65 |
+
# If you want to use redis then the following environment variables must be set:
|
66 |
+
# LANGFLOW_REDIS_HOST (default: localhost)
|
67 |
+
# LANGFLOW_REDIS_PORT (default: 6379)
|
68 |
+
# LANGFLOW_REDIS_DB (default: 0)
|
69 |
+
# LANGFLOW_REDIS_CACHE_EXPIRE (default: 3600)
|
70 |
+
LANGFLOW_CACHE_TYPE=
|
71 |
+
|
72 |
+
# Set AUTO_LOGIN to false if you want to disable auto login
|
73 |
+
# and use the login form to login. LANGFLOW_SUPERUSER and LANGFLOW_SUPERUSER_PASSWORD
|
74 |
+
# must be set if AUTO_LOGIN is set to false
|
75 |
+
# Values: true, false
|
76 |
+
LANGFLOW_AUTO_LOGIN=
|
77 |
+
|
78 |
+
# Superuser username
|
79 |
+
# Example: LANGFLOW_SUPERUSER=admin
|
80 |
+
LANGFLOW_SUPERUSER=
|
81 |
+
|
82 |
+
# Superuser password
|
83 |
+
# Example: LANGFLOW_SUPERUSER_PASSWORD=123456
|
84 |
+
LANGFLOW_SUPERUSER_PASSWORD=
|
85 |
+
|
86 |
+
# Should store environment variables in the database
|
87 |
+
# Values: true, false
|
88 |
+
LANGFLOW_STORE_ENVIRONMENT_VARIABLES=
|
89 |
+
|
90 |
+
# STORE_URL
|
91 |
+
# Example: LANGFLOW_STORE_URL=https://api.langflow.store
|
92 |
+
# LANGFLOW_STORE_URL=
|
93 |
+
|
94 |
+
# DOWNLOAD_WEBHOOK_URL
|
95 |
+
#
|
96 |
+
# LANGFLOW_DOWNLOAD_WEBHOOK_URL=
|
97 |
+
|
98 |
+
# LIKE_WEBHOOK_URL
|
99 |
+
#
|
100 |
+
# LANGFLOW_LIKE_WEBHOOK_URL=
|
101 |
+
|
102 |
+
# Value must finish with slash /
|
103 |
+
#BACKEND_URL=http://localhost:7860/
|
104 |
+
BACKEND_URL=
|
.eslintrc.json
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"extends": [
|
3 |
+
"eslint:recommended",
|
4 |
+
"plugin:react/recommended",
|
5 |
+
"plugin:prettier/recommended"
|
6 |
+
],
|
7 |
+
"plugins": [
|
8 |
+
"react",
|
9 |
+
"import-helpers",
|
10 |
+
"prettier"
|
11 |
+
],
|
12 |
+
"parser": "@typescript-eslint/parser",
|
13 |
+
"parserOptions": {
|
14 |
+
"project": [
|
15 |
+
"./tsconfig.node.json",
|
16 |
+
"./tsconfig.json"
|
17 |
+
],
|
18 |
+
"extraFileExtensions:": [
|
19 |
+
".mdx"
|
20 |
+
],
|
21 |
+
"extensions:": [
|
22 |
+
".mdx"
|
23 |
+
]
|
24 |
+
},
|
25 |
+
"env": {
|
26 |
+
"browser": true,
|
27 |
+
"es2021": true
|
28 |
+
},
|
29 |
+
"settings": {
|
30 |
+
"react": {
|
31 |
+
"version": "detect"
|
32 |
+
}
|
33 |
+
},
|
34 |
+
"rules": {
|
35 |
+
"no-console": "warn",
|
36 |
+
"no-self-assign": "warn",
|
37 |
+
"no-self-compare": "warn",
|
38 |
+
"complexity": [
|
39 |
+
"error",
|
40 |
+
{
|
41 |
+
"max": 15
|
42 |
+
}
|
43 |
+
],
|
44 |
+
"indent": [
|
45 |
+
"error",
|
46 |
+
2,
|
47 |
+
{
|
48 |
+
"SwitchCase": 1
|
49 |
+
}
|
50 |
+
],
|
51 |
+
"no-dupe-keys": "error",
|
52 |
+
"no-invalid-regexp": "error",
|
53 |
+
"no-undef": "error",
|
54 |
+
"no-return-assign": "error",
|
55 |
+
"no-redeclare": "error",
|
56 |
+
"no-empty": "error",
|
57 |
+
"no-await-in-loop": "error",
|
58 |
+
"react/react-in-jsx-scope": 0,
|
59 |
+
"node/exports-style": [
|
60 |
+
"error",
|
61 |
+
"module.exports"
|
62 |
+
],
|
63 |
+
"node/file-extension-in-import": [
|
64 |
+
"error",
|
65 |
+
"always"
|
66 |
+
],
|
67 |
+
"node/prefer-global/buffer": [
|
68 |
+
"error",
|
69 |
+
"always"
|
70 |
+
],
|
71 |
+
"node/prefer-global/console": [
|
72 |
+
"error",
|
73 |
+
"always"
|
74 |
+
],
|
75 |
+
"node/prefer-global/process": [
|
76 |
+
"error",
|
77 |
+
"always"
|
78 |
+
],
|
79 |
+
"node/prefer-global/url-search-params": [
|
80 |
+
"error",
|
81 |
+
"always"
|
82 |
+
],
|
83 |
+
"node/prefer-global/url": [
|
84 |
+
"error",
|
85 |
+
"always"
|
86 |
+
],
|
87 |
+
"node/prefer-promises/dns": "error",
|
88 |
+
"node/prefer-promises/fs": "error"
|
89 |
+
}
|
90 |
+
}
|
.gitattributes
CHANGED
@@ -1,35 +1,32 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
*.
|
6 |
-
*.
|
7 |
-
*.
|
8 |
-
*.
|
9 |
-
*.
|
10 |
-
*.
|
11 |
-
*.
|
12 |
-
*.
|
13 |
-
*.
|
14 |
-
*.
|
15 |
-
*.
|
16 |
-
*.
|
17 |
-
*.
|
18 |
-
*.
|
19 |
-
*.
|
20 |
-
*.
|
21 |
-
|
22 |
-
|
23 |
-
*.
|
24 |
-
|
25 |
-
*.
|
26 |
-
|
27 |
-
*.
|
28 |
-
*.
|
29 |
-
*.
|
30 |
-
*.
|
31 |
-
*.
|
32 |
-
*.
|
33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
1 |
+
# Set the default behavior, in case people don't have core.autocrlf set.
|
2 |
+
* text eol=lf
|
3 |
+
# Explicitly declare text files you want to always be normalized and converted
|
4 |
+
# to native line endings on checkout.
|
5 |
+
*.c text
|
6 |
+
*.h text
|
7 |
+
*.py text
|
8 |
+
*.js text
|
9 |
+
*.jsx text
|
10 |
+
*.ts text
|
11 |
+
*.tsx text
|
12 |
+
*.md text
|
13 |
+
*.mdx text
|
14 |
+
*.yml text
|
15 |
+
*.yaml text
|
16 |
+
*.xml text
|
17 |
+
*.csv text
|
18 |
+
*.json text
|
19 |
+
*.sh text
|
20 |
+
*.Dockerfile text
|
21 |
+
Dockerfile text
|
22 |
+
# Declare files that will always have CRLF line endings on checkout.
|
23 |
+
*.sln text eol=crlf
|
24 |
+
# Denote all files that are truly binary and should not be modified.
|
25 |
+
*.png filter=lfs diff=lfs merge=lfs -text
|
26 |
+
*.jpg filter=lfs diff=lfs merge=lfs -text
|
27 |
+
*.ico binary
|
28 |
+
*.gif binary
|
29 |
+
*.mp4 binary
|
30 |
+
*.svg binary
|
31 |
+
*.csv binary
|
32 |
+
*.gif filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
.github/ISSUE_TEMPLATE/bug-report.yaml
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: "🐛 Bug Report"
|
2 |
+
description: Submit a bug report to help us improve Langflow
|
3 |
+
labels: [ "bug" ]
|
4 |
+
body:
|
5 |
+
- type: markdown
|
6 |
+
attributes:
|
7 |
+
value: |
|
8 |
+
Thanks for taking the time to fill out this bug report!
|
9 |
+
|
10 |
+
- type: textarea
|
11 |
+
id: description
|
12 |
+
attributes:
|
13 |
+
label: Bug Description
|
14 |
+
description: A clear and concise description of what the bug is
|
15 |
+
placeholder: Tell us what you see!
|
16 |
+
validations:
|
17 |
+
required: true
|
18 |
+
|
19 |
+
- type: textarea
|
20 |
+
id: reproduction
|
21 |
+
validations:
|
22 |
+
required: true
|
23 |
+
attributes:
|
24 |
+
label: Reproduction
|
25 |
+
description: |
|
26 |
+
Please provide a code sample that reproduces the problem you ran into. It can be a Colab link or just a code snippet.
|
27 |
+
If you have code snippets, error messages, or stack traces please provide them here as well.
|
28 |
+
Important! Use code tags to format your code correctly. See https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting
|
29 |
+
Do not use screenshots, as they are hard to read, and (more importantly) don't allow others to copy-and-paste your code.
|
30 |
+
placeholder: |
|
31 |
+
Steps to reproduce the behavior:
|
32 |
+
|
33 |
+
1.
|
34 |
+
2.
|
35 |
+
3.
|
36 |
+
|
37 |
+
- type: textarea
|
38 |
+
id: expected-behavior
|
39 |
+
validations:
|
40 |
+
required: true
|
41 |
+
attributes:
|
42 |
+
label: Expected behavior
|
43 |
+
description: "A clear and concise description of what you would expect to happen."
|
44 |
+
|
45 |
+
- type: textarea
|
46 |
+
id: who-can-help
|
47 |
+
attributes:
|
48 |
+
label: Who can help?
|
49 |
+
description: |
|
50 |
+
Your issue will be replied to more quickly if you can figure out the right person to tag with @.
|
51 |
+
If you know the relevant code owner, please tag them. Otherwise, leave this blank and a core maintainer will direct the issue accordingly.
|
52 |
+
|
53 |
+
Please tag fewer than 3 people.
|
54 |
+
|
55 |
+
Specific Areas:
|
56 |
+
|
57 |
+
Frontend:
|
58 |
+
- @anovazzi1
|
59 |
+
- @Cristhianzl
|
60 |
+
- @lucaseduoli
|
61 |
+
- @igorrCarvalho
|
62 |
+
|
63 |
+
Backend:
|
64 |
+
- @italojohnny
|
65 |
+
|
66 |
+
Full Stack:
|
67 |
+
- @ogabrielluiz
|
68 |
+
- @nicoloboschi
|
69 |
+
- @zzzming
|
70 |
+
- @jordanrfrazier
|
71 |
+
- @mfortman11
|
72 |
+
- @NadirJ
|
73 |
+
|
74 |
+
placeholder: "@Username ..."
|
75 |
+
|
76 |
+
- type: markdown
|
77 |
+
attributes:
|
78 |
+
value: '## Environment'
|
79 |
+
|
80 |
+
- type: input
|
81 |
+
id: os
|
82 |
+
attributes:
|
83 |
+
label: Operating System
|
84 |
+
placeholder: ex. Ubuntu Linux 22.04
|
85 |
+
validations:
|
86 |
+
required: true
|
87 |
+
|
88 |
+
- type: input
|
89 |
+
id: langflow-version
|
90 |
+
attributes:
|
91 |
+
label: Langflow Version
|
92 |
+
placeholder: ex. 1.0.9
|
93 |
+
validations:
|
94 |
+
required: true
|
95 |
+
|
96 |
+
- type: dropdown
|
97 |
+
id: python-version
|
98 |
+
attributes:
|
99 |
+
label: "Python Version"
|
100 |
+
description: |
|
101 |
+
|
102 |
+
**Langflow requires Python version 3.10 or greater.**
|
103 |
+
options:
|
104 |
+
- "3.12"
|
105 |
+
- "3.11"
|
106 |
+
- "3.10"
|
107 |
+
|
108 |
+
- type: textarea
|
109 |
+
id: screenshot
|
110 |
+
attributes:
|
111 |
+
label: Screenshot
|
112 |
+
description: "If applicable, add screenshots to help explain your problem."
|
113 |
+
placeholder: "Paste your screenshot here."
|
114 |
+
|
115 |
+
- type: textarea
|
116 |
+
id: flow-file
|
117 |
+
attributes:
|
118 |
+
label: Flow File
|
119 |
+
description: "Add your flow if applicable to help replicate the problem."
|
120 |
+
placeholder: "Add your flow link here."
|
.github/ISSUE_TEMPLATE/feature-request.yaml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: "🚀 Feature Request"
|
2 |
+
description: Submit a proposal/request for a new Langflow feature
|
3 |
+
labels: [ "enhancement" ]
|
4 |
+
body:
|
5 |
+
- type: textarea
|
6 |
+
id: feature-request
|
7 |
+
validations:
|
8 |
+
required: true
|
9 |
+
attributes:
|
10 |
+
label: Feature Request
|
11 |
+
description: |
|
12 |
+
A clear and concise description of the feature proposal. Please provide any relevant links to papers, code, or other resources that support your proposal.
|
13 |
+
|
14 |
+
- type: textarea
|
15 |
+
id: motivation
|
16 |
+
validations:
|
17 |
+
required: true
|
18 |
+
attributes:
|
19 |
+
label: Motivation
|
20 |
+
description: |
|
21 |
+
Please outline the motivation for the proposal. Is your feature request related to a problem? e.g., I'm always frustrated when [...]. If this is related to another GitHub issue, please link it here as well.
|
22 |
+
|
23 |
+
- type: textarea
|
24 |
+
id: contribution
|
25 |
+
attributes:
|
26 |
+
label: Your Contribution
|
27 |
+
description: |
|
28 |
+
Is there any way that you could help, e.g., by submitting a PR? Make sure to read the CONTRIBUTING.md guidelines for Langflow before proceeding.
|
.github/ISSUE_TEMPLATE/work-in-progress.yaml
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Work in Progress
|
2 |
+
description: Use this template to describe the new feature or improvement you are currently working on.
|
3 |
+
labels: [enhancement]
|
4 |
+
|
5 |
+
body:
|
6 |
+
- type: markdown
|
7 |
+
attributes:
|
8 |
+
value: |
|
9 |
+
## Work in Progress
|
10 |
+
|
11 |
+
Thank you for contributing to our project! Please fill out the sections below to describe the new feature or improvement you are currently working on.
|
12 |
+
|
13 |
+
- type: input
|
14 |
+
id: title
|
15 |
+
attributes:
|
16 |
+
label: Title
|
17 |
+
description: Provide a concise title for your feature or improvement.
|
18 |
+
placeholder: "Short and descriptive title"
|
19 |
+
validations:
|
20 |
+
required: true
|
21 |
+
|
22 |
+
- type: dropdown
|
23 |
+
id: type
|
24 |
+
attributes:
|
25 |
+
label: Type
|
26 |
+
description: Is this a new feature or an improvement?
|
27 |
+
options:
|
28 |
+
- New Feature
|
29 |
+
- Improvement
|
30 |
+
validations:
|
31 |
+
required: true
|
32 |
+
|
33 |
+
- type: textarea
|
34 |
+
id: description
|
35 |
+
attributes:
|
36 |
+
label: Description
|
37 |
+
description: Provide a detailed description of the feature or improvement.
|
38 |
+
placeholder: "Explain the feature or improvement in detail"
|
39 |
+
validations:
|
40 |
+
required: true
|
41 |
+
|
42 |
+
- type: textarea
|
43 |
+
id: use-case
|
44 |
+
attributes:
|
45 |
+
label: Use Case
|
46 |
+
description: Describe the use case or user story that this feature or improvement addresses.
|
47 |
+
placeholder: "As a [user], I want to [do something] so that [benefit]."
|
48 |
+
validations:
|
49 |
+
required: false
|
50 |
+
|
51 |
+
- type: textarea
|
52 |
+
id: implementation
|
53 |
+
attributes:
|
54 |
+
label: Implementation Plan
|
55 |
+
description: Outline your plan for implementing this feature or improvement.
|
56 |
+
placeholder: "Describe how you plan to implement this feature or improvement."
|
57 |
+
validations:
|
58 |
+
required: false
|
.github/actions/install-playwright/action.yml
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Install Playwright
|
2 |
+
description: Install Playwright and dependencies with cache
|
3 |
+
|
4 |
+
# https://github.com/microsoft/playwright/issues/7249
|
5 |
+
|
6 |
+
inputs:
|
7 |
+
working-directory:
|
8 |
+
description: Where to install Playwright
|
9 |
+
default: ./
|
10 |
+
browsers:
|
11 |
+
description: Browsers to install
|
12 |
+
default: chromium webkit firefox
|
13 |
+
|
14 |
+
outputs:
|
15 |
+
version:
|
16 |
+
description: Installed version of Playwright
|
17 |
+
value: ${{ steps.version.outputs.version }}
|
18 |
+
cache-hit:
|
19 |
+
description: Whether cache for Playwright was found
|
20 |
+
value: ${{ steps.cache.outputs.cache-hit }}
|
21 |
+
|
22 |
+
runs:
|
23 |
+
using: composite
|
24 |
+
steps:
|
25 |
+
- name: Get Playwright version
|
26 |
+
uses: actions/github-script@v7
|
27 |
+
id: version
|
28 |
+
with:
|
29 |
+
script: |
|
30 |
+
const fs = require('fs');
|
31 |
+
const path = require('path');
|
32 |
+
|
33 |
+
// Get working directory
|
34 |
+
const workingDirectory = "${{ inputs.working-directory }}";
|
35 |
+
console.debug("Specified working directory:", workingDirectory);
|
36 |
+
if (workingDirectory) process.chdir(workingDirectory);
|
37 |
+
console.debug("Actual working directory:", process.cwd());
|
38 |
+
|
39 |
+
// Read package.json
|
40 |
+
let version = "";
|
41 |
+
try {
|
42 |
+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
43 |
+
version = (
|
44 |
+
packageJson.devDependencies?.['@playwright/test'] ||
|
45 |
+
packageJson.dependencies?.['@playwright/test'] ||
|
46 |
+
packageJson.dependencies?.['playwright'] ||
|
47 |
+
packageJson.devDependencies?.['playwright']
|
48 |
+
)?.replace(/[\^~]/g, '');
|
49 |
+
} catch (error) {
|
50 |
+
console.log(error.message);
|
51 |
+
}
|
52 |
+
|
53 |
+
console.debug("Version:", version);
|
54 |
+
if (version) {
|
55 |
+
core.exportVariable("PLAYWRIGHT_VERSION", version);
|
56 |
+
core.setOutput("version", version);
|
57 |
+
} else core.setFailed("Couldn't get Playwright version");
|
58 |
+
|
59 |
+
- name: Cache Playwright
|
60 |
+
id: cache
|
61 |
+
uses: actions/cache@v4
|
62 |
+
with:
|
63 |
+
path: ~/.cache/ms-playwright
|
64 |
+
key: playwright-${{ env.PLAYWRIGHT_VERSION }}
|
65 |
+
|
66 |
+
- name: Install Playwright and its dependencies
|
67 |
+
shell: bash
|
68 |
+
if: steps.cache.outputs.cache-hit != 'true'
|
69 |
+
working-directory: ${{ inputs.working-directory }}
|
70 |
+
run: npx playwright install ${{ inputs.browsers }} --with-deps
|
71 |
+
|
72 |
+
- name: Install just Playwright's dependencies
|
73 |
+
shell: bash
|
74 |
+
if: steps.cache.outputs.cache-hit == 'true'
|
75 |
+
working-directory: ${{ inputs.working-directory }}
|
76 |
+
run: npx playwright install-deps
|
.github/actions/poetry_caching/action.yml
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# An action for setting up poetry install with caching.
|
2 |
+
# Using a custom action since the default action does not
|
3 |
+
# take poetry install groups into account.
|
4 |
+
# Action code from:
|
5 |
+
# https://github.com/actions/setup-python/issues/505#issuecomment-1273013236
|
6 |
+
# Copy of https://github.com/langchain-ai/langchain/blob/2f8dd1a1619f25daa4737df4d378b1acd6ff83c4/.github/actions/poetry_setup/action.yml
|
7 |
+
name: poetry-install-with-caching
|
8 |
+
description: Poetry install with support for caching of dependency groups.
|
9 |
+
|
10 |
+
inputs:
|
11 |
+
python-version:
|
12 |
+
description: Python version, supporting MAJOR.MINOR only
|
13 |
+
required: true
|
14 |
+
|
15 |
+
poetry-version:
|
16 |
+
description: Poetry version
|
17 |
+
required: true
|
18 |
+
|
19 |
+
cache-key:
|
20 |
+
description: Cache key to use for manual handling of caching
|
21 |
+
required: true
|
22 |
+
|
23 |
+
working-directory:
|
24 |
+
description: Directory whose poetry.lock file should be cached
|
25 |
+
required: true
|
26 |
+
|
27 |
+
runs:
|
28 |
+
using: composite
|
29 |
+
steps:
|
30 |
+
- uses: actions/setup-python@v5
|
31 |
+
name: Setup python ${{ inputs.python-version }}
|
32 |
+
id: setup-python
|
33 |
+
with:
|
34 |
+
python-version: ${{ inputs.python-version }}
|
35 |
+
|
36 |
+
- uses: actions/cache@v4
|
37 |
+
id: cache-bin-poetry
|
38 |
+
name: Cache Poetry binary - Python ${{ inputs.python-version }}
|
39 |
+
env:
|
40 |
+
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "1"
|
41 |
+
with:
|
42 |
+
path: |
|
43 |
+
/opt/pipx/venvs/poetry
|
44 |
+
# This step caches the poetry installation, so make sure it's keyed on the poetry version as well.
|
45 |
+
key: bin-poetry-${{ runner.os }}-${{ runner.arch }}-py-${{ inputs.python-version }}-${{ inputs.poetry-version }}
|
46 |
+
|
47 |
+
- name: Refresh shell hashtable and fixup softlinks
|
48 |
+
if: steps.cache-bin-poetry.outputs.cache-hit == 'true'
|
49 |
+
shell: bash
|
50 |
+
env:
|
51 |
+
POETRY_VERSION: ${{ inputs.poetry-version }}
|
52 |
+
PYTHON_VERSION: ${{ inputs.python-version }}
|
53 |
+
run: |
|
54 |
+
set -eux
|
55 |
+
|
56 |
+
# Refresh the shell hashtable, to ensure correct `which` output.
|
57 |
+
hash -r
|
58 |
+
|
59 |
+
# `actions/cache@v3` doesn't always seem able to correctly unpack softlinks.
|
60 |
+
# Delete and recreate the softlinks pipx expects to have.
|
61 |
+
rm /opt/pipx/venvs/poetry/bin/python
|
62 |
+
cd /opt/pipx/venvs/poetry/bin
|
63 |
+
ln -s "$(which "python$PYTHON_VERSION")" python
|
64 |
+
chmod +x python
|
65 |
+
cd /opt/pipx_bin/
|
66 |
+
ln -s /opt/pipx/venvs/poetry/bin/poetry poetry
|
67 |
+
chmod +x poetry
|
68 |
+
|
69 |
+
# Ensure everything got set up correctly.
|
70 |
+
/opt/pipx/venvs/poetry/bin/python --version
|
71 |
+
/opt/pipx_bin/poetry --version
|
72 |
+
|
73 |
+
- name: Install poetry
|
74 |
+
if: steps.cache-bin-poetry.outputs.cache-hit != 'true'
|
75 |
+
shell: bash
|
76 |
+
env:
|
77 |
+
POETRY_VERSION: ${{ inputs.poetry-version || env.POETRY_VERSION }}
|
78 |
+
PYTHON_VERSION: ${{ inputs.python-version }}
|
79 |
+
# Install poetry using the python version installed by setup-python step.
|
80 |
+
run: |
|
81 |
+
pipx install "poetry==$POETRY_VERSION" --python '${{ steps.setup-python.outputs.python-path }}' --verbose
|
82 |
+
pipx ensurepath
|
83 |
+
# Ensure the poetry binary is available in the PATH.
|
84 |
+
# Test that the poetry binary is available.
|
85 |
+
poetry --version
|
86 |
+
|
87 |
+
- name: Restore pip and poetry cached dependencies
|
88 |
+
uses: actions/cache@v4
|
89 |
+
env:
|
90 |
+
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "4"
|
91 |
+
WORKDIR: ${{ inputs.working-directory == '' && '.' || inputs.working-directory }}
|
92 |
+
with:
|
93 |
+
path: |
|
94 |
+
~/.cache/pip
|
95 |
+
~/.cache/pypoetry/virtualenvs
|
96 |
+
~/.cache/pypoetry/cache
|
97 |
+
~/.cache/pypoetry/artifacts
|
98 |
+
${{ env.WORKDIR }}/.venv
|
99 |
+
key: py-deps-${{ runner.os }}-${{ runner.arch }}-py-${{ inputs.python-version }}-poetry-${{ inputs.poetry-version }}-${{ inputs.cache-key }}-${{ hashFiles(format('{0}/**/poetry.lock', env.WORKDIR)) }}
|
.github/actions/setup-uv/action.yml
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: "Setup uv"
|
2 |
+
description: "Checks out code, installs uv, and sets up Python environment"
|
3 |
+
|
4 |
+
runs:
|
5 |
+
using: "composite"
|
6 |
+
steps:
|
7 |
+
- name: Install uv
|
8 |
+
uses: astral-sh/setup-uv@v3
|
9 |
+
with:
|
10 |
+
enable-cache: true
|
11 |
+
cache-dependency-glob: "uv.lock"
|
12 |
+
|
13 |
+
- name: "Set up Python"
|
14 |
+
uses: actions/setup-python@v5
|
15 |
+
with:
|
16 |
+
python-version-file: "pyproject.toml"
|
17 |
+
|
18 |
+
- name: Restore uv cache
|
19 |
+
uses: actions/cache@v4
|
20 |
+
with:
|
21 |
+
path: /tmp/.uv-cache
|
22 |
+
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
23 |
+
restore-keys: |
|
24 |
+
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
25 |
+
uv-${{ runner.os }}
|
.github/changes-filter.yaml
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# https://github.com/dorny/paths-filter
|
2 |
+
python:
|
3 |
+
- "src/backend/**"
|
4 |
+
- "src/backend/**.py"
|
5 |
+
- "pyproject.toml"
|
6 |
+
- "poetry.lock"
|
7 |
+
- "**/python_test.yml"
|
8 |
+
components-changes:
|
9 |
+
- "src/backend/base/langflow/components/**"
|
10 |
+
starter-projects-changes:
|
11 |
+
- "src/backend/base/langflow/initial_setup/**"
|
12 |
+
frontend-tests:
|
13 |
+
- "src/frontend/tests/**"
|
14 |
+
frontend:
|
15 |
+
- "src/frontend/**"
|
16 |
+
- "**/typescript_test.yml"
|
17 |
+
docs:
|
18 |
+
- "docs/**"
|
19 |
+
|
20 |
+
# Test categories and their associated paths
|
21 |
+
starter-projects:
|
22 |
+
- "src/backend/base/langflow/initial_setup/**"
|
23 |
+
- "src/backend/base/langflow/components/**"
|
24 |
+
- "src/frontend/src/pages/MainPage/**"
|
25 |
+
- "src/frontend/src/utils/reactflowUtils.ts"
|
26 |
+
- "src/frontend/tests/extended/features/**"
|
27 |
+
|
28 |
+
components:
|
29 |
+
- "src/frontend/src/components/**"
|
30 |
+
- "src/frontend/src/modals/**"
|
31 |
+
- "src/frontend/src/pages/FlowPage/**"
|
32 |
+
- "src/frontend/src/shared/**"
|
33 |
+
- "src/frontend/src/hooks/**"
|
34 |
+
- "src/frontend/src/CustomNodes/**"
|
35 |
+
- "src/frontend/src/style/**"
|
36 |
+
- "src/frontend/src/utils/styleUtils.ts"
|
37 |
+
- "src/backend/base/langflow/components/**"
|
38 |
+
- "src/frontend/tests/core/features/**"
|
39 |
+
- "src/frontend/tests/core/integrations/**"
|
40 |
+
- "src/frontend/tests/core/regression/**"
|
41 |
+
- "src/frontend/tests/extended/integrations/**"
|
42 |
+
- "src/frontend/tests/extended/features/**"
|
43 |
+
- "src/frontend/tests/extended/regression/**"
|
44 |
+
|
45 |
+
workspace:
|
46 |
+
- "src/backend/base/langflow/inputs/**"
|
47 |
+
- "src/frontend/src/components/core/parameterRenderComponent/**"
|
48 |
+
- "src/frontend/src/CustomNodes/**"
|
49 |
+
- "src/frontend/src/modals/**"
|
50 |
+
- "src/frontend/src/style/**"
|
51 |
+
- "src/frontend/src/CustomEdges/**"
|
52 |
+
- "src/frontend/src/utils/reactflowUtils.ts"
|
53 |
+
- "src/frontend/src/utils/buildUtils.ts"
|
54 |
+
- "src/frontend/tests/core/features/**"
|
55 |
+
- "src/frontend/tests/core/unit/**"
|
56 |
+
- "src/frontend/tests/extended/features/**"
|
57 |
+
- "src/frontend/tests/core/regression/**"
|
58 |
+
|
59 |
+
api:
|
60 |
+
- "src/backend/base/langflow/api/**"
|
61 |
+
- "src/frontend/src/controllers/**"
|
62 |
+
- "src/frontend/tests/core/features/**"
|
63 |
+
- "src/frontend/tests/extended/features/**"
|
64 |
+
- "src/frontend/tests/extended/regression/**"
|
65 |
+
|
66 |
+
database:
|
67 |
+
- "src/backend/base/langflow/services/database/**"
|
68 |
+
- "src/backend/base/langflow/alembic/**"
|
69 |
+
- "src/frontend/src/controllers/**"
|
70 |
+
- "src/frontend/tests/core/features/**"
|
71 |
+
- "src/frontend/tests/extended/features/**"
|
.github/dependabot.yml
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Set update schedule for GitHub Actions
|
2 |
+
|
3 |
+
version: 2
|
4 |
+
updates:
|
5 |
+
- package-ecosystem: "github-actions"
|
6 |
+
directory: "/"
|
7 |
+
schedule:
|
8 |
+
interval: "monthly"
|
9 |
+
commit-message:
|
10 |
+
prefix: "build(deps):"
|
11 |
+
include: scope
|
.github/release.yml
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
changelog:
|
2 |
+
categories:
|
3 |
+
- title: 🚨 Breaking Changes
|
4 |
+
description: Changes that break existing functionality
|
5 |
+
labels:
|
6 |
+
- breaking
|
7 |
+
- title: ✨ New Features
|
8 |
+
description: New features and enhancements
|
9 |
+
labels:
|
10 |
+
- enhancement
|
11 |
+
- title: 🐛 Bug Fixes
|
12 |
+
description: Bug fixes and patches
|
13 |
+
labels:
|
14 |
+
- fix
|
15 |
+
- bug
|
16 |
+
- title: 📝 Documentation Updates
|
17 |
+
description: Changes to documentation
|
18 |
+
labels:
|
19 |
+
- documentation
|
20 |
+
- title: 🛠 Maintenance Tasks
|
21 |
+
description: Maintenance tasks and housekeeping
|
22 |
+
labels:
|
23 |
+
- chore
|
24 |
+
- refactor
|
25 |
+
- style
|
26 |
+
- performance
|
27 |
+
- build
|
28 |
+
- title: ✅ Tests
|
29 |
+
description: Changes to tests
|
30 |
+
labels:
|
31 |
+
- test
|
32 |
+
- title: Others
|
33 |
+
description: Other changes
|
34 |
+
labels:
|
35 |
+
- "*"
|
.github/semantic.yml
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
titleOnly: true
|
2 |
+
targetUrl: https://www.conventionalcommits.org/en/v1.0.0/#summary
|
.github/workflows/auto-update.yml
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Auto-update
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
branches:
|
6 |
+
- main
|
7 |
+
|
8 |
+
jobs:
|
9 |
+
Auto:
|
10 |
+
name: Auto-update
|
11 |
+
runs-on: ubuntu-latest
|
12 |
+
steps:
|
13 |
+
- uses: tibdex/auto-update@v2
|
.github/workflows/ci.yml
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: CI
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_call:
|
5 |
+
inputs:
|
6 |
+
python-versions:
|
7 |
+
description: "Python Versions"
|
8 |
+
required: false
|
9 |
+
type: string
|
10 |
+
default: "['3.10']"
|
11 |
+
frontend-tests-folder:
|
12 |
+
description: "Frontend Tests Folder"
|
13 |
+
required: false
|
14 |
+
type: string
|
15 |
+
default: "tests/core"
|
16 |
+
release:
|
17 |
+
description: "Release"
|
18 |
+
required: false
|
19 |
+
type: boolean
|
20 |
+
default: false
|
21 |
+
workflow_dispatch:
|
22 |
+
inputs:
|
23 |
+
branch:
|
24 |
+
description: "(Optional) Branch to checkout"
|
25 |
+
required: false
|
26 |
+
type: string
|
27 |
+
openai_api_key:
|
28 |
+
description: "OpenAI API Key"
|
29 |
+
required: false
|
30 |
+
type: string
|
31 |
+
store_api_key:
|
32 |
+
description: "Store API Key"
|
33 |
+
required: false
|
34 |
+
type: string
|
35 |
+
python-versions:
|
36 |
+
description: "Python Versions"
|
37 |
+
required: false
|
38 |
+
type: string
|
39 |
+
default: "['3.10']"
|
40 |
+
pull_request:
|
41 |
+
types: [synchronize, labeled]
|
42 |
+
|
43 |
+
concurrency:
|
44 |
+
group: ${{ github.workflow }}-${{ github.ref }}
|
45 |
+
cancel-in-progress: true
|
46 |
+
|
47 |
+
jobs:
|
48 |
+
set-ci-condition:
|
49 |
+
name: Should Run CI
|
50 |
+
runs-on: ubuntu-latest
|
51 |
+
outputs:
|
52 |
+
should-run-ci: ${{ (contains( github.event.pull_request.labels.*.name, 'lgtm') && github.event.pull_request.draft == false) || (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') }}
|
53 |
+
steps:
|
54 |
+
# Do anything just to make the job run
|
55 |
+
- run: echo "Debug CI Condition"
|
56 |
+
- run: echo "Labels -> ${{ join(github.event.pull_request.labels.*.name, ',') }}"
|
57 |
+
- run: echo "IsDraft -> ${{ github.event.pull_request.draft }}"
|
58 |
+
- run: echo "Event name -> ${{ github.event_name }}"
|
59 |
+
path-filter:
|
60 |
+
needs: set-ci-condition
|
61 |
+
if: ${{ needs.set-ci-condition.outputs.should-run-ci == 'true' }}
|
62 |
+
name: Filter Paths
|
63 |
+
runs-on: ubuntu-latest
|
64 |
+
outputs:
|
65 |
+
python: ${{ steps.filter.outputs.python }}
|
66 |
+
frontend: ${{ steps.filter.outputs.frontend }}
|
67 |
+
docs: ${{ steps.filter.outputs.docs }}
|
68 |
+
frontend-tests: ${{ steps.filter.outputs.frontend-tests }}
|
69 |
+
components-changes: ${{ steps.filter.outputs.components-changes }}
|
70 |
+
starter-projects-changes: ${{ steps.filter.outputs.starter-projects-changes }}
|
71 |
+
steps:
|
72 |
+
- name: Checkout code
|
73 |
+
uses: actions/checkout@v4
|
74 |
+
with:
|
75 |
+
ref: ${{ inputs.branch || github.ref }}
|
76 |
+
- name: Filter Paths
|
77 |
+
id: filter
|
78 |
+
uses: dorny/paths-filter@v3
|
79 |
+
with:
|
80 |
+
filters: ./.github/changes-filter.yaml
|
81 |
+
|
82 |
+
test-backend:
|
83 |
+
needs: path-filter
|
84 |
+
name: Run Backend Tests
|
85 |
+
if: ${{ needs.path-filter.outputs.python == 'true'}}
|
86 |
+
uses: ./.github/workflows/python_test.yml
|
87 |
+
with:
|
88 |
+
python-versions: ${{ inputs.python-versions || '["3.10"]' }}
|
89 |
+
|
90 |
+
test-frontend:
|
91 |
+
needs: path-filter
|
92 |
+
name: Run Frontend Tests
|
93 |
+
if: ${{ needs.path-filter.outputs.frontend == 'true' || needs.path-filter.outputs.frontend-tests == 'true' || needs.path-filter.outputs.components-changes == 'true' || needs.path-filter.outputs.starter-projects-changes == 'true' }}
|
94 |
+
uses: ./.github/workflows/typescript_test.yml
|
95 |
+
with:
|
96 |
+
tests_folder: ${{ inputs.frontend-tests-folder }}
|
97 |
+
release: ${{ inputs.release || false }}
|
98 |
+
secrets:
|
99 |
+
OPENAI_API_KEY: "${{ secrets.OPENAI_API_KEY }}"
|
100 |
+
STORE_API_KEY: "${{ secrets.STORE_API_KEY }}"
|
101 |
+
ANTHROPIC_API_KEY: "${{ secrets.ANTHROPIC_API_KEY }}"
|
102 |
+
TAVILY_API_KEY: "${{ secrets.TAVILY_API_KEY }}"
|
103 |
+
|
104 |
+
lint-backend:
|
105 |
+
needs: path-filter
|
106 |
+
if: ${{ needs.path-filter.outputs.python == 'true'}}
|
107 |
+
name: Lint Backend
|
108 |
+
uses: ./.github/workflows/lint-py.yml
|
109 |
+
|
110 |
+
test-docs-build:
|
111 |
+
needs: path-filter
|
112 |
+
if: ${{ needs.path-filter.outputs.docs == 'true' }}
|
113 |
+
name: Test Docs Build
|
114 |
+
uses: ./.github/workflows/docs_test.yml
|
115 |
+
|
116 |
+
# https://github.com/langchain-ai/langchain/blob/master/.github/workflows/check_diffs.yml
|
117 |
+
ci_success:
|
118 |
+
name: "CI Success"
|
119 |
+
needs:
|
120 |
+
[
|
121 |
+
test-backend,
|
122 |
+
test-frontend,
|
123 |
+
lint-backend,
|
124 |
+
test-docs-build,
|
125 |
+
set-ci-condition,
|
126 |
+
]
|
127 |
+
|
128 |
+
if: always()
|
129 |
+
runs-on: ubuntu-latest
|
130 |
+
env:
|
131 |
+
JOBS_JSON: ${{ toJSON(needs) }}
|
132 |
+
RESULTS_JSON: ${{ toJSON(needs.*.result) }}
|
133 |
+
EXIT_CODE: ${{!contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && needs.set-ci-condition.outputs.should-run-ci == 'true' && '0' || '1'}}
|
134 |
+
steps:
|
135 |
+
- name: "CI Success"
|
136 |
+
run: |
|
137 |
+
echo $JOBS_JSON
|
138 |
+
echo $RESULTS_JSON
|
139 |
+
echo "Exiting with $EXIT_CODE"
|
140 |
+
exit $EXIT_CODE
|
.github/workflows/codeql.yml
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: "CodeQL"
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
branches: [ 'dev', 'main' ]
|
6 |
+
pull_request:
|
7 |
+
# The branches below must be a subset of the branches above
|
8 |
+
branches: [ 'dev' ]
|
9 |
+
schedule:
|
10 |
+
- cron: '17 2 * * 1'
|
11 |
+
|
12 |
+
jobs:
|
13 |
+
analyze:
|
14 |
+
name: Analyze
|
15 |
+
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
16 |
+
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
17 |
+
permissions:
|
18 |
+
actions: read
|
19 |
+
contents: read
|
20 |
+
security-events: write
|
21 |
+
|
22 |
+
strategy:
|
23 |
+
fail-fast: false
|
24 |
+
matrix:
|
25 |
+
language: [ 'python', 'javascript' ]
|
26 |
+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
27 |
+
# Use only 'java' to analyze code written in Java, Kotlin or both
|
28 |
+
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
29 |
+
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
30 |
+
|
31 |
+
steps:
|
32 |
+
- name: Checkout repository
|
33 |
+
uses: actions/checkout@v4
|
34 |
+
|
35 |
+
# Initializes the CodeQL tools for scanning.
|
36 |
+
- name: Initialize CodeQL
|
37 |
+
uses: github/codeql-action/init@v3
|
38 |
+
with:
|
39 |
+
languages: ${{ matrix.language }}
|
40 |
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
41 |
+
# By default, queries listed here will override any specified in a config file.
|
42 |
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
43 |
+
|
44 |
+
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
45 |
+
# queries: security-extended,security-and-quality
|
46 |
+
|
47 |
+
|
48 |
+
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
49 |
+
# If this step fails, then you should remove it and run the build manually (see below)
|
50 |
+
- name: Autobuild
|
51 |
+
uses: github/codeql-action/autobuild@v3
|
52 |
+
|
53 |
+
# ℹ️ Command-line programs to run using the OS shell.
|
54 |
+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
55 |
+
|
56 |
+
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
57 |
+
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
58 |
+
|
59 |
+
# - run: |
|
60 |
+
# echo "Run, Build Application using script"
|
61 |
+
# ./location_of_script_within_repo/buildscript.sh
|
62 |
+
|
63 |
+
- name: Perform CodeQL Analysis
|
64 |
+
uses: github/codeql-action/analyze@v3
|
65 |
+
with:
|
66 |
+
category: "/language:${{matrix.language}}"
|
.github/workflows/codspeed.yml
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Run benchmarks
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
paths:
|
6 |
+
- "src/backend/base/**"
|
7 |
+
- "src/backend/tests/performance/**"
|
8 |
+
branches:
|
9 |
+
- "main" # or "master"
|
10 |
+
pull_request:
|
11 |
+
paths:
|
12 |
+
- "src/backend/base/**"
|
13 |
+
- "src/backend/tests/performance/**"
|
14 |
+
- "!src/backend/base/langflow/components/**"
|
15 |
+
workflow_dispatch:
|
16 |
+
|
17 |
+
concurrency:
|
18 |
+
group: ${{ github.workflow }}-${{ github.ref }}
|
19 |
+
cancel-in-progress: true
|
20 |
+
|
21 |
+
jobs:
|
22 |
+
codspeed:
|
23 |
+
name: Run benchmarks
|
24 |
+
runs-on: ubuntu-latest
|
25 |
+
strategy:
|
26 |
+
matrix:
|
27 |
+
python-version:
|
28 |
+
- "3.12"
|
29 |
+
steps:
|
30 |
+
- name: Check out the code at a specific ref
|
31 |
+
uses: actions/checkout@v4
|
32 |
+
- name: "Setup Environment"
|
33 |
+
uses: ./.github/actions/setup-uv
|
34 |
+
- name: Run benchmarks
|
35 |
+
uses: CodSpeedHQ/action@v3
|
36 |
+
with:
|
37 |
+
token: ${{ secrets.CODSPEED_TOKEN }}
|
38 |
+
run: |
|
39 |
+
uv run pytest src/backend/tests \
|
40 |
+
--ignore=src/backend/tests/integration \
|
41 |
+
--codspeed \
|
42 |
+
-m "not api_key_required" \
|
43 |
+
-n auto
|
44 |
+
- name: Minimize uv cache
|
45 |
+
run: uv cache prune --ci
|
.github/workflows/conventional-labels.yml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Warning, do not check out untrusted code with
|
2 |
+
# the pull_request_target event.
|
3 |
+
name: Label PRs with Conventional Commits
|
4 |
+
on:
|
5 |
+
pull_request_target:
|
6 |
+
types: [opened, edited]
|
7 |
+
|
8 |
+
jobs:
|
9 |
+
validate-pr:
|
10 |
+
name: Validate PR
|
11 |
+
runs-on: ubuntu-latest
|
12 |
+
steps:
|
13 |
+
- name: Validate the pull request
|
14 |
+
id: validate
|
15 |
+
uses: Namchee/conventional-pr@v0.15.5
|
16 |
+
with:
|
17 |
+
access_token: ${{ secrets.GITHUB_TOKEN }}
|
18 |
+
issue: false
|
19 |
+
|
20 |
+
label:
|
21 |
+
needs: validate-pr
|
22 |
+
name: Label PR
|
23 |
+
runs-on: ubuntu-latest
|
24 |
+
if: ${{ github.event.pull_request.user.type != 'Bot'}}
|
25 |
+
steps:
|
26 |
+
- uses: bcoe/conventional-release-labels@v1
|
27 |
+
with:
|
28 |
+
type_labels: '{"feat": "enhancement","fix": "bug","docs": "documentation","style": "style","refactor": "refactor","perf": "performance","test": "test","chore": "chore","build": "build"}'
|
.github/workflows/create-release.yml
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Create Release
|
2 |
+
on:
|
3 |
+
workflow_dispatch:
|
4 |
+
inputs:
|
5 |
+
version:
|
6 |
+
description: "Version to release"
|
7 |
+
required: true
|
8 |
+
type: string
|
9 |
+
ref:
|
10 |
+
description: "Commit to tag the release"
|
11 |
+
required: true
|
12 |
+
type: string
|
13 |
+
pre_release:
|
14 |
+
description: "Pre-release tag"
|
15 |
+
required: true
|
16 |
+
type: boolean
|
17 |
+
|
18 |
+
jobs:
|
19 |
+
create_release:
|
20 |
+
name: Create Release Job
|
21 |
+
runs-on: ubuntu-latest
|
22 |
+
steps:
|
23 |
+
- uses: actions/download-artifact@v4
|
24 |
+
with:
|
25 |
+
name: dist-main
|
26 |
+
path: dist
|
27 |
+
- name: Create Release Notes
|
28 |
+
uses: ncipollo/release-action@v1
|
29 |
+
with:
|
30 |
+
artifacts: "dist/*"
|
31 |
+
token: ${{ secrets.GITHUB_TOKEN }}
|
32 |
+
draft: false
|
33 |
+
generateReleaseNotes: true
|
34 |
+
prerelease: ${{ inputs.pre_release }}
|
35 |
+
tag: v${{ inputs.version }}
|
36 |
+
commit: ${{ inputs.ref }}
|
.github/workflows/deploy_gh-pages.yml
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Deploy to GitHub Pages
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
branches:
|
6 |
+
- main
|
7 |
+
paths:
|
8 |
+
- 'docs/**'
|
9 |
+
# Review gh actions docs if you want to further define triggers, paths, etc
|
10 |
+
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
|
11 |
+
|
12 |
+
jobs:
|
13 |
+
deploy:
|
14 |
+
name: Deploy to GitHub Pages
|
15 |
+
runs-on: ubuntu-latest
|
16 |
+
steps:
|
17 |
+
- uses: actions/checkout@v4
|
18 |
+
- uses: actions/setup-node@v4
|
19 |
+
with:
|
20 |
+
node-version: 18
|
21 |
+
cache: npm
|
22 |
+
cache-dependency-path: ./docs/package-lock.json
|
23 |
+
|
24 |
+
- name: Install dependencies
|
25 |
+
run: cd docs && npm install --legacy-peer-deps
|
26 |
+
- name: Build website
|
27 |
+
run: cd docs && npm run build
|
28 |
+
|
29 |
+
# Popular action to deploy to GitHub Pages:
|
30 |
+
# Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
|
31 |
+
- name: Deploy to GitHub Pages
|
32 |
+
uses: peaceiris/actions-gh-pages@v4
|
33 |
+
with:
|
34 |
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
35 |
+
# Build output to publish to the `gh-pages` branch:
|
36 |
+
publish_dir: ./docs/build
|
37 |
+
# The following lines assign commit authorship to the official
|
38 |
+
# GH-Actions bot for deploys to `gh-pages` branch:
|
39 |
+
# https://github.com/actions/checkout/issues/13#issuecomment-724415212
|
40 |
+
# The GH actions bot is used by default if you didn't specify the two fields.
|
41 |
+
# You can swap them out with your own user credentials.
|
.github/workflows/docker-build.yml
ADDED
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Docker Build and Push
|
2 |
+
run-name: Docker Build and Push @${{ inputs.release_type }} by @${{ github.actor }}
|
3 |
+
on:
|
4 |
+
workflow_call:
|
5 |
+
inputs:
|
6 |
+
main_version:
|
7 |
+
required: true
|
8 |
+
type: string
|
9 |
+
description: "Main version to tag images with. Required for both main and base releases."
|
10 |
+
base_version:
|
11 |
+
required: false
|
12 |
+
type: string
|
13 |
+
description: "Base version to tag images with. Required for base release type."
|
14 |
+
release_type:
|
15 |
+
required: true
|
16 |
+
type: string
|
17 |
+
description: "Release type. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base'."
|
18 |
+
pre_release:
|
19 |
+
required: false
|
20 |
+
type: boolean
|
21 |
+
default: false
|
22 |
+
ref:
|
23 |
+
required: false
|
24 |
+
type: string
|
25 |
+
description: "Ref to check out. If not specified, will default to the main version or current branch."
|
26 |
+
|
27 |
+
workflow_dispatch:
|
28 |
+
inputs:
|
29 |
+
main_version:
|
30 |
+
description: "Main version to tag images with. Required for both main and base releases."
|
31 |
+
required: false
|
32 |
+
type: string
|
33 |
+
base_version:
|
34 |
+
description: "Base version to tag images with. Required for base release type."
|
35 |
+
required: false
|
36 |
+
type: string
|
37 |
+
release_type:
|
38 |
+
description: "Type of release. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base'."
|
39 |
+
required: true
|
40 |
+
type: string
|
41 |
+
pre_release:
|
42 |
+
required: false
|
43 |
+
type: boolean
|
44 |
+
default: false
|
45 |
+
ref:
|
46 |
+
required: false
|
47 |
+
type: string
|
48 |
+
description: "Ref to check out. If not specified, will default to the main version or current branch."
|
49 |
+
|
50 |
+
|
51 |
+
env:
|
52 |
+
POETRY_VERSION: "1.8.2"
|
53 |
+
TEST_TAG: "langflowai/langflow:test"
|
54 |
+
|
55 |
+
jobs:
|
56 |
+
get-version:
|
57 |
+
name: Get Version
|
58 |
+
runs-on: ubuntu-latest
|
59 |
+
outputs:
|
60 |
+
version: ${{ steps.get-version-input.outputs.version || steps.get-version-base.outputs.version || steps.get-version-main.outputs.version }}
|
61 |
+
steps:
|
62 |
+
- name: Verify a main version exists
|
63 |
+
if: ${{ inputs.main_version == '' }}
|
64 |
+
run: |
|
65 |
+
# due to our how we split packages, we need to have a main version to check out.
|
66 |
+
echo "Must specify a main version to check out."
|
67 |
+
exit 1
|
68 |
+
|
69 |
+
- name: Check out the code at a specific ref
|
70 |
+
uses: actions/checkout@v4
|
71 |
+
with:
|
72 |
+
ref: ${{ inputs.ref || inputs.main_version || github.ref }}
|
73 |
+
persist-credentials: true
|
74 |
+
|
75 |
+
- name: Get Version to Tag
|
76 |
+
if: ${{ inputs.main_version != '' }}
|
77 |
+
id: get-version-input
|
78 |
+
run: |
|
79 |
+
# Produces the versions we will use to tag the docker images with.
|
80 |
+
|
81 |
+
if [[ "${{ inputs.release_type }}" == "base" && "${{ inputs.base_version }}" == '' ]]; then
|
82 |
+
echo "Must specify a base version for base release type."
|
83 |
+
exit 1
|
84 |
+
fi
|
85 |
+
|
86 |
+
if [[ "${{ inputs.release_type }}" == "nightly-base" && "${{ inputs.base_version }}" == '' ]]; then
|
87 |
+
echo "Must specify a base version for nightly-base release type."
|
88 |
+
exit 1
|
89 |
+
fi
|
90 |
+
|
91 |
+
if [[ "${{ inputs.release_type }}" == "main" && "${{ inputs.main_version }}" == '' ]]; then
|
92 |
+
echo "Must specify a main version for main release type."
|
93 |
+
exit 1
|
94 |
+
fi
|
95 |
+
|
96 |
+
if [[ "${{ inputs.release_type }}" == "main-ep" && "${{ inputs.main_version }}" == '' ]]; then
|
97 |
+
echo "Must specify a main version for main-ep release type."
|
98 |
+
exit 1
|
99 |
+
fi
|
100 |
+
|
101 |
+
if [[ "${{ inputs.release_type }}" == "nightly-main" && "${{ inputs.main_version }}" == '' ]]; then
|
102 |
+
echo "Must specify a main version for nightly-main release type."
|
103 |
+
exit 1
|
104 |
+
fi
|
105 |
+
|
106 |
+
if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
|
107 |
+
version=${{ inputs.base_version }}
|
108 |
+
echo "base version=${{ inputs.base_version }}"
|
109 |
+
echo version=$version
|
110 |
+
echo version=$version >> $GITHUB_OUTPUT
|
111 |
+
elif [[ "${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "main-ep" || "${{ inputs.release_type }}" == "nightly-main" ]]; then
|
112 |
+
version=${{ inputs.main_version }}
|
113 |
+
echo version=$version
|
114 |
+
echo version=$version >> $GITHUB_OUTPUT
|
115 |
+
else
|
116 |
+
echo "No version or ref specified. Exiting the workflow."
|
117 |
+
exit 1
|
118 |
+
fi
|
119 |
+
- name: Get Version Base
|
120 |
+
if: ${{ inputs.base_version == '' && (inputs.release_type == 'base' || inputs.release_type == 'nightly-base') }}
|
121 |
+
id: get-version-base
|
122 |
+
run: |
|
123 |
+
version=$(uv tree | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//')
|
124 |
+
if [ -z "$version" ]; then
|
125 |
+
echo "Failed to extract version from uv tree output"
|
126 |
+
exit 1
|
127 |
+
fi
|
128 |
+
echo version=$version
|
129 |
+
echo version=$version >> $GITHUB_OUTPUT
|
130 |
+
- name: Get Version Main
|
131 |
+
if: ${{ inputs.main_version == '' && (inputs.release_type == 'main' || inputs.release_type == 'main-ep' || inputs.release_type == 'nightly-main') }}
|
132 |
+
id: get-version-main
|
133 |
+
run: |
|
134 |
+
version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}' | sed 's/^v//')
|
135 |
+
echo version=$version
|
136 |
+
echo version=$version >> $GITHUB_OUTPUT
|
137 |
+
setup:
|
138 |
+
runs-on: ubuntu-latest
|
139 |
+
needs: get-version
|
140 |
+
outputs:
|
141 |
+
docker_tags: ${{ steps.set-vars.outputs.docker_tags }}
|
142 |
+
ghcr_tags: ${{ steps.set-vars.outputs.ghcr_tags }}
|
143 |
+
file: ${{ steps.set-vars.outputs.file }}
|
144 |
+
steps:
|
145 |
+
- name: Set Dockerfile and Tags
|
146 |
+
id: set-vars
|
147 |
+
run: |
|
148 |
+
nightly_suffix=''
|
149 |
+
if [[ "${{ inputs.release_type }}" == "nightly-base" || "${{ inputs.release_type }}" == "nightly-main" ]]; then
|
150 |
+
nightly_suffix="-nightly"
|
151 |
+
fi
|
152 |
+
|
153 |
+
if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
|
154 |
+
# LANGFLOW-BASE RELEASE
|
155 |
+
echo "docker_tags=langflowai/langflow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},langflowai/langflow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
|
156 |
+
echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
|
157 |
+
echo "file=./docker/build_and_push_base.Dockerfile" >> $GITHUB_OUTPUT
|
158 |
+
else
|
159 |
+
if [[ "${{ inputs.pre_release }}" == "true" ]]; then
|
160 |
+
# LANGFLOW-MAIN PRE-RELEASE
|
161 |
+
echo "docker_tags=langflowai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
|
162 |
+
echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
|
163 |
+
echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
|
164 |
+
elif [[ "${{ inputs.release_type }}" == "main-ep" ]]; then
|
165 |
+
# LANGFLOW-MAIN (ENTRYPOINT) RELEASE
|
166 |
+
echo "docker_tags=langflowai/langflow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
|
167 |
+
echo "ghcr_tags=ghcr.io/langflow-ai/langflow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
|
168 |
+
echo "file=./docker/build_and_push_ep.Dockerfile" >> $GITHUB_OUTPUT
|
169 |
+
elif [[ "${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "nightly-main" ]]; then
|
170 |
+
# LANGFLOW-MAIN RELEASE
|
171 |
+
echo "docker_tags=langflowai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow${nightly_suffix}:latest" >> $GITHUB_OUTPUT
|
172 |
+
echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow${nightly_suffix}:latest" >> $GITHUB_OUTPUT
|
173 |
+
echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
|
174 |
+
else
|
175 |
+
echo "Invalid release type. Exiting the workflow."
|
176 |
+
exit 1
|
177 |
+
fi
|
178 |
+
fi
|
179 |
+
build:
|
180 |
+
runs-on: ubuntu-latest
|
181 |
+
needs: [get-version, setup]
|
182 |
+
steps:
|
183 |
+
- name: Check out the code at a specific ref
|
184 |
+
uses: actions/checkout@v4
|
185 |
+
with:
|
186 |
+
ref: ${{ inputs.ref || inputs.main_version || github.ref }}
|
187 |
+
persist-credentials: true
|
188 |
+
- name: "Setup Environment"
|
189 |
+
uses: ./.github/actions/setup-uv
|
190 |
+
- name: Install the project
|
191 |
+
run: |
|
192 |
+
if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
|
193 |
+
uv sync --directory src/backend/base --no-dev --no-sources
|
194 |
+
else
|
195 |
+
uv sync --no-dev --no-sources
|
196 |
+
fi
|
197 |
+
|
198 |
+
- name: Set up Docker Buildx
|
199 |
+
uses: docker/setup-buildx-action@v3
|
200 |
+
|
201 |
+
- name: Login to Docker Hub
|
202 |
+
uses: docker/login-action@v3
|
203 |
+
with:
|
204 |
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
205 |
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
206 |
+
|
207 |
+
- name: Build and Push to Docker Hub
|
208 |
+
uses: docker/build-push-action@v6
|
209 |
+
with:
|
210 |
+
context: .
|
211 |
+
push: true
|
212 |
+
file: ${{ needs.setup.outputs.file }}
|
213 |
+
tags: ${{ needs.setup.outputs.docker_tags }}
|
214 |
+
platforms: linux/amd64,linux/arm64
|
215 |
+
cache-from: type=gha
|
216 |
+
cache-to: type=gha,mode=max
|
217 |
+
|
218 |
+
- name: Login to Github Container Registry
|
219 |
+
uses: docker/login-action@v3
|
220 |
+
with:
|
221 |
+
registry: ghcr.io
|
222 |
+
username: ${{ github.actor }}
|
223 |
+
password: ${{ secrets.TEMP_GHCR_TOKEN}}
|
224 |
+
|
225 |
+
- name: Build and push to Github Container Registry
|
226 |
+
uses: docker/build-push-action@v6
|
227 |
+
with:
|
228 |
+
context: .
|
229 |
+
push: true
|
230 |
+
file: ${{ needs.setup.outputs.file }}
|
231 |
+
tags: ${{ needs.setup.outputs.ghcr_tags }}
|
232 |
+
platforms: linux/amd64,linux/arm64
|
233 |
+
cache-from: type=gha
|
234 |
+
cache-to: type=gha,mode=max
|
235 |
+
|
236 |
+
build_components:
|
237 |
+
if: ${{ inputs.release_type == 'main' }}
|
238 |
+
runs-on: ubuntu-latest
|
239 |
+
permissions:
|
240 |
+
packages: write
|
241 |
+
needs: [build, get-version]
|
242 |
+
strategy:
|
243 |
+
matrix:
|
244 |
+
component: [docker-backend, docker-frontend, ghcr-backend, ghcr-frontend]
|
245 |
+
include:
|
246 |
+
- component: docker-backend
|
247 |
+
dockerfile: ./docker/build_and_push_backend.Dockerfile
|
248 |
+
tags: langflowai/langflow-backend:${{ needs.get-version.outputs.version }},langflowai/langflow-backend:latest
|
249 |
+
langflow_image: langflowai/langflow:${{ needs.get-version.outputs.version }}
|
250 |
+
- component: docker-frontend
|
251 |
+
dockerfile: ./docker/frontend/build_and_push_frontend.Dockerfile
|
252 |
+
tags: langflowai/langflow-frontend:${{ needs.get-version.outputs.version }},langflowai/langflow-frontend:latest
|
253 |
+
langflow_image: langflowai/langflow:${{ needs.get-version.outputs.version }}
|
254 |
+
- component: ghcr-backend
|
255 |
+
dockerfile: ./docker/build_and_push_backend.Dockerfile
|
256 |
+
tags: ghcr.io/langflow-ai/langflow-backend:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-backend:latest
|
257 |
+
langflow_image: ghcr.io/langflow-ai/langflow:${{ needs.get-version.outputs.version }}
|
258 |
+
- component: ghcr-frontend
|
259 |
+
dockerfile: ./docker/frontend/build_and_push_frontend.Dockerfile
|
260 |
+
tags: ghcr.io/langflow-ai/langflow-frontend:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-frontend:latest
|
261 |
+
langflow_image: ghcr.io/langflow-ai/langflow:${{ needs.get-version.outputs.version }}
|
262 |
+
steps:
|
263 |
+
- name: Check out the code at a specific ref
|
264 |
+
uses: actions/checkout@v4
|
265 |
+
with:
|
266 |
+
ref: ${{ inputs.ref || inputs.main_version || github.ref }}
|
267 |
+
|
268 |
+
- name: Set up Docker Buildx
|
269 |
+
uses: docker/setup-buildx-action@v3
|
270 |
+
|
271 |
+
- name: Login to Docker Hub
|
272 |
+
if: ${{ matrix.component == 'docker-backend' }} || ${{ matrix.component == 'docker-frontend' }}
|
273 |
+
uses: docker/login-action@v3
|
274 |
+
with:
|
275 |
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
276 |
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
277 |
+
|
278 |
+
- name: Login to Github Container Registry
|
279 |
+
if: ${{ matrix.component == 'ghcr-backend' }} || ${{ matrix.component == 'ghcr-frontend' }}
|
280 |
+
uses: docker/login-action@v3
|
281 |
+
with:
|
282 |
+
registry: ghcr.io
|
283 |
+
username: ${{ github.actor }}
|
284 |
+
password: ${{ secrets.TEMP_GHCR_TOKEN}}
|
285 |
+
|
286 |
+
- name: Wait for propagation (for backend)
|
287 |
+
run: sleep 120
|
288 |
+
|
289 |
+
- name: Build and push ${{ matrix.component }}
|
290 |
+
uses: docker/build-push-action@v6
|
291 |
+
with:
|
292 |
+
context: .
|
293 |
+
push: true
|
294 |
+
build-args: |
|
295 |
+
LANGFLOW_IMAGE=${{ matrix.langflow_image }}
|
296 |
+
file: ${{ matrix.dockerfile }}
|
297 |
+
tags: ${{ matrix.tags }}
|
298 |
+
# provenance: false will result in a single manifest for all platforms which makes the image pullable from arm64 machines via the emulation (e.g. Apple Silicon machines)
|
299 |
+
provenance: false
|
300 |
+
|
301 |
+
restart-space:
|
302 |
+
name: Restart HuggingFace Spaces
|
303 |
+
if: ${{ inputs.release_type == 'main' }}
|
304 |
+
runs-on: ubuntu-latest
|
305 |
+
needs: [build, get-version]
|
306 |
+
strategy:
|
307 |
+
matrix:
|
308 |
+
python-version:
|
309 |
+
- "3.12"
|
310 |
+
steps:
|
311 |
+
- name: Check out the code at a specific ref
|
312 |
+
uses: actions/checkout@v4
|
313 |
+
with:
|
314 |
+
ref: ${{ inputs.ref || inputs.main_version || github.ref }}
|
315 |
+
- name: "Setup Environment"
|
316 |
+
uses: ./.github/actions/setup-uv
|
317 |
+
|
318 |
+
- name: Restart HuggingFace Spaces Build
|
319 |
+
run: |
|
320 |
+
uv run ./scripts/factory_restart_space.py --space "Langflow/Langflow" --token ${{ secrets.HUGGINGFACE_API_TOKEN }}
|
321 |
+
|
322 |
+
|
323 |
+
|
.github/workflows/docker_test.yml
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Test Docker images
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
branches: [main]
|
6 |
+
paths:
|
7 |
+
- "docker/**"
|
8 |
+
- "poetry.lock"
|
9 |
+
- "pyproject.toml"
|
10 |
+
- "src/backend/**"
|
11 |
+
- ".github/workflows/docker_test.yml"
|
12 |
+
pull_request:
|
13 |
+
branches: [dev]
|
14 |
+
paths:
|
15 |
+
- "docker/**"
|
16 |
+
- "poetry.lock"
|
17 |
+
- "pyproject.toml"
|
18 |
+
- "src/**"
|
19 |
+
- ".github/workflows/docker_test.yml"
|
20 |
+
|
21 |
+
env:
|
22 |
+
POETRY_VERSION: "1.8.2"
|
23 |
+
|
24 |
+
jobs:
|
25 |
+
test-docker:
|
26 |
+
runs-on: ubuntu-latest
|
27 |
+
name: Test docker images
|
28 |
+
steps:
|
29 |
+
- uses: actions/checkout@v4
|
30 |
+
- name: Build image
|
31 |
+
run: |
|
32 |
+
docker build -t langflowai/langflow:latest-dev \
|
33 |
+
-f docker/build_and_push.Dockerfile \
|
34 |
+
.
|
35 |
+
- name: Test image
|
36 |
+
run: |
|
37 |
+
expected_version=$(cat pyproject.toml | grep version | head -n 1 | cut -d '"' -f 2)
|
38 |
+
version=$(docker run --rm --entrypoint bash langflowai/langflow:latest-dev -c "python -c 'from langflow.utils.version import get_version_info; print(get_version_info()[\"version\"])'")
|
39 |
+
if [ "$expected_version" != "$version" ]; then
|
40 |
+
echo "Expected version: $expected_version"
|
41 |
+
echo "Actual version: $version"
|
42 |
+
exit 1
|
43 |
+
fi
|
44 |
+
|
45 |
+
- name: Build backend image
|
46 |
+
run: |
|
47 |
+
docker build -t langflowai/langflow-backend:latest-dev \
|
48 |
+
--build-arg LANGFLOW_IMAGE=langflowai/langflow:latest-dev \
|
49 |
+
-f docker/build_and_push_backend.Dockerfile \
|
50 |
+
.
|
51 |
+
- name: Test backend image
|
52 |
+
run: |
|
53 |
+
expected_version=$(cat pyproject.toml | grep version | head -n 1 | cut -d '"' -f 2)
|
54 |
+
version=$(docker run --rm --entrypoint bash langflowai/langflow-backend:latest-dev -c "python -c 'from langflow.utils.version import get_version_info; print(get_version_info()[\"version\"])'")
|
55 |
+
if [ "$expected_version" != "$version" ]; then
|
56 |
+
echo "Expected version: $expected_version"
|
57 |
+
echo "Actual version: $version"
|
58 |
+
exit 1
|
59 |
+
fi
|
60 |
+
- name: Build frontend image
|
61 |
+
run: |
|
62 |
+
docker build -t langflowai/langflow-frontend:latest-dev \
|
63 |
+
-f docker/frontend/build_and_push_frontend.Dockerfile \
|
64 |
+
.
|
.github/workflows/docs_test.yml
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Test Docs Build
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_call:
|
5 |
+
workflow_dispatch:
|
6 |
+
inputs:
|
7 |
+
branch:
|
8 |
+
description: "(Optional) Branch to checkout"
|
9 |
+
required: false
|
10 |
+
type: string
|
11 |
+
|
12 |
+
env:
|
13 |
+
NODE_VERSION: "21"
|
14 |
+
|
15 |
+
jobs:
|
16 |
+
test-docs-build:
|
17 |
+
name: Test Docs Build
|
18 |
+
runs-on: ubuntu-latest
|
19 |
+
|
20 |
+
steps:
|
21 |
+
- name: Checkout code
|
22 |
+
uses: actions/checkout@v4
|
23 |
+
with:
|
24 |
+
ref: ${{ inputs.branch || github.ref }}
|
25 |
+
- name: Setup Node.js
|
26 |
+
uses: actions/setup-node@v4
|
27 |
+
id: setup-node
|
28 |
+
with:
|
29 |
+
node-version: ${{ env.NODE_VERSION }}
|
30 |
+
|
31 |
+
- name: Cache Node.js dependencies
|
32 |
+
uses: actions/cache@v4
|
33 |
+
id: npm-cache
|
34 |
+
with:
|
35 |
+
path: ~/.npm
|
36 |
+
key: ${{ runner.os }}-node-${{ hashFiles('docs/package-lock.json') }}
|
37 |
+
restore-keys: |
|
38 |
+
${{ runner.os }}-node-
|
39 |
+
|
40 |
+
- name: Install Node.js dependencies
|
41 |
+
run: |
|
42 |
+
cd docs
|
43 |
+
npm install --legacy-peer-deps
|
44 |
+
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
|
45 |
+
|
46 |
+
- name: Build Docs
|
47 |
+
run: |
|
48 |
+
cd docs
|
49 |
+
npm run build
|
.github/workflows/fetch_docs_notion.yml
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Fetch Docs from Notion
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_dispatch:
|
5 |
+
|
6 |
+
env:
|
7 |
+
NODE_VERSION: "21"
|
8 |
+
|
9 |
+
jobs:
|
10 |
+
fetch-docs:
|
11 |
+
name: Fetch Docs from Notion
|
12 |
+
runs-on: ubuntu-latest
|
13 |
+
|
14 |
+
steps:
|
15 |
+
- name: Get current date
|
16 |
+
id: date
|
17 |
+
run: echo "DATE=$(date +'%Y%m%d%H%M%S')" >> "$GITHUB_OUTPUT"
|
18 |
+
|
19 |
+
- name: Checkout code
|
20 |
+
uses: actions/checkout@v4
|
21 |
+
|
22 |
+
- name: Setup Node.js
|
23 |
+
uses: actions/setup-node@v4
|
24 |
+
id: setup-node
|
25 |
+
with:
|
26 |
+
node-version: ${{ env.NODE_VERSION }}
|
27 |
+
|
28 |
+
- name: Cache Node.js dependencies
|
29 |
+
uses: actions/cache@v4
|
30 |
+
id: npm-cache
|
31 |
+
with:
|
32 |
+
path: ~/.npm
|
33 |
+
key: ${{ runner.os }}-node-${{ hashFiles('docs/package-lock.json') }}
|
34 |
+
restore-keys: |
|
35 |
+
${{ runner.os }}-node-
|
36 |
+
|
37 |
+
- name: Install Node.js dependencies
|
38 |
+
run: |
|
39 |
+
cd docs
|
40 |
+
npm install --legacy-peer-deps
|
41 |
+
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
|
42 |
+
|
43 |
+
- name: Fetch Docs from Notion
|
44 |
+
run: |
|
45 |
+
cd docs
|
46 |
+
npm run pull
|
47 |
+
env:
|
48 |
+
NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
|
49 |
+
NOTION_DOCS_ROOT_PAGE_ID: ${{ secrets.NOTION_DOCS_ROOT_PAGE_ID }}
|
50 |
+
|
51 |
+
- name: Create Pull Request
|
52 |
+
id: create_pr
|
53 |
+
uses: peter-evans/create-pull-request@v7
|
54 |
+
with:
|
55 |
+
token: ${{ secrets.GITHUB_TOKEN }}
|
56 |
+
commit-message: Update docs from Notion
|
57 |
+
branch: update-docs-${{ steps.date.outputs.DATE }}
|
58 |
+
base: main
|
59 |
+
title: "docs: update docs from notion"
|
60 |
+
body: This PR updates the documentation from Notion.
|
61 |
+
labels: documentation
|
.github/workflows/integration_tests.yml
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Integration Tests
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_dispatch:
|
5 |
+
inputs:
|
6 |
+
ref:
|
7 |
+
description: "(Optional) ref to checkout"
|
8 |
+
required: false
|
9 |
+
type: string
|
10 |
+
workflow_call:
|
11 |
+
inputs:
|
12 |
+
python-versions:
|
13 |
+
description: "(Optional) Python versions to test"
|
14 |
+
required: true
|
15 |
+
type: string
|
16 |
+
default: "['3.10', '3.11', '3.12']"
|
17 |
+
ref:
|
18 |
+
description: "(Optional) ref to checkout"
|
19 |
+
required: false
|
20 |
+
type: string
|
21 |
+
|
22 |
+
env:
|
23 |
+
POETRY_VERSION: "1.8.2"
|
24 |
+
|
25 |
+
jobs:
|
26 |
+
integration-tests:
|
27 |
+
name: Run Integration Tests
|
28 |
+
runs-on: ubuntu-latest
|
29 |
+
strategy:
|
30 |
+
max-parallel: 1 # Currently, we can only run at a time for collection-per-db-constraints
|
31 |
+
matrix:
|
32 |
+
python-version:
|
33 |
+
- "3.12"
|
34 |
+
- "3.11"
|
35 |
+
- "3.10"
|
36 |
+
env:
|
37 |
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
38 |
+
ASTRA_DB_API_ENDPOINT: ${{ secrets.ASTRA_DB_API_ENDPOINT }}
|
39 |
+
ASTRA_DB_APPLICATION_TOKEN: ${{ secrets.ASTRA_DB_APPLICATION_TOKEN }}
|
40 |
+
steps:
|
41 |
+
- name: Checkout code
|
42 |
+
uses: actions/checkout@v4
|
43 |
+
with:
|
44 |
+
ref: ${{ inputs.ref || github.ref }}
|
45 |
+
- name: "Setup Environment"
|
46 |
+
uses: ./.github/actions/setup-uv
|
47 |
+
- name: Run integration tests with api keys
|
48 |
+
timeout-minutes: 20
|
49 |
+
run: |
|
50 |
+
make integration_tests_api_keys
|
.github/workflows/js_autofix.yml
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: autofix.ci
|
2 |
+
|
3 |
+
on:
|
4 |
+
pull_request:
|
5 |
+
paths:
|
6 |
+
- "src/frontend/**"
|
7 |
+
|
8 |
+
permissions:
|
9 |
+
contents: read
|
10 |
+
|
11 |
+
env:
|
12 |
+
NODE_VERSION: "21"
|
13 |
+
jobs:
|
14 |
+
autofix:
|
15 |
+
runs-on: ubuntu-latest
|
16 |
+
steps:
|
17 |
+
- name: Checkout code
|
18 |
+
uses: actions/checkout@v4
|
19 |
+
|
20 |
+
- name: Setup Node.js
|
21 |
+
uses: actions/setup-node@v4
|
22 |
+
id: setup-node
|
23 |
+
with:
|
24 |
+
node-version: ${{ env.NODE_VERSION }}
|
25 |
+
|
26 |
+
- name: Cache Node.js dependencies
|
27 |
+
uses: actions/cache@v4
|
28 |
+
id: npm-cache
|
29 |
+
with:
|
30 |
+
path: ~/.npm
|
31 |
+
key: ${{ runner.os }}-node-${{ hashFiles('src/frontend/package-lock.json') }}
|
32 |
+
restore-keys: |
|
33 |
+
${{ runner.os }}-node-
|
34 |
+
|
35 |
+
- name: Install Node.js dependencies
|
36 |
+
run: |
|
37 |
+
cd src/frontend
|
38 |
+
npm ci
|
39 |
+
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
|
40 |
+
- name: Run Prettier
|
41 |
+
run: |
|
42 |
+
cd src/frontend
|
43 |
+
npm run format
|
44 |
+
|
45 |
+
- uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
|
.github/workflows/lint-js.yml
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Lint Frontend
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_call:
|
5 |
+
workflow_dispatch:
|
6 |
+
inputs:
|
7 |
+
branch:
|
8 |
+
description: "(Optional) Branch to checkout"
|
9 |
+
required: false
|
10 |
+
type: string
|
11 |
+
|
12 |
+
|
13 |
+
env:
|
14 |
+
NODE_VERSION: "21"
|
15 |
+
|
16 |
+
jobs:
|
17 |
+
run-linters:
|
18 |
+
name: Run Prettier
|
19 |
+
runs-on: ubuntu-latest
|
20 |
+
permissions:
|
21 |
+
contents: write
|
22 |
+
|
23 |
+
steps:
|
24 |
+
- name: Checkout code
|
25 |
+
uses: actions/checkout@v4
|
26 |
+
with:
|
27 |
+
ref: ${{ inputs.branch || github.ref }}
|
28 |
+
|
29 |
+
- name: Setup Node.js
|
30 |
+
uses: actions/setup-node@v4
|
31 |
+
id: setup-node
|
32 |
+
with:
|
33 |
+
node-version: ${{ env.NODE_VERSION }}
|
34 |
+
|
35 |
+
- name: Cache Node.js dependencies
|
36 |
+
uses: actions/cache@v4
|
37 |
+
id: npm-cache
|
38 |
+
with:
|
39 |
+
path: ~/.npm
|
40 |
+
key: ${{ runner.os }}-node-${{ hashFiles('src/frontend/package-lock.json') }}
|
41 |
+
restore-keys: |
|
42 |
+
${{ runner.os }}-node-
|
43 |
+
|
44 |
+
- name: Install Node.js dependencies
|
45 |
+
run: |
|
46 |
+
cd src/frontend
|
47 |
+
npm install
|
48 |
+
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
|
49 |
+
|
50 |
+
- name: Run Prettier
|
51 |
+
run: |
|
52 |
+
cd src/frontend
|
53 |
+
npm run check-format
|
.github/workflows/lint-py.yml
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Lint Python
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_call:
|
5 |
+
workflow_dispatch:
|
6 |
+
inputs:
|
7 |
+
branch:
|
8 |
+
description: "(Optional) Branch to checkout"
|
9 |
+
required: false
|
10 |
+
type: string
|
11 |
+
env:
|
12 |
+
POETRY_VERSION: "1.8.2"
|
13 |
+
|
14 |
+
|
15 |
+
jobs:
|
16 |
+
lint:
|
17 |
+
name: Run Mypy
|
18 |
+
runs-on: ubuntu-latest
|
19 |
+
strategy:
|
20 |
+
matrix:
|
21 |
+
python-version:
|
22 |
+
- "3.12"
|
23 |
+
- "3.11"
|
24 |
+
- "3.10"
|
25 |
+
steps:
|
26 |
+
- name: Check out the code at a specific ref
|
27 |
+
uses: actions/checkout@v4
|
28 |
+
with:
|
29 |
+
ref: ${{ inputs.branch || github.ref }}
|
30 |
+
persist-credentials: true
|
31 |
+
- name: "Setup Environment"
|
32 |
+
uses: ./.github/actions/setup-uv
|
33 |
+
- name: Install the project
|
34 |
+
run: uv sync --dev
|
35 |
+
- name: Run Mypy
|
36 |
+
run: |
|
37 |
+
uv run mypy --namespace-packages -p "langflow"
|
38 |
+
env:
|
39 |
+
GITHUB_TOKEN: ${{ secrets.github_token }}
|
40 |
+
- name: Minimize uv cache
|
41 |
+
run: uv cache prune --ci
|
.github/workflows/matchers/ruff.json
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"problemMatcher": [
|
3 |
+
{
|
4 |
+
"owner": "ruff",
|
5 |
+
"pattern": [
|
6 |
+
{
|
7 |
+
"regexp": "^(Would reformat): (.+)$",
|
8 |
+
"message": 1,
|
9 |
+
"file": 2
|
10 |
+
}
|
11 |
+
]
|
12 |
+
}
|
13 |
+
]
|
14 |
+
}
|
.github/workflows/nightly_build.yml
ADDED
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Nightly Build
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_dispatch:
|
5 |
+
schedule:
|
6 |
+
# Run job at 6:30 UTC, 10.30pm PST, or 11.30pm PDT
|
7 |
+
- cron: "30 6 * * *"
|
8 |
+
|
9 |
+
env:
|
10 |
+
POETRY_VERSION: "1.8.3"
|
11 |
+
PYTHON_VERSION: "3.12"
|
12 |
+
|
13 |
+
jobs:
|
14 |
+
create-nightly-tag:
|
15 |
+
if: github.repository == 'langflow-ai/langflow'
|
16 |
+
runs-on: ubuntu-latest
|
17 |
+
defaults:
|
18 |
+
run:
|
19 |
+
shell: bash -ex -o pipefail {0}
|
20 |
+
permissions:
|
21 |
+
# Required to create tag
|
22 |
+
contents: write
|
23 |
+
outputs:
|
24 |
+
main_tag: ${{ steps.generate_main_tag.outputs.main_tag }}
|
25 |
+
base_tag: ${{ steps.set_base_tag.outputs.base_tag }}
|
26 |
+
steps:
|
27 |
+
- name: Checkout code
|
28 |
+
uses: actions/checkout@v4
|
29 |
+
with:
|
30 |
+
persist-credentials: true
|
31 |
+
- name: "Setup Environment"
|
32 |
+
uses: ./.github/actions/setup-uv
|
33 |
+
- name: Install the project
|
34 |
+
run: uv sync --dev
|
35 |
+
|
36 |
+
- name: Generate main nightly tag
|
37 |
+
id: generate_main_tag
|
38 |
+
run: |
|
39 |
+
# NOTE: This outputs the tag with the `v` prefix.
|
40 |
+
MAIN_TAG="$(uv run ./scripts/ci/pypi_nightly_tag.py main)"
|
41 |
+
echo "main_tag=$MAIN_TAG" >> $GITHUB_OUTPUT
|
42 |
+
echo "main_tag=$MAIN_TAG"
|
43 |
+
|
44 |
+
- name: Check if main tag already exists
|
45 |
+
id: check_main_tag
|
46 |
+
run: |
|
47 |
+
git fetch --tags
|
48 |
+
if git rev-parse -q --verify "refs/tags/${{ steps.generate_main_tag.outputs.main_tag }}" >/dev/null; then
|
49 |
+
echo "main_tag_exists=true" >> $GITHUB_OUTPUT
|
50 |
+
else
|
51 |
+
echo "main_tag_exists=false" >> $GITHUB_OUTPUT
|
52 |
+
fi
|
53 |
+
|
54 |
+
- name: Generate base nightly tag
|
55 |
+
id: generate_base_tag
|
56 |
+
if: ${{ steps.check_main_tag.outputs.main_tag_exists == 'false' }}
|
57 |
+
run: |
|
58 |
+
# NOTE: This outputs the tag with the `v` prefix.
|
59 |
+
BASE_TAG="$(uv run ./scripts/ci/pypi_nightly_tag.py base)"
|
60 |
+
echo "base_tag=$BASE_TAG" >> $GITHUB_OUTPUT
|
61 |
+
echo "base_tag=$BASE_TAG"
|
62 |
+
|
63 |
+
- name: Commit tag
|
64 |
+
id: commit_tag
|
65 |
+
if: ${{ steps.check_main_tag.outputs.main_tag_exists == 'false' }}
|
66 |
+
run: |
|
67 |
+
# If the main tag does not exist in GH, we create the base tag from the existing codebase.
|
68 |
+
|
69 |
+
git config --global user.email "bot-nightly-builds@langflow.org"
|
70 |
+
git config --global user.name "Langflow Bot"
|
71 |
+
|
72 |
+
MAIN_TAG="${{ steps.generate_main_tag.outputs.main_tag }}"
|
73 |
+
BASE_TAG="${{ steps.generate_base_tag.outputs.base_tag }}"
|
74 |
+
echo "Updating base project version to $BASE_TAG and updating main project version to $MAIN_TAG"
|
75 |
+
uv run ./scripts/ci/update_pyproject_combined.py main $MAIN_TAG $BASE_TAG
|
76 |
+
|
77 |
+
uv lock
|
78 |
+
cd src/backend/base && uv lock && cd ../../..
|
79 |
+
|
80 |
+
git add pyproject.toml src/backend/base/pyproject.toml uv.lock src/backend/base/uv.lock
|
81 |
+
git commit -m "Update version and project name"
|
82 |
+
|
83 |
+
echo "Tagging main with $MAIN_TAG"
|
84 |
+
if ! git tag -a $MAIN_TAG -m "Langflow nightly $MAIN_TAG"; then
|
85 |
+
echo "Tag creation failed. Exiting the workflow."
|
86 |
+
exit 1
|
87 |
+
fi
|
88 |
+
|
89 |
+
echo "Pushing main tag $MAIN_TAG"
|
90 |
+
if ! git push origin $MAIN_TAG; then
|
91 |
+
echo "Tag push failed. Check if the tag already exists. Exiting the workflow."
|
92 |
+
exit 1
|
93 |
+
fi
|
94 |
+
# TODO: notify on failure
|
95 |
+
|
96 |
+
- name: Checkout main nightly tag
|
97 |
+
uses: actions/checkout@v4
|
98 |
+
if: ${{ steps.check_main_tag.outputs.main_tag_exists == 'true' }}
|
99 |
+
with:
|
100 |
+
ref: ${{ steps.generate_main_tag.outputs.main_tag }}
|
101 |
+
|
102 |
+
- name: Retrieve Base Tag
|
103 |
+
id: retrieve_base_tag
|
104 |
+
if: ${{ steps.check_main_tag.outputs.main_tag_exists == 'true' }}
|
105 |
+
working-directory: src/backend/base
|
106 |
+
run: |
|
107 |
+
# If the main tag already exists, we need to retrieve the base version from the main tag codebase.
|
108 |
+
version=$(uv tree | grep 'langflow-base' | awk '{print $3}')
|
109 |
+
echo "base_tag=$version" >> $GITHUB_OUTPUT
|
110 |
+
echo "base_tag=$version"
|
111 |
+
|
112 |
+
- name: Set Base Tag
|
113 |
+
id: set_base_tag
|
114 |
+
run: |
|
115 |
+
if [ "${{ steps.retrieve_base_tag.conclusion }}" != "skipped" ] && [ "${{ steps.retrieve_base_tag.outputs.base_tag }}" ]; then
|
116 |
+
BASE_TAG="${{ steps.retrieve_base_tag.outputs.base_tag }}"
|
117 |
+
echo "base_tag=$BASE_TAG" >> $GITHUB_OUTPUT
|
118 |
+
echo "base_tag=$BASE_TAG"
|
119 |
+
elif [ "${{ steps.commit_tag.conclusion }}" != "skipped" ] && [ "${{ steps.generate_base_tag.outputs.base_tag }}" ]; then
|
120 |
+
BASE_TAG="${{ steps.generate_base_tag.outputs.base_tag }}"
|
121 |
+
echo "base_tag=$BASE_TAG" >> $GITHUB_OUTPUT
|
122 |
+
echo "base_tag=$BASE_TAG"
|
123 |
+
else
|
124 |
+
echo "No base tag found. Exiting the workflow."
|
125 |
+
exit 1
|
126 |
+
fi
|
127 |
+
|
128 |
+
frontend-tests:
|
129 |
+
if: github.repository == 'langflow-ai/langflow'
|
130 |
+
name: Run Frontend Tests
|
131 |
+
needs: create-nightly-tag
|
132 |
+
uses: ./.github/workflows/typescript_test.yml
|
133 |
+
with:
|
134 |
+
tests_folder: "tests"
|
135 |
+
release: true
|
136 |
+
secrets:
|
137 |
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
138 |
+
STORE_API_KEY: ${{ secrets.STORE_API_KEY }}
|
139 |
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
140 |
+
TAVILY_API_KEY: ${{ secrets.TAVILY_API_KEY }}
|
141 |
+
|
142 |
+
backend-unit-tests:
|
143 |
+
if: github.repository == 'langflow-ai/langflow'
|
144 |
+
name: Run Backend Unit Tests
|
145 |
+
needs: create-nightly-tag
|
146 |
+
uses: ./.github/workflows/python_test.yml
|
147 |
+
with:
|
148 |
+
python-versions: '["3.10", "3.11", "3.12"]'
|
149 |
+
|
150 |
+
# Not making nightly builds dependent on integration test success
|
151 |
+
# due to inherent flakiness of 3rd party integrations
|
152 |
+
# Revisit when https://github.com/langflow-ai/langflow/pull/3607 is merged.
|
153 |
+
# backend-integration-tests:
|
154 |
+
# name: Run Backend Integration Tests
|
155 |
+
# needs: create-nightly-tag
|
156 |
+
# uses: ./.github/workflows/integration_tests.yml
|
157 |
+
# with:
|
158 |
+
# python-versions: '["3.10", "3.11", "3.12"]'
|
159 |
+
# ref: ${{ needs.create-nightly-tag.outputs.tag }}
|
160 |
+
|
161 |
+
release-nightly-build:
|
162 |
+
if: github.repository == 'langflow-ai/langflow'
|
163 |
+
name: Run Nightly Langflow Build
|
164 |
+
needs: [frontend-tests, backend-unit-tests, create-nightly-tag]
|
165 |
+
uses: ./.github/workflows/release_nightly.yml
|
166 |
+
with:
|
167 |
+
build_docker_base: true
|
168 |
+
build_docker_main: true
|
169 |
+
nightly_tag_main: ${{ needs.create-nightly-tag.outputs.main_tag }}
|
170 |
+
nightly_tag_base: ${{ needs.create-nightly-tag.outputs.base_tag }}
|
171 |
+
secrets: inherit
|
172 |
+
|
173 |
+
# slack-notification:
|
174 |
+
# name: Send Slack Notification
|
175 |
+
# needs: run-nightly-build
|
176 |
+
# runs-on: ubuntu-latest
|
177 |
+
# steps:
|
178 |
+
# - name: Send success notification to Slack
|
179 |
+
# if: success()
|
180 |
+
# uses: slackapi/slack-github-action@v1.26.0
|
181 |
+
# with:
|
182 |
+
# payload: |
|
183 |
+
# {
|
184 |
+
# "channel": "#langflow-nightly-builds",
|
185 |
+
# "username": "GitHub Actions",
|
186 |
+
# "text": "Nightly Build Successful :white_check_mark:",
|
187 |
+
# "icon_emoji": ":rocket:"
|
188 |
+
# }
|
189 |
+
# env:
|
190 |
+
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
191 |
+
|
192 |
+
# - name: Send failure notification to Slack
|
193 |
+
# if: failure()
|
194 |
+
# uses: slackapi/slack-github-action@v1.26.0
|
195 |
+
# with:
|
196 |
+
# payload: |
|
197 |
+
# {
|
198 |
+
# "channel": "#langflow-nightly-builds",
|
199 |
+
# "username": "GitHub Actions",
|
200 |
+
# "text": "Nightly Build Failed :x:",
|
201 |
+
# "icon_emoji": ":warning:"
|
202 |
+
# }
|
203 |
+
# env:
|
204 |
+
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
.github/workflows/py_autofix.yml
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: autofix.ci
|
2 |
+
on:
|
3 |
+
pull_request:
|
4 |
+
paths:
|
5 |
+
- "**/*.py"
|
6 |
+
env:
|
7 |
+
POETRY_VERSION: "1.8.2"
|
8 |
+
|
9 |
+
jobs:
|
10 |
+
lint:
|
11 |
+
name: Run Ruff Check and Format
|
12 |
+
runs-on: ubuntu-latest
|
13 |
+
steps:
|
14 |
+
- uses: actions/checkout@v4
|
15 |
+
- name: "Setup Environment"
|
16 |
+
uses: ./.github/actions/setup-uv
|
17 |
+
- run: uv run ruff check --fix-only .
|
18 |
+
- run: uv run ruff format .
|
19 |
+
- uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
|
20 |
+
- name: Minimize uv cache
|
21 |
+
run: uv cache prune --ci
|
.github/workflows/python_test.yml
ADDED
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Python tests
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_call:
|
5 |
+
inputs:
|
6 |
+
python-versions:
|
7 |
+
description: "(Optional) Python versions to test"
|
8 |
+
required: true
|
9 |
+
type: string
|
10 |
+
default: "['3.10', '3.11', '3.12']"
|
11 |
+
ref:
|
12 |
+
description: "(Optional) ref to checkout"
|
13 |
+
required: false
|
14 |
+
type: string
|
15 |
+
nightly:
|
16 |
+
description: "Whether run is from the nightly build"
|
17 |
+
required: false
|
18 |
+
type: boolean
|
19 |
+
default: false
|
20 |
+
workflow_dispatch:
|
21 |
+
inputs:
|
22 |
+
python-versions:
|
23 |
+
description: "(Optional) Python versions to test"
|
24 |
+
required: true
|
25 |
+
type: string
|
26 |
+
default: "['3.10', '3.11', '3.12']"
|
27 |
+
env:
|
28 |
+
POETRY_VERSION: "1.8.2"
|
29 |
+
NODE_VERSION: "21"
|
30 |
+
PYTEST_RUN_PATH: "src/backend/tests"
|
31 |
+
|
32 |
+
jobs:
|
33 |
+
build:
|
34 |
+
name: Unit Tests - Python ${{ matrix.python-version }} - Group ${{ matrix.group }}
|
35 |
+
runs-on: ubuntu-latest
|
36 |
+
env:
|
37 |
+
UV_CACHE_DIR: /tmp/.uv-cache
|
38 |
+
strategy:
|
39 |
+
matrix:
|
40 |
+
python-version: ${{ fromJson(inputs.python-versions || '["3.10", "3.11", "3.12"]' ) }}
|
41 |
+
splitCount: [5]
|
42 |
+
group: [1, 2, 3, 4, 5]
|
43 |
+
steps:
|
44 |
+
- uses: actions/checkout@v4
|
45 |
+
with:
|
46 |
+
ref: ${{ inputs.ref || github.ref }}
|
47 |
+
- name: Setup Node.js
|
48 |
+
uses: actions/setup-node@v4
|
49 |
+
id: setup-node
|
50 |
+
with:
|
51 |
+
node-version: ${{ env.NODE_VERSION }}
|
52 |
+
- name: Install uv
|
53 |
+
uses: astral-sh/setup-uv@v4
|
54 |
+
with:
|
55 |
+
enable-cache: true
|
56 |
+
cache-dependency-glob: "uv.lock"
|
57 |
+
- name: "Set up Python"
|
58 |
+
uses: actions/setup-python@v5
|
59 |
+
with:
|
60 |
+
python-version-file: "pyproject.toml"
|
61 |
+
- name: Restore uv cache
|
62 |
+
uses: actions/cache@v4
|
63 |
+
with:
|
64 |
+
path: /tmp/.uv-cache
|
65 |
+
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
66 |
+
restore-keys: |
|
67 |
+
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
68 |
+
uv-${{ runner.os }}
|
69 |
+
- name: Install the project
|
70 |
+
run: uv sync --dev
|
71 |
+
- name: Run unit tests
|
72 |
+
uses: nick-fields/retry@v3
|
73 |
+
with:
|
74 |
+
timeout_minutes: 12
|
75 |
+
max_attempts: 2
|
76 |
+
command: make unit_tests async=false args="-x --splits ${{ matrix.splitCount }} --group ${{ matrix.group }}"
|
77 |
+
- name: Minimize uv cache
|
78 |
+
run: uv cache prune --ci
|
79 |
+
integration-tests:
|
80 |
+
name: Integration Tests - Python ${{ matrix.python-version }}
|
81 |
+
runs-on: ubuntu-latest
|
82 |
+
strategy:
|
83 |
+
matrix:
|
84 |
+
python-version: ${{ fromJson(inputs.python-versions || '["3.10", "3.11", "3.12"]' ) }}
|
85 |
+
steps:
|
86 |
+
- uses: actions/checkout@v4
|
87 |
+
with:
|
88 |
+
ref: ${{ inputs.ref || github.ref }}
|
89 |
+
- name: Install uv
|
90 |
+
uses: astral-sh/setup-uv@v4
|
91 |
+
with:
|
92 |
+
enable-cache: true
|
93 |
+
cache-dependency-glob: "uv.lock"
|
94 |
+
- name: "Set up Python"
|
95 |
+
uses: actions/setup-python@v5
|
96 |
+
with:
|
97 |
+
python-version-file: "pyproject.toml"
|
98 |
+
- name: Restore uv cache
|
99 |
+
uses: actions/cache@v4
|
100 |
+
with:
|
101 |
+
path: /tmp/.uv-cache
|
102 |
+
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
103 |
+
restore-keys: |
|
104 |
+
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
105 |
+
uv-${{ runner.os }}
|
106 |
+
- name: Install the project
|
107 |
+
run: uv sync --dev
|
108 |
+
- name: Run integration tests
|
109 |
+
run: make integration_tests_no_api_keys
|
110 |
+
- name: Minimize uv cache
|
111 |
+
run: uv cache prune --ci
|
112 |
+
test-cli:
|
113 |
+
name: Test CLI - Python ${{ matrix.python-version }}
|
114 |
+
runs-on: ubuntu-latest
|
115 |
+
strategy:
|
116 |
+
matrix:
|
117 |
+
python-version: ${{ fromJson(inputs.python-versions || '["3.10", "3.11", "3.12"]') }}
|
118 |
+
steps:
|
119 |
+
- name: Check out the code at a specific ref
|
120 |
+
uses: actions/checkout@v4
|
121 |
+
with:
|
122 |
+
ref: ${{ inputs.ref || github.ref }}
|
123 |
+
- name: "Setup Environment"
|
124 |
+
uses: ./.github/actions/setup-uv
|
125 |
+
|
126 |
+
- name: Check Version
|
127 |
+
id: check-version
|
128 |
+
# We need to print $3 because langflow-base is a dependency of langflow
|
129 |
+
# For langlow we'd use print $2
|
130 |
+
run: |
|
131 |
+
version=$(uv tree | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//')
|
132 |
+
url="https://pypi.org/pypi/langflow-base/json"
|
133 |
+
if [ ${{ inputs.nightly }} == true ]; then
|
134 |
+
url="https://pypi.org/pypi/langflow-base-nightly/json"
|
135 |
+
fi
|
136 |
+
|
137 |
+
last_released_version=$(curl -s $url | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
|
138 |
+
if [ "$version" != "$last_released_version" ]; then
|
139 |
+
echo "Version $version has not been released yet. Skipping the rest of the job."
|
140 |
+
echo skipped=true >> $GITHUB_OUTPUT
|
141 |
+
exit 0
|
142 |
+
else
|
143 |
+
echo version=$version >> $GITHUB_OUTPUT
|
144 |
+
echo skipped=false >> $GITHUB_OUTPUT
|
145 |
+
fi
|
146 |
+
- name: Build wheel
|
147 |
+
if: steps.check-version.outputs.skipped == 'false'
|
148 |
+
run: |
|
149 |
+
make build main=true
|
150 |
+
- name: Install wheel and Test CLI
|
151 |
+
if: steps.check-version.outputs.skipped == 'false'
|
152 |
+
run: |
|
153 |
+
uv venv new-venv
|
154 |
+
source new-venv/bin/activate
|
155 |
+
uv pip install dist/*.whl
|
156 |
+
- name: Test CLI
|
157 |
+
if: steps.check-version.outputs.skipped == 'false'
|
158 |
+
run: |
|
159 |
+
source new-venv/bin/activate
|
160 |
+
python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
|
161 |
+
SERVER_PID=$!
|
162 |
+
# Wait for the server to start
|
163 |
+
timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/api/v1/auto_login; do sleep 5; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
|
164 |
+
# Terminate the server
|
165 |
+
kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
|
166 |
+
sleep 20 # give the server some time to terminate
|
167 |
+
# Check if the server is still running
|
168 |
+
if kill -0 $SERVER_PID 2>/dev/null; then
|
169 |
+
echo "Failed to terminate the server"
|
170 |
+
exit 0
|
171 |
+
else
|
172 |
+
echo "Server terminated successfully"
|
173 |
+
fi
|
174 |
+
- name: Minimize uv cache
|
175 |
+
run: uv cache prune --ci
|
.github/workflows/release.yml
ADDED
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Langflow Release
|
2 |
+
run-name: Langflow Release by @${{ github.actor }}
|
3 |
+
|
4 |
+
on:
|
5 |
+
workflow_dispatch:
|
6 |
+
inputs:
|
7 |
+
release_package_base:
|
8 |
+
description: "Release Langflow Base"
|
9 |
+
required: true
|
10 |
+
type: boolean
|
11 |
+
default: false
|
12 |
+
release_package_main:
|
13 |
+
description: "Release Langflow"
|
14 |
+
required: true
|
15 |
+
type: boolean
|
16 |
+
default: false
|
17 |
+
build_docker_base:
|
18 |
+
description: "Build Docker Image for Langflow Base"
|
19 |
+
required: true
|
20 |
+
type: boolean
|
21 |
+
default: false
|
22 |
+
build_docker_main:
|
23 |
+
description: "Build Docker Image for Langflow"
|
24 |
+
required: true
|
25 |
+
type: boolean
|
26 |
+
default: false
|
27 |
+
build_docker_ep:
|
28 |
+
description: "Build Docker Image for Langflow with Entrypoint"
|
29 |
+
required: false
|
30 |
+
type: boolean
|
31 |
+
default: false
|
32 |
+
pre_release:
|
33 |
+
description: "Pre-release"
|
34 |
+
required: false
|
35 |
+
type: boolean
|
36 |
+
default: false
|
37 |
+
create_release:
|
38 |
+
description: "Whether to create a gh release"
|
39 |
+
required: false
|
40 |
+
type: boolean
|
41 |
+
default: true
|
42 |
+
|
43 |
+
|
44 |
+
jobs:
|
45 |
+
ci:
|
46 |
+
if: ${{ github.event.inputs.release_package_base == 'true' || github.event.inputs.release_package_main == 'true' }}
|
47 |
+
name: CI
|
48 |
+
uses: ./.github/workflows/ci.yml
|
49 |
+
with:
|
50 |
+
python-versions: "['3.10', '3.11', '3.12']"
|
51 |
+
frontend-tests-folder: "tests"
|
52 |
+
release: true
|
53 |
+
|
54 |
+
release-base:
|
55 |
+
name: Release Langflow Base
|
56 |
+
needs: [ci]
|
57 |
+
if: inputs.release_package_base == true
|
58 |
+
runs-on: ubuntu-latest
|
59 |
+
outputs:
|
60 |
+
version: ${{ steps.check-version.outputs.version }}
|
61 |
+
skipped: ${{ steps.check-version.outputs.skipped }}
|
62 |
+
steps:
|
63 |
+
- name: Checkout code
|
64 |
+
uses: actions/checkout@v4
|
65 |
+
- name: Setup Environment
|
66 |
+
uses: ./.github/actions/setup-uv
|
67 |
+
- name: Install the project
|
68 |
+
run: uv sync --dev
|
69 |
+
- name: Check Version
|
70 |
+
id: check-version
|
71 |
+
run: |
|
72 |
+
version=$(uv tree | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//')
|
73 |
+
last_released_version=$(curl -s "https://pypi.org/pypi/langflow-base/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
|
74 |
+
if [ "$version" = "$last_released_version" ]; then
|
75 |
+
echo "Version $version is already released. Skipping release."
|
76 |
+
echo skipped=true >> $GITHUB_OUTPUT
|
77 |
+
exit 0
|
78 |
+
else
|
79 |
+
echo version=$version >> $GITHUB_OUTPUT
|
80 |
+
echo skipped=false >> $GITHUB_OUTPUT
|
81 |
+
fi
|
82 |
+
- name: Build project for distribution
|
83 |
+
if: steps.check-version.outputs.skipped == 'false'
|
84 |
+
run: make build base=true args="--wheel"
|
85 |
+
- name: Test CLI
|
86 |
+
if: steps.check-version.outputs.skipped == 'false'
|
87 |
+
run: |
|
88 |
+
# TODO: Unsure why the whl is not built in src/backend/base/dist
|
89 |
+
mkdir src/backend/base/dist
|
90 |
+
mv dist/*.whl src/backend/base/dist
|
91 |
+
uv pip install src/backend/base/dist/*.whl
|
92 |
+
uv run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
|
93 |
+
SERVER_PID=$!
|
94 |
+
# Wait for the server to start
|
95 |
+
timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/api/v1/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
|
96 |
+
# Terminate the server
|
97 |
+
kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
|
98 |
+
sleep 20 # give the server some time to terminate
|
99 |
+
# Check if the server is still running
|
100 |
+
if kill -0 $SERVER_PID 2>/dev/null; then
|
101 |
+
echo "Failed to terminate the server"
|
102 |
+
exit 0
|
103 |
+
else
|
104 |
+
echo "Server terminated successfully"
|
105 |
+
fi
|
106 |
+
- name: Publish to PyPI
|
107 |
+
if: steps.check-version.outputs.skipped == 'false'
|
108 |
+
env:
|
109 |
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
110 |
+
run: |
|
111 |
+
make publish base=true
|
112 |
+
- name: Upload Artifact
|
113 |
+
if: steps.check-version.outputs.skipped == 'false'
|
114 |
+
uses: actions/upload-artifact@v4
|
115 |
+
with:
|
116 |
+
name: dist-base
|
117 |
+
path: src/backend/base/dist
|
118 |
+
|
119 |
+
release-main:
|
120 |
+
name: Release Langflow Main
|
121 |
+
if: inputs.release_package_main == true
|
122 |
+
needs: [release-base]
|
123 |
+
runs-on: ubuntu-latest
|
124 |
+
outputs:
|
125 |
+
version: ${{ steps.check-version.outputs.version }}
|
126 |
+
steps:
|
127 |
+
- name: Checkout code
|
128 |
+
uses: actions/checkout@v4
|
129 |
+
- name: Setup Environment
|
130 |
+
uses: ./.github/actions/setup-uv
|
131 |
+
- name: Install the project
|
132 |
+
run: uv sync --dev
|
133 |
+
|
134 |
+
# If pre-release is true, we need to check if ["a", "b", "rc", "dev", "post"] is in the version string
|
135 |
+
# if the version string is incorrect, we need to exit the workflow
|
136 |
+
- name: Check if pre-release
|
137 |
+
if: inputs.pre_release == 'true'
|
138 |
+
run: |
|
139 |
+
version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}' | sed 's/^v//')
|
140 |
+
if [[ "${version}" =~ ^([0-9]+\.)?([0-9]+\.)?[0-9]+((a|b|rc|dev|post)([0-9]+))$ ]]; then
|
141 |
+
echo "Pre-release version detected. Continuing with the release."
|
142 |
+
else
|
143 |
+
echo "Invalid pre-release version detected. Exiting the workflow."
|
144 |
+
exit 1
|
145 |
+
fi
|
146 |
+
- name: Check Version
|
147 |
+
id: check-version
|
148 |
+
run: |
|
149 |
+
version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}' | sed 's/^v//')
|
150 |
+
last_released_version=$(curl -s "https://pypi.org/pypi/langflow/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
|
151 |
+
if [ "$version" = "$last_released_version" ]; then
|
152 |
+
echo "Version $version is already released. Skipping release."
|
153 |
+
exit 1
|
154 |
+
else
|
155 |
+
echo version=$version >> $GITHUB_OUTPUT
|
156 |
+
fi
|
157 |
+
- name: Wait for PyPI Propagation
|
158 |
+
if: needs.release-base.outputs.skipped == 'false'
|
159 |
+
run: sleep 300 # wait for 5 minutes to ensure PyPI propagation
|
160 |
+
|
161 |
+
- name: Build project for distribution
|
162 |
+
run: make build main=true args="--no-sources --wheel"
|
163 |
+
- name: Test CLI
|
164 |
+
run: |
|
165 |
+
uv pip install dist/*.whl
|
166 |
+
uv run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
|
167 |
+
SERVER_PID=$!
|
168 |
+
# Wait for the server to start
|
169 |
+
timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health_check; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
|
170 |
+
# Terminate the server
|
171 |
+
kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
|
172 |
+
sleep 20 # give the server some time to terminate
|
173 |
+
# Check if the server is still running
|
174 |
+
if kill -0 $SERVER_PID 2>/dev/null; then
|
175 |
+
echo "Failed to terminate the server"
|
176 |
+
exit 0
|
177 |
+
else
|
178 |
+
echo "Server terminated successfully"
|
179 |
+
fi
|
180 |
+
- name: Publish to PyPI
|
181 |
+
env:
|
182 |
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
183 |
+
run: |
|
184 |
+
make publish main=true
|
185 |
+
- name: Upload Artifact
|
186 |
+
uses: actions/upload-artifact@v4
|
187 |
+
with:
|
188 |
+
name: dist-main
|
189 |
+
path: dist
|
190 |
+
|
191 |
+
call_docker_build_base:
|
192 |
+
name: Call Docker Build Workflow for Langflow Base
|
193 |
+
if: inputs.build_docker_base == true
|
194 |
+
needs: [release-base, release-main]
|
195 |
+
uses: ./.github/workflows/docker-build.yml
|
196 |
+
with:
|
197 |
+
base_version: ${{ needs.release-base.outputs.version }}
|
198 |
+
main_version: ${{ needs.release-main.outputs.version }}
|
199 |
+
release_type: base
|
200 |
+
pre_release: ${{ inputs.pre_release }}
|
201 |
+
secrets: inherit
|
202 |
+
|
203 |
+
call_docker_build_main:
|
204 |
+
name: Call Docker Build Workflow for Langflow
|
205 |
+
if: inputs.build_docker_main == true
|
206 |
+
needs: [release-main]
|
207 |
+
uses: ./.github/workflows/docker-build.yml
|
208 |
+
with:
|
209 |
+
main_version: ${{ needs.release-main.outputs.version }}
|
210 |
+
release_type: main
|
211 |
+
pre_release: ${{ inputs.pre_release }}
|
212 |
+
secrets: inherit
|
213 |
+
|
214 |
+
call_docker_build_main_ep:
|
215 |
+
name: Call Docker Build Workflow for Langflow with Entrypoint
|
216 |
+
if: inputs.build_docker_ep == true
|
217 |
+
needs: [release-main]
|
218 |
+
uses: ./.github/workflows/docker-build.yml
|
219 |
+
with:
|
220 |
+
main_version: ${{ needs.release-main.outputs.version }}
|
221 |
+
release_type: main-ep
|
222 |
+
pre_release: False
|
223 |
+
secrets: inherit
|
224 |
+
|
225 |
+
create_release:
|
226 |
+
name: Create Release
|
227 |
+
runs-on: ubuntu-latest
|
228 |
+
needs: release-main
|
229 |
+
steps:
|
230 |
+
- uses: actions/download-artifact@v4
|
231 |
+
with:
|
232 |
+
name: dist-main
|
233 |
+
path: dist
|
234 |
+
- name: Create Release
|
235 |
+
uses: ncipollo/release-action@v1
|
236 |
+
with:
|
237 |
+
artifacts: "dist/*"
|
238 |
+
token: ${{ secrets.GITHUB_TOKEN }}
|
239 |
+
draft: false
|
240 |
+
generateReleaseNotes: true
|
241 |
+
prerelease: ${{ inputs.pre_release }}
|
242 |
+
tag: ${{ needs.release-main.outputs.version }}
|
243 |
+
commit: ${{ github.ref }}
|
.github/workflows/release_nightly.yml
ADDED
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Langflow Nightly Build
|
2 |
+
run-name: Langflow Nightly Release by @${{ github.actor }}
|
3 |
+
|
4 |
+
on:
|
5 |
+
workflow_dispatch:
|
6 |
+
inputs:
|
7 |
+
build_docker_base:
|
8 |
+
description: "Build Docker Image for Langflow Nightly Base"
|
9 |
+
required: true
|
10 |
+
type: boolean
|
11 |
+
default: false
|
12 |
+
build_docker_main:
|
13 |
+
description: "Build Docker Image for Langflow Nightly"
|
14 |
+
required: true
|
15 |
+
type: boolean
|
16 |
+
default: false
|
17 |
+
build_docker_ep:
|
18 |
+
description: "Build Docker Image for Langflow Nightly with Entrypoint"
|
19 |
+
required: false
|
20 |
+
type: boolean
|
21 |
+
default: false
|
22 |
+
nightly_tag_main:
|
23 |
+
description: "Tag for the nightly main build"
|
24 |
+
required: true
|
25 |
+
type: string
|
26 |
+
nightly_tag_base:
|
27 |
+
description: "Tag for the nightly base build"
|
28 |
+
required: true
|
29 |
+
type: string
|
30 |
+
workflow_call:
|
31 |
+
inputs:
|
32 |
+
build_docker_base:
|
33 |
+
description: "Build Docker Image for Langflow Nightly Base"
|
34 |
+
required: true
|
35 |
+
type: boolean
|
36 |
+
default: false
|
37 |
+
build_docker_main:
|
38 |
+
description: "Build Docker Image for Langflow Nightly"
|
39 |
+
required: true
|
40 |
+
type: boolean
|
41 |
+
default: false
|
42 |
+
build_docker_ep:
|
43 |
+
description: "Build Docker Image for Langflow Nightly with Entrypoint"
|
44 |
+
required: false
|
45 |
+
type: boolean
|
46 |
+
default: false
|
47 |
+
nightly_tag_main:
|
48 |
+
description: "Tag for the nightly main build"
|
49 |
+
required: true
|
50 |
+
type: string
|
51 |
+
nightly_tag_base:
|
52 |
+
description: "Tag for the nightly base build"
|
53 |
+
required: true
|
54 |
+
type: string
|
55 |
+
|
56 |
+
env:
|
57 |
+
POETRY_VERSION: "1.8.3"
|
58 |
+
PYTHON_VERSION: "3.12"
|
59 |
+
|
60 |
+
jobs:
|
61 |
+
release-nightly-base:
|
62 |
+
name: Release Langflow Nightly Base
|
63 |
+
runs-on: ubuntu-latest
|
64 |
+
defaults:
|
65 |
+
run:
|
66 |
+
shell: bash
|
67 |
+
outputs:
|
68 |
+
version: ${{ steps.verify.outputs.version }}
|
69 |
+
steps:
|
70 |
+
- name: Check out the code at a specific ref
|
71 |
+
uses: actions/checkout@v4
|
72 |
+
with:
|
73 |
+
ref: ${{ inputs.nightly_tag_main }}
|
74 |
+
persist-credentials: true
|
75 |
+
- name: "Setup Environment"
|
76 |
+
uses: ./.github/actions/setup-uv
|
77 |
+
- name: Install the project
|
78 |
+
run: uv sync --dev
|
79 |
+
|
80 |
+
- name: Verify Nightly Name and Version
|
81 |
+
id: verify
|
82 |
+
run: |
|
83 |
+
name=$(uv tree | grep 'langflow-base' | awk '{print $2}')
|
84 |
+
version=$(uv tree | grep 'langflow-base' | awk '{print $3}')
|
85 |
+
if [ "$name" != "langflow-base-nightly" ]; then
|
86 |
+
echo "Name $name does not match langflow-base-nightly. Exiting the workflow."
|
87 |
+
exit 1
|
88 |
+
fi
|
89 |
+
if [ "$version" != "${{ inputs.nightly_tag_base }}" ]; then
|
90 |
+
echo "Version $version does not match nightly tag ${{ inputs.nightly_tag_base }}. Exiting the workflow."
|
91 |
+
exit 1
|
92 |
+
fi
|
93 |
+
# Strip the leading `v` from the version
|
94 |
+
version=$(echo $version | sed 's/^v//')
|
95 |
+
echo "version=$version" >> $GITHUB_OUTPUT
|
96 |
+
|
97 |
+
- name: Build project for distribution
|
98 |
+
run: make build base=true args="--wheel"
|
99 |
+
|
100 |
+
- name: Test CLI
|
101 |
+
run: |
|
102 |
+
# TODO: Unsure why the whl is not built in src/backend/base/dist
|
103 |
+
mkdir src/backend/base/dist
|
104 |
+
mv dist/*.whl src/backend/base/dist/
|
105 |
+
uv pip install src/backend/base/dist/*.whl
|
106 |
+
uv run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
|
107 |
+
SERVER_PID=$!
|
108 |
+
# Wait for the server to start
|
109 |
+
timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/api/v1/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
|
110 |
+
# Terminate the server
|
111 |
+
kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
|
112 |
+
sleep 20 # give the server some time to terminate
|
113 |
+
# Check if the server is still running
|
114 |
+
if kill -0 $SERVER_PID 2>/dev/null; then
|
115 |
+
echo "Failed to terminate the server"
|
116 |
+
exit 0
|
117 |
+
else
|
118 |
+
echo "Server terminated successfully"
|
119 |
+
fi
|
120 |
+
|
121 |
+
- name: Publish to PyPI
|
122 |
+
env:
|
123 |
+
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
|
124 |
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
125 |
+
run: |
|
126 |
+
make publish base=true
|
127 |
+
|
128 |
+
- name: Upload Artifact
|
129 |
+
uses: actions/upload-artifact@v4
|
130 |
+
with:
|
131 |
+
name: dist-base
|
132 |
+
path: src/backend/base/dist
|
133 |
+
|
134 |
+
release-nightly-main:
|
135 |
+
name: Release Langflow Nightly Main
|
136 |
+
needs: [release-nightly-base]
|
137 |
+
runs-on: ubuntu-latest
|
138 |
+
outputs:
|
139 |
+
version: ${{ steps.verify.outputs.version }}
|
140 |
+
defaults:
|
141 |
+
run:
|
142 |
+
shell: bash
|
143 |
+
steps:
|
144 |
+
- name: Check out the code at a specific ref
|
145 |
+
uses: actions/checkout@v4
|
146 |
+
with:
|
147 |
+
ref: ${{ inputs.nightly_tag_main}}
|
148 |
+
persist-credentials: true
|
149 |
+
- name: "Setup Environment"
|
150 |
+
uses: ./.github/actions/setup-uv
|
151 |
+
- name: Install the project
|
152 |
+
run: uv sync --dev
|
153 |
+
|
154 |
+
- name: Verify Nightly Name and Version
|
155 |
+
id: verify
|
156 |
+
run: |
|
157 |
+
name=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $1}')
|
158 |
+
version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}')
|
159 |
+
if [ "$name" != "langflow-nightly" ]; then
|
160 |
+
echo "Name $name does not match langflow-nightly. Exiting the workflow."
|
161 |
+
exit 1
|
162 |
+
fi
|
163 |
+
if [ "$version" != "${{ inputs.nightly_tag_main }}" ]; then
|
164 |
+
echo "Version $version does not match nightly tag ${{ inputs.nightly_tag_main }}. Exiting the workflow."
|
165 |
+
exit 1
|
166 |
+
fi
|
167 |
+
# Strip the leading `v` from the version
|
168 |
+
version=$(echo $version | sed 's/^v//')
|
169 |
+
echo "version=$version" >> $GITHUB_OUTPUT
|
170 |
+
- name: Wait for PyPI Propagation
|
171 |
+
run: sleep 300 # wait for 5 minutes to ensure PyPI propagation of base
|
172 |
+
|
173 |
+
- name: Build project for distribution
|
174 |
+
run: make build main=true args="--no-sources --wheel"
|
175 |
+
- name: Test CLI
|
176 |
+
run: |
|
177 |
+
uv pip install dist/*.whl
|
178 |
+
uv run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
|
179 |
+
SERVER_PID=$!
|
180 |
+
# Wait for the server to start
|
181 |
+
timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health_check; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
|
182 |
+
# Terminate the server
|
183 |
+
kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
|
184 |
+
sleep 20 # give the server some time to terminate
|
185 |
+
# Check if the server is still running
|
186 |
+
if kill -0 $SERVER_PID 2>/dev/null; then
|
187 |
+
echo "Failed to terminate the server"
|
188 |
+
exit 0
|
189 |
+
else
|
190 |
+
echo "Server terminated successfully"
|
191 |
+
fi
|
192 |
+
- name: Publish to PyPI
|
193 |
+
env:
|
194 |
+
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
|
195 |
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
196 |
+
run: |
|
197 |
+
make publish main=true
|
198 |
+
- name: Upload Artifact
|
199 |
+
uses: actions/upload-artifact@v4
|
200 |
+
with:
|
201 |
+
name: dist-main
|
202 |
+
path: dist
|
203 |
+
|
204 |
+
call_docker_build_base:
|
205 |
+
name: Call Docker Build Workflow for Langflow Base
|
206 |
+
if: always() && ${{ inputs.build_docker_base == 'true' }}
|
207 |
+
needs: [release-nightly-base, release-nightly-main]
|
208 |
+
uses: ./.github/workflows/docker-build.yml
|
209 |
+
with:
|
210 |
+
release_type: nightly-base
|
211 |
+
base_version: ${{ inputs.nightly_tag_base }}
|
212 |
+
main_version: ${{ inputs.nightly_tag_main }}
|
213 |
+
secrets: inherit
|
214 |
+
|
215 |
+
call_docker_build_main:
|
216 |
+
name: Call Docker Build Workflow for Langflow
|
217 |
+
if: always() && ${{ inputs.build_docker_main == 'true' }}
|
218 |
+
needs: [release-nightly-main]
|
219 |
+
uses: ./.github/workflows/docker-build.yml
|
220 |
+
with:
|
221 |
+
release_type: nightly-main
|
222 |
+
main_version: ${{ inputs.nightly_tag_main }}
|
223 |
+
secrets: inherit
|
224 |
+
|
225 |
+
call_docker_build_main_ep:
|
226 |
+
name: Call Docker Build Workflow for Langflow with Entrypoint
|
227 |
+
if: always() && ${{ inputs.build_docker_ep == 'true' }}
|
228 |
+
needs: [release-nightly-main]
|
229 |
+
uses: ./.github/workflows/docker-build.yml
|
230 |
+
with:
|
231 |
+
release_type: main-ep
|
232 |
+
main_version: ${{ inputs.nightly_tag_main }}
|
233 |
+
secrets: inherit
|
.github/workflows/store_pytest_durations.yml
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Store pytest durations
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_dispatch:
|
5 |
+
schedule:
|
6 |
+
# Run job at 6:30 UTC, 10.30pm PST, or 11.30pm PDT
|
7 |
+
- cron: "30 6 * * *"
|
8 |
+
|
9 |
+
env:
|
10 |
+
PYTEST_RUN_PATH: "src/backend/tests"
|
11 |
+
|
12 |
+
jobs:
|
13 |
+
build:
|
14 |
+
name: Run pytest and store durations
|
15 |
+
runs-on: ubuntu-latest
|
16 |
+
permissions:
|
17 |
+
contents: write
|
18 |
+
pull-requests: write
|
19 |
+
env:
|
20 |
+
UV_CACHE_DIR: /tmp/.uv-cache
|
21 |
+
steps:
|
22 |
+
- uses: actions/checkout@v4
|
23 |
+
- name: Install uv
|
24 |
+
uses: astral-sh/setup-uv@v4
|
25 |
+
with:
|
26 |
+
enable-cache: true
|
27 |
+
cache-dependency-glob: "uv.lock"
|
28 |
+
- name: "Set up Python"
|
29 |
+
uses: actions/setup-python@v5
|
30 |
+
with:
|
31 |
+
python-version-file: "pyproject.toml"
|
32 |
+
- name: Restore uv cache
|
33 |
+
uses: actions/cache@v4
|
34 |
+
with:
|
35 |
+
path: /tmp/.uv-cache
|
36 |
+
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
37 |
+
restore-keys: |
|
38 |
+
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
39 |
+
uv-${{ runner.os }}
|
40 |
+
- name: Install the project
|
41 |
+
run: uv sync --dev
|
42 |
+
- name: Run unit tests
|
43 |
+
uses: nick-fields/retry@v3
|
44 |
+
with:
|
45 |
+
timeout_minutes: 12
|
46 |
+
max_attempts: 2
|
47 |
+
command: uv run pytest src/backend/tests --durations-path src/backend/tests/.test_durations --splitting-algorithm least_duration --store-durations
|
48 |
+
- name: Minimize uv cache
|
49 |
+
run: uv cache prune --ci
|
50 |
+
|
51 |
+
- name: Create Pull Request
|
52 |
+
uses: peter-evans/create-pull-request@v7
|
53 |
+
with:
|
54 |
+
token: ${{ secrets.GITHUB_TOKEN }}
|
55 |
+
branch-token: ${{ secrets.GITHUB_TOKEN }}
|
56 |
+
commit-message: "chore: update test durations"
|
57 |
+
title: "chore: update test durations"
|
58 |
+
body: |
|
59 |
+
Automated PR to update test durations file.
|
60 |
+
|
61 |
+
This PR was automatically created by the store_pytest_durations workflow.
|
62 |
+
branch: update-test-durations
|
63 |
+
branch-suffix: timestamp
|
64 |
+
delete-branch: true
|
65 |
+
maintainer-can-modify: true
|
.github/workflows/style-check-py.yml
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Ruff Style Check
|
2 |
+
|
3 |
+
on:
|
4 |
+
pull_request:
|
5 |
+
types: [opened, synchronize, reopened, auto_merge_enabled]
|
6 |
+
paths:
|
7 |
+
- "**/*.py"
|
8 |
+
|
9 |
+
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
jobs:
|
14 |
+
lint:
|
15 |
+
name: Ruff Style Check
|
16 |
+
runs-on: ubuntu-latest
|
17 |
+
strategy:
|
18 |
+
matrix:
|
19 |
+
python-version:
|
20 |
+
- "3.12"
|
21 |
+
steps:
|
22 |
+
- name: Check out the code at a specific ref
|
23 |
+
uses: actions/checkout@v4
|
24 |
+
- name: "Setup Environment"
|
25 |
+
uses: ./.github/actions/setup-uv
|
26 |
+
- name: Register problem matcher
|
27 |
+
run: echo "::add-matcher::.github/workflows/matchers/ruff.json"
|
28 |
+
- name: Run Ruff Check
|
29 |
+
run: uv run --only-dev ruff check --output-format=github .
|
30 |
+
- name: Minimize uv cache
|
31 |
+
run: uv cache prune --ci
|
.github/workflows/typescript_test.yml
ADDED
@@ -0,0 +1,348 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Run Frontend Tests
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_call:
|
5 |
+
secrets:
|
6 |
+
OPENAI_API_KEY:
|
7 |
+
required: true
|
8 |
+
STORE_API_KEY:
|
9 |
+
required: true
|
10 |
+
ANTHROPIC_API_KEY:
|
11 |
+
required: true
|
12 |
+
TAVILY_API_KEY:
|
13 |
+
required: true
|
14 |
+
inputs:
|
15 |
+
suites:
|
16 |
+
description: "Test suites to run (JSON array)"
|
17 |
+
required: false
|
18 |
+
type: string
|
19 |
+
default: '[]'
|
20 |
+
release:
|
21 |
+
description: "Whether this is a release build"
|
22 |
+
required: false
|
23 |
+
type: boolean
|
24 |
+
default: false
|
25 |
+
tests_folder:
|
26 |
+
description: "(Optional) Tests to run"
|
27 |
+
required: false
|
28 |
+
type: string
|
29 |
+
default: "tests"
|
30 |
+
ref:
|
31 |
+
description: "(Optional) ref to checkout"
|
32 |
+
required: false
|
33 |
+
type: string
|
34 |
+
workflow_dispatch:
|
35 |
+
inputs:
|
36 |
+
suites:
|
37 |
+
description: "Test suites to run (JSON array)"
|
38 |
+
required: false
|
39 |
+
type: string
|
40 |
+
default: '[]'
|
41 |
+
release:
|
42 |
+
description: "Whether this is a release build"
|
43 |
+
required: false
|
44 |
+
type: boolean
|
45 |
+
default: false
|
46 |
+
tests_folder:
|
47 |
+
description: "(Optional) Tests to run"
|
48 |
+
required: false
|
49 |
+
type: string
|
50 |
+
default: "tests"
|
51 |
+
|
52 |
+
env:
|
53 |
+
NODE_VERSION: "21"
|
54 |
+
PYTHON_VERSION: "3.12"
|
55 |
+
# Define the directory where Playwright browsers will be installed.
|
56 |
+
# Adjust if your project uses a different path.
|
57 |
+
PLAYWRIGHT_BROWSERS_PATH: "ms-playwright"
|
58 |
+
|
59 |
+
jobs:
|
60 |
+
determine-test-suite:
|
61 |
+
name: Determine Test Suites and Shard Distribution
|
62 |
+
runs-on: ubuntu-latest
|
63 |
+
outputs:
|
64 |
+
matrix: ${{ steps.setup-matrix.outputs.matrix }}
|
65 |
+
test_grep: ${{ steps.set-matrix.outputs.test_grep }}
|
66 |
+
suites: ${{ steps.set-matrix.outputs.suites }}
|
67 |
+
steps:
|
68 |
+
- uses: actions/checkout@v4
|
69 |
+
with:
|
70 |
+
ref: ${{ inputs.ref || github.ref }}
|
71 |
+
fetch-depth: 0
|
72 |
+
|
73 |
+
- name: Paths Filter
|
74 |
+
id: filter
|
75 |
+
uses: dorny/paths-filter@v3
|
76 |
+
with:
|
77 |
+
filters: .github/changes-filter.yaml
|
78 |
+
|
79 |
+
- name: Determine Test Suites from Changes
|
80 |
+
id: set-matrix
|
81 |
+
run: |
|
82 |
+
# Start with input suites if provided, otherwise empty array
|
83 |
+
echo "Changes filter output: ${{ steps.filter.outputs }}"
|
84 |
+
SUITES='${{ inputs.suites }}'
|
85 |
+
echo "Initial suites: $SUITES"
|
86 |
+
TEST_GREP=""
|
87 |
+
|
88 |
+
RELEASE="${{ inputs.release || 'false' }}"
|
89 |
+
echo "Release build: $RELEASE"
|
90 |
+
|
91 |
+
# Only set to release if it's explicitly a release build
|
92 |
+
if [[ "$RELEASE" == "true" ]]; then
|
93 |
+
SUITES='["release"]'
|
94 |
+
echo "Release build detected - setting suites to: $SUITES"
|
95 |
+
# grep pattern for release is the @release tag - run all tests
|
96 |
+
TEST_GREP="--grep=\"@release\""
|
97 |
+
else
|
98 |
+
# If input suites were not provided, determine based on changes
|
99 |
+
if [[ "$SUITES" == "[]" ]]; then
|
100 |
+
echo "No input suites provided - determining from changes"
|
101 |
+
TAGS=()
|
102 |
+
# Add suites and tags based on changed files
|
103 |
+
if [[ "${{ steps.filter.outputs.components }}" == "true" ]]; then
|
104 |
+
SUITES=$(echo $SUITES | jq -c '. += ["components"]')
|
105 |
+
TAGS+=("@components")
|
106 |
+
echo "Added components suite"
|
107 |
+
fi
|
108 |
+
if [[ "${{ steps.filter.outputs.starter-projects }}" == "true" ]]; then
|
109 |
+
SUITES=$(echo $SUITES | jq -c '. += ["starter-projects"]')
|
110 |
+
TAGS+=("@starter-projects")
|
111 |
+
echo "Added starter-projects suite"
|
112 |
+
fi
|
113 |
+
if [[ "${{ steps.filter.outputs.workspace }}" == "true" ]]; then
|
114 |
+
SUITES=$(echo $SUITES | jq -c '. += ["workspace"]')
|
115 |
+
TAGS+=("@workspace")
|
116 |
+
echo "Added workspace suite"
|
117 |
+
fi
|
118 |
+
if [[ "${{ steps.filter.outputs.api }}" == "true" ]]; then
|
119 |
+
SUITES=$(echo $SUITES | jq -c '. += ["api"]')
|
120 |
+
TAGS+=("@api")
|
121 |
+
echo "Added api suite"
|
122 |
+
fi
|
123 |
+
if [[ "${{ steps.filter.outputs.database }}" == "true" ]]; then
|
124 |
+
SUITES=$(echo $SUITES | jq -c '. += ["database"]')
|
125 |
+
TAGS+=("@database")
|
126 |
+
echo "Added database suite"
|
127 |
+
fi
|
128 |
+
|
129 |
+
# Create grep pattern if we have tags
|
130 |
+
if [ ${#TAGS[@]} -gt 0 ]; then
|
131 |
+
# Join tags with | for OR logic
|
132 |
+
REGEX_PATTERN=$(IFS='|'; echo "${TAGS[*]}")
|
133 |
+
TEST_GREP="--grep=\"${REGEX_PATTERN}\""
|
134 |
+
fi
|
135 |
+
else
|
136 |
+
# Process input suites to tags
|
137 |
+
TAGS=()
|
138 |
+
if echo "$SUITES" | jq -e 'contains(["components"])' > /dev/null; then
|
139 |
+
TAGS+=("@components")
|
140 |
+
fi
|
141 |
+
if echo "$SUITES" | jq -e 'contains(["starter-projects"])' > /dev/null; then
|
142 |
+
TAGS+=("@starter-projects")
|
143 |
+
fi
|
144 |
+
if echo "$SUITES" | jq -e 'contains(["workspace"])' > /dev/null; then
|
145 |
+
TAGS+=("@workspace")
|
146 |
+
fi
|
147 |
+
if echo "$SUITES" | jq -e 'contains(["api"])' > /dev/null; then
|
148 |
+
TAGS+=("@api")
|
149 |
+
fi
|
150 |
+
if echo "$SUITES" | jq -e 'contains(["database"])' > /dev/null; then
|
151 |
+
TAGS+=("@database")
|
152 |
+
fi
|
153 |
+
|
154 |
+
if [ ${#TAGS[@]} -gt 0 ]; then
|
155 |
+
# Join tags with | for OR logic
|
156 |
+
REGEX_PATTERN=$(IFS='|'; echo "${TAGS[*]}")
|
157 |
+
TEST_GREP="--grep \"${REGEX_PATTERN}\""
|
158 |
+
fi
|
159 |
+
fi
|
160 |
+
fi
|
161 |
+
|
162 |
+
# Ensure compact JSON output
|
163 |
+
SUITES=$(echo "$SUITES" | jq -c '.')
|
164 |
+
|
165 |
+
echo "Final test suites to run: $SUITES"
|
166 |
+
echo "Test grep pattern: $TEST_GREP"
|
167 |
+
# Ensure proper JSON formatting for matrix output
|
168 |
+
echo "matrix=$(echo $SUITES | jq -c .)" >> $GITHUB_OUTPUT
|
169 |
+
echo "test_grep=$TEST_GREP" >> $GITHUB_OUTPUT
|
170 |
+
|
171 |
+
- name: Setup Node ${{ env.NODE_VERSION }}
|
172 |
+
uses: actions/setup-node@v4
|
173 |
+
id: setup-node
|
174 |
+
with:
|
175 |
+
node-version: ${{ env.NODE_VERSION }}
|
176 |
+
cache: "npm"
|
177 |
+
cache-dependency-path: ./src/frontend/package-lock.json
|
178 |
+
|
179 |
+
- name: Install Frontend Dependencies
|
180 |
+
run: npm ci
|
181 |
+
working-directory: ./src/frontend
|
182 |
+
|
183 |
+
- name: Calculate Test Shards Distribution
|
184 |
+
id: setup-matrix
|
185 |
+
run: |
|
186 |
+
cd src/frontend
|
187 |
+
|
188 |
+
# Get the test count using playwright's built-in grep
|
189 |
+
if [ -n "${{ steps.set-matrix.outputs.test_grep }}" ]; then
|
190 |
+
TEST_COUNT=$(npx playwright test ${{ inputs.tests_folder }} ${{ steps.set-matrix.outputs.test_grep }} --list | wc -l)
|
191 |
+
else
|
192 |
+
TEST_COUNT=$(npx playwright test ${{ inputs.tests_folder }} --list | wc -l)
|
193 |
+
fi
|
194 |
+
|
195 |
+
echo "Total tests to run: $TEST_COUNT"
|
196 |
+
|
197 |
+
# Calculate optimal shard count - 1 shard per 5 tests, min 1, max 10
|
198 |
+
SHARD_COUNT=$(( (TEST_COUNT + 4) / 5 ))
|
199 |
+
if [ $SHARD_COUNT -lt 1 ]; then
|
200 |
+
SHARD_COUNT=1
|
201 |
+
elif [ $SHARD_COUNT -gt 10 ]; then
|
202 |
+
SHARD_COUNT=10
|
203 |
+
fi
|
204 |
+
|
205 |
+
# Create the matrix combinations string
|
206 |
+
MATRIX_COMBINATIONS=""
|
207 |
+
for i in $(seq 1 $SHARD_COUNT); do
|
208 |
+
if [ $i -gt 1 ]; then
|
209 |
+
MATRIX_COMBINATIONS="$MATRIX_COMBINATIONS,"
|
210 |
+
fi
|
211 |
+
MATRIX_COMBINATIONS="$MATRIX_COMBINATIONS{\"shardIndex\": $i, \"shardTotal\": $SHARD_COUNT}"
|
212 |
+
done
|
213 |
+
|
214 |
+
echo "matrix={\"include\":[$MATRIX_COMBINATIONS]}" >> "$GITHUB_OUTPUT"
|
215 |
+
|
216 |
+
setup-and-test:
|
217 |
+
name: Playwright Tests - Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
218 |
+
runs-on: ubuntu-latest
|
219 |
+
if: ${{ needs.determine-test-suite.outputs.test_grep != '' }}
|
220 |
+
needs: determine-test-suite
|
221 |
+
strategy:
|
222 |
+
fail-fast: false
|
223 |
+
matrix: ${{ fromJson(needs.determine-test-suite.outputs.matrix) }}
|
224 |
+
env:
|
225 |
+
OPENAI_API_KEY: ${{ inputs.openai_api_key || secrets.OPENAI_API_KEY }}
|
226 |
+
STORE_API_KEY: ${{ inputs.store_api_key || secrets.STORE_API_KEY }}
|
227 |
+
SEARCH_API_KEY: "${{ secrets.SEARCH_API_KEY }}"
|
228 |
+
ASTRA_DB_APPLICATION_TOKEN: "${{ secrets.ASTRA_DB_APPLICATION_TOKEN }}"
|
229 |
+
ASTRA_DB_API_ENDPOINT: "${{ secrets.ASTRA_DB_API_ENDPOINT }}"
|
230 |
+
ANTHROPIC_API_KEY: "${{ secrets.ANTHROPIC_API_KEY }}"
|
231 |
+
TAVILY_API_KEY: "${{ secrets.TAVILY_API_KEY }}"
|
232 |
+
UV_CACHE_DIR: /tmp/.uv-cache
|
233 |
+
outputs:
|
234 |
+
failed: ${{ steps.check-failure.outputs.failed }}
|
235 |
+
steps:
|
236 |
+
- name: Checkout Repository
|
237 |
+
uses: actions/checkout@v4
|
238 |
+
with:
|
239 |
+
ref: ${{ inputs.ref || github.ref }}
|
240 |
+
|
241 |
+
- name: Setup Node.js Environment
|
242 |
+
uses: actions/setup-node@v4
|
243 |
+
id: setup-node
|
244 |
+
with:
|
245 |
+
node-version: ${{ env.NODE_VERSION }}
|
246 |
+
cache: "npm"
|
247 |
+
cache-dependency-path: ./src/frontend/package-lock.json
|
248 |
+
|
249 |
+
- name: Install Frontend Dependencies
|
250 |
+
run: npm ci
|
251 |
+
working-directory: ./src/frontend
|
252 |
+
|
253 |
+
- name: Install Playwright Browser Dependencies
|
254 |
+
id: install-playwright
|
255 |
+
uses: ./.github/actions/install-playwright
|
256 |
+
with:
|
257 |
+
working-directory: ./src/frontend
|
258 |
+
browsers: chromium
|
259 |
+
|
260 |
+
- name: Setup Python Environment with UV
|
261 |
+
uses: ./.github/actions/setup-uv
|
262 |
+
|
263 |
+
- name: Install Python Dependencies
|
264 |
+
run: uv sync --dev
|
265 |
+
|
266 |
+
- name: Configure Environment Variables
|
267 |
+
run: |
|
268 |
+
touch .env
|
269 |
+
echo "${{ secrets.ENV_VARS }}" > .env
|
270 |
+
|
271 |
+
- name: Execute Playwright Tests
|
272 |
+
uses: nick-fields/retry@v3
|
273 |
+
with:
|
274 |
+
timeout_minutes: 12
|
275 |
+
max_attempts: 2
|
276 |
+
command: |
|
277 |
+
cd src/frontend
|
278 |
+
echo 'Running tests with pattern: ${{ needs.determine-test-suite.outputs.test_grep }}'
|
279 |
+
npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --list
|
280 |
+
# echo command before running
|
281 |
+
echo "npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2"
|
282 |
+
|
283 |
+
npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2
|
284 |
+
|
285 |
+
- name: Upload Test Results
|
286 |
+
if: always()
|
287 |
+
uses: actions/upload-artifact@v4
|
288 |
+
with:
|
289 |
+
name: blob-report-${{ matrix.shardIndex }}
|
290 |
+
path: src/frontend/blob-report
|
291 |
+
retention-days: 1
|
292 |
+
|
293 |
+
- name: Cleanup UV Cache
|
294 |
+
run: uv cache prune --ci
|
295 |
+
|
296 |
+
merge-reports:
|
297 |
+
# We need to repeat the condition at every step
|
298 |
+
# https://github.com/actions/runner/issues/662
|
299 |
+
needs: setup-and-test
|
300 |
+
runs-on: ubuntu-latest
|
301 |
+
if: always()
|
302 |
+
env:
|
303 |
+
EXIT_CODE: ${{!contains(needs.setup-and-test.result, 'failure') && !contains(needs.setup-and-test.result, 'cancelled') && '0' || '1'}}
|
304 |
+
steps:
|
305 |
+
- name: "Should Merge Reports"
|
306 |
+
# If the CI was successful, we don't need to merge the reports
|
307 |
+
# so we can skip all the steps below
|
308 |
+
id: should_merge_reports
|
309 |
+
run: |
|
310 |
+
if [ "$EXIT_CODE" == "0" ]; then
|
311 |
+
echo "should_merge_reports=false" >> $GITHUB_OUTPUT
|
312 |
+
else
|
313 |
+
echo "should_merge_reports=true" >> $GITHUB_OUTPUT
|
314 |
+
fi
|
315 |
+
- name: Checkout code
|
316 |
+
if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
|
317 |
+
uses: actions/checkout@v4
|
318 |
+
|
319 |
+
- name: Setup Node.js
|
320 |
+
|
321 |
+
if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
|
322 |
+
uses: actions/setup-node@v4
|
323 |
+
with:
|
324 |
+
node-version: ${{ env.NODE_VERSION }}
|
325 |
+
|
326 |
+
- name: Download blob reports from GitHub Actions Artifacts
|
327 |
+
|
328 |
+
if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
|
329 |
+
uses: actions/download-artifact@v4
|
330 |
+
with:
|
331 |
+
path: all-blob-reports
|
332 |
+
pattern: blob-report-*
|
333 |
+
merge-multiple: true
|
334 |
+
|
335 |
+
- name: Merge into HTML Report
|
336 |
+
|
337 |
+
if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
|
338 |
+
run: |
|
339 |
+
npx playwright merge-reports --reporter html ./all-blob-reports
|
340 |
+
|
341 |
+
- name: Upload HTML report
|
342 |
+
|
343 |
+
if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
|
344 |
+
uses: actions/upload-artifact@v4
|
345 |
+
with:
|
346 |
+
name: html-report--attempt-${{ github.run_attempt }}
|
347 |
+
path: playwright-report
|
348 |
+
retention-days: 14
|
.gitignore
ADDED
@@ -0,0 +1,279 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This is to avoid Opencommit hook from getting pushed
|
2 |
+
prepare-commit-msg
|
3 |
+
# Logs
|
4 |
+
logs
|
5 |
+
*.log
|
6 |
+
npm-debug.log*
|
7 |
+
yarn-debug.log*
|
8 |
+
yarn-error.log*
|
9 |
+
lerna-debug.log*
|
10 |
+
qdrant_storage
|
11 |
+
|
12 |
+
.dspy_cache
|
13 |
+
# Mac
|
14 |
+
.DS_Store
|
15 |
+
|
16 |
+
# VSCode
|
17 |
+
.vscode/settings.json
|
18 |
+
.chroma
|
19 |
+
.ruff_cache
|
20 |
+
|
21 |
+
# PyCharm
|
22 |
+
.idea/
|
23 |
+
|
24 |
+
# Diagnostic reports (https://nodejs.org/api/report.html)
|
25 |
+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
26 |
+
|
27 |
+
# Runtime data
|
28 |
+
pids
|
29 |
+
*.pid
|
30 |
+
*.seed
|
31 |
+
*.pid.lock
|
32 |
+
|
33 |
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
34 |
+
lib-cov
|
35 |
+
|
36 |
+
# Coverage directory used by tools like istanbul
|
37 |
+
coverage
|
38 |
+
*.lcov
|
39 |
+
|
40 |
+
# nyc test coverage
|
41 |
+
.nyc_output
|
42 |
+
|
43 |
+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
44 |
+
.grunt
|
45 |
+
|
46 |
+
# Bower dependency directory (https://bower.io/)
|
47 |
+
bower_components
|
48 |
+
|
49 |
+
# node-waf configuration
|
50 |
+
.lock-wscript
|
51 |
+
|
52 |
+
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
53 |
+
build/Release
|
54 |
+
|
55 |
+
# Dependency directories
|
56 |
+
node_modules/
|
57 |
+
jspm_packages/
|
58 |
+
|
59 |
+
# TypeScript v1 declaration files
|
60 |
+
typings/
|
61 |
+
|
62 |
+
# TypeScript cache
|
63 |
+
*.tsbuildinfo
|
64 |
+
|
65 |
+
# Optional npm cache directory
|
66 |
+
.npm
|
67 |
+
|
68 |
+
# Optional eslint cache
|
69 |
+
.eslintcache
|
70 |
+
|
71 |
+
# Microbundle cache
|
72 |
+
.rpt2_cache/
|
73 |
+
.rts2_cache_cjs/
|
74 |
+
.rts2_cache_es/
|
75 |
+
.rts2_cache_umd/
|
76 |
+
|
77 |
+
# Optional REPL history
|
78 |
+
.node_repl_history
|
79 |
+
|
80 |
+
# Output of 'npm pack'
|
81 |
+
*.tgz
|
82 |
+
|
83 |
+
# Yarn Integrity file
|
84 |
+
.yarn-integrity
|
85 |
+
|
86 |
+
# dotenv environment variables file
|
87 |
+
.env
|
88 |
+
.env.test
|
89 |
+
|
90 |
+
# parcel-bundler cache (https://parceljs.org/)
|
91 |
+
.cache
|
92 |
+
|
93 |
+
# Next.js build output
|
94 |
+
.next
|
95 |
+
|
96 |
+
# Nuxt.js build / generate output
|
97 |
+
.nuxt
|
98 |
+
dist
|
99 |
+
|
100 |
+
# Gatsby files
|
101 |
+
.cache/
|
102 |
+
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
103 |
+
# https://nextjs.org/blog/next-9-1#public-directory-support
|
104 |
+
# public
|
105 |
+
|
106 |
+
# vuepress build output
|
107 |
+
.vuepress/dist
|
108 |
+
|
109 |
+
# Serverless directories
|
110 |
+
.serverless/
|
111 |
+
|
112 |
+
# FuseBox cache
|
113 |
+
.fusebox/
|
114 |
+
|
115 |
+
# DynamoDB Local files
|
116 |
+
.dynamodb/
|
117 |
+
|
118 |
+
# TernJS port file
|
119 |
+
.tern-port
|
120 |
+
# Byte-compiled / optimized / DLL files
|
121 |
+
__pycache__/
|
122 |
+
*.py[cod]
|
123 |
+
*$py.class
|
124 |
+
notebooks
|
125 |
+
|
126 |
+
# C extensions
|
127 |
+
*.so
|
128 |
+
|
129 |
+
# Distribution / packaging
|
130 |
+
.Python
|
131 |
+
build/
|
132 |
+
develop-eggs/
|
133 |
+
dist/
|
134 |
+
downloads/
|
135 |
+
eggs/
|
136 |
+
.eggs/
|
137 |
+
lib/
|
138 |
+
lib64/
|
139 |
+
parts/
|
140 |
+
sdist/
|
141 |
+
var/
|
142 |
+
wheels/
|
143 |
+
pip-wheel-metadata/
|
144 |
+
share/python-wheels/
|
145 |
+
*.egg-info/
|
146 |
+
.installed.cfg
|
147 |
+
*.egg
|
148 |
+
MANIFEST
|
149 |
+
|
150 |
+
# PyInstaller
|
151 |
+
# Usually these files are written by a python script from a template
|
152 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
153 |
+
*.manifest
|
154 |
+
*.spec
|
155 |
+
|
156 |
+
# Installer logs
|
157 |
+
pip-log.txt
|
158 |
+
pip-delete-this-directory.txt
|
159 |
+
|
160 |
+
# Unit test / coverage reports
|
161 |
+
htmlcov/
|
162 |
+
.tox/
|
163 |
+
.nox/
|
164 |
+
.coverage
|
165 |
+
.coverage.*
|
166 |
+
.cache
|
167 |
+
nosetests.xml
|
168 |
+
coverage.xml
|
169 |
+
*.cover
|
170 |
+
*.py,cover
|
171 |
+
.hypothesis/
|
172 |
+
.pytest_cache/
|
173 |
+
.testmondata*
|
174 |
+
|
175 |
+
# Translations
|
176 |
+
*.mo
|
177 |
+
*.pot
|
178 |
+
|
179 |
+
# Django stuff:
|
180 |
+
*.log
|
181 |
+
local_settings.py
|
182 |
+
db.sqlite3
|
183 |
+
db.sqlite3-journal
|
184 |
+
*.db-shm
|
185 |
+
*.db-wal
|
186 |
+
|
187 |
+
# Flask stuff:
|
188 |
+
instance/
|
189 |
+
.webassets-cache
|
190 |
+
|
191 |
+
# Scrapy stuff:
|
192 |
+
.scrapy
|
193 |
+
|
194 |
+
# Sphinx documentation
|
195 |
+
docs/_build/
|
196 |
+
|
197 |
+
# PyBuilder
|
198 |
+
target/
|
199 |
+
|
200 |
+
# Jupyter Notebook
|
201 |
+
.ipynb_checkpoints
|
202 |
+
|
203 |
+
# IPython
|
204 |
+
profile_default/
|
205 |
+
ipython_config.py
|
206 |
+
|
207 |
+
# pyenv
|
208 |
+
.python-version
|
209 |
+
|
210 |
+
# pipenv
|
211 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
212 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
213 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
214 |
+
# install all needed dependencies.
|
215 |
+
#Pipfile.lock
|
216 |
+
|
217 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
218 |
+
__pypackages__/
|
219 |
+
|
220 |
+
# Celery stuff
|
221 |
+
celerybeat-schedule
|
222 |
+
celerybeat.pid
|
223 |
+
|
224 |
+
# SageMath parsed files
|
225 |
+
*.sage.py
|
226 |
+
|
227 |
+
# Environments
|
228 |
+
.env
|
229 |
+
.venv
|
230 |
+
env/
|
231 |
+
venv/
|
232 |
+
ENV/
|
233 |
+
env.bak/
|
234 |
+
venv.bak/
|
235 |
+
|
236 |
+
# Spyder project settings
|
237 |
+
.spyderproject
|
238 |
+
.spyproject
|
239 |
+
|
240 |
+
# Rope project settings
|
241 |
+
.ropeproject
|
242 |
+
|
243 |
+
# mkdocs documentation
|
244 |
+
/site
|
245 |
+
|
246 |
+
# mypy
|
247 |
+
.mypy_cache/
|
248 |
+
.dmypy.json
|
249 |
+
dmypy.json
|
250 |
+
|
251 |
+
# Poetry
|
252 |
+
.testenv/*
|
253 |
+
langflow.db
|
254 |
+
|
255 |
+
|
256 |
+
.githooks/prepare-commit-msg
|
257 |
+
.langchain.db
|
258 |
+
|
259 |
+
# docusaurus
|
260 |
+
.docusaurus/
|
261 |
+
|
262 |
+
/tmp/*
|
263 |
+
src/backend/langflow/frontend/
|
264 |
+
src/backend/base/langflow/frontend/
|
265 |
+
.docker
|
266 |
+
scratchpad*
|
267 |
+
chroma*/*
|
268 |
+
stuff/*
|
269 |
+
src/frontend/playwright-report/index.html
|
270 |
+
*.bak
|
271 |
+
prof/*
|
272 |
+
|
273 |
+
src/frontend/temp
|
274 |
+
*-shm
|
275 |
+
*-wal
|
276 |
+
.history
|
277 |
+
|
278 |
+
.dspy_cache/
|
279 |
+
*.db
|
.pre-commit-config.yaml
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
repos:
|
2 |
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
3 |
+
rev: v4.1.0
|
4 |
+
hooks:
|
5 |
+
- id: check-case-conflict
|
6 |
+
- id: end-of-file-fixer
|
7 |
+
# python, js and ts only
|
8 |
+
files: \.(py|js|ts)$
|
9 |
+
- id: mixed-line-ending
|
10 |
+
files: \.(py|js|ts)$
|
11 |
+
args:
|
12 |
+
- --fix=lf
|
13 |
+
- id: trailing-whitespace
|
14 |
+
- repo: local
|
15 |
+
hooks:
|
16 |
+
- id: ruff-check
|
17 |
+
name: ruff check
|
18 |
+
language: system
|
19 |
+
entry: bash -c "uv run ruff check"
|
20 |
+
types: [file, python]
|
21 |
+
- id: ruff-format
|
22 |
+
name: ruff format
|
23 |
+
language: system
|
24 |
+
entry: bash -c "uv run ruff format"
|
25 |
+
types: [file, python]
|
.vscode/launch.json
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"version": "0.2.0",
|
3 |
+
"configurations": [
|
4 |
+
{
|
5 |
+
"name": "Debug Backend",
|
6 |
+
"type": "debugpy",
|
7 |
+
"request": "launch",
|
8 |
+
"module": "uvicorn",
|
9 |
+
"preLaunchTask": "Install Backend",
|
10 |
+
|
11 |
+
"args": [
|
12 |
+
"--factory",
|
13 |
+
"langflow.main:create_app",
|
14 |
+
"--port",
|
15 |
+
"7860",
|
16 |
+
"--reload",
|
17 |
+
"--log-level",
|
18 |
+
"debug",
|
19 |
+
"--loop",
|
20 |
+
"asyncio",
|
21 |
+
"--reload-include",
|
22 |
+
"./src/backend/*"
|
23 |
+
],
|
24 |
+
"jinja": true,
|
25 |
+
"justMyCode": false,
|
26 |
+
"env": {
|
27 |
+
"LANGFLOW_LOG_LEVEL": "debug",
|
28 |
+
"LANGFLOW_PROMETHEUS_PORT": "9090"
|
29 |
+
},
|
30 |
+
"envFile": "${workspaceFolder}/.env"
|
31 |
+
},
|
32 |
+
{
|
33 |
+
"name": "Debug CLI",
|
34 |
+
"type": "debugpy",
|
35 |
+
"request": "launch",
|
36 |
+
"module": "langflow",
|
37 |
+
"args": [
|
38 |
+
"run",
|
39 |
+
"--path",
|
40 |
+
"${workspaceFolder}/src/backend/base/langflow/frontend",
|
41 |
+
"--env-file",
|
42 |
+
"${workspaceFolder}/.env"
|
43 |
+
],
|
44 |
+
// "python": "/path/to/your/python_env/python", // Replace with the path to your Python executable
|
45 |
+
"jinja": true,
|
46 |
+
"justMyCode": false
|
47 |
+
},
|
48 |
+
{
|
49 |
+
"name": "Python: Remote Attach",
|
50 |
+
"type": "debugpy",
|
51 |
+
"request": "attach",
|
52 |
+
"justMyCode": true,
|
53 |
+
"connect": {
|
54 |
+
"port": 5678
|
55 |
+
},
|
56 |
+
"pathMappings": [
|
57 |
+
{
|
58 |
+
"localRoot": "${workspaceFolder}",
|
59 |
+
"remoteRoot": "."
|
60 |
+
}
|
61 |
+
]
|
62 |
+
},
|
63 |
+
{
|
64 |
+
"name": "Debug Frontend",
|
65 |
+
"type": "chrome",
|
66 |
+
"request": "launch",
|
67 |
+
"url": "http://localhost:3000/",
|
68 |
+
"webRoot": "${workspaceRoot}/src/frontend"
|
69 |
+
},
|
70 |
+
{
|
71 |
+
"name": "Python: Debug Tests",
|
72 |
+
"type": "debugpy",
|
73 |
+
"request": "launch",
|
74 |
+
"program": "${file}",
|
75 |
+
"purpose": ["debug-test"],
|
76 |
+
"console": "integratedTerminal",
|
77 |
+
"justMyCode": false
|
78 |
+
}
|
79 |
+
]
|
80 |
+
}
|
.vscode/tasks.json
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
3 |
+
// for the documentation about the tasks.json format
|
4 |
+
"version": "2.0.0",
|
5 |
+
"tasks": [
|
6 |
+
{
|
7 |
+
"label": "Init",
|
8 |
+
"type": "shell",
|
9 |
+
"command": "make init"
|
10 |
+
},
|
11 |
+
// make backend
|
12 |
+
{
|
13 |
+
"label": "Backend",
|
14 |
+
"type": "shell",
|
15 |
+
"command": "make backend"
|
16 |
+
},
|
17 |
+
// make frontend
|
18 |
+
{
|
19 |
+
"label": "Frontend",
|
20 |
+
"type": "shell",
|
21 |
+
"command": "make frontend"
|
22 |
+
},
|
23 |
+
// make test
|
24 |
+
{
|
25 |
+
"label": "Test",
|
26 |
+
"type": "shell",
|
27 |
+
"command": "make unit_tests"
|
28 |
+
},
|
29 |
+
// make lint
|
30 |
+
{
|
31 |
+
"label": "Lint",
|
32 |
+
"type": "shell",
|
33 |
+
"command": "make lint"
|
34 |
+
},
|
35 |
+
// make format
|
36 |
+
{
|
37 |
+
"label": "Format",
|
38 |
+
"type": "shell",
|
39 |
+
"command": "make format"
|
40 |
+
},
|
41 |
+
// make install
|
42 |
+
{
|
43 |
+
"label": "Install",
|
44 |
+
"type": "shell",
|
45 |
+
"command": "make install_backend && make install_frontend"
|
46 |
+
},
|
47 |
+
// install backend
|
48 |
+
{
|
49 |
+
"label": "Install Backend",
|
50 |
+
"type": "shell",
|
51 |
+
"command": "make install_backend"
|
52 |
+
}
|
53 |
+
]
|
54 |
+
}
|
CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Contributor Covenant Code of Conduct
|
2 |
+
|
3 |
+
## Our Pledge
|
4 |
+
|
5 |
+
We as members, contributors, and leaders pledge to make participation in our
|
6 |
+
community a harassment-free experience for everyone, regardless of age, body
|
7 |
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
8 |
+
identity and expression, level of experience, education, socioeconomic status,
|
9 |
+
nationality, personal appearance, race, religion, or sexual identity
|
10 |
+
and orientation.
|
11 |
+
|
12 |
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
13 |
+
diverse, inclusive, and healthy community.
|
14 |
+
|
15 |
+
## Our Standards
|
16 |
+
|
17 |
+
Examples of behavior that contributes to a positive environment for our
|
18 |
+
community include:
|
19 |
+
|
20 |
+
- Demonstrating empathy and kindness toward other people
|
21 |
+
- Being respectful of differing opinions, viewpoints, and experiences
|
22 |
+
- Giving and gracefully accepting constructive feedback
|
23 |
+
- Accepting responsibility and apologizing to those affected by our mistakes,
|
24 |
+
and learning from the experience
|
25 |
+
- Focusing on what is best not just for us as individuals, but for the
|
26 |
+
overall community
|
27 |
+
|
28 |
+
Examples of unacceptable behavior include:
|
29 |
+
|
30 |
+
- The use of sexualized language or imagery, and sexual attention or
|
31 |
+
advances of any kind
|
32 |
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
33 |
+
- Public or private harassment
|
34 |
+
- Publishing others' private information, such as a physical or email
|
35 |
+
address, without their explicit permission
|
36 |
+
- Other conduct which could reasonably be considered inappropriate in a
|
37 |
+
professional setting
|
38 |
+
|
39 |
+
## Enforcement Responsibilities
|
40 |
+
|
41 |
+
Community leaders are responsible for clarifying and enforcing our standards of
|
42 |
+
acceptable behavior and will take appropriate and fair corrective action in
|
43 |
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
44 |
+
or harmful.
|
45 |
+
|
46 |
+
Community leaders have the right and responsibility to remove, edit, or reject
|
47 |
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
48 |
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
49 |
+
decisions when appropriate.
|
50 |
+
|
51 |
+
## Scope
|
52 |
+
|
53 |
+
This Code of Conduct applies within all community spaces, and also applies when
|
54 |
+
an individual is officially representing the community in public spaces.
|
55 |
+
Examples of representing our community include using an official e-mail address,
|
56 |
+
posting via an official social media account, or acting as an appointed
|
57 |
+
representative at an online or offline event.
|
58 |
+
|
59 |
+
## Enforcement
|
60 |
+
|
61 |
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
62 |
+
reported to the community leaders responsible for enforcement at
|
63 |
+
contact@langflow.org.
|
64 |
+
All complaints will be reviewed and investigated promptly and fairly.
|
65 |
+
|
66 |
+
All community leaders are obligated to respect the privacy and security of the
|
67 |
+
reporter of any incident.
|
68 |
+
|
69 |
+
## Enforcement Guidelines
|
70 |
+
|
71 |
+
Community leaders will follow these Community Impact Guidelines in determining
|
72 |
+
the consequences for any action they deem in violation of this Code of Conduct:
|
73 |
+
|
74 |
+
### 1. Correction
|
75 |
+
|
76 |
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
77 |
+
unprofessional or unwelcome in the community.
|
78 |
+
|
79 |
+
**Consequence**: A private, written warning from community leaders, providing
|
80 |
+
clarity around the nature of the violation and an explanation of why the
|
81 |
+
behavior was inappropriate. A public apology may be requested.
|
82 |
+
|
83 |
+
### 2. Warning
|
84 |
+
|
85 |
+
**Community Impact**: A violation through a single incident or series
|
86 |
+
of actions.
|
87 |
+
|
88 |
+
**Consequence**: A warning with consequences for continued behavior. No
|
89 |
+
interaction with the people involved, including unsolicited interaction with
|
90 |
+
those enforcing the Code of Conduct, for a specified period of time. This
|
91 |
+
includes avoiding interactions in community spaces as well as external channels
|
92 |
+
like social media. Violating these terms may lead to a temporary or
|
93 |
+
permanent ban.
|
94 |
+
|
95 |
+
### 3. Temporary Ban
|
96 |
+
|
97 |
+
**Community Impact**: A serious violation of community standards, including
|
98 |
+
sustained inappropriate behavior.
|
99 |
+
|
100 |
+
**Consequence**: A temporary ban from any sort of interaction or public
|
101 |
+
communication with the community for a specified period of time. No public or
|
102 |
+
private interaction with the people involved, including unsolicited interaction
|
103 |
+
with those enforcing the Code of Conduct, is allowed during this period.
|
104 |
+
Violating these terms may lead to a permanent ban.
|
105 |
+
|
106 |
+
### 4. Permanent Ban
|
107 |
+
|
108 |
+
**Community Impact**: Demonstrating a pattern of violation of community
|
109 |
+
standards, including sustained inappropriate behavior, harassment of an
|
110 |
+
individual, or aggression toward or disparagement of classes of individuals.
|
111 |
+
|
112 |
+
**Consequence**: A permanent ban from any sort of public interaction within
|
113 |
+
the community.
|
114 |
+
|
115 |
+
## Attribution
|
116 |
+
|
117 |
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
118 |
+
version 2.0, available at
|
119 |
+
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
120 |
+
|
121 |
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
122 |
+
enforcement ladder](https://github.com/mozilla/diversity).
|
123 |
+
|
124 |
+
[homepage]: https://www.contributor-covenant.org
|
125 |
+
|
126 |
+
For answers to common questions about this code of conduct, see the FAQ at
|
127 |
+
https://www.contributor-covenant.org/faq. Translations are available at
|
128 |
+
https://www.contributor-covenant.org/translations.
|
CONTRIBUTING.md
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Contributing to Langflow
|
2 |
+
|
3 |
+
This guide is intended to help you get started contributing to Langflow.
|
4 |
+
As an open-source project in a rapidly developing field, we are extremely open
|
5 |
+
to contributions, whether it be in the form of a new feature, improved infra, or better documentation.
|
6 |
+
|
7 |
+
To contribute to this project, please follow the [fork and pull request](https://docs.github.com/en/get-started/quickstart/contributing-to-projects) workflow.
|
8 |
+
|
9 |
+
## Reporting bugs or suggesting improvements
|
10 |
+
|
11 |
+
Our [GitHub issues](https://github.com/langflow-ai/langflow/issues) page is kept up to date
|
12 |
+
with bugs, improvements, and feature requests. There is a taxonomy of labels to help
|
13 |
+
with sorting and discovery of issues of interest. [See this page](https://github.com/langflow-ai/langflow/labels) for an overview of
|
14 |
+
the system we use to tag our issues and pull requests.
|
15 |
+
|
16 |
+
If you're looking for help with your code, consider posting a question on the
|
17 |
+
[GitHub Discussions board](https://github.com/langflow-ai/langflow/discussions). Please
|
18 |
+
understand that we won't be able to provide individual support via email. We
|
19 |
+
also believe that help is much more valuable if it's **shared publicly**,
|
20 |
+
so that more people can benefit from it.
|
21 |
+
|
22 |
+
- **Describing your issue:** Try to provide as many details as possible. What
|
23 |
+
exactly goes wrong? _How_ is it failing? Is there an error?
|
24 |
+
"XY doesn't work" usually isn't that helpful for tracking down problems. Always
|
25 |
+
remember to include the code you ran and if possible, extract only the relevant
|
26 |
+
parts and don't just dump your entire script. This will make it easier for us to
|
27 |
+
reproduce the error.
|
28 |
+
|
29 |
+
- **Sharing long blocks of code or logs:** If you need to include long code,
|
30 |
+
logs or tracebacks, you can wrap them in `<details>` and `</details>`. This
|
31 |
+
[collapses the content](https://developer.mozilla.org/en/docs/Web/HTML/Element/details)
|
32 |
+
so it only becomes visible on click, making the issue easier to read and follow.
|
33 |
+
|
34 |
+
## Contributing code and documentation
|
35 |
+
|
36 |
+
You can develop Langflow locally via uv + NodeJS.
|
37 |
+
|
38 |
+
### Clone the Langflow Repository
|
39 |
+
|
40 |
+
Navigate to the [Langflow GitHub repository](https://github.com/langflow-ai/langflow) and press "Fork" in the upper right-hand corner.
|
41 |
+
|
42 |
+
Add the new remote to your local repository on your local machine:
|
43 |
+
|
44 |
+
```bash
|
45 |
+
git remote add fork https://github.com/<your username>/langflow.git
|
46 |
+
```
|
47 |
+
|
48 |
+
We also provide a .vscode/launch.json file for debugging the backend in VSCode, which is a lot faster than using docker compose.
|
49 |
+
|
50 |
+
### Prepare the environment
|
51 |
+
|
52 |
+
Setting up hooks:
|
53 |
+
|
54 |
+
```bash
|
55 |
+
make init
|
56 |
+
```
|
57 |
+
|
58 |
+
This will set up the development environment by installing backend and frontend dependencies, building the frontend static files, and initializing the project. It runs `make install_backend`, `make install_frontend`, `make build_frontend`, and finally `uv run langflow run` to start the application.
|
59 |
+
|
60 |
+
It is advised to run `make lint`, `make format`, and `make unit_tests` before pushing to the repository.
|
61 |
+
|
62 |
+
### Run locally (uv and Node.js)
|
63 |
+
|
64 |
+
Langflow can run locally by cloning the repository and installing the dependencies. We recommend using a virtual environment to isolate the dependencies from your system.
|
65 |
+
|
66 |
+
Before you start, make sure you have the following installed:
|
67 |
+
|
68 |
+
- uv (>=0.4)
|
69 |
+
- Node.js
|
70 |
+
|
71 |
+
Then, in the root folder, install the dependencies and start the development server for the backend:
|
72 |
+
|
73 |
+
```bash
|
74 |
+
make backend
|
75 |
+
```
|
76 |
+
|
77 |
+
And the frontend:
|
78 |
+
|
79 |
+
```bash
|
80 |
+
make frontend
|
81 |
+
```
|
82 |
+
|
83 |
+
### Run documentation
|
84 |
+
|
85 |
+
The documentation is built using [Docusaurus](https://docusaurus.io/). To run the documentation locally, run the following commands:
|
86 |
+
|
87 |
+
```bash
|
88 |
+
cd docs
|
89 |
+
npm install
|
90 |
+
npm run start
|
91 |
+
```
|
92 |
+
|
93 |
+
The documentation will be available at `localhost:3000` and all the files are located in the `docs/docs` folder.
|
94 |
+
|
95 |
+
## Opening a pull request
|
96 |
+
|
97 |
+
Once you wrote and manually tested your change, you can start sending the patch to the main repository.
|
98 |
+
|
99 |
+
- Open a new GitHub pull request with the patch against the `main` branch.
|
100 |
+
- Ensure the PR title follows semantic commits conventions.
|
101 |
+
- For example, `feat: add new feature`, `fix: correct issue with X`.
|
102 |
+
- Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
|
LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2024 Langflow
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
Makefile
ADDED
@@ -0,0 +1,446 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.PHONY: all init format lint build build_frontend install_frontend run_frontend run_backend dev help tests coverage clean_python_cache clean_npm_cache clean_all
|
2 |
+
|
3 |
+
# Configurations
|
4 |
+
VERSION=$(shell grep "^version" pyproject.toml | sed 's/.*\"\(.*\)\"$$/\1/')
|
5 |
+
DOCKERFILE=docker/build_and_push.Dockerfile
|
6 |
+
DOCKERFILE_BACKEND=docker/build_and_push_backend.Dockerfile
|
7 |
+
DOCKERFILE_FRONTEND=docker/frontend/build_and_push_frontend.Dockerfile
|
8 |
+
DOCKER_COMPOSE=docker_example/docker-compose.yml
|
9 |
+
PYTHON_REQUIRED=$(shell grep '^requires-python[[:space:]]*=' pyproject.toml | sed -n 's/.*"\([^"]*\)".*/\1/p')
|
10 |
+
RED=\033[0;31m
|
11 |
+
NC=\033[0m # No Color
|
12 |
+
GREEN=\033[0;32m
|
13 |
+
|
14 |
+
log_level ?= debug
|
15 |
+
host ?= 0.0.0.0
|
16 |
+
port ?= 7860
|
17 |
+
env ?= .env
|
18 |
+
open_browser ?= true
|
19 |
+
path = src/backend/base/langflow/frontend
|
20 |
+
workers ?= 1
|
21 |
+
async ?= true
|
22 |
+
lf ?= false
|
23 |
+
ff ?= true
|
24 |
+
all: help
|
25 |
+
|
26 |
+
######################
|
27 |
+
# UTILITIES
|
28 |
+
######################
|
29 |
+
|
30 |
+
# increment the patch version of the current package
|
31 |
+
patch: ## bump the version in langflow and langflow-base
|
32 |
+
@echo 'Patching the version'
|
33 |
+
@poetry version patch
|
34 |
+
@echo 'Patching the version in langflow-base'
|
35 |
+
@cd src/backend/base && poetry version patch
|
36 |
+
@make lock
|
37 |
+
|
38 |
+
# check for required tools
|
39 |
+
check_tools:
|
40 |
+
@command -v uv >/dev/null 2>&1 || { echo >&2 "$(RED)uv is not installed. Aborting.$(NC)"; exit 1; }
|
41 |
+
@command -v npm >/dev/null 2>&1 || { echo >&2 "$(RED)NPM is not installed. Aborting.$(NC)"; exit 1; }
|
42 |
+
@echo "$(GREEN)All required tools are installed.$(NC)"
|
43 |
+
|
44 |
+
|
45 |
+
help: ## show this help message
|
46 |
+
@echo '----'
|
47 |
+
@grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | \
|
48 |
+
awk -F ':.*##' '{printf "\033[36mmake %s\033[0m: %s\n", $$1, $$2}' | \
|
49 |
+
column -c2 -t -s :
|
50 |
+
@echo '----'
|
51 |
+
|
52 |
+
######################
|
53 |
+
# INSTALL PROJECT
|
54 |
+
######################
|
55 |
+
|
56 |
+
reinstall_backend: ## forces reinstall all dependencies (no caching)
|
57 |
+
@echo 'Installing backend dependencies'
|
58 |
+
@uv sync -n --reinstall --frozen
|
59 |
+
|
60 |
+
install_backend: ## install the backend dependencies
|
61 |
+
@echo 'Installing backend dependencies'
|
62 |
+
@uv sync --frozen
|
63 |
+
|
64 |
+
install_frontend: ## install the frontend dependencies
|
65 |
+
@echo 'Installing frontend dependencies'
|
66 |
+
@cd src/frontend && npm install > /dev/null 2>&1
|
67 |
+
|
68 |
+
build_frontend: ## build the frontend static files
|
69 |
+
@echo 'Building frontend static files'
|
70 |
+
@cd src/frontend && CI='' npm run build > /dev/null 2>&1
|
71 |
+
@rm -rf src/backend/base/langflow/frontend
|
72 |
+
@cp -r src/frontend/build src/backend/base/langflow/frontend
|
73 |
+
|
74 |
+
init: check_tools clean_python_cache clean_npm_cache ## initialize the project
|
75 |
+
@make install_backend
|
76 |
+
@make install_frontend
|
77 |
+
@make build_frontend
|
78 |
+
@echo "$(GREEN)All requirements are installed.$(NC)"
|
79 |
+
@uv run langflow run
|
80 |
+
|
81 |
+
######################
|
82 |
+
# CLEAN PROJECT
|
83 |
+
######################
|
84 |
+
|
85 |
+
clean_python_cache:
|
86 |
+
@echo "Cleaning Python cache..."
|
87 |
+
find . -type d -name '__pycache__' -exec rm -r {} +
|
88 |
+
find . -type f -name '*.py[cod]' -exec rm -f {} +
|
89 |
+
find . -type f -name '*~' -exec rm -f {} +
|
90 |
+
find . -type f -name '.*~' -exec rm -f {} +
|
91 |
+
find . -type d -empty -delete
|
92 |
+
@echo "$(GREEN)Python cache cleaned.$(NC)"
|
93 |
+
|
94 |
+
clean_npm_cache:
|
95 |
+
@echo "Cleaning npm cache..."
|
96 |
+
cd src/frontend && npm cache clean --force
|
97 |
+
rm -rf src/frontend/node_modules src/frontend/build src/backend/base/langflow/frontend src/frontend/package-lock.json
|
98 |
+
@echo "$(GREEN)NPM cache and frontend directories cleaned.$(NC)"
|
99 |
+
|
100 |
+
clean_all: clean_python_cache clean_npm_cache # clean all caches and temporary directories
|
101 |
+
@echo "$(GREEN)All caches and temporary directories cleaned.$(NC)"
|
102 |
+
|
103 |
+
setup_uv: ## install poetry using pipx
|
104 |
+
pipx install uv
|
105 |
+
|
106 |
+
add:
|
107 |
+
@echo 'Adding dependencies'
|
108 |
+
ifdef devel
|
109 |
+
@cd src/backend/base && uv add --group dev $(devel)
|
110 |
+
endif
|
111 |
+
|
112 |
+
ifdef main
|
113 |
+
@uv add $(main)
|
114 |
+
endif
|
115 |
+
|
116 |
+
ifdef base
|
117 |
+
@cd src/backend/base && uv add $(base)
|
118 |
+
endif
|
119 |
+
|
120 |
+
|
121 |
+
|
122 |
+
######################
|
123 |
+
# CODE TESTS
|
124 |
+
######################
|
125 |
+
|
126 |
+
coverage: ## run the tests and generate a coverage report
|
127 |
+
@uv run coverage run
|
128 |
+
@uv run coverage erase
|
129 |
+
|
130 |
+
unit_tests: ## run unit tests
|
131 |
+
@uv sync --extra dev --frozen
|
132 |
+
@EXTRA_ARGS=""
|
133 |
+
@if [ "$(async)" = "true" ]; then \
|
134 |
+
EXTRA_ARGS="$$EXTRA_ARGS --instafail -n auto"; \
|
135 |
+
fi; \
|
136 |
+
if [ "$(lf)" = "true" ]; then \
|
137 |
+
EXTRA_ARGS="$$EXTRA_ARGS --lf"; \
|
138 |
+
fi; \
|
139 |
+
if [ "$(ff)" = "true" ]; then \
|
140 |
+
EXTRA_ARGS="$$EXTRA_ARGS --ff"; \
|
141 |
+
fi; \
|
142 |
+
uv run pytest src/backend/tests --ignore=src/backend/tests/integration $$EXTRA_ARGS --instafail -ra -m 'not api_key_required' --durations-path src/backend/tests/.test_durations --splitting-algorithm least_duration $(args)
|
143 |
+
|
144 |
+
unit_tests_looponfail:
|
145 |
+
@make unit_tests args="-f"
|
146 |
+
|
147 |
+
integration_tests:
|
148 |
+
uv run pytest src/backend/tests/integration \
|
149 |
+
--instafail -ra \
|
150 |
+
$(args)
|
151 |
+
|
152 |
+
integration_tests_no_api_keys:
|
153 |
+
uv run pytest src/backend/tests/integration \
|
154 |
+
--instafail -ra -m "not api_key_required" \
|
155 |
+
$(args)
|
156 |
+
|
157 |
+
integration_tests_api_keys:
|
158 |
+
uv run pytest src/backend/tests/integration \
|
159 |
+
--instafail -ra -m "api_key_required" \
|
160 |
+
$(args)
|
161 |
+
|
162 |
+
tests: ## run unit, integration, coverage tests
|
163 |
+
@echo 'Running Unit Tests...'
|
164 |
+
make unit_tests
|
165 |
+
@echo 'Running Integration Tests...'
|
166 |
+
make integration_tests
|
167 |
+
@echo 'Running Coverage Tests...'
|
168 |
+
make coverage
|
169 |
+
|
170 |
+
######################
|
171 |
+
# CODE QUALITY
|
172 |
+
######################
|
173 |
+
|
174 |
+
codespell: ## run codespell to check spelling
|
175 |
+
@poetry install --with spelling
|
176 |
+
poetry run codespell --toml pyproject.toml
|
177 |
+
|
178 |
+
fix_codespell: ## run codespell to fix spelling errors
|
179 |
+
@poetry install --with spelling
|
180 |
+
poetry run codespell --toml pyproject.toml --write
|
181 |
+
|
182 |
+
format: ## run code formatters
|
183 |
+
@uv run ruff check . --fix
|
184 |
+
@uv run ruff format . --config pyproject.toml
|
185 |
+
@cd src/frontend && npm run format
|
186 |
+
|
187 |
+
unsafe_fix:
|
188 |
+
@uv run ruff check . --fix --unsafe-fixes
|
189 |
+
|
190 |
+
lint: install_backend ## run linters
|
191 |
+
@uv run mypy --namespace-packages -p "langflow"
|
192 |
+
|
193 |
+
install_frontendci:
|
194 |
+
@cd src/frontend && npm ci > /dev/null 2>&1
|
195 |
+
|
196 |
+
install_frontendc:
|
197 |
+
@cd src/frontend && rm -rf node_modules package-lock.json && npm install > /dev/null 2>&1
|
198 |
+
|
199 |
+
run_frontend: ## run the frontend
|
200 |
+
@-kill -9 `lsof -t -i:3000`
|
201 |
+
@cd src/frontend && npm start
|
202 |
+
|
203 |
+
tests_frontend: ## run frontend tests
|
204 |
+
ifeq ($(UI), true)
|
205 |
+
@cd src/frontend && npx playwright test --ui --project=chromium
|
206 |
+
else
|
207 |
+
@cd src/frontend && npx playwright test --project=chromium
|
208 |
+
endif
|
209 |
+
|
210 |
+
run_cli: install_frontend install_backend build_frontend ## run the CLI
|
211 |
+
@echo 'Running the CLI'
|
212 |
+
@uv run langflow run \
|
213 |
+
--frontend-path $(path) \
|
214 |
+
--log-level $(log_level) \
|
215 |
+
--host $(host) \
|
216 |
+
--port $(port) \
|
217 |
+
$(if $(env),--env-file $(env),) \
|
218 |
+
$(if $(filter false,$(open_browser)),--no-open-browser)
|
219 |
+
|
220 |
+
run_cli_debug:
|
221 |
+
@echo 'Running the CLI in debug mode'
|
222 |
+
@make install_frontend > /dev/null
|
223 |
+
@echo 'Building the frontend'
|
224 |
+
@make build_frontend > /dev/null
|
225 |
+
@echo 'Install backend dependencies'
|
226 |
+
@make install_backend > /dev/null
|
227 |
+
ifdef env
|
228 |
+
@make start env=$(env) host=$(host) port=$(port) log_level=debug
|
229 |
+
else
|
230 |
+
@make start host=$(host) port=$(port) log_level=debug
|
231 |
+
endif
|
232 |
+
|
233 |
+
|
234 |
+
setup_devcontainer: ## set up the development container
|
235 |
+
make install_backend
|
236 |
+
make install_frontend
|
237 |
+
make build_frontend
|
238 |
+
uv run langflow --frontend-path src/frontend/build
|
239 |
+
|
240 |
+
setup_env: ## set up the environment
|
241 |
+
@sh ./scripts/setup/setup_env.sh
|
242 |
+
|
243 |
+
frontend: install_frontend ## run the frontend in development mode
|
244 |
+
make run_frontend
|
245 |
+
|
246 |
+
frontendc: install_frontendc
|
247 |
+
make run_frontend
|
248 |
+
|
249 |
+
|
250 |
+
backend: setup_env install_backend ## run the backend in development mode
|
251 |
+
@-kill -9 $$(lsof -t -i:7860) || true
|
252 |
+
ifdef login
|
253 |
+
@echo "Running backend autologin is $(login)";
|
254 |
+
LANGFLOW_AUTO_LOGIN=$(login) uv run uvicorn \
|
255 |
+
--factory langflow.main:create_app \
|
256 |
+
--host 0.0.0.0 \
|
257 |
+
--port $(port) \
|
258 |
+
$(if $(filter-out 1,$(workers)),, --reload) \
|
259 |
+
--env-file $(env) \
|
260 |
+
--loop asyncio \
|
261 |
+
$(if $(workers),--workers $(workers),)
|
262 |
+
else
|
263 |
+
@echo "Running backend respecting the $(env) file";
|
264 |
+
uv run uvicorn \
|
265 |
+
--factory langflow.main:create_app \
|
266 |
+
--host 0.0.0.0 \
|
267 |
+
--port $(port) \
|
268 |
+
$(if $(filter-out 1,$(workers)),, --reload) \
|
269 |
+
--env-file $(env) \
|
270 |
+
--loop asyncio \
|
271 |
+
$(if $(workers),--workers $(workers),)
|
272 |
+
endif
|
273 |
+
|
274 |
+
build_and_run: setup_env ## build the project and run it
|
275 |
+
rm -rf dist
|
276 |
+
rm -rf src/backend/base/dist
|
277 |
+
make build
|
278 |
+
uv run pip install dist/*.tar.gz
|
279 |
+
uv run langflow run
|
280 |
+
|
281 |
+
build_and_install: ## build the project and install it
|
282 |
+
@echo 'Removing dist folder'
|
283 |
+
rm -rf dist
|
284 |
+
rm -rf src/backend/base/dist
|
285 |
+
make build && uv run pip install dist/*.whl && pip install src/backend/base/dist/*.whl --force-reinstall
|
286 |
+
|
287 |
+
build: setup_env ## build the frontend static files and package the project
|
288 |
+
ifdef base
|
289 |
+
make install_frontendci
|
290 |
+
make build_frontend
|
291 |
+
make build_langflow_base args="$(args)"
|
292 |
+
endif
|
293 |
+
|
294 |
+
ifdef main
|
295 |
+
make install_frontendci
|
296 |
+
make build_frontend
|
297 |
+
make build_langflow_base args="$(args)"
|
298 |
+
make build_langflow args="$(args)"
|
299 |
+
endif
|
300 |
+
|
301 |
+
build_langflow_base:
|
302 |
+
cd src/backend/base && uv build $(args)
|
303 |
+
rm -rf src/backend/base/langflow/frontend
|
304 |
+
|
305 |
+
build_langflow_backup:
|
306 |
+
uv lock && uv build
|
307 |
+
|
308 |
+
build_langflow:
|
309 |
+
uv lock --no-upgrade
|
310 |
+
uv build $(args)
|
311 |
+
ifdef restore
|
312 |
+
mv pyproject.toml.bak pyproject.toml
|
313 |
+
mv uv.lock.bak uv.lock
|
314 |
+
endif
|
315 |
+
|
316 |
+
|
317 |
+
docker_build: dockerfile_build clear_dockerimage ## build DockerFile
|
318 |
+
|
319 |
+
docker_build_backend: dockerfile_build_be clear_dockerimage ## build Backend DockerFile
|
320 |
+
|
321 |
+
docker_build_frontend: dockerfile_build_fe clear_dockerimage ## build Frontend Dockerfile
|
322 |
+
|
323 |
+
dockerfile_build:
|
324 |
+
@echo 'BUILDING DOCKER IMAGE: ${DOCKERFILE}'
|
325 |
+
@docker build --rm \
|
326 |
+
-f ${DOCKERFILE} \
|
327 |
+
-t langflow:${VERSION} .
|
328 |
+
|
329 |
+
dockerfile_build_be: dockerfile_build
|
330 |
+
@echo 'BUILDING DOCKER IMAGE BACKEND: ${DOCKERFILE_BACKEND}'
|
331 |
+
@docker build --rm \
|
332 |
+
--build-arg LANGFLOW_IMAGE=langflow:${VERSION} \
|
333 |
+
-f ${DOCKERFILE_BACKEND} \
|
334 |
+
-t langflow_backend:${VERSION} .
|
335 |
+
|
336 |
+
dockerfile_build_fe: dockerfile_build
|
337 |
+
@echo 'BUILDING DOCKER IMAGE FRONTEND: ${DOCKERFILE_FRONTEND}'
|
338 |
+
@docker build --rm \
|
339 |
+
--build-arg LANGFLOW_IMAGE=langflow:${VERSION} \
|
340 |
+
-f ${DOCKERFILE_FRONTEND} \
|
341 |
+
-t langflow_frontend:${VERSION} .
|
342 |
+
|
343 |
+
clear_dockerimage:
|
344 |
+
@echo 'Clearing the docker build'
|
345 |
+
@if docker images -f "dangling=true" -q | grep -q '.*'; then \
|
346 |
+
docker rmi $$(docker images -f "dangling=true" -q); \
|
347 |
+
fi
|
348 |
+
|
349 |
+
docker_compose_up: docker_build docker_compose_down
|
350 |
+
@echo 'Running docker compose up'
|
351 |
+
docker compose -f $(DOCKER_COMPOSE) up --remove-orphans
|
352 |
+
|
353 |
+
docker_compose_down:
|
354 |
+
@echo 'Running docker compose down'
|
355 |
+
docker compose -f $(DOCKER_COMPOSE) down || true
|
356 |
+
|
357 |
+
dcdev_up:
|
358 |
+
@echo 'Running docker compose up'
|
359 |
+
docker compose -f docker/dev.docker-compose.yml down || true
|
360 |
+
docker compose -f docker/dev.docker-compose.yml up --remove-orphans
|
361 |
+
|
362 |
+
lock_base:
|
363 |
+
cd src/backend/base && uv lock
|
364 |
+
|
365 |
+
lock_langflow:
|
366 |
+
uv lock
|
367 |
+
|
368 |
+
lock: ## lock dependencies
|
369 |
+
@echo 'Locking dependencies'
|
370 |
+
cd src/backend/base && uv lock
|
371 |
+
uv lock
|
372 |
+
|
373 |
+
update: ## update dependencies
|
374 |
+
@echo 'Updating dependencies'
|
375 |
+
cd src/backend/base && uv sync --upgrade
|
376 |
+
uv sync --upgrade
|
377 |
+
|
378 |
+
publish_base:
|
379 |
+
cd src/backend/base && uv publish
|
380 |
+
|
381 |
+
publish_langflow:
|
382 |
+
uv publish
|
383 |
+
|
384 |
+
publish_base_testpypi:
|
385 |
+
# TODO: update this to use the test-pypi repository
|
386 |
+
cd src/backend/base && uv publish -r test-pypi
|
387 |
+
|
388 |
+
publish_langflow_testpypi:
|
389 |
+
# TODO: update this to use the test-pypi repository
|
390 |
+
uv publish -r test-pypi
|
391 |
+
|
392 |
+
publish: ## build the frontend static files and package the project and publish it to PyPI
|
393 |
+
@echo 'Publishing the project'
|
394 |
+
ifdef base
|
395 |
+
make publish_base
|
396 |
+
endif
|
397 |
+
|
398 |
+
ifdef main
|
399 |
+
make publish_langflow
|
400 |
+
endif
|
401 |
+
|
402 |
+
publish_testpypi: ## build the frontend static files and package the project and publish it to PyPI
|
403 |
+
@echo 'Publishing the project'
|
404 |
+
|
405 |
+
ifdef base
|
406 |
+
#TODO: replace with uvx twine upload dist/*
|
407 |
+
poetry config repositories.test-pypi https://test.pypi.org/legacy/
|
408 |
+
make publish_base_testpypi
|
409 |
+
endif
|
410 |
+
|
411 |
+
ifdef main
|
412 |
+
#TODO: replace with uvx twine upload dist/*
|
413 |
+
poetry config repositories.test-pypi https://test.pypi.org/legacy/
|
414 |
+
make publish_langflow_testpypi
|
415 |
+
endif
|
416 |
+
|
417 |
+
|
418 |
+
# example make alembic-revision message="Add user table"
|
419 |
+
alembic-revision: ## generate a new migration
|
420 |
+
@echo 'Generating a new Alembic revision'
|
421 |
+
cd src/backend/base/langflow/ && uv run alembic revision --autogenerate -m "$(message)"
|
422 |
+
|
423 |
+
|
424 |
+
alembic-upgrade: ## upgrade database to the latest version
|
425 |
+
@echo 'Upgrading database to the latest version'
|
426 |
+
cd src/backend/base/langflow/ && uv run alembic upgrade head
|
427 |
+
|
428 |
+
alembic-downgrade: ## downgrade database by one version
|
429 |
+
@echo 'Downgrading database by one version'
|
430 |
+
cd src/backend/base/langflow/ && uv run alembic downgrade -1
|
431 |
+
|
432 |
+
alembic-current: ## show current revision
|
433 |
+
@echo 'Showing current Alembic revision'
|
434 |
+
cd src/backend/base/langflow/ && uv run alembic current
|
435 |
+
|
436 |
+
alembic-history: ## show migration history
|
437 |
+
@echo 'Showing Alembic migration history'
|
438 |
+
cd src/backend/base/langflow/ && uv run alembic history --verbose
|
439 |
+
|
440 |
+
alembic-check: ## check migration status
|
441 |
+
@echo 'Running alembic check'
|
442 |
+
cd src/backend/base/langflow/ && uv run alembic check
|
443 |
+
|
444 |
+
alembic-stamp: ## stamp the database with a specific revision
|
445 |
+
@echo 'Stamping the database with revision $(revision)'
|
446 |
+
cd src/backend/base/langflow/ && uv run alembic stamp $(revision)
|
README.md
CHANGED
@@ -1,11 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Agent Flow
|
3 |
-
emoji: 🐠
|
4 |
-
colorFrom: indigo
|
5 |
-
colorTo: purple
|
6 |
-
sdk: static
|
7 |
-
pinned: false
|
8 |
-
license: mit
|
9 |
-
---
|
10 |
-
|
11 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|