From 0285448b68e8841408f0c855b097aeb7ab267f3c Mon Sep 17 00:00:00 2001
From: Karel van Klink <karel.vanklink@geant.org>
Date: Tue, 24 Jun 2025 16:06:55 +0200
Subject: [PATCH] Allow for a subscription validation to be skipped with a
 special note

When the note of a subscription starts with "SKIP VALIDATION: " followed by a reason, it is not included in the nightly schedule.
---
 gso/schedules/validate_subscriptions.py | 13 +++++++++++++
 test/schedules/test_scheduling.py       | 22 +++++++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/gso/schedules/validate_subscriptions.py b/gso/schedules/validate_subscriptions.py
index db3573802..fb728a1a9 100644
--- a/gso/schedules/validate_subscriptions.py
+++ b/gso/schedules/validate_subscriptions.py
@@ -7,6 +7,8 @@ From this list, each workflow is selected that meets the following:
     * The name of the workflow follows the pattern `validate_*`.
 """
 
+import re
+
 import structlog
 from celery import shared_task
 from orchestrator.services.processes import get_execution_context
@@ -37,6 +39,17 @@ def validate_subscriptions() -> None:
         return
 
     for subscription in subscriptions:
+        if re.search(r"SKIP VALIDATION: .+", subscription.note or ""):
+            #  The subscription is marked to skip validation altogether. We continue to the next subscription.
+            logger.warning(
+                "Manually skipped validation workflows for a subscription.",
+                product=subscription.product.name,
+                subscription_id=subscription.subscription_id,
+                subscription_description=subscription.description,
+                skip_reason=subscription.note,
+            )
+            continue
+
         found_a_validation_workflow = False
         for workflow in subscription.product.workflows:
             if workflow.target == Target.SYSTEM and workflow.name.startswith("validate_"):
diff --git a/test/schedules/test_scheduling.py b/test/schedules/test_scheduling.py
index a1eb56b48..8f6feafcc 100644
--- a/test/schedules/test_scheduling.py
+++ b/test/schedules/test_scheduling.py
@@ -93,7 +93,10 @@ def test_subscriptions_without_system_target_workflow(
     mock_logger,
     validate_subscriptions,
 ):
-    mock_get_active_subscriptions.return_value = [MagicMock(product=MagicMock(workflows=[]))]
+    subscription_mock = MagicMock()
+    subscription_mock.product.workflows = []
+    subscription_mock.note = None
+    mock_get_active_subscriptions.return_value = [subscription_mock]
     validate_subscriptions()
     mock_logger.warning.assert_called_once()
 
@@ -106,6 +109,7 @@ def test_subscription_status_not_usable(
     subscription_mock = MagicMock()
     subscription_mock.product.workflows = [MagicMock(target=Target.SYSTEM, name="workflow_name")]
     subscription_mock.status = "Not Usable Status"
+    subscription_mock.note = None
 
     mock_get_active_subscriptions.return_value = [subscription_mock]
     validate_subscriptions()
@@ -123,6 +127,7 @@ def test_valid_subscriptions_for_validation(
     mocked_workflow = MagicMock(target=Target.SYSTEM, name="workflow_name")
     subscription_mock.product.workflows = [mocked_workflow]
     subscription_mock.status = "active"
+    subscription_mock.note = None
     mock_get_active_subscriptions.return_value = [subscription_mock]
     validate_subscriptions()
     validate_func = mock_get_execution_context()["validate"]
@@ -130,3 +135,18 @@ def test_valid_subscriptions_for_validation(
         mocked_workflow.name,
         json=[{"subscription_id": str(subscription_mock.subscription_id)}],
     )
+
+
+def test_subscription_skipped_with_note(
+    mock_get_active_subscriptions,
+    mock_get_execution_context,
+    validate_subscriptions,
+):
+    subscription_mock = MagicMock()
+    subscription_mock.product.workflows = [MagicMock(target=Target.SYSTEM, name="workflow_name")]
+    subscription_mock.note = "SKIP VALIDATION: Because we don't want to."
+    mock_get_active_subscriptions.return_value = [subscription_mock]
+    validate_subscriptions()
+
+    validate_func = mock_get_execution_context()["validate"]
+    validate_func.assert_not_called()
-- 
GitLab