From d8a0b0c44928f4b5cfdd77eea8a73e0c1ee18827 Mon Sep 17 00:00:00 2001 From: kitos Date: Wed, 27 May 2026 16:29:50 +0200 Subject: [PATCH] =?UTF-8?q?fix(jira):=20correct=20ticket=20hierarchy=20?= =?UTF-8?q?=E2=80=94=20campaigns=3DEpic,=20all=20tests=3DTask?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Campaign issue type changed from Task to Epic (required to nest under Initiative OFS-20795 in classic Jira) - Added customfield_10011 (Epic Name) — required when creating Epics - Removed JIRA_ISSUE_TYPE_SUBTASK; all tests are now Task regardless of whether they are inside a campaign or standalone - Standalone tests use the configured standalone parent (OFS-20798, an Epic) so Task→Task parent is never attempted - Campaign tests use the campaign Epic key passed via parent_ticket_override Co-Authored-By: Claude Sonnet 4.6 --- backend/app/config.py | 5 ++--- backend/app/services/jira_service.py | 29 ++++++++++------------------ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/backend/app/config.py b/backend/app/config.py index b4f82cd..2d2d701 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -51,9 +51,8 @@ class Settings(BaseSettings): JIRA_API_TOKEN: str = "" JIRA_IS_CLOUD: bool = True JIRA_DEFAULT_PROJECT: str = "" - JIRA_ISSUE_TYPE_TEST: str = "Task" - JIRA_ISSUE_TYPE_CAMPAIGN: str = "Task" - JIRA_ISSUE_TYPE_SUBTASK: str = "Sub-task" + JIRA_ISSUE_TYPE_TEST: str = "Task" # tests (campaign or standalone) + JIRA_ISSUE_TYPE_CAMPAIGN: str = "Epic" # campaigns (under Initiative) # ── Tempo Integration ───────────────────────────────────────────── TEMPO_ENABLED: bool = False diff --git a/backend/app/services/jira_service.py b/backend/app/services/jira_service.py index 4633d0a..18328bb 100644 --- a/backend/app/services/jira_service.py +++ b/backend/app/services/jira_service.py @@ -406,9 +406,11 @@ def auto_create_campaign_issue( "description": _build_campaign_description(campaign), "issuetype": {"name": settings.JIRA_ISSUE_TYPE_CAMPAIGN}, "labels": ["aegis", "campaign"], + # customfield_10011 = Epic Name (required for Epic type in classic Jira) + "customfield_10011": campaign.name, } - # Always nest under the configured parent ticket (e.g. OFS-9107) + # Nest under the configured parent ticket (Initiative, e.g. OFS-20795) if parent_ticket: fields["parent"] = {"key": parent_ticket} @@ -478,24 +480,13 @@ def auto_create_test_issue( try: jira = get_user_jira_client(actor, db) - # Resolve parent and issue type together: - # - campaign parent override → Sub-task (Task cannot parent Task) - # - explicit standalone parent configured → Sub-task (same reason; - # the standalone parent is a Task, e.g. OFS-20798) - # - only the general parent ticket (Epic) → Task - standalone_parent = get_jira_parent_ticket_standalone(db) - general_parent = get_jira_parent_ticket(db) - parent = parent_ticket_override or standalone_parent - - has_explicit_parent = bool( - parent_ticket_override - or (standalone_parent and standalone_parent != general_parent) - ) - issue_type = ( - settings.JIRA_ISSUE_TYPE_SUBTASK - if has_explicit_parent - else settings.JIRA_ISSUE_TYPE_TEST - ) + # All tests — whether inside a campaign or standalone — are created + # as Task. Campaign tests use the campaign Jira key as parent + # (passed via parent_ticket_override); standalone tests use the + # configured standalone parent ticket (e.g. OFS-20798, which is an + # Epic so it can parent Tasks). + parent = parent_ticket_override or get_jira_parent_ticket_standalone(db) + issue_type = settings.JIRA_ISSUE_TYPE_TEST # always Task fields: dict = { "project": {"key": project_key},