diff --git a/connector_jira/README.rst b/connector_jira/README.rst index dfd657c10..af9694024 100644 --- a/connector_jira/README.rst +++ b/connector_jira/README.rst @@ -17,18 +17,19 @@ JIRA Connector :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fconnector--jira-lightgray.png?logo=github - :target: https://github.com/OCA/connector-jira/tree/15.0/connector_jira + :target: https://github.com/OCA/connector-jira/tree/17.0/connector_jira :alt: OCA/connector-jira .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/connector-jira-15-0/connector-jira-15-0-connector_jira + :target: https://translation.odoo-community.org/projects/connector-jira-17-0/connector-jira-17-0-connector_jira :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/connector-jira&target_branch=15.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/connector-jira&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| -This module adds Jira synchronization feature. It works with Jira Cloud by behaving as an Atlassian Connect App. +This module adds Jira synchronization feature. It works with Jira Cloud +by behaving as an Atlassian Connect App. **Table of contents** @@ -40,175 +41,188 @@ Installation You need the following Python packages: -* requests -* jira -* oauthlib -* requests-oauthlib -* requests-toolbelt -* PyJWT -* cryptography -* atlassian-jwt - +- requests +- jira +- oauthlib +- requests-oauthlib +- requests-toolbelt +- PyJWT +- cryptography +- atlassian-jwt Once the addon is installed, follow these steps: Job Queue -~~~~~~~~~ +--------- In ``odoo.conf``, configure similarly: -.. code-block:: - - [queue_job] - channels = root:1,root.connector_jira.import:2 +:: + [queue_job] + channels = root:1,root.connector_jira.import:2 Backend -~~~~~~~ +------- 1. Open the menu Connectors > Jira > Backends 2. Create a new Jira Backend - * Put the name you want - * You can also select the company where records will be created and the - default project template used when Odoo will create the projects in Jira - * Save + - Put the name you want + - You can also select the company where records will be created and + the default project template used when Odoo will create the + projects in Jira + - Save -3. Make note of the value of the App Descriptor URL (important: make sure that - the system parameter `web.base.url` is set properly. For local development you - will want to use ngrok to make your computer reachable over https from Jira Cloud). +3. Make note of the value of the App Descriptor URL (important: make + sure that the system parameter web.base.url is set properly. For + local development you will want to use ngrok to make your computer + reachable over https from Jira Cloud). Installing the backend as a Jira App -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------ -In case this gets outdated, refer to https://developer.atlassian.com/platform/marketplace/listing-connect-apps/#list-a-connect-app +In case this gets outdated, refer to +https://developer.atlassian.com/platform/marketplace/listing-connect-apps/#list-a-connect-app 1. Login on marketplace.atlassian.com (possibly create an account) -2. On the top right corner, the icon with your avatar leads to a menu -> select the `Publish an App` entry +2. On the top right corner, the icon with your avatar leads to a menu -> + select the Publish an App entry 3. On the Publish a new app screen: - * select a Vendor (normally your company) - * upload your app: select `Provide a URL to your artifact` - * click on the `Enter URL` button - * paste the App Descriptor URL in the pop-up and click on the `Done` button - * the `Name` field should get populated from the `name` of your backend - * Compatible application: select `Jira` - * build number: can be kept as is -4. Click on the `Save as private` button - (!) Important: do not click the "Next: Make public" button. That flow would allow anyone on Jira Cloud to install your backend. -5. On the next screen, you can go to the "Private Listings" page, and click on the "Create a token" button: this token can be used to install the app on your Jira instance. + - select a Vendor (normally your company) + - upload your app: select Provide a URL to your artifact + - click on the Enter URL button + - paste the App Descriptor URL in the pop-up and click on the Done + button + - the Name field should get populated from the name of your backend + - Compatible application: select Jira + - build number: can be kept as is + +4. Click on the Save as private button (!) Important: do not click the + "Next: Make public" button. That flow would allow anyone on Jira + Cloud to install your backend. +5. On the next screen, you can go to the "Private Listings" page, and + click on the "Create a token" button: this token can be used to + install the app on your Jira instance. Installing the Jira App on your Jira Cloud instance -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------------------------- 1. Connect to your Jira instance with an account with Admin access -2. In the Apps menu, select `Manage your apps` -3. In the Apps screen, click on the Settings link which is under the User-installed apps list -4. In the settings screen, check the `Enable private listings` box, and click on `Apply` -5. Refresh the Apps page: you should see an `Upload app` link: click on it -6. On the Upload app dialog, paste the token URL you received in the previous procedure, and click on `Upload` - +2. In the Apps menu, select Manage your apps +3. In the Apps screen, click on the Settings link which is under the + User-installed apps list +4. In the settings screen, check the Enable private listings box, and + click on Apply +5. Refresh the Apps page: you should see an Upload app link: click on it +6. On the Upload app dialog, paste the token URL you received in the + previous procedure, and click on Upload Configuration of the Backend -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Going back to Odoo, the backend should now be in the Running state, with some information filled in, such as the Jira URI. +---------------------------- +Going back to Odoo, the backend should now be in the Running state, with +some information filled in, such as the Jira URI. **Configure the Epic Link** -If you use Epics, you need to click on "Configure Epic Link", Odoo will search -the name of the custom field used for the Epic Link. +If you use Epics, you need to click on "Configure Epic Link", Odoo will +search the name of the custom field used for the Epic Link. Congratulations, you're done! Usage ===== -The tasks and worklogs are always imported from JIRA to Odoo, there -is no synchronization in the other direction. +The tasks and worklogs are always imported from JIRA to Odoo, there is +no synchronization in the other direction. Initial synchronizations -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ -You can already select the "Imports" tab in the Backend and click on "Link -users" and "Import issue types". The users will be matched either by login or by email. +You can already select the "Imports" tab in the Backend and click on +"Link users" and "Import issue types". The users will be matched either +by login or by email. Create and export a project -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- -Projects can be created in Odoo and exported to Jira. You can then create a -project, and use the action "Link with JIRA" and use the "Export to JIRA" action. +Projects can be created in Odoo and exported to Jira. You can then +create a project, and use the action "Link with JIRA" and use the +"Export to JIRA" action. -When you choose to export a project to JIRA, if you change the name -or the key of the project, the new values will be pushed to JIRA. +When you choose to export a project to JIRA, if you change the name or +the key of the project, the new values will be pushed to JIRA. Link a project with JIRA -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ -If you already have a project on JIRA or prefer to create it first on JIRA, -you can link an Odoo project. Use the "Link with JIRA" action on the project -and select the "Link with JIRA" action. +If you already have a project on JIRA or prefer to create it first on +JIRA, you can link an Odoo project. Use the "Link with JIRA" action on +the project and select the "Link with JIRA" action. -This action establish the link, then changes of the name or the key on either -side are not pushed. +This action establish the link, then changes of the name or the key on +either side are not pushed. Issue Types on Projects -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- -When you link a project, you have to select which issue types are synchronized. -Only tasks of the selected types will be created in Odoo. +When you link a project, you have to select which issue types are +synchronized. Only tasks of the selected types will be created in Odoo. If a JIRA worklog is added to a type of issue that is not synchronized, will attach to the closest task following these rules: -* if a subtask, find the parent task -* if no parent task, find the epic task (only if it is on the same project) -* if no epic, attach to the project without being linked to a task +- if a subtask, find the parent task +- if no parent task, find the epic task (only if it is on the same + project) +- if no epic, attach to the project without being linked to a task Change synchronization configuration on a project -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------- If you want to change the configuration of a project, such as which -issue types are synchronized, you can open the "Connector" tab in -the project settings and edit the "binding" with the backend. +issue types are synchronized, you can open the "Connector" tab in the +project settings and edit the "binding" with the backend. Synchronize tasks and worklogs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ -If the webhooks are active, as soon as they are created in Jira they should appear in Odoo. -If they are not active, you can open the Jira Backend and run the -synchronizations manually, or activate the Scheduled Actions to run the batch -imports. It is important to select the issue types so don't miss this step (need improvement). +If the webhooks are active, as soon as they are created in Jira they +should appear in Odoo. If they are not active, you can open the Jira +Backend and run the synchronizations manually, or activate the Scheduled +Actions to run the batch imports. It is important to select the issue +types so don't miss this step (need improvement). Known issues / Roadmap ====================== -* If an odoo user has no linked employee, worklogs will still be imported but - with no employee. +- If an odoo user has no linked employee, worklogs will still be + imported but with no employee. **Allowing several bindings per project** -The design evolved to allow more than one Jira binding per project in Odoo. -This conveniently allows to fetch tasks and worklogs for many projects in Jira, -which will be tracked in only one project in Odoo. +The design evolved to allow more than one Jira binding per project in +Odoo. This conveniently allows to fetch tasks and worklogs for many +projects in Jira, which will be tracked in only one project in Odoo. In order to push data to Jira, we have to apply restrictions on these "multi-bindings" projects, as we cannot know to which binding data must be pushed: -* Not more than one project (can be zero) can have a "Sync Action" set to - "Export to JIRA". As this configuration pushes the name and key of the project - to Jira, we cannot push it to more than one project. -* If we implement push of tasks to Jira, we'll have to add a way to restrict or - choose to which project we push the task, this is not supported yet (for - instance, add a Boolean "export tasks" on the project binding, or explicitly - select the target binding on the task) -* Now that the webhooks are authenticated, use the values sent by the webhooks - rather than querying them back -* We now can have multiple backends, registering multiple webhooks. If we want - to use this in practice, testing must be done and probably some things will - need fixing. +- Not more than one project (can be zero) can have a "Sync Action" set + to "Export to JIRA". As this configuration pushes the name and key of + the project to Jira, we cannot push it to more than one project. +- If we implement push of tasks to Jira, we'll have to add a way to + restrict or choose to which project we push the task, this is not + supported yet (for instance, add a Boolean "export tasks" on the + project binding, or explicitly select the target binding on the task) +- Now that the webhooks are authenticated, use the values sent by the + webhooks rather than querying them back +- We now can have multiple backends, registering multiple webhooks. If + we want to use this in practice, testing must be done and probably + some things will need fixing. Bug Tracker =========== @@ -216,7 +230,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -224,35 +238,36 @@ Credits ======= Authors -~~~~~~~ +------- * Camptocamp Contributors -~~~~~~~~~~~~ +------------ + +- `Camptocamp `__: -* `Camptocamp `_: - * Damien Crier - * Thierry Ducrest - * Tonow-c2c - * Simone Orsi - * Timon Tschanz - * jcoux - * Patrick Tombez - * Guewen Baconnier - * Akim Juillerat - * Alexandre Fayolle + - Damien Crier + - Thierry Ducrest + - Tonow-c2c + - Simone Orsi + - Timon Tschanz + - jcoux + - Patrick Tombez + - Guewen Baconnier + - Akim Juillerat + - Alexandre Fayolle -* `CorporateHub `__ +- `CorporateHub `__ - * Alexey Pelykh + - Alexey Pelykh -* `Trobz `_: +- `Trobz `__: - * Son Ho + - Son Ho Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -264,6 +279,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/connector-jira `_ project on GitHub. +This module is part of the `OCA/connector-jira `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/connector_jira/components/backend_adapter.py b/connector_jira/components/backend_adapter.py index 5c3e3d453..12d184a99 100644 --- a/connector_jira/components/backend_adapter.py +++ b/connector_jira/components/backend_adapter.py @@ -61,7 +61,7 @@ def _post_get_json( try: r_json = jira.utils.json_loads(r) except ValueError as e: - logging.error("{}\n{}".format(e, r.text)) + logging.error(f"{e}\n{r.text}") raise e return r_json @@ -76,12 +76,7 @@ def handle_404(self): yield except jira.exceptions.JIRAError as err: if err.status_code == 404: - raise IDMissingInBackend( - "{} (url: {})".format( - err.text, - err.url, - ) - ) from err + raise IDMissingInBackend(f"{err.text} (url: {err.url})") from err raise @contextmanager diff --git a/connector_jira/controllers/main.py b/connector_jira/controllers/main.py index 9b922c9e9..1332d71f9 100644 --- a/connector_jira/controllers/main.py +++ b/connector_jira/controllers/main.py @@ -187,6 +187,7 @@ def _validate_jwt_token(self): jwt_token = authorization_header[4:] decoded = jwt.get_unverified_header(jwt_token) if "kid" in decoded: + # pylint: disable=E8106 response = requests.get( f"https://connect-install-keys.atlassian.com/{decoded['kid']}" ) diff --git a/connector_jira/fields.py b/connector_jira/fields.py index 41b4b04d8..bbe77acf0 100644 --- a/connector_jira/fields.py +++ b/connector_jira/fields.py @@ -31,7 +31,7 @@ def from_string(value): if isinstance(value, datetime): if value.tzinfo: raise ValueError( - "MilliDatetime field expects a naive datetime: %s" % value + f"MilliDatetime field expects a naive datetime: {value}" ) return value if len(value) > fields.DATETIME_LENGTH: @@ -58,6 +58,6 @@ def convert_to_cache(self, value, record, validate=True): return False if isinstance(value, date) and not isinstance(value, datetime): raise TypeError( - "%s (field %s) must be string or datetime" ", not date." % (value, self) + f"{value} (field {self}) must be string or datetime, not date." ) return self.from_string(value) diff --git a/connector_jira/models/account_analytic_line/common.py b/connector_jira/models/account_analytic_line/common.py index 57e93f9da..b9819c5a8 100644 --- a/connector_jira/models/account_analytic_line/common.py +++ b/connector_jira/models/account_analytic_line/common.py @@ -284,8 +284,7 @@ def yield_read(self, worklog_ids): for chunk in self._chunks(worklog_ids, 1000): payload = json.dumps({"ids": chunk}) result = self._post_get_json(path, data=payload) - for worklog in result: - yield worklog + yield from result def updated_since(self, since=None): path = "worklog/updated" diff --git a/connector_jira/models/account_analytic_line/importer.py b/connector_jira/models/account_analytic_line/importer.py index ef09f93e2..a994351e3 100644 --- a/connector_jira/models/account_analytic_line/importer.py +++ b/connector_jira/models/account_analytic_line/importer.py @@ -85,11 +85,11 @@ def author(self, record): email = jira_author.get("emailAddress", "") raise MappingError( _( - 'No user found with login "%(jira_author_key)s" or email "%(email)s".' - "You must create a user or link it manually if the " - "login/email differs.", - jira_author_key=jira_author_key, - email=email, + "No user found with login '%(key)s' or email '%(mail)s'." + " You must create a user or link it manually if the" + " login/email differs.", + key=jira_author_key, + mail=email, ) ) employee = ( diff --git a/connector_jira/models/jira_backend/common.py b/connector_jira/models/jira_backend/common.py index e4e1dbb06..6bf2dd3d2 100644 --- a/connector_jira/models/jira_backend/common.py +++ b/connector_jira/models/jira_backend/common.py @@ -85,8 +85,9 @@ class JiraBackend(models.Model): application_key = fields.Char( compute="_compute_application_key", store=True, - help="The name that will be used as application key to register the app on the " - "Atlassian marketplace website. It has to be unique among all apps on the marketplace.", + help="The name that will be used as application key to register the app on the" + " Atlassian marketplace website.\n" + "It has to be unique among all apps on the marketplace.", ) company_id = fields.Many2one( comodel_name="res.company", @@ -464,7 +465,7 @@ def _scheduler_delete_analytic_line(self): backend.search([]).delete_analytic_line() def make_issue_url(self, jira_issue_id): - return urllib.parse.urljoin(self.uri, "/browse/{}".format(jira_issue_id)) + return urllib.parse.urljoin(self.uri, f"/browse/{jira_issue_id}") def _get_base_url(self): fqdn = self.env["ir.config_parameter"].get_param("web.base.url", "") @@ -536,11 +537,11 @@ def _install_app(self, payload): 'sharedSecret': Use to sign JWT tokens 'serverVersion': DEPRECATED 'pluginsVersion': DEPRECATED - 'baseUrl': URL prefix for this Atlassian product instance. All of its REST endpoints - begin with this `baseUrl`. Do not use the `baseUrl` as an identifier for the - Atlassian product as this value may not be unique. - 'displayUrl': If the Atlassian product instance has an associated custom domain, this - is the URL through which users will access the product. + 'baseUrl': URL prefix for this Atlassian product instance. All of its REST + endpoints begin with this `baseUrl`. Do not use the `baseUrl` as an + identifier for the Atlassian product as this value may not be unique. + 'displayUrl': If the Atlassian product instance has an associated custom + domain, this is the URL through which users will access the product. 'productType': 'jira', 'description': 'Atlassian JIRA at https: //testcamptocamp.atlassian.net ', 'eventType': 'installed', diff --git a/connector_jira/models/project_project/common.py b/connector_jira/models/project_project/common.py index 45cd43e0d..f79c5a906 100644 --- a/connector_jira/models/project_project/common.py +++ b/connector_jira/models/project_project/common.py @@ -99,8 +99,8 @@ def _selection_project_type(self): def _add_sql_constraints(self): # we replace the sql constraint by a python one # to include the organizations - for (key, definition, _msg) in self._sql_constraints: - conname = "{}_{}".format(self._table, key) + for key, definition, _msg in self._sql_constraints: + conname = f"{self._table}_{key}" if key == "jira_binding_uniq": has_definition = tools.constraint_definition( self.env.cr, self._table, conname @@ -256,7 +256,7 @@ def name_get(self): for project in self: project_id, name = super(ProjectProject, project).name_get()[0] if project.jira_key: - name = "[{}] {}".format(project.jira_key, name) + name = f"[{project.jira_key}] {name}" names.append((project_id, name)) return names @@ -289,7 +289,6 @@ def create_and_link_jira(self): class ProjectAdapter(Component): - _name = "jira.project.adapter" _inherit = ["jira.webservice.adapter"] _apply_on = ["jira.project.project"] @@ -362,7 +361,7 @@ def create_shared(self, key=None, name=None, shared_key=None, lead=None): if self.logging: logging.error( "Unexpected result while running create shared project." - "Server response saved in %s for further investigation " - "[HTTP response=%s]." % (f.name, r.status_code) + f" Server response saved in {f.name} for further investigation" + f" [HTTP response={r.status_code}]." ) return False diff --git a/connector_jira/models/project_task/common.py b/connector_jira/models/project_task/common.py index 3a53fb6be..83b8ce11a 100644 --- a/connector_jira/models/project_task/common.py +++ b/connector_jira/models/project_task/common.py @@ -158,7 +158,7 @@ def name_get(self): for task in self: task_id, name = super(ProjectTask, task).name_get()[0] if task.jira_compound_key: - name = "[{}] {}".format(task.jira_compound_key, name) + name = f"[{task.jira_compound_key}] {name}" names.append((task_id, name)) return names diff --git a/connector_jira/models/project_task/importer.py b/connector_jira/models/project_task/importer.py index 4d63b78b8..0896aae64 100644 --- a/connector_jira/models/project_task/importer.py +++ b/connector_jira/models/project_task/importer.py @@ -211,7 +211,7 @@ def _create_data(self, map_record, **kwargs): map_record, jira_epic=self.jira_epic, project_binding=self.project_binding, - **kwargs + **kwargs, ) def _update_data(self, map_record, **kwargs): @@ -219,7 +219,7 @@ def _update_data(self, map_record, **kwargs): map_record, jira_epic=self.jira_epic, project_binding=self.project_binding, - **kwargs + **kwargs, ) def _import(self, binding, **kwargs): diff --git a/connector_jira/models/res_users/common.py b/connector_jira/models/res_users/common.py index 9a566446b..6d3bfe9af 100644 --- a/connector_jira/models/res_users/common.py +++ b/connector_jira/models/res_users/common.py @@ -106,7 +106,7 @@ def link_with_jira(self, backends=None, raise_if_mismatch=False): "key": resolve_by_key, "value": resolve_by_value, "error": "other_user_bound", - "detail": "linked with {}".format(existing.login), + "detail": f"linked with {existing.login}", } ) continue diff --git a/connector_jira/pyproject.toml b/connector_jira/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/connector_jira/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/connector_jira/readme/CONTRIBUTORS.md b/connector_jira/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..b58fa3525 --- /dev/null +++ b/connector_jira/readme/CONTRIBUTORS.md @@ -0,0 +1,20 @@ +- [Camptocamp](https://camptocamp.com): + + - Damien Crier + - Thierry Ducrest + - Tonow-c2c + - Simone Orsi \<\> + - Timon Tschanz \<\> + - jcoux \<\> + - Patrick Tombez \<\> + - Guewen Baconnier \<\> + - Akim Juillerat \<\> + - Alexandre Fayolle \<\> + +- [CorporateHub](https://corporatehub.eu/) + + - Alexey Pelykh \<\> + +- [Trobz](https://trobz.com): + + > - Son Ho \<\> diff --git a/connector_jira/readme/CONTRIBUTORS.rst b/connector_jira/readme/CONTRIBUTORS.rst deleted file mode 100644 index eb578145a..000000000 --- a/connector_jira/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,19 +0,0 @@ -* `Camptocamp `_: - * Damien Crier - * Thierry Ducrest - * Tonow-c2c - * Simone Orsi - * Timon Tschanz - * jcoux - * Patrick Tombez - * Guewen Baconnier - * Akim Juillerat - * Alexandre Fayolle - -* `CorporateHub `__ - - * Alexey Pelykh - -* `Trobz `_: - - * Son Ho diff --git a/connector_jira/readme/DESCRIPTION.rst b/connector_jira/readme/DESCRIPTION.md similarity index 56% rename from connector_jira/readme/DESCRIPTION.rst rename to connector_jira/readme/DESCRIPTION.md index 1a2d3f895..c85b702c1 100644 --- a/connector_jira/readme/DESCRIPTION.rst +++ b/connector_jira/readme/DESCRIPTION.md @@ -1 +1,2 @@ -This module adds Jira synchronization feature. It works with Jira Cloud by behaving as an Atlassian Connect App. +This module adds Jira synchronization feature. It works with Jira Cloud +by behaving as an Atlassian Connect App. diff --git a/connector_jira/readme/INSTALL.md b/connector_jira/readme/INSTALL.md new file mode 100644 index 000000000..28dd701fe --- /dev/null +++ b/connector_jira/readme/INSTALL.md @@ -0,0 +1,84 @@ +You need the following Python packages: + +- requests +- jira +- oauthlib +- requests-oauthlib +- requests-toolbelt +- PyJWT +- cryptography +- atlassian-jwt + +Once the addon is installed, follow these steps: + +## Job Queue + +In `odoo.conf`, configure similarly: + +``` +[queue_job] +channels = root:1,root.connector_jira.import:2 +``` + +## Backend + +1. Open the menu Connectors \> Jira \> Backends +2. Create a new Jira Backend + - Put the name you want + - You can also select the company where records will be created and + the default project template used when Odoo will create the + projects in Jira + - Save +3. Make note of the value of the App Descriptor URL (important: make + sure that the system parameter web.base.url is set properly. For + local development you will want to use ngrok to make your computer + reachable over https from Jira Cloud). + +## Installing the backend as a Jira App + +In case this gets outdated, refer to + + +1. Login on marketplace.atlassian.com (possibly create an account) +2. On the top right corner, the icon with your avatar leads to a menu + -\> select the Publish an App entry +3. On the Publish a new app screen: + - select a Vendor (normally your company) + - upload your app: select Provide a URL to your artifact + - click on the Enter URL button + - paste the App Descriptor URL in the pop-up and click on the Done + button + - the Name field should get populated from the name of your backend + - Compatible application: select Jira + - build number: can be kept as is +4. Click on the Save as private button (!) Important: do not click the + "Next: Make public" button. That flow would allow anyone on Jira + Cloud to install your backend. +5. On the next screen, you can go to the "Private Listings" page, and + click on the "Create a token" button: this token can be used to + install the app on your Jira instance. + +## Installing the Jira App on your Jira Cloud instance + +1. Connect to your Jira instance with an account with Admin access +2. In the Apps menu, select Manage your apps +3. In the Apps screen, click on the Settings link which is under the + User-installed apps list +4. In the settings screen, check the Enable private listings box, and + click on Apply +5. Refresh the Apps page: you should see an Upload app link: click on + it +6. On the Upload app dialog, paste the token URL you received in the + previous procedure, and click on Upload + +## Configuration of the Backend + +Going back to Odoo, the backend should now be in the Running state, with +some information filled in, such as the Jira URI. + +**Configure the Epic Link** + +If you use Epics, you need to click on "Configure Epic Link", Odoo will +search the name of the custom field used for the Epic Link. + +Congratulations, you're done! diff --git a/connector_jira/readme/INSTALL.rst b/connector_jira/readme/INSTALL.rst deleted file mode 100644 index 6ff557c44..000000000 --- a/connector_jira/readme/INSTALL.rst +++ /dev/null @@ -1,83 +0,0 @@ -You need the following Python packages: - -* requests -* jira -* oauthlib -* requests-oauthlib -* requests-toolbelt -* PyJWT -* cryptography -* atlassian-jwt - - -Once the addon is installed, follow these steps: - -Job Queue -~~~~~~~~~ - -In ``odoo.conf``, configure similarly: - -.. code-block:: - - [queue_job] - channels = root:1,root.connector_jira.import:2 - - -Backend -~~~~~~~ - -1. Open the menu Connectors > Jira > Backends -2. Create a new Jira Backend - - * Put the name you want - * You can also select the company where records will be created and the - default project template used when Odoo will create the projects in Jira - * Save - -3. Make note of the value of the App Descriptor URL (important: make sure that - the system parameter `web.base.url` is set properly. For local development you - will want to use ngrok to make your computer reachable over https from Jira Cloud). - -Installing the backend as a Jira App -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In case this gets outdated, refer to https://developer.atlassian.com/platform/marketplace/listing-connect-apps/#list-a-connect-app - -1. Login on marketplace.atlassian.com (possibly create an account) -2. On the top right corner, the icon with your avatar leads to a menu -> select the `Publish an App` entry -3. On the Publish a new app screen: - * select a Vendor (normally your company) - * upload your app: select `Provide a URL to your artifact` - * click on the `Enter URL` button - * paste the App Descriptor URL in the pop-up and click on the `Done` button - * the `Name` field should get populated from the `name` of your backend - * Compatible application: select `Jira` - * build number: can be kept as is -4. Click on the `Save as private` button - (!) Important: do not click the "Next: Make public" button. That flow would allow anyone on Jira Cloud to install your backend. -5. On the next screen, you can go to the "Private Listings" page, and click on the "Create a token" button: this token can be used to install the app on your Jira instance. - - -Installing the Jira App on your Jira Cloud instance -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -1. Connect to your Jira instance with an account with Admin access -2. In the Apps menu, select `Manage your apps` -3. In the Apps screen, click on the Settings link which is under the User-installed apps list -4. In the settings screen, check the `Enable private listings` box, and click on `Apply` -5. Refresh the Apps page: you should see an `Upload app` link: click on it -6. On the Upload app dialog, paste the token URL you received in the previous procedure, and click on `Upload` - - -Configuration of the Backend -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Going back to Odoo, the backend should now be in the Running state, with some information filled in, such as the Jira URI. - - -**Configure the Epic Link** - -If you use Epics, you need to click on "Configure Epic Link", Odoo will search -the name of the custom field used for the Epic Link. - -Congratulations, you're done! diff --git a/connector_jira/readme/ROADMAP.md b/connector_jira/readme/ROADMAP.md new file mode 100644 index 000000000..82bb8bb53 --- /dev/null +++ b/connector_jira/readme/ROADMAP.md @@ -0,0 +1,25 @@ +- If an odoo user has no linked employee, worklogs will still be + imported but with no employee. + +**Allowing several bindings per project** + +The design evolved to allow more than one Jira binding per project in +Odoo. This conveniently allows to fetch tasks and worklogs for many +projects in Jira, which will be tracked in only one project in Odoo. + +In order to push data to Jira, we have to apply restrictions on these +"multi-bindings" projects, as we cannot know to which binding data must +be pushed: + +- Not more than one project (can be zero) can have a "Sync Action" set + to "Export to JIRA". As this configuration pushes the name and key of + the project to Jira, we cannot push it to more than one project. +- If we implement push of tasks to Jira, we'll have to add a way to + restrict or choose to which project we push the task, this is not + supported yet (for instance, add a Boolean "export tasks" on the + project binding, or explicitly select the target binding on the task) +- Now that the webhooks are authenticated, use the values sent by the + webhooks rather than querying them back +- We now can have multiple backends, registering multiple webhooks. If + we want to use this in practice, testing must be done and probably + some things will need fixing. diff --git a/connector_jira/readme/ROADMAP.rst b/connector_jira/readme/ROADMAP.rst deleted file mode 100644 index af5272422..000000000 --- a/connector_jira/readme/ROADMAP.rst +++ /dev/null @@ -1,25 +0,0 @@ -* If an odoo user has no linked employee, worklogs will still be imported but - with no employee. - -**Allowing several bindings per project** - -The design evolved to allow more than one Jira binding per project in Odoo. -This conveniently allows to fetch tasks and worklogs for many projects in Jira, -which will be tracked in only one project in Odoo. - -In order to push data to Jira, we have to apply restrictions on these -"multi-bindings" projects, as we cannot know to which binding data must -be pushed: - -* Not more than one project (can be zero) can have a "Sync Action" set to - "Export to JIRA". As this configuration pushes the name and key of the project - to Jira, we cannot push it to more than one project. -* If we implement push of tasks to Jira, we'll have to add a way to restrict or - choose to which project we push the task, this is not supported yet (for - instance, add a Boolean "export tasks" on the project binding, or explicitly - select the target binding on the task) -* Now that the webhooks are authenticated, use the values sent by the webhooks - rather than querying them back -* We now can have multiple backends, registering multiple webhooks. If we want - to use this in practice, testing must be done and probably some things will - need fixing. diff --git a/connector_jira/readme/USAGE.md b/connector_jira/readme/USAGE.md new file mode 100644 index 000000000..adc6ae464 --- /dev/null +++ b/connector_jira/readme/USAGE.md @@ -0,0 +1,53 @@ +The tasks and worklogs are always imported from JIRA to Odoo, there is +no synchronization in the other direction. + +## Initial synchronizations + +You can already select the "Imports" tab in the Backend and click on +"Link users" and "Import issue types". The users will be matched either +by login or by email. + +## Create and export a project + +Projects can be created in Odoo and exported to Jira. You can then +create a project, and use the action "Link with JIRA" and use the +"Export to JIRA" action. + +When you choose to export a project to JIRA, if you change the name or +the key of the project, the new values will be pushed to JIRA. + +## Link a project with JIRA + +If you already have a project on JIRA or prefer to create it first on +JIRA, you can link an Odoo project. Use the "Link with JIRA" action on +the project and select the "Link with JIRA" action. + +This action establish the link, then changes of the name or the key on +either side are not pushed. + +## Issue Types on Projects + +When you link a project, you have to select which issue types are +synchronized. Only tasks of the selected types will be created in Odoo. + +If a JIRA worklog is added to a type of issue that is not synchronized, +will attach to the closest task following these rules: + +- if a subtask, find the parent task +- if no parent task, find the epic task (only if it is on the same + project) +- if no epic, attach to the project without being linked to a task + +## Change synchronization configuration on a project + +If you want to change the configuration of a project, such as which +issue types are synchronized, you can open the "Connector" tab in the +project settings and edit the "binding" with the backend. + +## Synchronize tasks and worklogs + +If the webhooks are active, as soon as they are created in Jira they +should appear in Odoo. If they are not active, you can open the Jira +Backend and run the synchronizations manually, or activate the Scheduled +Actions to run the batch imports. It is important to select the issue +types so don't miss this step (need improvement). diff --git a/connector_jira/readme/USAGE.rst b/connector_jira/readme/USAGE.rst deleted file mode 100644 index 7d64ce9fe..000000000 --- a/connector_jira/readme/USAGE.rst +++ /dev/null @@ -1,55 +0,0 @@ -The tasks and worklogs are always imported from JIRA to Odoo, there -is no synchronization in the other direction. - -Initial synchronizations -~~~~~~~~~~~~~~~~~~~~~~~~ - -You can already select the "Imports" tab in the Backend and click on "Link -users" and "Import issue types". The users will be matched either by login or by email. - -Create and export a project -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Projects can be created in Odoo and exported to Jira. You can then create a -project, and use the action "Link with JIRA" and use the "Export to JIRA" action. - -When you choose to export a project to JIRA, if you change the name -or the key of the project, the new values will be pushed to JIRA. - -Link a project with JIRA -~~~~~~~~~~~~~~~~~~~~~~~~ - -If you already have a project on JIRA or prefer to create it first on JIRA, -you can link an Odoo project. Use the "Link with JIRA" action on the project -and select the "Link with JIRA" action. - -This action establish the link, then changes of the name or the key on either -side are not pushed. - -Issue Types on Projects -~~~~~~~~~~~~~~~~~~~~~~~ - -When you link a project, you have to select which issue types are synchronized. -Only tasks of the selected types will be created in Odoo. - -If a JIRA worklog is added to a type of issue that is not synchronized, -will attach to the closest task following these rules: - -* if a subtask, find the parent task -* if no parent task, find the epic task (only if it is on the same project) -* if no epic, attach to the project without being linked to a task - -Change synchronization configuration on a project -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you want to change the configuration of a project, such as which -issue types are synchronized, you can open the "Connector" tab in -the project settings and edit the "binding" with the backend. - -Synchronize tasks and worklogs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If the webhooks are active, as soon as they are created in Jira they should appear in Odoo. -If they are not active, you can open the Jira Backend and run the -synchronizations manually, or activate the Scheduled Actions to run the batch -imports. It is important to select the issue types so don't miss this step (need improvement). diff --git a/connector_jira/static/description/index.html b/connector_jira/static/description/index.html index 87fcf42cd..d0adc69fa 100644 --- a/connector_jira/static/description/index.html +++ b/connector_jira/static/description/index.html @@ -1,4 +1,3 @@ - @@ -9,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -275,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -301,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -369,8 +369,9 @@

JIRA Connector

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:f21e9da36fa047bba211c31662246c7856a1144d0f66ee163b201f26f7f1934f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/connector-jira Translate me on Weblate Try me on Runboat

-

This module adds Jira synchronization feature. It works with Jira Cloud by behaving as an Atlassian Connect App.

+

Beta License: AGPL-3 OCA/connector-jira Translate me on Weblate Try me on Runboat

+

This module adds Jira synchronization feature. It works with Jira Cloud +by behaving as an Atlassian Connect App.

Table of contents

    @@ -418,7 +419,7 @@

    Installation

    Job Queue

    In odoo.conf, configure similarly:

    -
    +
     [queue_job]
     channels = root:1,root.connector_jira.import:2
     
    @@ -429,131 +430,149 @@

    Backend

  • Open the menu Connectors > Jira > Backends
  • Create a new Jira Backend
    • Put the name you want
    • -
    • You can also select the company where records will be created and the -default project template used when Odoo will create the projects in Jira
    • +
    • You can also select the company where records will be created and +the default project template used when Odoo will create the +projects in Jira
    • Save
  • -
  • Make note of the value of the App Descriptor URL (important: make sure that -the system parameter web.base.url is set properly. For local development you -will want to use ngrok to make your computer reachable over https from Jira Cloud).
  • +
  • Make note of the value of the App Descriptor URL (important: make +sure that the system parameter web.base.url is set properly. For +local development you will want to use ngrok to make your computer +reachable over https from Jira Cloud).
  • Installing the backend as a Jira App

    -

    In case this gets outdated, refer to https://developer.atlassian.com/platform/marketplace/listing-connect-apps/#list-a-connect-app

    +

    In case this gets outdated, refer to +https://developer.atlassian.com/platform/marketplace/listing-connect-apps/#list-a-connect-app

    1. Login on marketplace.atlassian.com (possibly create an account)
    2. -
    3. On the top right corner, the icon with your avatar leads to a menu -> select the Publish an App entry
    4. -
    5. On the Publish a new app screen: -* select a Vendor (normally your company) -* upload your app: select Provide a URL to your artifact -* click on the Enter URL button -* paste the App Descriptor URL in the pop-up and click on the Done button -* the Name field should get populated from the name of your backend -* Compatible application: select Jira -* build number: can be kept as is
    6. -
    7. Click on the Save as private button -(!) Important: do not click the “Next: Make public” button. That flow would allow anyone on Jira Cloud to install your backend.
    8. -
    9. On the next screen, you can go to the “Private Listings” page, and click on the “Create a token” button: this token can be used to install the app on your Jira instance.
    10. +
    11. On the top right corner, the icon with your avatar leads to a menu -> +select the Publish an App entry
    12. +
    13. On the Publish a new app screen:
        +
      • select a Vendor (normally your company)
      • +
      • upload your app: select Provide a URL to your artifact
      • +
      • click on the Enter URL button
      • +
      • paste the App Descriptor URL in the pop-up and click on the Done +button
      • +
      • the Name field should get populated from the name of your backend
      • +
      • Compatible application: select Jira
      • +
      • build number: can be kept as is
      • +
      +
    14. +
    15. Click on the Save as private button (!) Important: do not click the +“Next: Make public” button. That flow would allow anyone on Jira +Cloud to install your backend.
    16. +
    17. On the next screen, you can go to the “Private Listings” page, and +click on the “Create a token” button: this token can be used to +install the app on your Jira instance.

    Installing the Jira App on your Jira Cloud instance

    1. Connect to your Jira instance with an account with Admin access
    2. -
    3. In the Apps menu, select Manage your apps
    4. -
    5. In the Apps screen, click on the Settings link which is under the User-installed apps list
    6. -
    7. In the settings screen, check the Enable private listings box, and click on Apply
    8. -
    9. Refresh the Apps page: you should see an Upload app link: click on it
    10. -
    11. On the Upload app dialog, paste the token URL you received in the previous procedure, and click on Upload
    12. +
    13. In the Apps menu, select Manage your apps
    14. +
    15. In the Apps screen, click on the Settings link which is under the +User-installed apps list
    16. +
    17. In the settings screen, check the Enable private listings box, and +click on Apply
    18. +
    19. Refresh the Apps page: you should see an Upload app link: click on it
    20. +
    21. On the Upload app dialog, paste the token URL you received in the +previous procedure, and click on Upload

    Configuration of the Backend

    -

    Going back to Odoo, the backend should now be in the Running state, with some information filled in, such as the Jira URI.

    +

    Going back to Odoo, the backend should now be in the Running state, with +some information filled in, such as the Jira URI.

    Configure the Epic Link

    -

    If you use Epics, you need to click on “Configure Epic Link”, Odoo will search -the name of the custom field used for the Epic Link.

    +

    If you use Epics, you need to click on “Configure Epic Link”, Odoo will +search the name of the custom field used for the Epic Link.

    Congratulations, you’re done!

Usage

-

The tasks and worklogs are always imported from JIRA to Odoo, there -is no synchronization in the other direction.

+

The tasks and worklogs are always imported from JIRA to Odoo, there is +no synchronization in the other direction.

Initial synchronizations

-

You can already select the “Imports” tab in the Backend and click on “Link -users” and “Import issue types”. The users will be matched either by login or by email.

+

You can already select the “Imports” tab in the Backend and click on +“Link users” and “Import issue types”. The users will be matched either +by login or by email.

Create and export a project

-

Projects can be created in Odoo and exported to Jira. You can then create a -project, and use the action “Link with JIRA” and use the “Export to JIRA” action.

-

When you choose to export a project to JIRA, if you change the name -or the key of the project, the new values will be pushed to JIRA.

+

Projects can be created in Odoo and exported to Jira. You can then +create a project, and use the action “Link with JIRA” and use the +“Export to JIRA” action.

+

When you choose to export a project to JIRA, if you change the name or +the key of the project, the new values will be pushed to JIRA.

Issue Types on Projects

-

When you link a project, you have to select which issue types are synchronized. -Only tasks of the selected types will be created in Odoo.

+

When you link a project, you have to select which issue types are +synchronized. Only tasks of the selected types will be created in Odoo.

If a JIRA worklog is added to a type of issue that is not synchronized, will attach to the closest task following these rules:

  • if a subtask, find the parent task
  • -
  • if no parent task, find the epic task (only if it is on the same project)
  • +
  • if no parent task, find the epic task (only if it is on the same +project)
  • if no epic, attach to the project without being linked to a task

Change synchronization configuration on a project

If you want to change the configuration of a project, such as which -issue types are synchronized, you can open the “Connector” tab in -the project settings and edit the “binding” with the backend.

+issue types are synchronized, you can open the “Connector” tab in the +project settings and edit the “binding” with the backend.

Synchronize tasks and worklogs

-

If the webhooks are active, as soon as they are created in Jira they should appear in Odoo. -If they are not active, you can open the Jira Backend and run the -synchronizations manually, or activate the Scheduled Actions to run the batch -imports. It is important to select the issue types so don’t miss this step (need improvement).

+

If the webhooks are active, as soon as they are created in Jira they +should appear in Odoo. If they are not active, you can open the Jira +Backend and run the synchronizations manually, or activate the Scheduled +Actions to run the batch imports. It is important to select the issue +types so don’t miss this step (need improvement).

Known issues / Roadmap

    -
  • If an odoo user has no linked employee, worklogs will still be imported but -with no employee.
  • +
  • If an odoo user has no linked employee, worklogs will still be +imported but with no employee.

Allowing several bindings per project

-

The design evolved to allow more than one Jira binding per project in Odoo. -This conveniently allows to fetch tasks and worklogs for many projects in Jira, -which will be tracked in only one project in Odoo.

+

The design evolved to allow more than one Jira binding per project in +Odoo. This conveniently allows to fetch tasks and worklogs for many +projects in Jira, which will be tracked in only one project in Odoo.

In order to push data to Jira, we have to apply restrictions on these “multi-bindings” projects, as we cannot know to which binding data must be pushed:

    -
  • Not more than one project (can be zero) can have a “Sync Action” set to -“Export to JIRA”. As this configuration pushes the name and key of the project -to Jira, we cannot push it to more than one project.
  • -
  • If we implement push of tasks to Jira, we’ll have to add a way to restrict or -choose to which project we push the task, this is not supported yet (for -instance, add a Boolean “export tasks” on the project binding, or explicitly -select the target binding on the task)
  • -
  • Now that the webhooks are authenticated, use the values sent by the webhooks -rather than querying them back
  • -
  • We now can have multiple backends, registering multiple webhooks. If we want -to use this in practice, testing must be done and probably some things will -need fixing.
  • +
  • Not more than one project (can be zero) can have a “Sync Action” set +to “Export to JIRA”. As this configuration pushes the name and key of +the project to Jira, we cannot push it to more than one project.
  • +
  • If we implement push of tasks to Jira, we’ll have to add a way to +restrict or choose to which project we push the task, this is not +supported yet (for instance, add a Boolean “export tasks” on the +project binding, or explicitly select the target binding on the task)
  • +
  • Now that the webhooks are authenticated, use the values sent by the +webhooks rather than querying them back
  • +
  • We now can have multiple backends, registering multiple webhooks. If +we want to use this in practice, testing must be done and probably +some things will need fixing.
@@ -561,7 +580,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -575,17 +594,19 @@

Authors

Contributors

diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..ae19d4351 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +# generated from manifests external_dependencies +PyJWT>=1.7.1,<2.9.0 +atlassian_jwt>=3.0.0 +cryptography<37 +jira>=2.0.0 +oauthlib>=2.1.0 +requests-jwt>=0.6.0 +requests-oauthlib>=1.1.0 +requests-toolbelt>=0.9.1 +requests>=2.21.0