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/.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/.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/.helmignore b/chart/.helmignore index 6d231e11b673e..c2acd301a7584 100644 --- a/chart/.helmignore +++ b/chart/.helmignore @@ -40,3 +40,16 @@ 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/ +# 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/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/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 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/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()) 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 = [