From d71bec672c1909a0435376e0fd82d17db046b2dd Mon Sep 17 00:00:00 2001 From: pratiksha badheka Date: Mon, 4 May 2026 06:48:08 -0700 Subject: [PATCH 1/4] install airflowctl into airflowcore --- airflow-core/pyproject.toml | 1 + .../airflowctl/test_airflowctl_imports | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml index a875d9e9c77e7..ac7eae0dd6be7 100644 --- a/airflow-core/pyproject.toml +++ b/airflow-core/pyproject.toml @@ -322,6 +322,7 @@ required-version = ">=0.11.8" [tool.uv.sources] apache-airflow-core = {workspace = true} +apache-airflow-ctl = {workspace = true} apache-airflow-devel-common = { workspace = true } [tool.airflow] diff --git a/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports b/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports new file mode 100644 index 0000000000000..b3a83eca736ec --- /dev/null +++ b/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports @@ -0,0 +1,22 @@ +from __future__ import annotations + +import subprocess +import sys + + +def test_airflowctl_is_importable(): + # checks if airflowctl imports correctly + result = subprocess.run( + [ + sys.executable, + "-c", + "import airflowctl; print('airflowctl imported successfully')", + ], + capture_output=True, + text=True, + ) + assert result.returncode == 0, ( + f"airflowctl import failed!\n" + f"stdout: {result.stdout}\n" + f"stderr: {result.stderr}" + ) From 0e7ca48e8fb7f2ef1f525f8fe4e740c119d4db1a Mon Sep 17 00:00:00 2001 From: pratiksha badheka Date: Wed, 6 May 2026 06:30:15 -0700 Subject: [PATCH 2/4] some small nits in pyproject.toml and tests --- airflow-core/pyproject.toml | 1 + .../airflowctl/test_airflowctl_imports | 22 ----------- .../airflowctl/test_airflowctl_imports.py | 38 +++++++++++++++++++ uv.lock | 2 + 4 files changed, 41 insertions(+), 22 deletions(-) delete mode 100644 airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports create mode 100644 airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports.py diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml index ac7eae0dd6be7..35f1a9eb5baf9 100644 --- a/airflow-core/pyproject.toml +++ b/airflow-core/pyproject.toml @@ -150,6 +150,7 @@ dependencies = [ "universal-pathlib>=0.3.8", "uuid6>=2024.7.10", "apache-airflow-task-sdk<1.4.0,>=1.3.0", + "apache-airflow-ctl", # pre-installed providers "apache-airflow-providers-common-compat>=1.7.4", "apache-airflow-providers-common-io>=1.6.3", diff --git a/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports b/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports deleted file mode 100644 index b3a83eca736ec..0000000000000 --- a/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports +++ /dev/null @@ -1,22 +0,0 @@ -from __future__ import annotations - -import subprocess -import sys - - -def test_airflowctl_is_importable(): - # checks if airflowctl imports correctly - result = subprocess.run( - [ - sys.executable, - "-c", - "import airflowctl; print('airflowctl imported successfully')", - ], - capture_output=True, - text=True, - ) - assert result.returncode == 0, ( - f"airflowctl import failed!\n" - f"stdout: {result.stdout}\n" - f"stderr: {result.stderr}" - ) diff --git a/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports.py b/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports.py new file mode 100644 index 0000000000000..f7957f1a576eb --- /dev/null +++ b/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports.py @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from __future__ import annotations + +import subprocess +import sys + + +def test_airflowctl_is_importable(): + # checks if airflowctl imports correctly + result = subprocess.run( + [ + sys.executable, + "-c", + "import airflowctl; print('airflowctl imported successfully')", + ], + capture_output=True, + text=True, + check=False, + ) + assert result.returncode == 0, ( + f"airflowctl import failed!\nstdout: {result.stdout}\nstderr: {result.stderr}" + ) diff --git a/uv.lock b/uv.lock index 30e362221b84a..c2cefb4bb7a04 100644 --- a/uv.lock +++ b/uv.lock @@ -1799,6 +1799,7 @@ dependencies = [ { name = "a2wsgi" }, { name = "aiosqlite" }, { name = "alembic" }, + { name = "apache-airflow-ctl" }, { name = "apache-airflow-providers-common-compat" }, { name = "apache-airflow-providers-common-io" }, { name = "apache-airflow-providers-common-sql" }, @@ -1926,6 +1927,7 @@ requires-dist = [ { name = "aiosqlite", specifier = ">=0.20.0,<0.22.0" }, { name = "alembic", specifier = ">=1.13.1,<2.0" }, { name = "apache-airflow-core", extras = ["graphviz", "gunicorn", "kerberos", "otel", "statsd"], marker = "extra == 'all'", editable = "airflow-core" }, + { name = "apache-airflow-ctl", editable = "airflow-ctl" }, { name = "apache-airflow-providers-common-compat", editable = "providers/common/compat" }, { name = "apache-airflow-providers-common-io", editable = "providers/common/io" }, { name = "apache-airflow-providers-common-sql", editable = "providers/common/sql" }, From 2b40d602a10594df4cd6dd71c2c37811cf977f1e Mon Sep 17 00:00:00 2001 From: pratiksha badheka Date: Thu, 7 May 2026 01:43:56 -0700 Subject: [PATCH 3/4] update version constraints for airflowctl in pyproject.toml --- airflow-core/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml index 35f1a9eb5baf9..e84c78693293a 100644 --- a/airflow-core/pyproject.toml +++ b/airflow-core/pyproject.toml @@ -150,7 +150,7 @@ dependencies = [ "universal-pathlib>=0.3.8", "uuid6>=2024.7.10", "apache-airflow-task-sdk<1.4.0,>=1.3.0", - "apache-airflow-ctl", + "apache-airflow-ctl<0.1.5,>=0.1.4", # pre-installed providers "apache-airflow-providers-common-compat>=1.7.4", "apache-airflow-providers-common-io>=1.6.3", From 4935c88183f16013ec083b0562acfb18fd4e87ff Mon Sep 17 00:00:00 2001 From: pratiksha badheka Date: Sun, 10 May 2026 07:16:24 -0700 Subject: [PATCH 4/4] move the tests to to basic_tests --- .../{airflowctl => basic_tests}/test_airflowctl_imports.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename airflow-e2e-tests/tests/airflow_e2e_tests/{airflowctl => basic_tests}/test_airflowctl_imports.py (100%) diff --git a/airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports.py b/airflow-e2e-tests/tests/airflow_e2e_tests/basic_tests/test_airflowctl_imports.py similarity index 100% rename from airflow-e2e-tests/tests/airflow_e2e_tests/airflowctl/test_airflowctl_imports.py rename to airflow-e2e-tests/tests/airflow_e2e_tests/basic_tests/test_airflowctl_imports.py