diff --git a/README.md b/README.md index 138dac8..c49a01a 100644 --- a/README.md +++ b/README.md @@ -24,16 +24,19 @@ Built with the [Meltano Singer SDK](https://sdk.meltano.com). ## Settings -| Setting | Required | Default | Description | -| :-------------------------------- | :------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| start_date | False | None | Earliest record date to sync | -| end_date | False | None | Latest record date to sync | -| domain | True | None | The Domain for your Jira account, e.g. meltano.atlassian.net | -| api_token | True | None | Jira API Token. | -| email | True | None | The user email for your Jira account. | -| page_size | False | None | | -| page_size.issues | False | 100 | Page size for issues stream | -| include_audit_logs | False | False | Include the audit logs stream | +| Setting | Required | Default | Description | +| :------------------------ | :------- | :------ | :----------------------------------------------------------- | +| start_date | False | None | Earliest record date to sync | +| end_date | False | None | Latest record date to sync | +| domain | True | None | The Domain for your Jira account, e.g. meltano.atlassian.net | +| api_token | True | None | Jira API Token. | +| email | True | None | The user email for your Jira account. | +| page_size | False | None | | +| page_size.issues | False | 100 | Page size for issues stream | +| stream_options | False | None | Options for individual streams | +| stream_options.issues | False | None | Options specific to the issues stream | +| stream_options.issues.jql | False | None | A JQL query to filter issues | +| include_audit_logs | False | False | Include the audit logs stream | ### Built-in capabilities diff --git a/meltano.yml b/meltano.yml index 5fb2f9e..665286d 100644 --- a/meltano.yml +++ b/meltano.yml @@ -1,11 +1,11 @@ version: 1 send_anonymous_usage_stats: true -project_id: "tap-jira" +project_id: tap-jira default_environment: dev plugins: extractors: - - name: "tap-jira" - namespace: "tap_jira" + - name: tap-jira + namespace: tap_jira pip_url: -e . capabilities: - state @@ -13,18 +13,35 @@ plugins: - discover - about - stream-maps + settings_group_validation: + - [domain, api_token, email] settings: - name: start_date + kind: date_iso8601 + description: Earliest record date to sync - name: end_date + kind: date_iso8601 + description: Latest record date to sync - name: domain - - name: auth_type - - name: auth.flow - - name: auth.access_token - kind: password - - name: auth.username - - name: auth.password - kind: password + kind: string + description: The Domain for your Jira account, e.g. meltano.atlassian.net + - name: api_token + kind: string + description: Jira API Token + sensitive: true + - name: email + kind: string + description: The user email for your Jira account + - name: page_size.issues + kind: integer + value: 100 + description: Page size for issues stream + - name: stream_options.issues.jql + kind: string + description: A JQL query to filter issues environments: - name: dev - name: staging - name: prod +venv: + backend: uv diff --git a/tap_jira/streams.py b/tap_jira/streams.py index fb4929c..8017e38 100644 --- a/tap_jira/streams.py +++ b/tap_jira/streams.py @@ -1661,7 +1661,7 @@ def get_url_params( params["maxResults"] = self.config.get("page_size", {}).get("issues", 10) - params["jql"] = [] # init a query param + jql: list[str] = [] if next_page_token: params["startAt"] = next_page_token @@ -1672,18 +1672,21 @@ def get_url_params( if "start_date" in self.config: start_date = self.config["start_date"] - params["jql"].append(f"(created>={start_date} or updated>={start_date})") + jql.append(f"(created>='{start_date}' or updated>='{start_date}')") if "end_date" in self.config: end_date = self.config["end_date"] - params["jql"].append(f"(created<{end_date} or updated<{start_date})") + jql.append(f"(created<'{end_date}' or updated<'{end_date}')") - if params["jql"]: - jql = " and ".join(params["jql"]) - params["jql"] = jql + if ( + base_jql := self.config.get("stream_options", {}) + .get("issues", {}) + .get("jql") + ): + jql.append(f"({base_jql})") - else: - params.pop("jql") # drop if there's no query + if jql: + params["jql"] = " and ".join(jql) return params diff --git a/tap_jira/tap.py b/tap_jira/tap.py index 1a60fb6..01efcff 100644 --- a/tap_jira/tap.py +++ b/tap_jira/tap.py @@ -35,6 +35,8 @@ class TapJira(Tap): th.StringType, description="Jira API Token.", required=True, + secret=True, + title="API Token", ), th.Property( "email", @@ -53,6 +55,25 @@ class TapJira(Tap): ), ), ), + th.Property( + "stream_options", + th.ObjectType( + th.Property( + "issues", + th.ObjectType( + th.Property( + "jql", + th.StringType, + description="A JQL query to filter issues", + title="JQL Query", + ), + ), + title="Issues Stream Options", + description="Options specific to the issues stream", + ), + ), + description="Options for individual streams", + ), th.Property( "include_audit_logs", th.BooleanType, diff --git a/tests/conftest.py b/tests/conftest.py index 4ba4b21..e2acad1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1 +1,20 @@ """Test Configuration.""" + +from __future__ import annotations + +import os +import typing as t + +if t.TYPE_CHECKING: + import pathlib + + import pytest + + +def pytest_report_header( + config: pytest.Config, # noqa: ARG001 + start_path: pathlib.Path, # noqa: ARG001 +) -> list[str] | str: + """Add a header to the test report.""" + tap_jira_vars = [var for var in os.environ if var.startswith("TAP_JIRA")] + return f"tap-jira environment variables: {tap_jira_vars}"