diff --git a/integrations/jira/.port/resources/blueprints.json b/integrations/jira/.port/resources/blueprints.json index 9a58db66ce..f298bc0c3b 100644 --- a/integrations/jira/.port/resources/blueprints.json +++ b/integrations/jira/.port/resources/blueprints.json @@ -11,6 +11,11 @@ "type": "string", "format": "url", "description": "URL to the project in Jira" + }, + "totalIssues": { + "title": "Total Issues", + "type": "number", + "description": "The total number of issues in the project" } } }, diff --git a/integrations/jira/.port/resources/port-app-config.yaml b/integrations/jira/.port/resources/port-app-config.yaml index 8ca51b6ac3..e3f7a841b1 100644 --- a/integrations/jira/.port/resources/port-app-config.yaml +++ b/integrations/jira/.port/resources/port-app-config.yaml @@ -12,6 +12,7 @@ resources: blueprint: '"jiraProject"' properties: url: (.self | split("/") | .[:3] | join("/")) + "/projects/" + .key + totalIssues: .insight.totalIssueCount - kind: user selector: diff --git a/integrations/jira/CHANGELOG.md b/integrations/jira/CHANGELOG.md index 9c457eaefa..f834f86cfb 100644 --- a/integrations/jira/CHANGELOG.md +++ b/integrations/jira/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## 0.2.8 (2024-12-24) + + +### Features + +- Added a field to display total issues in a project + + ## 0.2.7 (2024-12-24) diff --git a/integrations/jira/jira/client.py b/integrations/jira/jira/client.py index 6aa8f6df4a..e8729d93c5 100644 --- a/integrations/jira/jira/client.py +++ b/integrations/jira/jira/client.py @@ -1,14 +1,14 @@ import typing from typing import Any, AsyncGenerator, Generator -from httpx import Timeout, Auth, BasicAuth, Request, Response -from jira.overrides import JiraResourceConfig +from httpx import Auth, BasicAuth, Request, Response, Timeout from loguru import logger - from port_ocean.context.event import event from port_ocean.context.ocean import ocean from port_ocean.utils import http_async_client +from jira.overrides import JiraResourceConfig + PAGE_SIZE = 50 WEBHOOK_NAME = "Port-Ocean-Events-Webhook" @@ -117,11 +117,11 @@ async def get_single_project(self, project_key: str) -> dict[str, Any]: return project_response.json() async def get_paginated_projects( - self, + self, params: dict[str, Any] = {} ) -> AsyncGenerator[list[dict[str, Any]], None]: logger.info("Getting projects from Jira") - params = self._generate_base_req_params() + params.update(self._generate_base_req_params()) total_projects = (await self._get_paginated_projects(params))["total"] diff --git a/integrations/jira/jira/overrides.py b/integrations/jira/jira/overrides.py index 85edd71838..2fcd01a11b 100644 --- a/integrations/jira/jira/overrides.py +++ b/integrations/jira/jira/overrides.py @@ -1,8 +1,11 @@ +from typing import Annotated, Literal, Union + from port_ocean.core.handlers.port_app_config.models import ( PortAppConfig, ResourceConfig, + Selector, ) -from pydantic import BaseModel +from pydantic import BaseModel, Field class JiraResourceConfig(ResourceConfig): @@ -11,7 +14,29 @@ class Selector(BaseModel): jql: str | None = None selector: Selector # type: ignore + kind: Literal["issue", "user"] + + +class JiraProjectSelector(Selector): + expand: str = Field( + description="A comma-separated list of the parameters to expand.", + default="insight", + ) + + +class JiraProjectResourceConfig(ResourceConfig): + selector: JiraProjectSelector + kind: Literal["project"] + + +JiraResourcesConfig = Annotated[ + Union[ + JiraResourceConfig, + JiraProjectResourceConfig, + ], + Field(discriminator="kind"), +] class JiraPortAppConfig(PortAppConfig): - resources: list[JiraResourceConfig] # type: ignore + resources: list[JiraResourceConfig | JiraProjectResourceConfig] # type: ignore diff --git a/integrations/jira/main.py b/integrations/jira/main.py index 600072f78d..597a0f8698 100644 --- a/integrations/jira/main.py +++ b/integrations/jira/main.py @@ -1,11 +1,14 @@ from enum import StrEnum -from typing import Any +from typing import Any, cast -from jira.client import JiraClient from loguru import logger +from port_ocean.context.event import event from port_ocean.context.ocean import ocean from port_ocean.core.ocean_types import ASYNC_GENERATOR_RESYNC_TYPE +from jira.client import JiraClient +from jira.overrides import JiraProjectResourceConfig + class ObjectKind(StrEnum): PROJECT = "project" @@ -42,7 +45,10 @@ async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE: ocean.integration_config["atlassian_user_token"], ) - async for projects in client.get_paginated_projects(): + selector = cast(JiraProjectResourceConfig, event.resource_config).selector + params = {"expand": selector.expand} + + async for projects in client.get_paginated_projects(params): logger.info(f"Received project batch with {len(projects)} issues") yield projects diff --git a/integrations/jira/pyproject.toml b/integrations/jira/pyproject.toml index f1dd51b30e..e82d4a699a 100644 --- a/integrations/jira/pyproject.toml +++ b/integrations/jira/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "jira" -version = "0.2.7" +version = "0.2.8" description = "Integration to bring information from Jira into Port" authors = ["Mor Paz "]