Merge remote-tracking branch 'origin/release-1.10.1' into release-1.11.0

# Conflicts:
#	.secrets.baseline
#	pyproject.toml
#	src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json
#	src/backend/base/langflow/initial_setup/starter_projects/Structured Data Analysis Agent.json
#	src/backend/base/langflow/services/auth/service.py
#	src/backend/base/langflow/services/job_queue/service.py
#	src/backend/base/pyproject.toml
#	src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py
#	src/backend/tests/unit/test_redis_job_queue_service.py
#	src/bundles/lfx-bundles/src/lfx_bundles/deepseek/deepseek.py
#	src/bundles/lfx-bundles/src/lfx_bundles/glean/glean_search_api.py
#	src/bundles/lfx-bundles/src/lfx_bundles/homeassistant/home_assistant_control.py
#	src/bundles/lfx-bundles/src/lfx_bundles/homeassistant/list_home_assistant_states.py
#	src/bundles/lfx-bundles/src/lfx_bundles/huggingface/huggingface_inference_api.py
#	src/bundles/lfx-bundles/src/lfx_bundles/lmstudio/lmstudioembeddings.py
#	src/bundles/lfx-bundles/src/lfx_bundles/xai/xai.py
#	src/frontend/package-lock.json
#	src/frontend/package.json
#	src/lfx/pyproject.toml
#	src/lfx/src/lfx/_assets/component_index.json
#	src/lfx/src/lfx/components/files_and_knowledge/filesystem.py
#	src/lfx/tests/unit/components/tools/test_filesystem_deny_list.py
#	uv.lock
This commit is contained in:
Eric Hare
2026-06-23 17:22:13 -07:00
221 changed files with 14920 additions and 2711 deletions

View File

@ -1,39 +1,102 @@
#!/usr/bin/env python3
import re
from __future__ import annotations
import argparse
import sys
from typing import TYPE_CHECKING
ARGUMENT_NUMBER = 3
import packaging.version
from packaging.version import Version
if TYPE_CHECKING:
from collections.abc import Iterable
def create_tag(package_version: str, latest_released_version: str | None) -> str:
# normalize optional leading 'v' and whitespace
pkg = package_version.strip().lstrip("v")
latest = None
if latest_released_version is not None:
lr = latest_released_version.strip()
if lr != "":
latest = lr.lstrip("v")
def _read_released_versions(values: list[str]) -> list[str]:
if values == ["-"]:
return [line.strip() for line in sys.stdin if line.strip()]
return [value.strip() for value in values if value.strip()]
new_pre_release_version = f"{pkg}.rc0"
if latest:
# match either exact pkg or pkg.rcN (with or without dot before rc, per PEP 440 normalization)
m = re.match(rf"^{re.escape(pkg)}\.?rc(\d+)$", latest)
if m:
rc_number = int(m.group(1)) + 1
new_pre_release_version = f"{pkg}.rc{rc_number}"
elif latest == pkg:
new_pre_release_version = f"{pkg}.rc1"
def next_rc_number(package_version: str, released_versions: Iterable[str]) -> int:
base_version = Version(package_version.strip().lstrip("v")).base_version
rc_numbers: list[int] = []
exact_final_exists = False
return new_pre_release_version
for released_version_str in released_versions:
normalized_version_str = released_version_str.strip().lstrip("v")
if not normalized_version_str:
continue
try:
released_version = Version(normalized_version_str)
except packaging.version.InvalidVersion:
continue
if released_version.base_version != base_version:
continue
if released_version.pre and released_version.pre[0] == "rc":
rc_numbers.append(released_version.pre[1])
elif not released_version.is_prerelease:
exact_final_exists = True
if rc_numbers:
return max(rc_numbers) + 1
if exact_final_exists:
return 1
return 0
def create_tag(
package_version: str,
released_versions: Iterable[str] | str | None,
rc_number: int | None = None,
) -> str:
if released_versions is None:
versions: list[str] = []
elif isinstance(released_versions, str):
versions = [released_versions]
else:
versions = list(released_versions)
base_version = Version(package_version.strip().lstrip("v")).base_version
next_rc = next_rc_number(base_version, versions)
if rc_number is not None:
next_rc = max(next_rc, rc_number)
return str(Version(f"{base_version}rc{next_rc}"))
def main() -> None:
parser = argparse.ArgumentParser(
description="Return the next rc pre-release for a package base version.",
)
parser.add_argument("package_version")
parser.add_argument(
"released_versions",
nargs="*",
help="Released versions to inspect, or '-' to read one version per line from stdin.",
)
parser.add_argument(
"--rc-number",
type=int,
default=None,
help="Minimum rc number to use. This lets a workflow apply one shared rc number across packages.",
)
parser.add_argument(
"--print-rc-number",
action="store_true",
help="Print only the next rc number instead of the full version.",
)
args = parser.parse_args()
released_versions = _read_released_versions(args.released_versions)
if args.print_rc_number:
print(next_rc_number(args.package_version, released_versions))
else:
print(create_tag(args.package_version, released_versions, args.rc_number))
if __name__ == "__main__":
if len(sys.argv) != ARGUMENT_NUMBER:
msg = "Specify package_version and latest_released_version (use empty string for none)."
raise ValueError(msg)
package_version = sys.argv[1]
latest_released_version = sys.argv[2]
print(create_tag(package_version, latest_released_version))
main()

View File

@ -0,0 +1,73 @@
"""Unit tests for langflow_pre_release_tag.py.
Run directly or with pytest:
cd scripts/ci && uv run python test_langflow_pre_release_tag.py
cd scripts/ci && uv run python -m pytest test_langflow_pre_release_tag.py -q
"""
import contextlib
import io
import sys
from pathlib import Path
from unittest import mock
sys.path.insert(0, str(Path(__file__).parent))
import langflow_pre_release_tag as pr
def test_ignores_unrelated_newer_pre_release_line():
assert pr.create_tag("1.10.1", ["1.11.0.dev15"]) == "1.10.1rc0"
def test_increments_same_base_rc_with_or_without_dot():
releases = ["1.10.1rc0", "1.10.1.rc1", "1.11.0.dev15"]
assert pr.create_tag("1.10.1", releases) == "1.10.1rc2"
def test_final_same_base_starts_at_rc1():
assert pr.create_tag("1.10.1", ["1.10.1"]) == "1.10.1rc1"
def test_shared_rc_number_floor_applies_to_other_package_base():
assert pr.create_tag("0.10.1", [], rc_number=1) == "0.10.1rc1"
def test_shared_rc_number_floor_does_not_regress_existing_higher_rc():
assert pr.create_tag("1.10.1", ["1.10.1rc5"], rc_number=1) == "1.10.1rc6"
def test_cli_reads_released_versions_from_stdin():
output = io.StringIO()
with (
mock.patch.object(sys, "argv", ["langflow_pre_release_tag.py", "1.10.1", "--print-rc-number", "-"]),
mock.patch.object(sys, "stdin", io.StringIO("1.10.1rc0\n1.11.0.dev15\n")),
contextlib.redirect_stdout(output),
):
pr.main()
assert output.getvalue().strip() == "1"
def test_unparseable_versions_are_skipped():
assert pr.create_tag("1.10.1", ["not-a-version", "1.10.1rc0"]) == "1.10.1rc1"
def _main():
failures = 0
for name, fn in sorted(globals().items()):
if name.startswith("test_") and callable(fn):
try:
fn()
except Exception as exc: # noqa: BLE001
failures += 1
print(f"FAIL {name}: {exc}")
else:
print(f"ok {name}")
if failures:
msg = f"{failures} test(s) failed."
raise SystemExit(msg)
print("All langflow_pre_release_tag tests passed.")
if __name__ == "__main__":
_main()