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

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


The following commit(s) were added to refs/heads/main by this push:
     new 7024925  feat(generate-cve-json): set CNA_private.emailed="yes" when 
state is PUBLIC (#275)
7024925 is described below

commit 7024925c184c596e1f8d512c57ac2a3a14830160
Author: Jarek Potiuk <[email protected]>
AuthorDate: Mon May 25 12:59:36 2026 +0200

    feat(generate-cve-json): set CNA_private.emailed="yes" when state is PUBLIC 
(#275)
    
    Vulnogram's UI reads `CNA_private.emailed` to decide whether the
    advisory email has been sent. The generator was hard-coding it to
    `None` regardless of state, so even records pushed at PUBLIC state
    (post-archive-URL, the advisory has demonstrably shipped) showed
    up in the UI as not-yet-emailed.
    
    Wire `emailed` to the same signal that drives the PUBLIC state:
    when `compute_cna_private_state()` returns `"PUBLIC"` (CNA is
    review-ready AND a `vendor-advisory` reference is present), set
    `emailed = "yes"`; otherwise leave it `None`.
    
    Three new tests in `TestWrapCveRecord` cover `emailed` in each of
    the three workflow states.
    
    Generated-by: Claude Code (Opus 4.7)
---
 .../src/generate_cve_json/cve_json.py              |  9 +++++---
 .../tests/test_generate_cve_json.py                | 25 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git 
a/tools/vulnogram/generate-cve-json/src/generate_cve_json/cve_json.py 
b/tools/vulnogram/generate-cve-json/src/generate_cve_json/cve_json.py
index 8944570..21b45f5 100644
--- a/tools/vulnogram/generate-cve-json/src/generate_cve_json/cve_json.py
+++ b/tools/vulnogram/generate-cve-json/src/generate_cve_json/cve_json.py
@@ -1091,7 +1091,9 @@ def wrap_cve_record(cna: dict, *, cve_id: str, org_id: 
str) -> dict:
         advisory is out, the CVE record is ready to go public, and
         the next paste into Vulnogram should land the record at
         PUBLIC. See Steps 14 and 15 of the handling process in
-        ``README.md``.
+        ``README.md``. ``CNA_private.emailed`` is also flipped to
+        ``"yes"`` at this state so Vulnogram's UI reflects that the
+        advisory email has been sent.
 
     - ``cveMetadata.state`` is the **CVE 5.x schema state** per
       `the CVE-List schema
@@ -1104,13 +1106,14 @@ def wrap_cve_record(cna: dict, *, cve_id: str, org_id: 
str) -> dict:
       that cve.org reads when the record eventually flows through
       Vulnogram.
     """
+    cna_private_state = compute_cna_private_state(cna, cve_id)
     record: dict = {
         "CNA_private": {
-            "emailed": None,
+            "emailed": "yes" if cna_private_state == "PUBLIC" else None,
             "projecturl": CNA_PRIVATE_PROJECT_URL,
             "owner": CNA_PRIVATE_OWNER,
             "userslist": CNA_PRIVATE_USERS_LIST,
-            "state": compute_cna_private_state(cna, cve_id),
+            "state": cna_private_state,
             "todo": [],
             "type": "unsure",
         },
diff --git a/tools/vulnogram/generate-cve-json/tests/test_generate_cve_json.py 
b/tools/vulnogram/generate-cve-json/tests/test_generate_cve_json.py
index b01dce4..148054d 100644
--- a/tools/vulnogram/generate-cve-json/tests/test_generate_cve_json.py
+++ b/tools/vulnogram/generate-cve-json/tests/test_generate_cve_json.py
@@ -777,6 +777,31 @@ class TestWrapCveRecord:
         assert record["CNA_private"]["owner"] == "example"
         assert record["CNA_private"]["userslist"] == "[email protected]"
 
+    def test_emailed_is_none_in_draft_state(self):
+        cna = _ready_cna()
+        cna["credits"] = []
+        record = wrap_cve_record(cna, cve_id="CVE-2026-00001", org_id="org")
+        assert record["CNA_private"]["state"] == "DRAFT"
+        assert record["CNA_private"]["emailed"] is None
+
+    def test_emailed_is_none_in_review_state(self):
+        record = wrap_cve_record(_ready_cna(), cve_id="CVE-2026-00001", 
org_id="org")
+        assert record["CNA_private"]["state"] == "REVIEW"
+        assert record["CNA_private"]["emailed"] is None
+
+    def test_emailed_is_yes_in_public_state(self):
+        cna = _ready_cna()
+        cna["references"] = build_references(
+            mailing_list_field="",
+            pr_field="https://github.com/apache/airflow/pull/123";,
+            extra_urls=[
+                "https://lists.apache.org/thread/abc123xyz789";,
+            ],
+        )
+        record = wrap_cve_record(cna, cve_id="CVE-2026-00001", org_id="org")
+        assert record["CNA_private"]["state"] == "PUBLIC"
+        assert record["CNA_private"]["emailed"] == "yes"
+
 
 # ---------------------------------------------------------------------------
 # compute_cna_private_state

Reply via email to