Skip to content

Commit 7f30e3a

Browse files
committed
feat: track last successful unfurl date
Signed-off-by: Keshav Priyadarshi <git@keshav.space>
1 parent 58b7873 commit 7f30e3a

File tree

8 files changed

+63
-22
lines changed

8 files changed

+63
-22
lines changed

vulnerabilities/migrations/0120_impactedpackage_last_range_unfurl_at_and_more.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 5.2.11 on 2026-04-06 20:51
1+
# Generated by Django 5.2.11 on 2026-04-08 09:28
22

33
from django.db import migrations, models
44

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 5.2.11 on 2026-04-08 09:28
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("vulnerabilities", "0120_impactedpackage_last_range_unfurl_at_and_more"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="impactedpackage",
15+
name="last_successful_range_unfurl_at",
16+
field=models.DateTimeField(
17+
blank=True,
18+
db_index=True,
19+
help_text="Timestamp of the last successful vers range unfurl.",
20+
null=True,
21+
),
22+
),
23+
]

vulnerabilities/models.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,9 +1139,9 @@ def get_affecting_vulnerabilities(self):
11391139
next_fixed_package_vulns = list(fixed_by_pkg.affected_by)
11401140

11411141
fixed_by_package_details["fixed_by_purl"] = fixed_by_purl
1142-
fixed_by_package_details[
1143-
"fixed_by_purl_vulnerabilities"
1144-
] = next_fixed_package_vulns
1142+
fixed_by_package_details["fixed_by_purl_vulnerabilities"] = (
1143+
next_fixed_package_vulns
1144+
)
11451145
fixed_by_pkgs.append(fixed_by_package_details)
11461146

11471147
vuln_details["fixed_by_package_details"] = fixed_by_pkgs
@@ -3259,6 +3259,13 @@ class ImpactedPackage(models.Model):
32593259
help_text="Timestamp of the last vers range unfurl.",
32603260
)
32613261

3262+
last_successful_range_unfurl_at = models.DateTimeField(
3263+
blank=True,
3264+
null=True,
3265+
db_index=True,
3266+
help_text="Timestamp of the last successful vers range unfurl.",
3267+
)
3268+
32623269
def to_dict(self):
32633270
from vulnerabilities.utils import purl_to_dict
32643271

vulnerabilities/pipelines/v2_improvers/unfurl_version_range.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,25 @@ def unfurl_version_range(self):
5252
processed_impacted_packages_count = 0
5353
processed_affected_packages_count = 0
5454
cached_versions = {}
55-
impacts_to_update = []
56-
update_batch_size = 5
55+
update_unfurl_date = []
56+
update_successful_unfurl_date = []
57+
update_batch_size = 5000
58+
chunk_size = 5000
5759

5860
impacted_packages = impacted_package_qs(cutoff_day=self.reunfurl_after_days)
5961
impacted_packages_count = impacted_packages.count()
6062
self.log(f"Unfurl affected vers range for {impacted_packages_count:,d} ImpactedPackage.")
6163

62-
progress = LoopProgress(total_iterations=impacted_packages_count, logger=self.log)
63-
for impact in progress.iter(impacted_packages.iterator(chunk_size=5000)):
64-
impacts_to_update.append(impact.pk)
64+
progress = LoopProgress(
65+
total_iterations=impacted_packages_count, progress_step=5, logger=self.log
66+
)
67+
for impact in progress.iter(impacted_packages.iterator(chunk_size=chunk_size)):
68+
update_unfurl_date.append(impact.pk)
6569
purl = PackageURL.from_string(impact.base_purl)
6670
if not impact.affecting_vers or not any(
6771
c in impact.affecting_vers for c in ("<", ">", "!")
6872
):
73+
update_successful_unfurl_date.append(impact.pk)
6974
continue
7075
if purl.type not in FETCHCODE_SUPPORTED_ECOSYSTEMS:
7176
continue
@@ -87,17 +92,25 @@ def unfurl_version_range(self):
8792
relation=ImpactedPackageAffecting,
8893
logger=self.log,
8994
)
95+
update_successful_unfurl_date.append(impact.pk)
9096
processed_impacted_packages_count += 1
9197

92-
if len(impacts_to_update) > update_batch_size:
93-
ImpactedPackage.objects.filter(pk__in=impacts_to_update).update(
98+
if len(update_unfurl_date) > update_batch_size:
99+
ImpactedPackage.objects.filter(pk__in=update_unfurl_date).update(
94100
last_range_unfurl_at=timezone.now()
95101
)
96-
impacts_to_update.clear()
102+
ImpactedPackage.objects.filter(pk__in=update_successful_unfurl_date).update(
103+
last_successful_range_unfurl_at=timezone.now()
104+
)
105+
update_unfurl_date.clear()
106+
update_successful_unfurl_date.clear()
97107

98-
ImpactedPackage.objects.filter(pk__in=impacts_to_update).update(
108+
ImpactedPackage.objects.filter(pk__in=update_unfurl_date).update(
99109
last_range_unfurl_at=timezone.now()
100110
)
111+
ImpactedPackage.objects.filter(pk__in=update_successful_unfurl_date).update(
112+
last_successful_range_unfurl_at=timezone.now()
113+
)
101114
self.log(f"Successfully processed {processed_impacted_packages_count:,d} ImpactedPackage.")
102115
self.log(f"{processed_affected_packages_count:,d} new Impact-Package relation created.")
103116

vulnerabilities/pipes/openssl.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@ def get_reference(reference_name, tag, reference_url):
8989
ref_type = (
9090
AdvisoryReference.COMMIT
9191
if "commit" in name or tag == "patch"
92-
else AdvisoryReference.ADVISORY
93-
if "advisory" in name
94-
else AdvisoryReference.OTHER
92+
else AdvisoryReference.ADVISORY if "advisory" in name else AdvisoryReference.OTHER
9593
)
9694

9795
return ReferenceV2(

vulnerabilities/tests/pipelines/v2_importers/test_collect_fix_commit.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ def test_collect_fix_commits_groups_by_vuln(mock_repo, pipeline):
5252
side_effect=lambda c: (
5353
["CVE-2021-0001"]
5454
if "CVE" in c.message
55-
else ["GHSA-dead-beef-baad"]
56-
if "GHSA" in c.message
57-
else []
55+
else ["GHSA-dead-beef-baad"] if "GHSA" in c.message else []
5856
)
5957
)
6058

vulnerabilities/tests/pipelines/v2_improvers/test_unfurl_version_range.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ def test_affecting_version_range_unfurl(self, mock_fetch):
111111
self.assertEqual(3, PackageV2.objects.count())
112112
self.assertEqual(1, impact.fixed_by_packages.count())
113113
self.assertEqual(2, impact.affecting_packages.count())
114+
self.assertNotEqual(None, impact.last_range_unfurl_at)
115+
self.assertNotEqual(None, impact.last_successful_range_unfurl_at)
114116

115117
def test_impacted_package_qs_dont_process_empty_vers(self):
116118
insert_advisory_v2(

vulnerabilities/tests/test_api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ def cleaned_response(response):
7575
reference["scores"] = sorted(
7676
reference["scores"], key=lambda x: (x["value"], x["scoring_system"])
7777
)
78-
package_data["resolved_vulnerabilities"][index]["references"][index2][
79-
"scores"
80-
] = reference["scores"]
78+
package_data["resolved_vulnerabilities"][index]["references"][index2]["scores"] = (
79+
reference["scores"]
80+
)
8181

8282
cleaned_response.append(package_data)
8383

0 commit comments

Comments
 (0)