From 74e0af0a05453d2b979bb381a42e3b0e3d025495 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Mon, 4 May 2026 20:29:07 +0200 Subject: [PATCH 1/3] Move helm-tests/ to chart/tests/ and merge pyproject.toml into chart's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Helm chart Python tests previously lived as their own workspace member at `helm-tests/` with a dedicated `apache-airflow-helm-tests` package. The chart sources and tests are inseparable in practice, so this collapses them into a single `chart` workspace member: the test files move under `chart/tests/`, and `helm-tests/pyproject.toml` is merged into `chart/pyproject.toml` (which adopts the helm-tests pytest config, the `mypy` dependency-group, and the test-only deps on `apache-airflow-devel-common` and `apache-airflow-providers-cncf-kubernetes`). Names that are user/CI-visible are intentionally preserved: * `breeze testing helm-tests` — command name unchanged. * `mypy-helm-tests` — prek hook id unchanged (now lives in `chart/.pre-commit-config.yaml`, pointing at `chart/tests`). * `run-helm-tests` — selective-checks output / CI gate, unchanged. * `helm-tests.yml` — CI workflow file, unchanged. * The directory `chart/tests/helm_tests/` keeps the Python package name `helm_tests` so test imports / module paths don't shift. Path references updated everywhere they pointed at the old layout: root `pyproject.toml` (workspace members, `[tool.uv.sources]`, `apache-airflow-helm-chart = false` constraint rows, ruff per-file ignores, mypy include path, dev dependency-group); `.github/CODEOWNERS` (folded the `/helm-tests/` line into the existing `/chart/` entry — same owners); `.github/dependabot.yml` and `dev/update_github_branch_config.py`; breeze internals (`global_constants.all_helm_test_packages`, `run_tests.TEST_GROUP_TO_TEST_FOLDERS[GroupOfTests.HELM]`, `run_tests.find_pytest_arguments`, `docker_command_utils` mounts, `selective_checks` regexes); `scripts/ci/docker-compose/local.yml` and `scripts/ci/prek/run_mypy_full_dist_local_venv_or_breeze_in_ci.py` (with a `FOLDER_TO_PROJECT["chart/tests"] = "chart"` override since `chart/tests` is not its own uv project); `dev/ide_setup/setup_idea.py`; root `.pre-commit-config.yaml` exclusions; docs in `contributing-docs/testing/helm_unit_tests.rst` and `dev/breeze/doc/ci/04_selective_checks.md`; existing breeze unit tests in `dev/breeze/tests/test_*.py`. `uv.lock` regenerated. NOTE: developers running `breeze` via `uvx --from dev/breeze` may need a one-time `uv cache clean` (or `touch dev/breeze/pyproject.toml`) after pulling this commit so uvx rebuilds breeze from the current source — uvx caches by content hash and will otherwise serve a stale breeze that still references the old `helm-tests/tests/helm_tests` path. --- .github/CODEOWNERS | 1 - .github/dependabot.yml | 4 +- .pre-commit-config.yaml | 4 +- chart/.pre-commit-config.yaml | 7 ++ chart/pyproject.toml | 28 +++++++ .../tests/chart_utils/__init__.py | 0 .../chart_utils/helm_template_generator.py | 0 .../chart_utils/keda.sh_scaledobjects.yaml | 0 .../tests/chart_utils/log_groomer.py | 0 {helm-tests => chart}/tests/conftest.py | 0 .../tests/helm_tests/__init__.py | 0 .../tests/helm_tests/airflow_aux/__init__.py | 0 .../airflow_aux/test_airflow_common.py | 0 .../airflow_aux/test_annotations.py | 0 .../airflow_aux/test_basic_helm_chart.py | 0 .../airflow_aux/test_chart_quality.py | 0 .../airflow_aux/test_cleanup_pods.py | 0 .../helm_tests/airflow_aux/test_configmap.py | 0 .../airflow_aux/test_container_lifecycle.py | 0 .../airflow_aux/test_create_user_job.py | 0 .../airflow_aux/test_database_cleanup.py | 0 .../airflow_aux/test_extra_env_env_from.py | 0 .../airflow_aux/test_job_launcher_role.py | 0 .../test_logs_persistent_volume_claim.py | 0 .../airflow_aux/test_migrate_database_job.py | 0 .../airflow_aux/test_pod_launcher_role.py | 0 .../airflow_aux/test_pod_template_file.py | 0 .../airflow_aux/test_remote_logging.py | 0 .../tests/helm_tests/airflow_core/__init__.py | 0 .../airflow_core/test_api_server.py | 0 .../airflow_core/test_dag_processor.py | 0 .../tests/helm_tests/airflow_core/test_env.py | 0 .../airflow_core/test_pdb_api_server.py | 0 .../airflow_core/test_pdb_dag_processor.py | 0 .../airflow_core/test_pdb_scheduler.py | 0 .../airflow_core/test_pdb_triggerer.py | 0 .../airflow_core/test_pdb_worker.py | 0 .../helm_tests/airflow_core/test_scheduler.py | 0 .../helm_tests/airflow_core/test_triggerer.py | 0 .../helm_tests/airflow_core/test_worker.py | 0 .../airflow_core/test_worker_sets.py | 0 .../helm_tests/apiserver/test_apiserver.py | 0 .../apiserver/test_hpa_apiserver.py | 0 .../apiserver/test_ingress_apiserver.py | 0 .../tests/helm_tests/dagprocessor/__init__.py | 0 .../dagprocessor/test_labels_deployment.py | 0 .../test_labels_service_account.py | 0 .../tests/helm_tests/other/__init__.py | 0 .../test_dags_persistent_volume_claim.py | 0 .../tests/helm_tests/other/test_flower.py | 0 .../other/test_git_ssh_key_secret.py | 0 .../other/test_git_sync_scheduler.py | 0 .../other/test_git_sync_triggerer.py | 0 .../helm_tests/other/test_git_sync_worker.py | 0 .../tests/helm_tests/other/test_hpa.py | 0 .../tests/helm_tests/other/test_keda.py | 0 .../helm_tests/other/test_limit_ranges.py | 0 .../helm_tests/other/test_pdb_pgbouncer.py | 0 .../tests/helm_tests/other/test_pgbouncer.py | 0 .../tests/helm_tests/other/test_redis.py | 0 .../helm_tests/other/test_resource_quota.py | 0 .../tests/helm_tests/other/test_statsd.py | 0 .../tests/helm_tests/redis/__init__.py | 0 .../redis/test_labels_networkpolicy.py | 0 .../helm_tests/redis/test_labels_service.py | 0 .../redis/test_labels_serviceaccount.py | 0 .../redis/test_labels_statefulset.py | 0 .../tests/helm_tests/security/__init__.py | 0 .../security/test_elasticsearch_secret.py | 0 .../security/test_extra_configmaps_secrets.py | 0 .../security/test_fernetkey_secret.py | 0 .../helm_tests/security/test_kerberos.py | 0 .../test_metadata_connection_secret.py | 0 .../security/test_opensearch_secret.py | 0 .../tests/helm_tests/security/test_rbac.py | 0 .../security/test_rbac_pod_launcher.py | 0 .../security/test_rbac_pod_log_reader.py | 0 .../test_result_backend_connection_secret.py | 0 .../security/test_scc_rolebinding.py | 0 .../security/test_security_context.py | 0 .../tests/helm_tests/statsd/__init__.py | 0 .../statsd/test_labels_deployment.py | 0 .../helm_tests/statsd/test_labels_ingress.py | 0 .../statsd/test_labels_networkpolicy.py | 0 .../helm_tests/statsd/test_labels_service.py | 0 .../statsd/test_labels_serviceaccount.py | 0 contributing-docs/testing/helm_unit_tests.rst | 12 +-- dev/breeze/doc/ci/04_selective_checks.md | 2 +- .../src/airflow_breeze/global_constants.py | 2 +- .../utils/docker_command_utils.py | 1 - .../src/airflow_breeze/utils/run_tests.py | 4 +- .../airflow_breeze/utils/selective_checks.py | 5 +- .../tests/test_pytest_args_for_test_types.py | 6 +- dev/breeze/tests/test_selective_checks.py | 6 +- dev/ide_setup/setup_idea.py | 2 +- dev/update_github_branch_config.py | 2 +- helm-tests/.gitignore | 1 - helm-tests/.pre-commit-config.yaml | 31 ------- helm-tests/pyproject.toml | 81 ------------------- pyproject.toml | 16 ++-- scripts/ci/docker-compose/local.yml | 3 - ...py_full_dist_local_venv_or_breeze_in_ci.py | 7 +- uv.lock | 27 ++++--- 103 files changed, 89 insertions(+), 163 deletions(-) rename {helm-tests => chart}/tests/chart_utils/__init__.py (100%) rename {helm-tests => chart}/tests/chart_utils/helm_template_generator.py (100%) rename {helm-tests => chart}/tests/chart_utils/keda.sh_scaledobjects.yaml (100%) rename {helm-tests => chart}/tests/chart_utils/log_groomer.py (100%) rename {helm-tests => chart}/tests/conftest.py (100%) rename {helm-tests => chart}/tests/helm_tests/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_airflow_common.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_annotations.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_basic_helm_chart.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_chart_quality.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_cleanup_pods.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_configmap.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_container_lifecycle.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_create_user_job.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_database_cleanup.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_extra_env_env_from.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_job_launcher_role.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_logs_persistent_volume_claim.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_migrate_database_job.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_pod_launcher_role.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_pod_template_file.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_aux/test_remote_logging.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_api_server.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_dag_processor.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_env.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_pdb_api_server.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_pdb_dag_processor.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_pdb_scheduler.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_pdb_triggerer.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_pdb_worker.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_scheduler.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_triggerer.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_worker.py (100%) rename {helm-tests => chart}/tests/helm_tests/airflow_core/test_worker_sets.py (100%) rename {helm-tests => chart}/tests/helm_tests/apiserver/test_apiserver.py (100%) rename {helm-tests => chart}/tests/helm_tests/apiserver/test_hpa_apiserver.py (100%) rename {helm-tests => chart}/tests/helm_tests/apiserver/test_ingress_apiserver.py (100%) rename {helm-tests => chart}/tests/helm_tests/dagprocessor/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/dagprocessor/test_labels_deployment.py (100%) rename {helm-tests => chart}/tests/helm_tests/dagprocessor/test_labels_service_account.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_dags_persistent_volume_claim.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_flower.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_git_ssh_key_secret.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_git_sync_scheduler.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_git_sync_triggerer.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_git_sync_worker.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_hpa.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_keda.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_limit_ranges.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_pdb_pgbouncer.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_pgbouncer.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_redis.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_resource_quota.py (100%) rename {helm-tests => chart}/tests/helm_tests/other/test_statsd.py (100%) rename {helm-tests => chart}/tests/helm_tests/redis/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/redis/test_labels_networkpolicy.py (100%) rename {helm-tests => chart}/tests/helm_tests/redis/test_labels_service.py (100%) rename {helm-tests => chart}/tests/helm_tests/redis/test_labels_serviceaccount.py (100%) rename {helm-tests => chart}/tests/helm_tests/redis/test_labels_statefulset.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_elasticsearch_secret.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_extra_configmaps_secrets.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_fernetkey_secret.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_kerberos.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_metadata_connection_secret.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_opensearch_secret.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_rbac.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_rbac_pod_launcher.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_rbac_pod_log_reader.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_result_backend_connection_secret.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_scc_rolebinding.py (100%) rename {helm-tests => chart}/tests/helm_tests/security/test_security_context.py (100%) rename {helm-tests => chart}/tests/helm_tests/statsd/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/statsd/test_labels_deployment.py (100%) rename {helm-tests => chart}/tests/helm_tests/statsd/test_labels_ingress.py (100%) rename {helm-tests => chart}/tests/helm_tests/statsd/test_labels_networkpolicy.py (100%) rename {helm-tests => chart}/tests/helm_tests/statsd/test_labels_service.py (100%) rename {helm-tests => chart}/tests/helm_tests/statsd/test_labels_serviceaccount.py (100%) delete mode 100644 helm-tests/.gitignore delete mode 100644 helm-tests/.pre-commit-config.yaml delete mode 100644 helm-tests/pyproject.toml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6b9d9d2335e8f..0be08435cc863 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -11,7 +11,6 @@ # Helm Chart /chart/ @jedcunningham @hussein-awala @jscheffl @bugraoz93 -/helm-tests/ @jedcunningham @hussein-awala @jscheffl @bugraoz93 # Docs /docs/*.py @potiuk @ashb @gopidesupavan @amoghrajesh @jscheffl @bugraoz93 @jason810496 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c0a4ac03e2100..2183d42af6792 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -65,7 +65,7 @@ updates: - /dev/breeze - /docker-tests - /kubernetes-tests - - /helm-tests + - /chart - /task-sdk - / schedule: @@ -211,7 +211,7 @@ updates: - /dev/breeze - /docker-tests - /kubernetes-tests - - /helm-tests + - /chart - /task-sdk - / schedule: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e84a272c5ff35..acf47e9adebb3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -346,7 +346,7 @@ repos: ^.*airflow\.template\.yaml$| ^.*init_git_sync\.template\.yaml$| ^chart/(?:templates|files)/.*\.yaml$| - ^helm-tests/tests/chart_utils/keda.sh_scaledobjects\.yaml$| + ^chart/tests/chart_utils/keda.sh_scaledobjects\.yaml$| .*/v1.*\.yaml$| ^.*openapi.*\.yaml$| ^\.pre-commit-config\.yaml$| @@ -678,7 +678,7 @@ repos: .*/dist/.*| ^docs/apache-airflow-providers-amazon/secrets-backends/aws-ssm-parameter-store\.rst$| git| - ^helm-tests/tests/chart_utils/helm_template_generator\.py$| + ^chart/tests/chart_utils/helm_template_generator\.py$| package-lock\.json$| ^.*\.(png|gif|jp[e]?g|svg|tgz|lock|woff2?)$| ^\.pre-commit-config\.yaml$| diff --git a/chart/.pre-commit-config.yaml b/chart/.pre-commit-config.yaml index 699beac90d6f1..547ea03f972f7 100644 --- a/chart/.pre-commit-config.yaml +++ b/chart/.pre-commit-config.yaml @@ -44,6 +44,13 @@ repos: files: ^\.pre-commit-config\.yaml$|^../scripts/ci/prek/update_build_dependencies\.py$ pass_filenames: false require_serial: true + - id: mypy-helm-tests + name: Run mypy for helm-tests + language: python + entry: ../scripts/ci/prek/run_mypy_full_dist_local_venv_or_breeze_in_ci.py chart/tests + pass_filenames: false + files: ^tests/.*\.py$ + require_serial: true - repo: https://github.com/pre-commit/pre-commit-hooks rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 hooks: diff --git a/chart/pyproject.toml b/chart/pyproject.toml index 713a8c2a54ad3..584d16f14017b 100644 --- a/chart/pyproject.toml +++ b/chart/pyproject.toml @@ -57,8 +57,33 @@ version = "0.0.1" dependencies = [ "apache-airflow-core", + "apache-airflow-devel-common", + "apache-airflow-providers-cncf-kubernetes", ] +[tool.pytest] +addopts = [ + "-rasl", + "--verbosity=2", + "-p", "no:flaky", + "-p", "no:nose", + "-p", "no:legacypath", +] +norecursedirs = [ + ".eggs", +] +log_level = "INFO" +filterwarnings = [ + "error::pytest.PytestCollectionWarning", +] +python_files = [ + "*.py", +] + +# Keep temporary directories (created by `tmp_path`) for 2 recent runs only failed tests. +tmp_path_retention_count = "2" +tmp_path_retention_policy = "failed" + [tool.hatch.build.targets.sdist] exclude = ["*"] @@ -81,5 +106,8 @@ bypass-selection = true docs = [ "apache-airflow-devel-common[docs]" ] +mypy = [ + "apache-airflow-devel-common[mypy]", +] packages = [] diff --git a/helm-tests/tests/chart_utils/__init__.py b/chart/tests/chart_utils/__init__.py similarity index 100% rename from helm-tests/tests/chart_utils/__init__.py rename to chart/tests/chart_utils/__init__.py diff --git a/helm-tests/tests/chart_utils/helm_template_generator.py b/chart/tests/chart_utils/helm_template_generator.py similarity index 100% rename from helm-tests/tests/chart_utils/helm_template_generator.py rename to chart/tests/chart_utils/helm_template_generator.py diff --git a/helm-tests/tests/chart_utils/keda.sh_scaledobjects.yaml b/chart/tests/chart_utils/keda.sh_scaledobjects.yaml similarity index 100% rename from helm-tests/tests/chart_utils/keda.sh_scaledobjects.yaml rename to chart/tests/chart_utils/keda.sh_scaledobjects.yaml diff --git a/helm-tests/tests/chart_utils/log_groomer.py b/chart/tests/chart_utils/log_groomer.py similarity index 100% rename from helm-tests/tests/chart_utils/log_groomer.py rename to chart/tests/chart_utils/log_groomer.py diff --git a/helm-tests/tests/conftest.py b/chart/tests/conftest.py similarity index 100% rename from helm-tests/tests/conftest.py rename to chart/tests/conftest.py diff --git a/helm-tests/tests/helm_tests/__init__.py b/chart/tests/helm_tests/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/__init__.py rename to chart/tests/helm_tests/__init__.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/__init__.py b/chart/tests/helm_tests/airflow_aux/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/__init__.py rename to chart/tests/helm_tests/airflow_aux/__init__.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py b/chart/tests/helm_tests/airflow_aux/test_airflow_common.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py rename to chart/tests/helm_tests/airflow_aux/test_airflow_common.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_annotations.py b/chart/tests/helm_tests/airflow_aux/test_annotations.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_annotations.py rename to chart/tests/helm_tests/airflow_aux/test_annotations.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py b/chart/tests/helm_tests/airflow_aux/test_basic_helm_chart.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py rename to chart/tests/helm_tests/airflow_aux/test_basic_helm_chart.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_chart_quality.py b/chart/tests/helm_tests/airflow_aux/test_chart_quality.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_chart_quality.py rename to chart/tests/helm_tests/airflow_aux/test_chart_quality.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_cleanup_pods.py b/chart/tests/helm_tests/airflow_aux/test_cleanup_pods.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_cleanup_pods.py rename to chart/tests/helm_tests/airflow_aux/test_cleanup_pods.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_configmap.py b/chart/tests/helm_tests/airflow_aux/test_configmap.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_configmap.py rename to chart/tests/helm_tests/airflow_aux/test_configmap.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_container_lifecycle.py b/chart/tests/helm_tests/airflow_aux/test_container_lifecycle.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_container_lifecycle.py rename to chart/tests/helm_tests/airflow_aux/test_container_lifecycle.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_create_user_job.py b/chart/tests/helm_tests/airflow_aux/test_create_user_job.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_create_user_job.py rename to chart/tests/helm_tests/airflow_aux/test_create_user_job.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_database_cleanup.py b/chart/tests/helm_tests/airflow_aux/test_database_cleanup.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_database_cleanup.py rename to chart/tests/helm_tests/airflow_aux/test_database_cleanup.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_extra_env_env_from.py b/chart/tests/helm_tests/airflow_aux/test_extra_env_env_from.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_extra_env_env_from.py rename to chart/tests/helm_tests/airflow_aux/test_extra_env_env_from.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_job_launcher_role.py b/chart/tests/helm_tests/airflow_aux/test_job_launcher_role.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_job_launcher_role.py rename to chart/tests/helm_tests/airflow_aux/test_job_launcher_role.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_logs_persistent_volume_claim.py b/chart/tests/helm_tests/airflow_aux/test_logs_persistent_volume_claim.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_logs_persistent_volume_claim.py rename to chart/tests/helm_tests/airflow_aux/test_logs_persistent_volume_claim.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_migrate_database_job.py b/chart/tests/helm_tests/airflow_aux/test_migrate_database_job.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_migrate_database_job.py rename to chart/tests/helm_tests/airflow_aux/test_migrate_database_job.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_pod_launcher_role.py b/chart/tests/helm_tests/airflow_aux/test_pod_launcher_role.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_pod_launcher_role.py rename to chart/tests/helm_tests/airflow_aux/test_pod_launcher_role.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py b/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py rename to chart/tests/helm_tests/airflow_aux/test_pod_template_file.py diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_remote_logging.py b/chart/tests/helm_tests/airflow_aux/test_remote_logging.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_aux/test_remote_logging.py rename to chart/tests/helm_tests/airflow_aux/test_remote_logging.py diff --git a/helm-tests/tests/helm_tests/airflow_core/__init__.py b/chart/tests/helm_tests/airflow_core/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/__init__.py rename to chart/tests/helm_tests/airflow_core/__init__.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_api_server.py b/chart/tests/helm_tests/airflow_core/test_api_server.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_api_server.py rename to chart/tests/helm_tests/airflow_core/test_api_server.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_dag_processor.py b/chart/tests/helm_tests/airflow_core/test_dag_processor.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_dag_processor.py rename to chart/tests/helm_tests/airflow_core/test_dag_processor.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_env.py b/chart/tests/helm_tests/airflow_core/test_env.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_env.py rename to chart/tests/helm_tests/airflow_core/test_env.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_pdb_api_server.py b/chart/tests/helm_tests/airflow_core/test_pdb_api_server.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_pdb_api_server.py rename to chart/tests/helm_tests/airflow_core/test_pdb_api_server.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_pdb_dag_processor.py b/chart/tests/helm_tests/airflow_core/test_pdb_dag_processor.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_pdb_dag_processor.py rename to chart/tests/helm_tests/airflow_core/test_pdb_dag_processor.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_pdb_scheduler.py b/chart/tests/helm_tests/airflow_core/test_pdb_scheduler.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_pdb_scheduler.py rename to chart/tests/helm_tests/airflow_core/test_pdb_scheduler.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_pdb_triggerer.py b/chart/tests/helm_tests/airflow_core/test_pdb_triggerer.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_pdb_triggerer.py rename to chart/tests/helm_tests/airflow_core/test_pdb_triggerer.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_pdb_worker.py b/chart/tests/helm_tests/airflow_core/test_pdb_worker.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_pdb_worker.py rename to chart/tests/helm_tests/airflow_core/test_pdb_worker.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_scheduler.py b/chart/tests/helm_tests/airflow_core/test_scheduler.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_scheduler.py rename to chart/tests/helm_tests/airflow_core/test_scheduler.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_triggerer.py b/chart/tests/helm_tests/airflow_core/test_triggerer.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_triggerer.py rename to chart/tests/helm_tests/airflow_core/test_triggerer.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_worker.py b/chart/tests/helm_tests/airflow_core/test_worker.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_worker.py rename to chart/tests/helm_tests/airflow_core/test_worker.py diff --git a/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py b/chart/tests/helm_tests/airflow_core/test_worker_sets.py similarity index 100% rename from helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py rename to chart/tests/helm_tests/airflow_core/test_worker_sets.py diff --git a/helm-tests/tests/helm_tests/apiserver/test_apiserver.py b/chart/tests/helm_tests/apiserver/test_apiserver.py similarity index 100% rename from helm-tests/tests/helm_tests/apiserver/test_apiserver.py rename to chart/tests/helm_tests/apiserver/test_apiserver.py diff --git a/helm-tests/tests/helm_tests/apiserver/test_hpa_apiserver.py b/chart/tests/helm_tests/apiserver/test_hpa_apiserver.py similarity index 100% rename from helm-tests/tests/helm_tests/apiserver/test_hpa_apiserver.py rename to chart/tests/helm_tests/apiserver/test_hpa_apiserver.py diff --git a/helm-tests/tests/helm_tests/apiserver/test_ingress_apiserver.py b/chart/tests/helm_tests/apiserver/test_ingress_apiserver.py similarity index 100% rename from helm-tests/tests/helm_tests/apiserver/test_ingress_apiserver.py rename to chart/tests/helm_tests/apiserver/test_ingress_apiserver.py diff --git a/helm-tests/tests/helm_tests/dagprocessor/__init__.py b/chart/tests/helm_tests/dagprocessor/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/dagprocessor/__init__.py rename to chart/tests/helm_tests/dagprocessor/__init__.py diff --git a/helm-tests/tests/helm_tests/dagprocessor/test_labels_deployment.py b/chart/tests/helm_tests/dagprocessor/test_labels_deployment.py similarity index 100% rename from helm-tests/tests/helm_tests/dagprocessor/test_labels_deployment.py rename to chart/tests/helm_tests/dagprocessor/test_labels_deployment.py diff --git a/helm-tests/tests/helm_tests/dagprocessor/test_labels_service_account.py b/chart/tests/helm_tests/dagprocessor/test_labels_service_account.py similarity index 100% rename from helm-tests/tests/helm_tests/dagprocessor/test_labels_service_account.py rename to chart/tests/helm_tests/dagprocessor/test_labels_service_account.py diff --git a/helm-tests/tests/helm_tests/other/__init__.py b/chart/tests/helm_tests/other/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/other/__init__.py rename to chart/tests/helm_tests/other/__init__.py diff --git a/helm-tests/tests/helm_tests/other/test_dags_persistent_volume_claim.py b/chart/tests/helm_tests/other/test_dags_persistent_volume_claim.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_dags_persistent_volume_claim.py rename to chart/tests/helm_tests/other/test_dags_persistent_volume_claim.py diff --git a/helm-tests/tests/helm_tests/other/test_flower.py b/chart/tests/helm_tests/other/test_flower.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_flower.py rename to chart/tests/helm_tests/other/test_flower.py diff --git a/helm-tests/tests/helm_tests/other/test_git_ssh_key_secret.py b/chart/tests/helm_tests/other/test_git_ssh_key_secret.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_git_ssh_key_secret.py rename to chart/tests/helm_tests/other/test_git_ssh_key_secret.py diff --git a/helm-tests/tests/helm_tests/other/test_git_sync_scheduler.py b/chart/tests/helm_tests/other/test_git_sync_scheduler.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_git_sync_scheduler.py rename to chart/tests/helm_tests/other/test_git_sync_scheduler.py diff --git a/helm-tests/tests/helm_tests/other/test_git_sync_triggerer.py b/chart/tests/helm_tests/other/test_git_sync_triggerer.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_git_sync_triggerer.py rename to chart/tests/helm_tests/other/test_git_sync_triggerer.py diff --git a/helm-tests/tests/helm_tests/other/test_git_sync_worker.py b/chart/tests/helm_tests/other/test_git_sync_worker.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_git_sync_worker.py rename to chart/tests/helm_tests/other/test_git_sync_worker.py diff --git a/helm-tests/tests/helm_tests/other/test_hpa.py b/chart/tests/helm_tests/other/test_hpa.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_hpa.py rename to chart/tests/helm_tests/other/test_hpa.py diff --git a/helm-tests/tests/helm_tests/other/test_keda.py b/chart/tests/helm_tests/other/test_keda.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_keda.py rename to chart/tests/helm_tests/other/test_keda.py diff --git a/helm-tests/tests/helm_tests/other/test_limit_ranges.py b/chart/tests/helm_tests/other/test_limit_ranges.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_limit_ranges.py rename to chart/tests/helm_tests/other/test_limit_ranges.py diff --git a/helm-tests/tests/helm_tests/other/test_pdb_pgbouncer.py b/chart/tests/helm_tests/other/test_pdb_pgbouncer.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_pdb_pgbouncer.py rename to chart/tests/helm_tests/other/test_pdb_pgbouncer.py diff --git a/helm-tests/tests/helm_tests/other/test_pgbouncer.py b/chart/tests/helm_tests/other/test_pgbouncer.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_pgbouncer.py rename to chart/tests/helm_tests/other/test_pgbouncer.py diff --git a/helm-tests/tests/helm_tests/other/test_redis.py b/chart/tests/helm_tests/other/test_redis.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_redis.py rename to chart/tests/helm_tests/other/test_redis.py diff --git a/helm-tests/tests/helm_tests/other/test_resource_quota.py b/chart/tests/helm_tests/other/test_resource_quota.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_resource_quota.py rename to chart/tests/helm_tests/other/test_resource_quota.py diff --git a/helm-tests/tests/helm_tests/other/test_statsd.py b/chart/tests/helm_tests/other/test_statsd.py similarity index 100% rename from helm-tests/tests/helm_tests/other/test_statsd.py rename to chart/tests/helm_tests/other/test_statsd.py diff --git a/helm-tests/tests/helm_tests/redis/__init__.py b/chart/tests/helm_tests/redis/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/redis/__init__.py rename to chart/tests/helm_tests/redis/__init__.py diff --git a/helm-tests/tests/helm_tests/redis/test_labels_networkpolicy.py b/chart/tests/helm_tests/redis/test_labels_networkpolicy.py similarity index 100% rename from helm-tests/tests/helm_tests/redis/test_labels_networkpolicy.py rename to chart/tests/helm_tests/redis/test_labels_networkpolicy.py diff --git a/helm-tests/tests/helm_tests/redis/test_labels_service.py b/chart/tests/helm_tests/redis/test_labels_service.py similarity index 100% rename from helm-tests/tests/helm_tests/redis/test_labels_service.py rename to chart/tests/helm_tests/redis/test_labels_service.py diff --git a/helm-tests/tests/helm_tests/redis/test_labels_serviceaccount.py b/chart/tests/helm_tests/redis/test_labels_serviceaccount.py similarity index 100% rename from helm-tests/tests/helm_tests/redis/test_labels_serviceaccount.py rename to chart/tests/helm_tests/redis/test_labels_serviceaccount.py diff --git a/helm-tests/tests/helm_tests/redis/test_labels_statefulset.py b/chart/tests/helm_tests/redis/test_labels_statefulset.py similarity index 100% rename from helm-tests/tests/helm_tests/redis/test_labels_statefulset.py rename to chart/tests/helm_tests/redis/test_labels_statefulset.py diff --git a/helm-tests/tests/helm_tests/security/__init__.py b/chart/tests/helm_tests/security/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/security/__init__.py rename to chart/tests/helm_tests/security/__init__.py diff --git a/helm-tests/tests/helm_tests/security/test_elasticsearch_secret.py b/chart/tests/helm_tests/security/test_elasticsearch_secret.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_elasticsearch_secret.py rename to chart/tests/helm_tests/security/test_elasticsearch_secret.py diff --git a/helm-tests/tests/helm_tests/security/test_extra_configmaps_secrets.py b/chart/tests/helm_tests/security/test_extra_configmaps_secrets.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_extra_configmaps_secrets.py rename to chart/tests/helm_tests/security/test_extra_configmaps_secrets.py diff --git a/helm-tests/tests/helm_tests/security/test_fernetkey_secret.py b/chart/tests/helm_tests/security/test_fernetkey_secret.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_fernetkey_secret.py rename to chart/tests/helm_tests/security/test_fernetkey_secret.py diff --git a/helm-tests/tests/helm_tests/security/test_kerberos.py b/chart/tests/helm_tests/security/test_kerberos.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_kerberos.py rename to chart/tests/helm_tests/security/test_kerberos.py diff --git a/helm-tests/tests/helm_tests/security/test_metadata_connection_secret.py b/chart/tests/helm_tests/security/test_metadata_connection_secret.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_metadata_connection_secret.py rename to chart/tests/helm_tests/security/test_metadata_connection_secret.py diff --git a/helm-tests/tests/helm_tests/security/test_opensearch_secret.py b/chart/tests/helm_tests/security/test_opensearch_secret.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_opensearch_secret.py rename to chart/tests/helm_tests/security/test_opensearch_secret.py diff --git a/helm-tests/tests/helm_tests/security/test_rbac.py b/chart/tests/helm_tests/security/test_rbac.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_rbac.py rename to chart/tests/helm_tests/security/test_rbac.py diff --git a/helm-tests/tests/helm_tests/security/test_rbac_pod_launcher.py b/chart/tests/helm_tests/security/test_rbac_pod_launcher.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_rbac_pod_launcher.py rename to chart/tests/helm_tests/security/test_rbac_pod_launcher.py diff --git a/helm-tests/tests/helm_tests/security/test_rbac_pod_log_reader.py b/chart/tests/helm_tests/security/test_rbac_pod_log_reader.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_rbac_pod_log_reader.py rename to chart/tests/helm_tests/security/test_rbac_pod_log_reader.py diff --git a/helm-tests/tests/helm_tests/security/test_result_backend_connection_secret.py b/chart/tests/helm_tests/security/test_result_backend_connection_secret.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_result_backend_connection_secret.py rename to chart/tests/helm_tests/security/test_result_backend_connection_secret.py diff --git a/helm-tests/tests/helm_tests/security/test_scc_rolebinding.py b/chart/tests/helm_tests/security/test_scc_rolebinding.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_scc_rolebinding.py rename to chart/tests/helm_tests/security/test_scc_rolebinding.py diff --git a/helm-tests/tests/helm_tests/security/test_security_context.py b/chart/tests/helm_tests/security/test_security_context.py similarity index 100% rename from helm-tests/tests/helm_tests/security/test_security_context.py rename to chart/tests/helm_tests/security/test_security_context.py diff --git a/helm-tests/tests/helm_tests/statsd/__init__.py b/chart/tests/helm_tests/statsd/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/statsd/__init__.py rename to chart/tests/helm_tests/statsd/__init__.py diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_deployment.py b/chart/tests/helm_tests/statsd/test_labels_deployment.py similarity index 100% rename from helm-tests/tests/helm_tests/statsd/test_labels_deployment.py rename to chart/tests/helm_tests/statsd/test_labels_deployment.py diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_ingress.py b/chart/tests/helm_tests/statsd/test_labels_ingress.py similarity index 100% rename from helm-tests/tests/helm_tests/statsd/test_labels_ingress.py rename to chart/tests/helm_tests/statsd/test_labels_ingress.py diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_networkpolicy.py b/chart/tests/helm_tests/statsd/test_labels_networkpolicy.py similarity index 100% rename from helm-tests/tests/helm_tests/statsd/test_labels_networkpolicy.py rename to chart/tests/helm_tests/statsd/test_labels_networkpolicy.py diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_service.py b/chart/tests/helm_tests/statsd/test_labels_service.py similarity index 100% rename from helm-tests/tests/helm_tests/statsd/test_labels_service.py rename to chart/tests/helm_tests/statsd/test_labels_service.py diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_serviceaccount.py b/chart/tests/helm_tests/statsd/test_labels_serviceaccount.py similarity index 100% rename from helm-tests/tests/helm_tests/statsd/test_labels_serviceaccount.py rename to chart/tests/helm_tests/statsd/test_labels_serviceaccount.py diff --git a/contributing-docs/testing/helm_unit_tests.rst b/contributing-docs/testing/helm_unit_tests.rst index 4faacd9cb3a94..6edead0d64880 100644 --- a/contributing-docs/testing/helm_unit_tests.rst +++ b/contributing-docs/testing/helm_unit_tests.rst @@ -21,7 +21,7 @@ Helm Unit Tests On the Apache Airflow Project, we have decided to stick with pythonic testing for our Helm chart. This makes our chart easier to test, easier to modify, and able to run with the same testing infrastructure. To add Helm unit tests -add them under ``helm-tests/tests/helm_tests`` directory. +add them under ``chart/tests/helm_tests`` directory. .. code-block:: python @@ -56,14 +56,14 @@ following command (it takes quite a long time even on a multi-processor machine) breeze testing helm-tests -You can also execute tests from a selected package only. Tests in ``helm-tests/tests/helm_tests`` are grouped +You can also execute tests from a selected package only. Tests in ``chart/tests/helm_tests`` are grouped by packages so rather than running all tests, you can run only tests from a selected package. For example: .. code-block:: bash breeze testing helm-tests --test-type airflow_aux -Will run all tests from ``helm-tests/tests/helm_tests/airflow_aux`` package. +Will run all tests from ``chart/tests/helm_tests/airflow_aux`` package. You can also run Helm tests individually via the usual ``breeze`` command. Just enter breeze and run the @@ -80,19 +80,19 @@ This enters breeze container. .. code-block:: bash - pytest helm-tests -n auto + pytest chart/tests -n auto This runs all chart tests using all processors you have available. .. code-block:: bash - pytest helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py -n auto + pytest chart/tests/helm_tests/airflow_aux/test_airflow_common.py -n auto This will run all tests from ``tests_airflow_common.py`` file using all processors you have available. .. code-block:: bash - pytest helm-tests/tests/helm_tests/airflow_aux/test_airflow_common.py + pytest chart/tests/helm_tests/airflow_aux/test_airflow_common.py This will run all tests from ``tests_airflow_common.py`` file sequentially. diff --git a/dev/breeze/doc/ci/04_selective_checks.md b/dev/breeze/doc/ci/04_selective_checks.md index 0290bd9ee530e..fb0f9ef2e11a0 100644 --- a/dev/breeze/doc/ci/04_selective_checks.md +++ b/dev/breeze/doc/ci/04_selective_checks.md @@ -51,7 +51,7 @@ We have the following Groups of files for CI that determine which tests are run: * `Always test files` - Files that belong to "Always" run tests. * `API tests files` and `Codegen test files` - those are OpenAPI definition files that impact Open API specification and determine that we should run dedicated API tests. -* `Helm files` - change in those files impacts helm "rendering" tests - `chart` folder and `helm-tests` folder. +* `Helm files` - change in those files impacts helm "rendering" tests - `chart` folder (which contains the chart sources and tests under `chart/tests/`). * `Build files` - change in the files indicates that we should run `upgrade to newer dependencies` - build dependencies in `pyproject.toml` and generated dependencies files in `generated` folder. The dependencies are automatically generated from the `provider.yaml` files in provider by diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py index 4deaa3bf598b9..771b9c7e00d4f 100644 --- a/dev/breeze/src/airflow_breeze/global_constants.py +++ b/dev/breeze/src/airflow_breeze/global_constants.py @@ -360,7 +360,7 @@ def all_helm_test_packages() -> list[str]: return sorted( [ candidate.name - for candidate in (AIRFLOW_ROOT_PATH / "helm-tests" / "tests" / "helm_tests").iterdir() + for candidate in (AIRFLOW_ROOT_PATH / "chart" / "tests" / "helm_tests").iterdir() if candidate.is_dir() and candidate.name != "__pycache__" ] ) diff --git a/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py b/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py index 2f376d98e0158..5a9e8e21b62ab 100644 --- a/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py +++ b/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py @@ -101,7 +101,6 @@ ("docs", "/opt/airflow/docs"), ("generated", "/opt/airflow/generated"), ("go-sdk", "/opt/airflow/go-sdk"), - ("helm-tests", "/opt/airflow/helm-tests"), ("kubernetes-tests", "/opt/airflow/kubernetes-tests"), ("logs", "/root/airflow/logs"), ("providers", "/opt/airflow/providers"), diff --git a/dev/breeze/src/airflow_breeze/utils/run_tests.py b/dev/breeze/src/airflow_breeze/utils/run_tests.py index 752c3c66cf7c0..3bc2a2e0f7b1d 100644 --- a/dev/breeze/src/airflow_breeze/utils/run_tests.py +++ b/dev/breeze/src/airflow_breeze/utils/run_tests.py @@ -319,7 +319,7 @@ def are_all_test_paths_excluded( GroupOfTests.PROVIDERS: ALL_PROVIDER_TEST_FOLDERS, GroupOfTests.TASK_SDK: ["task-sdk/tests"], GroupOfTests.CTL: ["airflow-ctl/tests"], - GroupOfTests.HELM: ["helm-tests"], + GroupOfTests.HELM: ["chart/tests"], GroupOfTests.INTEGRATION_CORE: ["airflow-core/tests/integration"], GroupOfTests.INTEGRATION_PROVIDERS: ALL_PROVIDER_INTEGRATION_TEST_FOLDERS, GroupOfTests.PYTHON_API_CLIENT: ["clients/python"], @@ -398,7 +398,7 @@ def convert_test_type_to_pytest_args( sys.exit(1) helm_folder = TEST_GROUP_TO_TEST_FOLDERS[test_group][0] if test_type and test_type != ALL_TEST_TYPE: - return [f"{helm_folder}/tests/helm_tests/{test_type}"] + return [f"{helm_folder}/helm_tests/{test_type}"] return [helm_folder] if test_type == SelectiveCoreTestType.OTHER.value and test_group == GroupOfTests.CORE: return find_all_other_tests() diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py b/dev/breeze/src/airflow_breeze/utils/selective_checks.py index 27660b3fea841..e0639b22e9584 100644 --- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py +++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py @@ -236,7 +236,6 @@ def __hash__(self): r"^chart", r"^airflow-core/src/airflow/kubernetes", r"^airflow-core/tests/unit/kubernetes", - r"^helm-tests", ], FileGroupForCi.DOC_FILES: [ r"^docs", @@ -303,7 +302,7 @@ def __hash__(self): r"^scripts/.*\.py$", ], FileGroupForCi.ALL_HELM_TESTS_PYTHON_FILES: [ - r"^helm-tests/.*\.py$", + r"^chart/tests/.*\.py$", ], FileGroupForCi.ALL_AIRFLOW_E2E_TESTS_PYTHON_FILES: [ r"^airflow-e2e-tests/.*\.py$", @@ -328,7 +327,7 @@ def __hash__(self): r"^task-sdk/tests/.*", r"^devel-common/src/.*", r"^devel-common/tests/.*", - r"^helm-tests/tests/.*", + r"^chart/tests/.*", r"^kubernetes-tests/tests/.*", r"^docker-tests/tests/.*", ], diff --git a/dev/breeze/tests/test_pytest_args_for_test_types.py b/dev/breeze/tests/test_pytest_args_for_test_types.py index e184a70a357d7..4332d8dceb7d6 100644 --- a/dev/breeze/tests/test_pytest_args_for_test_types.py +++ b/dev/breeze/tests/test_pytest_args_for_test_types.py @@ -183,12 +183,12 @@ def _find_all_integration_folders() -> list[str]: ( GroupOfTests.HELM, "All", - ["helm-tests"], + ["chart/tests"], ), ( GroupOfTests.HELM, "airflow_aux", - ["helm-tests/tests/helm_tests/airflow_aux"], + ["chart/tests/helm_tests/airflow_aux"], ), ], ) @@ -304,7 +304,7 @@ def test_pytest_args_for_missing_provider(): GroupOfTests.HELM, "All", [ - "helm-tests", + "chart/tests", ], ), ( diff --git a/dev/breeze/tests/test_selective_checks.py b/dev/breeze/tests/test_selective_checks.py index 7ffd1370475ec..d8cbd2737a9ba 100644 --- a/dev/breeze/tests/test_selective_checks.py +++ b/dev/breeze/tests/test_selective_checks.py @@ -2623,7 +2623,7 @@ def test_docs_filter(files: tuple[str, ...], expected_outputs: dict[str, str]): ("files", "expected_outputs"), [ pytest.param( - ("helm-tests/tests/helm_tests/random_helm_test.py",), + ("chart/tests/helm_tests/random_helm_test.py",), { "ci-image-build": "true", "prod-image-build": "true", @@ -3700,7 +3700,7 @@ def side_effect(*args, **kwargs): ("files", "pr_labels", "expected_outputs"), [ pytest.param( - ("helm-tests/tests/helm_tests/random_helm_test.py",), + ("chart/tests/helm_tests/random_helm_test.py",), (), { "helm-test-kubernetes-versions": DEFAULT_HELM_K8S_VERSIONS_JSON, @@ -3708,7 +3708,7 @@ def side_effect(*args, **kwargs): id="Default K8s version when no all-versions label", ), pytest.param( - ("helm-tests/tests/helm_tests/random_helm_test.py",), + ("chart/tests/helm_tests/random_helm_test.py",), ("all versions",), { "helm-test-kubernetes-versions": ALL_HELM_K8S_VERSIONS_JSON, diff --git a/dev/ide_setup/setup_idea.py b/dev/ide_setup/setup_idea.py index 7cf570d6da336..6bdfd6b228201 100755 --- a/dev/ide_setup/setup_idea.py +++ b/dev/ide_setup/setup_idea.py @@ -60,7 +60,7 @@ "dev/breeze", "docker-tests", "kubernetes-tests", - "helm-tests", + "chart/tests", "scripts", "task-sdk-integration-tests", ] diff --git a/dev/update_github_branch_config.py b/dev/update_github_branch_config.py index 0cdb1691dd00f..757000ab22159 100755 --- a/dev/update_github_branch_config.py +++ b/dev/update_github_branch_config.py @@ -107,7 +107,7 @@ def update_dependabot(new_branch: str, prev_branch: str, new_dash: str) -> None: - /dev/breeze - /docker-tests - /kubernetes-tests - - /helm-tests + - /chart - /task-sdk - / schedule: diff --git a/helm-tests/.gitignore b/helm-tests/.gitignore deleted file mode 100644 index bff2d7629604d..0000000000000 --- a/helm-tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.iml diff --git a/helm-tests/.pre-commit-config.yaml b/helm-tests/.pre-commit-config.yaml deleted file mode 100644 index b654d6994cea4..0000000000000 --- a/helm-tests/.pre-commit-config.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# 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. ---- -default_stages: [pre-commit, pre-push] -minimum_prek_version: '0.3.4' -default_language_version: - python: python3 -repos: - - repo: local - hooks: - - id: mypy-helm-tests - name: Run mypy for helm-tests - language: python - entry: ../scripts/ci/prek/run_mypy_full_dist_local_venv_or_breeze_in_ci.py helm-tests - pass_filenames: false - files: ^.*\.py$ - require_serial: true diff --git a/helm-tests/pyproject.toml b/helm-tests/pyproject.toml deleted file mode 100644 index 5b16df07f28a6..0000000000000 --- a/helm-tests/pyproject.toml +++ /dev/null @@ -1,81 +0,0 @@ - -# 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. - -[build-system] -requires = [ - "hatchling==1.29.0", - "packaging==26.2", - "pathspec==1.1.1", - "pluggy==1.6.0", - "tomli==2.4.1; python_version < '3.11'", - "trove-classifiers==2026.4.28.13", -] -build-backend = "hatchling.build" - -[project] -name = "apache-airflow-helm-tests" -description = "Helm tests for Apache Airflow" -classifiers = [ - "Private :: Do Not Upload", -] -requires-python = ">=3.10,!=3.15" -authors = [ - { name = "Apache Software Foundation", email = "dev@airflow.apache.org" }, -] -maintainers = [ - { name = "Apache Software Foundation", email="dev@airflow.apache.org" }, -] -version = "0.0.1" -dependencies = [ - "apache-airflow-devel-common", - "apache-airflow-providers-cncf-kubernetes", -] - -[tool.pytest] -addopts = [ - "-rasl", - "--verbosity=2", - "-p", "no:flaky", - "-p", "no:nose", - "-p", "no:legacypath", -] -norecursedirs = [ - ".eggs", -] -log_level = "INFO" -filterwarnings = [ - "error::pytest.PytestCollectionWarning", -] -python_files = [ - "*.py", -] - -# Keep temporary directories (created by `tmp_path`) for 2 recent runs only failed tests. -tmp_path_retention_count = "2" -tmp_path_retention_policy = "failed" - -[tool.hatch.build.targets.sdist] -exclude = ["*"] - -[tool.hatch.build.targets.wheel] -bypass-selection = true - -[dependency-groups] -mypy = [ - "apache-airflow-devel-common[mypy]", -] diff --git a/pyproject.toml b/pyproject.toml index 4a988db2d3ea7..b460aa55275b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -794,7 +794,7 @@ testing = ["dev", "providers.tests", "tests_common", "tests", "system", "unit", "docker-tests/*" = ["D", "TID253", "S101", "TRY002"] "task-sdk-integration-tests/*" = ["D", "TID253", "S101", "TRY002"] "kubernetes-tests/*" = ["D", "TID253", "S101", "TRY002"] -"helm-tests/*" = ["D", "TID253", "S101", "TRY002"] +"chart/tests/*" = ["D", "TID253", "S101", "TRY002"] "providers/**/tests/*" = ["D", "TID253", "S101", "TRY002"] "performance/tests/*" = ["S101"] "dev/registry/tests/*" = ["S101"] @@ -847,7 +847,7 @@ testing = ["dev", "providers.tests", "tests_common", "tests", "system", "unit", "devel-common/src/sphinx_exts/exampleinclude.py" = ["E402", 'F401', ] # All the modules which do not follow B028 yet: https://docs.astral.sh/ruff/rules/no-explicit-stacklevel/ -"helm-tests/tests/helm_tests/airflow_aux/test_basic_helm_chart.py" = ["B028"] +"chart/tests/helm_tests/airflow_aux/test_basic_helm_chart.py" = ["B028"] # While pandas import is banned, sql.pyi should be excluded from it as it does not have a TYPE_CHECKING # mechanism and whole .pyi is really "type-checking" only @@ -1053,7 +1053,7 @@ mypy_path = [ "$MYPY_CONFIG_FILE_DIR/airflow-ctl-tests/tests", "$MYPY_CONFIG_FILE_DIR/dev", "$MYPY_CONFIG_FILE_DIR/devel-common/src", - "$MYPY_CONFIG_FILE_DIR/helm-tests/tests", + "$MYPY_CONFIG_FILE_DIR/chart/tests", "$MYPY_CONFIG_FILE_DIR/kubernetes-tests/tests", "$MYPY_CONFIG_FILE_DIR/docker-tests/tests", "$MYPY_CONFIG_FILE_DIR/task-sdk-integration-tests/tests", @@ -1310,7 +1310,7 @@ dev = [ "apache-airflow-devel-common[no-doc]", "apache-airflow-docker-tests", "apache-airflow-task-sdk-integration-tests", - "apache-airflow-helm-tests", + "apache-airflow-helm-chart", "apache-airflow-kubernetes-tests", "apache-airflow-task-sdk[all]", "apache-airflow-ctl", @@ -1377,7 +1377,7 @@ apache-airflow-dev = false apache-airflow-devel-common = false apache-airflow-docker-tests = false apache-airflow-e2e-tests = false -apache-airflow-helm-tests = false +apache-airflow-helm-chart = false apache-airflow-kubernetes-tests = false apache-airflow-mypy = false apache-airflow-providers = false @@ -1528,7 +1528,7 @@ apache-airflow-dev = false apache-airflow-devel-common = false apache-airflow-docker-tests = false apache-airflow-e2e-tests = false -apache-airflow-helm-tests = false +apache-airflow-helm-chart = false apache-airflow-kubernetes-tests = false apache-airflow-mypy = false apache-airflow-providers = false @@ -1674,7 +1674,7 @@ apache-airflow-devel-common = { workspace = true } apache-airflow-docker-tests = { workspace = true } apache-airflow-e2e-tests = { workspace = true } apache-airflow-task-sdk-integration-tests = { workspace = true } -apache-airflow-helm-tests = { workspace = true } +apache-airflow-helm-chart = { workspace = true } apache-airflow-kubernetes-tests = { workspace = true } apache-airflow-providers = { workspace = true } apache-aurflow-docker-stack = { workspace = true } @@ -1810,7 +1810,7 @@ members = [ "scripts", "docker-tests", "task-sdk-integration-tests", - "helm-tests", + "chart", "kubernetes-tests", "task-sdk", "providers-summary-docs", diff --git a/scripts/ci/docker-compose/local.yml b/scripts/ci/docker-compose/local.yml index 185f2f385c344..f91198189f6db 100644 --- a/scripts/ci/docker-compose/local.yml +++ b/scripts/ci/docker-compose/local.yml @@ -96,9 +96,6 @@ services: - type: bind source: ../../../go-sdk target: /opt/airflow/go-sdk - - type: bind - source: ../../../helm-tests - target: /opt/airflow/helm-tests - type: bind source: ../../../kubernetes-tests target: /opt/airflow/kubernetes-tests diff --git a/scripts/ci/prek/run_mypy_full_dist_local_venv_or_breeze_in_ci.py b/scripts/ci/prek/run_mypy_full_dist_local_venv_or_breeze_in_ci.py index 80d0d7d7ebb8e..ebe9749c4f9e2 100755 --- a/scripts/ci/prek/run_mypy_full_dist_local_venv_or_breeze_in_ci.py +++ b/scripts/ci/prek/run_mypy_full_dist_local_venv_or_breeze_in_ci.py @@ -24,7 +24,7 @@ """Run mypy on entire folders using local virtualenv (uv) instead of breeze. Used for non-provider projects: airflow-core, task-sdk, airflow-ctl, dev, scripts, -devel-common, airflow-ctl-tests, helm-tests, airflow-e2e-tests, +devel-common, airflow-ctl-tests, chart/tests, airflow-e2e-tests, task-sdk-integration-tests, docker-tests, kubernetes-tests, shared. """ @@ -65,7 +65,7 @@ "task-sdk", "airflow-ctl", "airflow-ctl-tests", - "helm-tests", + "chart/tests", "airflow-e2e-tests", "task-sdk-integration-tests", "docker-tests", @@ -83,6 +83,9 @@ # Map folder(s) to the uv project to use for running mypy. # When multiple folders are checked together, the first folder's project is used. FOLDER_TO_PROJECT = {f: f for f in ALLOWED_FOLDERS} +# `chart/tests` is not its own uv workspace member — it lives inside the +# `chart` workspace member, which carries the merged pyproject.toml. +FOLDER_TO_PROJECT["chart/tests"] = "chart" # Projects that ship their own [tool.mypy] configuration in their pyproject.toml; # mypy must be invoked with --config-file pointing at that file so those sections diff --git a/uv.lock b/uv.lock index ddebdf7a493e8..b340ee8361833 100644 --- a/uv.lock +++ b/uv.lock @@ -43,12 +43,11 @@ apache-airflow-providers-opensearch = false apache-airflow-providers-samba = false apache-airflow-providers-arangodb = false apache-airflow-providers-apache-spark = false -apache-airflow-helm-tests = false apache-airflow-providers-ftp = false apache-airflow-providers-jenkins = false apache-airflow-shared-listeners = false -apache-airflow-providers-telegram = false apache-airflow-shared-providers-discovery = false +apache-airflow-providers-telegram = false apache-airflow-providers-celery = false apache-airflow-providers-docker = false apache-airflow-providers-sendgrid = false @@ -67,6 +66,7 @@ apache-airflow-providers-alibaba = false apache-airflow-providers-microsoft-mssql = false apache-airflow-providers-teradata = false apache-airflow-providers-jdbc = false +apache-airflow-helm-chart = false apache-airflow-providers-common-io = false apache-airflow-providers-cohere = false apache-airflow-providers-pinecone = false @@ -110,8 +110,8 @@ uv = { timestamp = "0001-01-01T00:00:00Z", span = "PT12H" } apache-airflow-kubernetes-tests = false apache-airflow-providers-grpc = false apache-airflow-providers-apache-druid = false -apache-airflow-providers-cncf-kubernetes = false apache-airflow-providers-apache-flink = false +apache-airflow-providers-cncf-kubernetes = false apache-airflow-providers-apache-pig = false apache-airflow-providers-apache-tinkerpop = false apache-airflow-shared-timezones = false @@ -165,7 +165,7 @@ members = [ "apache-airflow-devel-common", "apache-airflow-docker-tests", "apache-airflow-e2e-tests", - "apache-airflow-helm-tests", + "apache-airflow-helm-chart", "apache-airflow-kubernetes-tests", "apache-airflow-mypy", "apache-airflow-providers", @@ -1423,7 +1423,7 @@ dev = [ { name = "apache-airflow-dev" }, { name = "apache-airflow-devel-common", extra = ["no-doc"] }, { name = "apache-airflow-docker-tests" }, - { name = "apache-airflow-helm-tests" }, + { name = "apache-airflow-helm-chart" }, { name = "apache-airflow-kubernetes-tests" }, { name = "apache-airflow-scripts" }, { name = "apache-airflow-shared-configuration" }, @@ -1696,7 +1696,7 @@ dev = [ { name = "apache-airflow-dev", editable = "dev" }, { name = "apache-airflow-devel-common", extras = ["no-doc"], editable = "devel-common" }, { name = "apache-airflow-docker-tests", editable = "docker-tests" }, - { name = "apache-airflow-helm-tests", editable = "helm-tests" }, + { name = "apache-airflow-helm-chart", editable = "chart" }, { name = "apache-airflow-kubernetes-tests", editable = "kubernetes-tests" }, { name = "apache-airflow-scripts", editable = "scripts" }, { name = "apache-airflow-shared-configuration", editable = "shared/configuration" }, @@ -2644,27 +2644,34 @@ requires-dist = [ mypy = [{ name = "apache-airflow-devel-common", extras = ["mypy"], editable = "devel-common" }] [[package]] -name = "apache-airflow-helm-tests" +name = "apache-airflow-helm-chart" version = "0.0.1" -source = { editable = "helm-tests" } +source = { editable = "chart" } dependencies = [ + { name = "apache-airflow-core" }, { name = "apache-airflow-devel-common" }, { name = "apache-airflow-providers-cncf-kubernetes" }, ] [package.dev-dependencies] +docs = [ + { name = "apache-airflow-devel-common", extra = ["docs"] }, +] mypy = [ { name = "apache-airflow-devel-common", extra = ["mypy"] }, ] [package.metadata] requires-dist = [ + { name = "apache-airflow-core", editable = "airflow-core" }, { name = "apache-airflow-devel-common", editable = "devel-common" }, { name = "apache-airflow-providers-cncf-kubernetes", editable = "providers/cncf/kubernetes" }, ] [package.metadata.requires-dev] +docs = [{ name = "apache-airflow-devel-common", extras = ["docs"], editable = "devel-common" }] mypy = [{ name = "apache-airflow-devel-common", extras = ["mypy"], editable = "devel-common" }] +packages = [] [[package]] name = "apache-airflow-kubernetes-tests" @@ -20295,8 +20302,8 @@ name = "secretstorage" version = "3.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cryptography", marker = "python_full_version >= '3.14' or platform_machine != 'arm64' or sys_platform != 'darwin'" }, - { name = "jeepney", marker = "python_full_version >= '3.14' or platform_machine != 'arm64' or sys_platform != 'darwin'" }, + { name = "cryptography", marker = "(python_full_version >= '3.14' and sys_platform == 'darwin') or (python_full_version < '3.15' and sys_platform == 'emscripten') or (python_full_version < '3.15' and sys_platform == 'win32') or (platform_machine != 'arm64' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32')" }, + { name = "jeepney", marker = "(python_full_version >= '3.14' and sys_platform == 'darwin') or (python_full_version < '3.15' and sys_platform == 'emscripten') or (python_full_version < '3.15' and sys_platform == 'win32') or (platform_machine != 'arm64' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" } wheels = [ From c6b1749cd0d12ca912fdd50c5da6ccccb5ff7040 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Tue, 5 May 2026 10:41:55 +0200 Subject: [PATCH 2/3] Tighten chart/.helmignore and verify packaged chart contents in CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Locally building the chart with `breeze release-management prepare-helm-chart-package` after the helm-tests → chart/tests move revealed that the published chart `.tgz` was bundling four files that chart consumers do not need and that we did not realise had been shipping for a while: * `pyproject.toml` (workspace-member metadata for the chart's pytest / mypy config — irrelevant to consumers) * `.pre-commit-config.yaml` (local dev/CI hook config) * `docs/` (chart documentation source — rendered to airflow.apache.org/docs/helm-chart/, not needed inside the .tgz) * `newsfragments/` (towncrier source for building RELEASE_NOTES.rst at release time) Add all four to `chart/.helmignore` so they are no longer bundled. To make sure this doesn't drift again, add a small verification script `scripts/ci/verify_helm_chart_package.py` that: * Reads the packaged `.tgz` and asserts the top-level entries match an explicit allowlist (Chart.yaml, values.yaml, templates/, etc.). Any newly-introduced top-level file fails the check until it is either added to the allowlist (chart-relevant) or to `.helmignore` (dev-only). * Runs `helm lint` against the same `.tgz`. Wire the script into the existing `tests-helm-release` job in `.github/workflows/helm-tests.yml`, right after `prepare-helm-chart-package` produces the artifact and before signing, so a regression in the packaged set fails CI immediately. The script is also runnable locally: uv run scripts/ci/verify_helm_chart_package.py dist/airflow-1.22.0.tgz --- .github/workflows/helm-tests.yml | 3 + chart/.helmignore | 10 ++ scripts/ci/verify_helm_chart_package.py | 181 ++++++++++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100755 scripts/ci/verify_helm_chart_package.py diff --git a/.github/workflows/helm-tests.yml b/.github/workflows/helm-tests.yml index 0137e17a62242..947ec7061f8f3 100644 --- a/.github/workflows/helm-tests.yml +++ b/.github/workflows/helm-tests.yml @@ -134,6 +134,9 @@ jobs: - name: "Helm release package" run: > breeze release-management prepare-helm-chart-package --sign-email dev@airflow.apache.org + - name: "Verify packaged chart contents and lint" + run: > + uv run scripts/ci/verify_helm_chart_package.py dist/airflow-*.tgz - name: "Sign artifacts for ASF distribution" run: ./dev/sign.sh dist/airflow-*.tgz dist/airflow-*-source.tar.gz env: diff --git a/chart/.helmignore b/chart/.helmignore index 6d231e11b673e..7f07373a08100 100644 --- a/chart/.helmignore +++ b/chart/.helmignore @@ -40,3 +40,13 @@ bin # We do not want to include our Python Helm Chart Unit test files tests +# Workspace-member metadata for the chart's pytest / mypy config — irrelevant +# to chart consumers. +pyproject.toml +# Local dev/CI hook config — irrelevant to chart consumers. +.pre-commit-config.yaml +# Chart documentation source (rendered to airflow.apache.org/docs/helm-chart/); +# chart consumers do not need the rst sources shipped inside the .tgz. +docs/ +# towncrier source fragments used to build RELEASE_NOTES.rst at release time. +newsfragments/ diff --git a/scripts/ci/verify_helm_chart_package.py b/scripts/ci/verify_helm_chart_package.py new file mode 100755 index 0000000000000..4621b54cd5277 --- /dev/null +++ b/scripts/ci/verify_helm_chart_package.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python3 +# 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. +# +# Verify a packaged Apache Airflow Helm chart `.tgz`: +# +# * Top-level entries match an explicit expected list (no IDE files, +# workspace metadata, dev hook configs, or test sources sneak into the +# published package). +# * `helm lint` passes against the packaged tarball. +# +# Used by the `tests-helm-release` job in `.github/workflows/helm-tests.yml` +# right after `breeze release-management prepare-helm-chart-package` has +# produced the chart `.tgz`. Can also be run locally: +# +# uv run scripts/ci/verify_helm_chart_package.py dist/airflow-1.22.0.tgz +# +# The expected top-level set is defined inline below; update it deliberately +# when a chart-level file is genuinely added or removed. Anything ignored via +# `chart/.helmignore` should not appear here. +# +# /// script +# requires-python = ">=3.10" +# dependencies = [] +# /// +from __future__ import annotations + +import argparse +import shutil +import subprocess +import sys +import tarfile +from pathlib import Path + +# Files / directories expected at the top level of the packaged chart, i.e. +# inside the `airflow/` directory of `airflow-.tgz`. Sorted for +# deterministic diffs. If you add or remove a file at the chart root, update +# this list along with `chart/.helmignore` (which controls what `helm package` +# bundles) so the two stay in sync. +EXPECTED_TOP_LEVEL: frozenset[str] = frozenset( + { + ".helmignore", + "Chart.lock", + "Chart.yaml", + "INSTALL", + "LICENSE", + "NOTICE", + "README.md", + "RELEASE_NOTES.rst", + "charts", + "dockerfiles", + "files", + "reproducible_build.yaml", + "templates", + "values.schema.json", + "values.yaml", + "values_schema.schema.json", + } +) + + +def _tarball_top_level(tarball: Path) -> tuple[str, set[str]]: + """ + Read the chart `.tgz` and return (chart_dir_name, set_of_top_level_entries). + + `helm package` produces an archive whose entries are all rooted under a + single directory named after the chart (e.g. `airflow/`). We strip that + prefix to compare against EXPECTED_TOP_LEVEL. + """ + chart_dirs: set[str] = set() + top_level: set[str] = set() + with tarfile.open(tarball, mode="r:gz") as tar: + for member in tar.getmembers(): + parts = Path(member.name).parts + if not parts: + continue + chart_dirs.add(parts[0]) + if len(parts) == 1: + # The root chart dir entry itself; ignore it for the + # top-level comparison. + continue + top_level.add(parts[1]) + + if len(chart_dirs) != 1: + raise SystemExit( + f"FAIL: expected the tarball to contain a single top-level chart " + f"directory, found {sorted(chart_dirs)} in {tarball}" + ) + return next(iter(chart_dirs)), top_level + + +def _check_top_level(tarball: Path) -> tuple[str, bool]: + chart_dir, actual = _tarball_top_level(tarball) + extra = sorted(actual - EXPECTED_TOP_LEVEL) + missing = sorted(EXPECTED_TOP_LEVEL - actual) + ok = not extra and not missing + + print(f"chart-dir: {chart_dir}") + print(f"top-level entries observed ({len(actual)}):") + for name in sorted(actual): + marker = "+" if name not in EXPECTED_TOP_LEVEL else " " + print(f" {marker} {name}") + if extra: + print() + print(f"FAIL: unexpected top-level entries shipped in {tarball.name}:") + for name in extra: + print(f" + {name}") + print() + print( + "Either add the file to chart/.helmignore so it is not bundled, " + "or — if it is genuinely a chart-consumer-relevant addition — " + "extend EXPECTED_TOP_LEVEL in this script." + ) + if missing: + print() + print(f"FAIL: expected top-level entries missing from {tarball.name}:") + for name in missing: + print(f" - {name}") + print() + print( + "If the file was genuinely removed from the chart on purpose, " + "drop it from EXPECTED_TOP_LEVEL in this script." + ) + return chart_dir, ok + + +def _run_helm_lint(tarball: Path) -> bool: + helm = shutil.which("helm") + if helm is None: + print("FAIL: `helm` not found on PATH; cannot lint the chart.") + return False + print() + print(f"$ helm lint {tarball}") + proc = subprocess.run([helm, "lint", str(tarball)], check=False) + return proc.returncode == 0 + + +def main() -> int: + parser = argparse.ArgumentParser( + description="Verify a packaged Apache Airflow Helm chart.", + ) + parser.add_argument( + "tarball", + type=Path, + help="Path to the packaged chart, e.g. dist/airflow-1.22.0.tgz", + ) + args = parser.parse_args() + + tarball: Path = args.tarball + if not tarball.is_file(): + print(f"FAIL: not a file: {tarball}") + return 1 + + print(f"Verifying packaged chart: {tarball}") + print() + _, top_level_ok = _check_top_level(tarball) + lint_ok = _run_helm_lint(tarball) + + print() + print("=== Summary ===") + print(f" top-level contents: {'OK' if top_level_ok else 'FAIL'}") + print(f" helm lint: {'OK' if lint_ok else 'FAIL'}") + return 0 if top_level_ok and lint_ok else 1 + + +if __name__ == "__main__": + sys.exit(main()) From 2f09095e72746473dd30147ef4ee36d7a834ddb8 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Thu, 7 May 2026 04:35:53 +0200 Subject: [PATCH 3/3] Move missed otel_collector helm tests and ignore kustomize-overlays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes two regressions caught by CI after the rebase: * `helm-tests/tests/helm_tests/otel_collector/` was added on main after the original move commit was authored, so the rebase didn't pick it up. Move it to `chart/tests/helm_tests/otel_collector/` so the helm-tests tree is fully consolidated under chart/ as intended, and ruff / helm-tests no longer trip over the orphaned directory. * The packaged-chart verification script flagged `kustomize-overlays/` as an unexpected top-level entry. The directory's own README states it is "not distributed with chart releases" — add it to `chart/.helmignore` so the .tgz matches that documented intent. Refresh the breeze helm-tests command-help SVG/txt picked up by the auto-fixer prek hook (now that breeze sees `otel_collector` as a valid sub-package under `chart/tests/helm_tests/`). --- chart/.helmignore | 3 +++ .../tests/helm_tests/otel_collector/__init__.py | 0 .../tests/helm_tests/otel_collector/test_labels_deployment.py | 0 .../helm_tests/otel_collector/test_labels_networkpolicy.py | 0 .../tests/helm_tests/otel_collector/test_labels_service.py | 0 .../helm_tests/otel_collector/test_labels_serviceaccount.py | 0 .../tests/helm_tests/otel_collector/test_otel_collector.py | 0 7 files changed, 3 insertions(+) rename {helm-tests => chart}/tests/helm_tests/otel_collector/__init__.py (100%) rename {helm-tests => chart}/tests/helm_tests/otel_collector/test_labels_deployment.py (100%) rename {helm-tests => chart}/tests/helm_tests/otel_collector/test_labels_networkpolicy.py (100%) rename {helm-tests => chart}/tests/helm_tests/otel_collector/test_labels_service.py (100%) rename {helm-tests => chart}/tests/helm_tests/otel_collector/test_labels_serviceaccount.py (100%) rename {helm-tests => chart}/tests/helm_tests/otel_collector/test_otel_collector.py (100%) diff --git a/chart/.helmignore b/chart/.helmignore index 7f07373a08100..c2acd301a7584 100644 --- a/chart/.helmignore +++ b/chart/.helmignore @@ -50,3 +50,6 @@ pyproject.toml docs/ # towncrier source fragments used to build RELEASE_NOTES.rst at release time. newsfragments/ +# Reference Kustomize overlays — published in the source tree, explicitly NOT +# distributed inside the chart .tgz (see kustomize-overlays/README.rst). +kustomize-overlays/ diff --git a/helm-tests/tests/helm_tests/otel_collector/__init__.py b/chart/tests/helm_tests/otel_collector/__init__.py similarity index 100% rename from helm-tests/tests/helm_tests/otel_collector/__init__.py rename to chart/tests/helm_tests/otel_collector/__init__.py diff --git a/helm-tests/tests/helm_tests/otel_collector/test_labels_deployment.py b/chart/tests/helm_tests/otel_collector/test_labels_deployment.py similarity index 100% rename from helm-tests/tests/helm_tests/otel_collector/test_labels_deployment.py rename to chart/tests/helm_tests/otel_collector/test_labels_deployment.py diff --git a/helm-tests/tests/helm_tests/otel_collector/test_labels_networkpolicy.py b/chart/tests/helm_tests/otel_collector/test_labels_networkpolicy.py similarity index 100% rename from helm-tests/tests/helm_tests/otel_collector/test_labels_networkpolicy.py rename to chart/tests/helm_tests/otel_collector/test_labels_networkpolicy.py diff --git a/helm-tests/tests/helm_tests/otel_collector/test_labels_service.py b/chart/tests/helm_tests/otel_collector/test_labels_service.py similarity index 100% rename from helm-tests/tests/helm_tests/otel_collector/test_labels_service.py rename to chart/tests/helm_tests/otel_collector/test_labels_service.py diff --git a/helm-tests/tests/helm_tests/otel_collector/test_labels_serviceaccount.py b/chart/tests/helm_tests/otel_collector/test_labels_serviceaccount.py similarity index 100% rename from helm-tests/tests/helm_tests/otel_collector/test_labels_serviceaccount.py rename to chart/tests/helm_tests/otel_collector/test_labels_serviceaccount.py diff --git a/helm-tests/tests/helm_tests/otel_collector/test_otel_collector.py b/chart/tests/helm_tests/otel_collector/test_otel_collector.py similarity index 100% rename from helm-tests/tests/helm_tests/otel_collector/test_otel_collector.py rename to chart/tests/helm_tests/otel_collector/test_otel_collector.py