This is an automated email from the ASF dual-hosted git repository.

kaxilnaik pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 6177bd637fa Check chart annotations with pre-commit (#52365)
6177bd637fa is described below

commit 6177bd637fa343e4a76fddce3dd23091a93af112
Author: Jed Cunningham <[email protected]>
AuthorDate: Fri Jun 27 16:43:00 2025 -0600

    Check chart annotations with pre-commit (#52365)
    
    It's easy to get "valid" helm annotations, but still be invalid
    artifacthub annotations because they are strings with yaml in them.
    Let's validate the strings are valid yaml too.
---
 .pre-commit-config.yaml                            |  7 ++
 chart/Chart.yaml                                   |  2 +-
 contributing-docs/08_static_code_checks.rst        |  2 +
 dev/breeze/doc/images/output_static-checks.svg     |  4 +-
 dev/breeze/doc/images/output_static-checks.txt     |  2 +-
 dev/breeze/src/airflow_breeze/pre_commit_ids.py    |  1 +
 .../ci/pre_commit/validate_chart_annotations.py    | 75 ++++++++++++++++++++++
 7 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index c31f3d6d7b1..265f52fd1c2 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -924,6 +924,13 @@ repos:
         files: ^chart
         require_serial: true
         additional_dependencies: ['rich>=12.4.4','requests>=2.31.0']
+      - id: validate-chart-annotations
+        name: Validate chart annotations
+        entry: ./scripts/ci/pre_commit/validate_chart_annotations.py
+        language: python
+        pass_filenames: false
+        files: ^chart/Chart\.yaml$
+        additional_dependencies: ['pyyaml>=6.0.2', 'rich>=12.4.4']
       - id: kubeconform
         name: Kubeconform check on our helm chart
         entry: ./scripts/ci/pre_commit/check_kubeconform.py
diff --git a/chart/Chart.yaml b/chart/Chart.yaml
index f53fc21407e..5f247d5650e 100644
--- a/chart/Chart.yaml
+++ b/chart/Chart.yaml
@@ -136,7 +136,7 @@ annotations:
     - description: 'Fix execution_api_server_url when base_url has a subpath'
       kind: changed
       links:
-      - name: '#51454
+      - name: '#51454'
         url: https://github.com/apache/airflow/pull/51454
     - description: 'Docs: Bump minimum helm version in docs'
       kind: changed
diff --git a/contributing-docs/08_static_code_checks.rst 
b/contributing-docs/08_static_code_checks.rst
index db0c4e3129d..70fd44db68d 100644
--- a/contributing-docs/08_static_code_checks.rst
+++ b/contributing-docs/08_static_code_checks.rst
@@ -412,6 +412,8 @@ require Breeze Docker image to be built locally.
 
+-----------------------------------------------------------+--------------------------------------------------------+---------+
 | update-version                                            | Update versions 
in docs                                |         |
 
+-----------------------------------------------------------+--------------------------------------------------------+---------+
+| validate-chart-annotations                                | Validate chart 
annotations                             |         |
++-----------------------------------------------------------+--------------------------------------------------------+---------+
 | validate-operators-init                                   | No templated 
field logic checks in operator __init__   |         |
 
+-----------------------------------------------------------+--------------------------------------------------------+---------+
 | yamllint                                                  | Check YAML files 
with yamllint                         |         |
diff --git a/dev/breeze/doc/images/output_static-checks.svg 
b/dev/breeze/doc/images/output_static-checks.svg
index 9918dedfb8b..0e6fb97574d 100644
--- a/dev/breeze/doc/images/output_static-checks.svg
+++ b/dev/breeze/doc/images/output_static-checks.svg
@@ -384,8 +384,8 @@
 </text><text class="breeze-static-checks-r5" x="0" y="1410.8" 
textLength="12.2" clip-path="url(#breeze-static-checks-line-57)">│</text><text 
class="breeze-static-checks-r7" x="451.4" y="1410.8" textLength="988.2" 
clip-path="url(#breeze-static-checks-line-57)">update-providers-build-files&#160;|&#160;update-providers-dependencies&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-static-checks- [...]
 </text><text class="breeze-static-checks-r5" x="0" y="1435.2" 
textLength="12.2" clip-path="url(#breeze-static-checks-line-58)">│</text><text 
class="breeze-static-checks-r7" x="451.4" y="1435.2" textLength="988.2" 
clip-path="url(#breeze-static-checks-line-58)">update-pyproject-toml&#160;|&#160;update-reproducible-source-date-epoch&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-static-checks-r5" x [...]
 </text><text class="breeze-static-checks-r5" x="0" y="1459.6" 
textLength="12.2" clip-path="url(#breeze-static-checks-line-59)">│</text><text 
class="breeze-static-checks-r7" x="451.4" y="1459.6" textLength="988.2" 
clip-path="url(#breeze-static-checks-line-59)">update-spelling-wordlist-to-be-sorted&#160;|&#160;update-supported-versions&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text
 class="breeze-static-checks-r5" x="1451.8" y="1459.6" [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1484" textLength="12.2" 
clip-path="url(#breeze-static-checks-line-60)">│</text><text 
class="breeze-static-checks-r7" x="451.4" y="1484" textLength="988.2" 
clip-path="url(#breeze-static-checks-line-60)">update-vendored-in-k8s-json-schema&#160;|&#160;update-version&#160;|&#160;validate-operators-init&#160;|&#160;&#160;</text><text
 class="breeze-static-checks-r5" x="1451.8" y="1484" textLength="12.2" 
clip-path="url(#breeze-static-checks- [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1508.4" 
textLength="12.2" clip-path="url(#breeze-static-checks-line-61)">│</text><text 
class="breeze-static-checks-r7" x="451.4" y="1508.4" textLength="988.2" 
clip-path="url(#breeze-static-checks-line-61)">yamllint&#160;|&#160;zizmor)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
 [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1484" textLength="12.2" 
clip-path="url(#breeze-static-checks-line-60)">│</text><text 
class="breeze-static-checks-r7" x="451.4" y="1484" textLength="988.2" 
clip-path="url(#breeze-static-checks-line-60)">update-vendored-in-k8s-json-schema&#160;|&#160;update-version&#160;|&#160;validate-chart-annotations&#160;</text><text
 class="breeze-static-checks-r5" x="1451.8" y="1484" textLength="12.2" 
clip-path="url(#breeze-static-checks-line-60)"> [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1508.4" 
textLength="12.2" clip-path="url(#breeze-static-checks-line-61)">│</text><text 
class="breeze-static-checks-r7" x="451.4" y="1508.4" textLength="988.2" 
clip-path="url(#breeze-static-checks-line-61)">|&#160;validate-operators-init&#160;|&#160;yamllint&#160;|&#160;zizmor)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160
 [...]
 </text><text class="breeze-static-checks-r5" x="0" y="1532.8" 
textLength="12.2" clip-path="url(#breeze-static-checks-line-62)">│</text><text 
class="breeze-static-checks-r4" x="24.4" y="1532.8" textLength="268.4" 
clip-path="url(#breeze-static-checks-line-62)">--show-diff-on-failure</text><text
 class="breeze-static-checks-r6" x="402.6" y="1532.8" textLength="24.4" 
clip-path="url(#breeze-static-checks-line-62)">-s</text><text 
class="breeze-static-checks-r1" x="451.4" y="1532.8" textLength=" [...]
 </text><text class="breeze-static-checks-r5" x="0" y="1557.2" 
textLength="12.2" clip-path="url(#breeze-static-checks-line-63)">│</text><text 
class="breeze-static-checks-r4" x="24.4" y="1557.2" textLength="292.8" 
clip-path="url(#breeze-static-checks-line-63)">--initialize-environment</text><text
 class="breeze-static-checks-r1" x="451.4" y="1557.2" textLength="549" 
clip-path="url(#breeze-static-checks-line-63)">Initialize&#160;environment&#160;before&#160;running&#160;checks.</text><text
 c [...]
 </text><text class="breeze-static-checks-r5" x="0" y="1581.6" 
textLength="12.2" clip-path="url(#breeze-static-checks-line-64)">│</text><text 
class="breeze-static-checks-r4" x="24.4" y="1581.6" textLength="353.8" 
clip-path="url(#breeze-static-checks-line-64)">--max-initialization-attempts</text><text
 class="breeze-static-checks-r1" x="451.4" y="1581.6" textLength="854" 
clip-path="url(#breeze-static-checks-line-64)">Maximum&#160;number&#160;of&#160;attempts&#160;to&#160;initialize&#160;env
 [...]
diff --git a/dev/breeze/doc/images/output_static-checks.txt 
b/dev/breeze/doc/images/output_static-checks.txt
index e1d3187c586..e8dbbc57b62 100644
--- a/dev/breeze/doc/images/output_static-checks.txt
+++ b/dev/breeze/doc/images/output_static-checks.txt
@@ -1 +1 @@
-d0dc18a59b8997b9c06a3bd15879c8c7
+4d21a8da51102b0c61707aac83f31b3a
diff --git a/dev/breeze/src/airflow_breeze/pre_commit_ids.py 
b/dev/breeze/src/airflow_breeze/pre_commit_ids.py
index c5ad5b2040a..9f1a79c15a4 100644
--- a/dev/breeze/src/airflow_breeze/pre_commit_ids.py
+++ b/dev/breeze/src/airflow_breeze/pre_commit_ids.py
@@ -158,6 +158,7 @@ PRE_COMMIT_LIST = [
     "update-supported-versions",
     "update-vendored-in-k8s-json-schema",
     "update-version",
+    "validate-chart-annotations",
     "validate-operators-init",
     "yamllint",
     "zizmor",
diff --git a/scripts/ci/pre_commit/validate_chart_annotations.py 
b/scripts/ci/pre_commit/validate_chart_annotations.py
new file mode 100755
index 00000000000..77f001e13fb
--- /dev/null
+++ b/scripts/ci/pre_commit/validate_chart_annotations.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import sys
+from pathlib import Path
+
+import yaml
+
+sys.path.insert(0, str(Path(__file__).parent.resolve()))
+from common_precommit_utils import AIRFLOW_ROOT_PATH, console
+
+CHART_YAML_FILE = AIRFLOW_ROOT_PATH / "chart" / "Chart.yaml"
+
+# List of artifacthub.io annotations that should contain valid YAML strings
+ARTIFACTHUB_ANNOTATIONS_TO_CHECK = [
+    "artifacthub.io/links",
+    "artifacthub.io/screenshots",
+    "artifacthub.io/changes",
+]
+
+
+def validate_chart_annotations():
+    """Validate that chart annotations are valid - e.g. strings that hold yaml 
are valid yaml"""
+    errors = []
+
+    try:
+        chart_content = yaml.safe_load(CHART_YAML_FILE.read_text())
+    except yaml.YAMLError as e:
+        console.print(f"[red]Error parsing Chart.yaml: {e}")
+        return False
+
+    annotations = chart_content.get("annotations", {})
+
+    for annotation_key in ARTIFACTHUB_ANNOTATIONS_TO_CHECK:
+        if annotation_key in annotations:
+            annotation_value = annotations[annotation_key]
+            try:
+                # Try to parse the string value as YAML
+                yaml.safe_load(annotation_value)
+                console.print(f"[green]✓[/] {annotation_key} contains valid 
YAML")
+            except yaml.YAMLError as e:
+                error_msg = f"Invalid YAML in annotation '{annotation_key}': 
{e}"
+                errors.append(error_msg)
+                console.print(f"[red]✗ {error_msg}[/]")
+
+    if errors:
+        console.print("\n[red]Chart.yaml validation failed![/]")
+        console.print("[red]The following artifacthub.io annotations contain 
invalid YAML:[/]")
+        for error in errors:
+            console.print(f"[red]  - {error}[/]")
+        return False
+
+    console.print("\n[green]All artifacthub.io annotations contain valid 
YAML![/]")
+    return True
+
+
+if __name__ == "__main__":
+    if not validate_chart_annotations():
+        sys.exit(1)

Reply via email to