diff --git a/.circleci/config.yml b/.circleci/config.yml index 09af132..bf8c580 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,10 +25,6 @@ jobs: name: Run Test command: docker-compose run --rm odoo run_pytest.sh - - run: - name: Codacy Coverage - command: bash <(curl -Ls https://coverage.codacy.com/get.sh) report -l python -r .log/coverage.xml - - store_test_results: path: .log @@ -46,9 +42,9 @@ jobs: curl -L $NWS_BIN_LOCATION > ./nws chmod +x ./nws - run: - name: Set tag + name: Set tag on isidor-odoo command: | - ./nws circleci create-tag -t odoo-base + ./nws circleci create-tag -t isidor-odoo workflows: version: 2 diff --git a/.docker_files/main/__init__.py b/.docker_files/main/__init__.py index 76f103f..3942b41 100644 --- a/.docker_files/main/__init__.py +++ b/.docker_files/main/__init__.py @@ -1,2 +1,2 @@ -# © 2023 - today Numigi +# © 2024 - today Numigi # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). diff --git a/.docker_files/main/__manifest__.py b/.docker_files/main/__manifest__.py index 0736ecf..d29cc53 100644 --- a/.docker_files/main/__manifest__.py +++ b/.docker_files/main/__manifest__.py @@ -1,20 +1,19 @@ -# © 2019 - today Numigi +# © 2024 - today Numigi # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). { - 'name': 'Main Module', - 'version': '1.0.0', - 'author': 'Numigi', - 'maintainer': 'Numigi', - 'website': 'https://www.numigi.com', - 'license': 'LGPL-3', - 'category': 'Other', - 'summary': 'Install all addons required for testing.', - 'depends': [ - 'github_event', - 'github_event_webhook', - 'github_pull_request', - 'github_pull_request_project', + "name": "Main Module", + "version": "1.0.0", + "author": "Numigi", + "maintainer": "Numigi", + "website": "https://www.numigi.com", + "license": "LGPL-3", + "category": "Other", + "summary": "Install all addons required for testing.", + "depends": [ + "base", + "github_event", + "github_pull_request", ], - 'installable': True, + "installable": True, } diff --git a/.docker_files/odoo.conf b/.docker_files/odoo.conf index 2a7cdc7..973acdb 100644 --- a/.docker_files/odoo.conf +++ b/.docker_files/odoo.conf @@ -49,7 +49,7 @@ test_report_directory = False translate_modules = ['all'] unaccent = False without_demo = False -workers = 2 +workers = 0 xmlrpc = True xmlrpc_interface = xmlrpc_port = 8069 diff --git a/.docker_files/requirements.txt b/.docker_files/test-requirements.txt similarity index 100% rename from .docker_files/requirements.txt rename to .docker_files/test-requirements.txt diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..b6a254e --- /dev/null +++ b/.flake8 @@ -0,0 +1,12 @@ +[flake8] +max-line-length = 88 +max-complexity = 16 +# B = bugbear +# B9 = bugbear opinionated (incl line length) +select = C,E,F,W,B,B9 +# E203: whitespace before ':' (black behaviour) +# E501: flake8 line length (covered by bugbear B950) +# W503: line break before binary operator (black behaviour) +ignore = E203,E501,W503,F821 +per-file-ignores= + __init__.py:F401 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..94dc196 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,36 @@ +name: pre-commit + +on: + pull_request: + branches: + - "16.0" + push: + branches: + - "16.0" + +jobs: + pre-commit: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v2 + with: + python-version: "3.11" + - name: Get python version + run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV + - uses: actions/cache@v1 + with: + path: ~/.cache/pre-commit + key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} + - name: Install pre-commit + run: pip install pre-commit + - name: Run pre-commit + run: pre-commit run --all-files --show-diff-on-failure --color=always + - name: Check that all files generated by pre-commit are in git + run: | + newfiles="$(git ls-files --others --exclude-from=.gitignore)" + if [ "$newfiles" != "" ] ; then + echo "Please check-in the following files:" + echo "$newfiles" + exit 1 + fi diff --git a/.gitignore b/.gitignore index 693f7d9..58df918 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ -.log +/.idea/ +venv +log /.idea -__pycache__ +__pycache__/ +*.pyc +.venv +Pipfile +docker-compose.override.yml +.DS_STORE +.pytest_cache +.vscode/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..3cd01ba --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,34 @@ +exclude: | + (?x) + # NOT INSTALLABLE ADDONS + # END NOT INSTALLABLE ADDONS + # Files and folders generated by bots, to avoid loops + ^setup/|/static/description/index\.html$| + # We don't want to mess with tool-generated files + .svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/| + # Maybe reactivate this when all README files include prettier ignore tags? + ^README\.md$| + # Library files can have extraneous formatting (even minimized) + /static/(src/)?lib/| + # Repos using Sphinx to generate docs don't need prettying + ^docs/_templates/.*\.html$| + # Don't bother non-technical authors with formatting issues in docs + readme/.*\.(rst|md)$| + # Ignore build and dist directories in addons + /build/|/dist/| + # You don't usually want a bot to modify your legal texts + (LICENSE.*|COPYING.*) +default_language_version: + python: python3 + node: "14.13.0" +repos: + - repo: https://github.com/psf/black + rev: 22.8.0 + hooks: + - id: black + - repo: https://github.com/PyCQA/flake8 + rev: 3.8.3 + hooks: + - id: flake8 + name: flake8 + additional_dependencies: ["flake8-bugbear==20.1.4"] diff --git a/Dockerfile b/Dockerfile index 940be5c..373713c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,10 @@ -FROM quay.io/numigi/odoo-public:14.latest -MAINTAINER numigi +FROM quay.io/numigi/odoo-public:16.latest +LABEL maintainer="contact@numigi.com" USER root -COPY .docker_files/requirements.txt . -RUN pip3 install -r requirements.txt - -# Variable used for fetching private git repositories. -ARG GIT_TOKEN +COPY .docker_files/test-requirements.txt . +RUN pip3 install -r test-requirements.txt ENV THIRD_PARTY_ADDONS /mnt/third-party-addons RUN mkdir -p "${THIRD_PARTY_ADDONS}" && chown -R odoo "${THIRD_PARTY_ADDONS}" @@ -16,10 +13,8 @@ RUN gitoo install-all --conf_file /gitoo.yml --destination "${THIRD_PARTY_ADDONS USER odoo -COPY ./github_event /mnt/extra-addons/github_event -COPY ./github_event_webhook /mnt/extra-addons/github_event_webhook -COPY ./github_pull_request /mnt/extra-addons/github_pull_request -COPY ./github_pull_request_project /mnt/extra-addons/github_pull_request_project +COPY github_event /mnt/extra-addons/github_event +COPY github_pull_request /mnt/extra-addons/github_pull_request COPY .docker_files/main /mnt/extra-addons/main COPY .docker_files/odoo.conf /etc/odoo diff --git a/README.md b/README.md index d107060..c541a67 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # odoo-git-addons + git and github related odoo modules diff --git a/docker-compose.yml b/docker-compose.yml index 3870816..a61165e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,10 +4,8 @@ services: build: context: . dockerfile: Dockerfile - args: - - GIT_TOKEN=${GIT_TOKEN} volumes: - - odoo-web-data:/var/lib/odoo + - odoo16-web-data:/var/lib/odoo - ./.log:/var/log/odoo ports: - "8069:8069" @@ -18,16 +16,16 @@ services: environment: - LOG_ODOO=/var/log/odoo db: - image: quay.io/numigi/postgres-odoo:13.1.6 + image: postgres:16.0 environment: - POSTGRES_PASSWORD=odoo - POSTGRES_USER=odoo - PGDATA=/var/lib/postgresql/data/pgdata volumes: - - odoo-db-data:/var/lib/postgresql/data/pgdata + - odoo16-db-data:/var/lib/postgresql/data/pgdata expose: - 5432 volumes: - odoo-web-data: - odoo-db-data: + odoo16-web-data: + odoo16-db-data: diff --git a/github_event/__init__.py b/github_event/__init__.py index 22b7d41..ac4a686 100644 --- a/github_event/__init__.py +++ b/github_event/__init__.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). from . import models diff --git a/github_event/__manifest__.py b/github_event/__manifest__.py index 881b210..181c2da 100644 --- a/github_event/__manifest__.py +++ b/github_event/__manifest__.py @@ -1,22 +1,22 @@ -# © 2023 - Today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - Today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). { - 'name': 'Github Events', - 'version': "14.0.1.0.0", - 'author': 'Numigi', - 'maintainer': 'Numigi', - 'website': 'https://bit.ly/numigi-com', - 'license': 'LGPL-3', - 'category': 'Connector', - 'summary': 'Define what is a github event as an odoo object', - 'depends': [ - 'base_sparse_field', + "name": "Github Events", + "version": "16.0.1.0.0", + "author": "Numigi", + "maintainer": "Numigi", + "website": "https://bit.ly/numigi-com", + "license": "LGPL-3", + "category": "Connector", + "summary": "Define what is a github event as an odoo object", + "depends": [ + "base_sparse_field", ], - 'data': [ - 'security/ir.model.access.csv', - 'views/github_event.xml', - 'views/menu.xml', + "data": [ + "security/ir.model.access.csv", + "views/github_event.xml", + "views/menu.xml", ], - 'installable': True, + "installable": True, } diff --git a/github_event/i18n/fr.po b/github_event/i18n/fr.po index 18573e9..e27986f 100644 --- a/github_event/i18n/fr.po +++ b/github_event/i18n/fr.po @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-12-04 19:28+0000\n" "PO-Revision-Date: 2019-12-04 14:30-0500\n" diff --git a/github_event/models/__init__.py b/github_event/models/__init__.py index a4baa0a..f229828 100644 --- a/github_event/models/__init__.py +++ b/github_event/models/__init__.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). from . import ( diff --git a/github_event/models/github_event.py b/github_event/models/github_event.py index 8a7d179..727482e 100644 --- a/github_event/models/github_event.py +++ b/github_event/models/github_event.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). import json @@ -11,21 +11,18 @@ class GithubEvent(models.Model): _name = "github.event" _description = "Github Event" - _order = 'id desc' + _order = "id desc" + action = fields.Char() payload = fields.Text() - payload_serialized = Serialized( - compute='_compute_payload_serialized' - ) + payload_serialized = Serialized(compute="_compute_payload_serialized") - @api.depends('payload') + @api.depends("payload") def _compute_payload_serialized(self): events_with_payloads = self.filtered(lambda e: e.payload) for event in events_with_payloads: event.payload_serialized = json.loads(event.payload) - action = fields.Char() - def _get_value_from_payload(self, path): """Get a value from the payload. @@ -33,13 +30,15 @@ def _get_value_from_payload(self, path): :return: the value contained at the given path. """ section = self.payload_serialized - keys = path.split('.') + keys = path.split(".") for key in keys[:-1]: if not isinstance(section, dict) or key not in section: - raise ValidationError(_( - "The payload does not contain a value at the path {}." - ).format(path)) + raise ValidationError( + _("The payload does not contain a value at the path {}.").format( + path + ) + ) section = section[key] @@ -51,4 +50,4 @@ def process(self): This method is intended to be inherited by other modules to add extra behavior when processing a github event. """ - self.action = self._get_value_from_payload('action') + self.action = self._get_value_from_payload("action") diff --git a/github_event/static/description/event_form.png b/github_event/static/description/event_form.png index e4206e1..116d0cd 100644 Binary files a/github_event/static/description/event_form.png and b/github_event/static/description/event_form.png differ diff --git a/github_event/static/description/event_form_process_button.png b/github_event/static/description/event_form_process_button.png index 1ab06c5..2f1f088 100644 Binary files a/github_event/static/description/event_form_process_button.png and b/github_event/static/description/event_form_process_button.png differ diff --git a/github_event/static/description/event_tree.png b/github_event/static/description/event_tree.png index 35764c0..705aa67 100644 Binary files a/github_event/static/description/event_tree.png and b/github_event/static/description/event_tree.png differ diff --git a/github_event/static/description/menu_technical_events.png b/github_event/static/description/menu_technical_events.png index 7b91042..0da787b 100644 Binary files a/github_event/static/description/menu_technical_events.png and b/github_event/static/description/menu_technical_events.png differ diff --git a/github_event/tests/__init__.py b/github_event/tests/__init__.py index 7fa1774..6a24851 100644 --- a/github_event/tests/__init__.py +++ b/github_event/tests/__init__.py @@ -1,2 +1,2 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). diff --git a/github_event/tests/common.py b/github_event/tests/common.py index 0b41d11..2355178 100644 --- a/github_event/tests/common.py +++ b/github_event/tests/common.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). import os @@ -6,15 +6,14 @@ class GithubEventCase(common.SavepointCase): - @classmethod def setUpClass(cls): super().setUpClass() - cls.event_1 = cls.env['github.event'].create({}) - cls.event_2 = cls.env['github.event'].create({}) + cls.event_1 = cls.env["github.event"].create({}) + cls.event_2 = cls.env["github.event"].create({}) def _read_payload(self, filename): test_folder = os.path.dirname(os.path.realpath(__file__)) - payload_file_path = os.path.join(test_folder, 'data', filename) - with open(payload_file_path, 'r') as file: + payload_file_path = os.path.join(test_folder, "data", filename) + with open(payload_file_path, "r") as file: return file.read() diff --git a/github_event/tests/test_github_event.py b/github_event/tests/test_github_event.py index ff412bc..ec2c37b 100644 --- a/github_event/tests/test_github_event.py +++ b/github_event/tests/test_github_event.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). from ddt import ddt, data, unpack @@ -7,12 +7,11 @@ @ddt class TestGithubEvent(GithubEventCase): - @data( - ('pull_request_1_merged.json', 'closed'), - ('pull_request_2_closed.json', 'closed'), - ('pull_request_2_reopened.json', 'reopened'), - ('check_run_completed.json', 'completed'), + ("pull_request_1_merged.json", "closed"), + ("pull_request_2_closed.json", "closed"), + ("pull_request_2_reopened.json", "reopened"), + ("check_run_completed.json", "completed"), ) @unpack def test_action(self, filename, expected_action): diff --git a/github_event/views/github_event.xml b/github_event/views/github_event.xml index 9fc2540..eab9b3e 100644 --- a/github_event/views/github_event.xml +++ b/github_event/views/github_event.xml @@ -7,16 +7,16 @@
-
- - + + - + @@ -29,8 +29,8 @@ github.event - - + + diff --git a/github_event_webhook/README.rst b/github_event_webhook/README.rst deleted file mode 100644 index 03bad74..0000000 --- a/github_event_webhook/README.rst +++ /dev/null @@ -1,39 +0,0 @@ -Github Event Webhook -==================== -This module defines an HTTP controller to register events in Odoo using github webhook. - -Each event is processed asynchronously in a queue job. - -.. contents:: Table of Contents - -Configuration -------------- - -Define your Secret -~~~~~~~~~~~~~~~~~~ -First, generate a secret that will be used to authentify the webhook with your Odoo instance. -You may use the tool of your choice to create the secret. - -Then, create a system parameter: - -* Key: ``github_pull_request.github_secret`` -* Value: Your secret - -.. image:: static/description/webhook_secret_parameter.png - -Setup the Webhook -~~~~~~~~~~~~~~~~~ -Then, in Github, setup the webhook. - -.. image:: static/description/github_webhook_example.png - -* Payload URL: ``{base_url}/web/github/event`` -* Content Type: ``application/x-www-form-urlencoded`` -* Secret: Your secret - -In the section ``Which events would you like to trigger this webhook?``, -select ``Let me select individual events``, then check ``Pull requests``. - -Contributors ------------- -* Numigi (tm) and all its contributors (https://bit.ly/numigiens) diff --git a/github_event_webhook/__init__.py b/github_event_webhook/__init__.py deleted file mode 100644 index 7c3200f..0000000 --- a/github_event_webhook/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import models, controllers diff --git a/github_event_webhook/__manifest__.py b/github_event_webhook/__manifest__.py deleted file mode 100644 index 1a9dee9..0000000 --- a/github_event_webhook/__manifest__.py +++ /dev/null @@ -1,21 +0,0 @@ -# © 2023 - Today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -{ - 'name': 'Github Event Webhook', - 'version': "14.0.1.0.0", - 'author': 'Numigi', - 'maintainer': 'Numigi', - 'website': 'https://bit.ly/numigi-com', - 'license': 'LGPL-3', - 'category': 'Connector', - 'summary': 'Add a controller for importing events from github', - 'depends': [ - 'github_event', - 'queue_job', - ], - 'data': [ - 'data/queue_job_function_data.xml', - ], - 'installable': True, -} diff --git a/github_event_webhook/controllers/__init__.py b/github_event_webhook/controllers/__init__.py deleted file mode 100644 index 24a35e2..0000000 --- a/github_event_webhook/controllers/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2023 - Today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import github diff --git a/github_event_webhook/controllers/github.py b/github_event_webhook/controllers/github.py deleted file mode 100644 index ade5630..0000000 --- a/github_event_webhook/controllers/github.py +++ /dev/null @@ -1,70 +0,0 @@ -# © 2023 - Today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -import json -import hmac -import hashlib -from odoo import http -from odoo.http import request, Response -from werkzeug.urls import url_encode - -import logging -_logger = logging.getLogger(__name__) - -GITHUB_EVENT_SECRET_PARAM = 'github_pull_request.github_secret' -GITHUB_SIGNATURE_HEADER = 'X-Hub-Signature' - - -def make_github_signature(request_body: str, secret: str) -> str: - """Make a Github signature from the given request body and secret. - - :param request_body: the request body - :param secret: the secret (token) - """ - digest = hmac.new(secret.encode(), request_body.encode(), - hashlib.sha1).hexdigest() - return 'sha1={}'.format(digest) - - -def _get_github_signature_from_headers() -> str: - return request.httprequest.headers.get(GITHUB_SIGNATURE_HEADER, "") - - -def _check_github_event_signature(signature: str) -> bool: - request_body = url_encode(request.httprequest.form) - secret = request.env['ir.config_parameter'].with_user( - request.uid).get_param(GITHUB_EVENT_SECRET_PARAM) - return make_github_signature(request_body, secret) == signature - - -class GithubEvent(http.Controller): - - @http.route('/web/github/event', type='http', auth='none', sitemap=False, csrf=False) - def new_github_event(self, **data): - signature = _get_github_signature_from_headers() - - if not signature: - message = "The github signature is required to submit a new event." - _logger.info(message) - return Response(message, status=401) - - if not _check_github_event_signature(signature): - message = "The given github signature is not valid." - _logger.info(message) - return Response(message, status=401) - - json_payload = self._get_json_payload(data) - event = self._create_event(json_payload) - event.with_delay().process_job() - - return Response(status=201) - - @staticmethod - def _get_json_payload(data): - return data['payload'] - - @staticmethod - def _create_event(json_payload): - return request.env['github.event'].sudo().create({ - 'payload': json_payload, - }) diff --git a/github_event_webhook/data/queue_job_function_data.xml b/github_event_webhook/data/queue_job_function_data.xml deleted file mode 100644 index ee92fa9..0000000 --- a/github_event_webhook/data/queue_job_function_data.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - github_event - - - - - - process_job - - - - - diff --git a/github_event_webhook/models/__init__.py b/github_event_webhook/models/__init__.py deleted file mode 100644 index a4baa0a..0000000 --- a/github_event_webhook/models/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import ( - github_event, -) diff --git a/github_event_webhook/models/github_event.py b/github_event_webhook/models/github_event.py deleted file mode 100644 index 3c09846..0000000 --- a/github_event_webhook/models/github_event.py +++ /dev/null @@ -1,13 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from odoo import models - - -class GithubEvent(models.Model): - - _inherit = "github.event" - - def process_job(self): - """Process a github event.""" - self.process() diff --git a/github_event_webhook/static/description/github_webhook_example.png b/github_event_webhook/static/description/github_webhook_example.png deleted file mode 100644 index bf7a51d..0000000 Binary files a/github_event_webhook/static/description/github_webhook_example.png and /dev/null differ diff --git a/github_event_webhook/static/description/icon.png b/github_event_webhook/static/description/icon.png deleted file mode 100644 index 92a86b1..0000000 Binary files a/github_event_webhook/static/description/icon.png and /dev/null differ diff --git a/github_event_webhook/static/description/webhook_secret_parameter.png b/github_event_webhook/static/description/webhook_secret_parameter.png deleted file mode 100644 index 57ae1bb..0000000 Binary files a/github_event_webhook/static/description/webhook_secret_parameter.png and /dev/null differ diff --git a/github_event_webhook/tests/__init__.py b/github_event_webhook/tests/__init__.py deleted file mode 100644 index 7fa1774..0000000 --- a/github_event_webhook/tests/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). diff --git a/github_event_webhook/tests/test_github_controller.py b/github_event_webhook/tests/test_github_controller.py deleted file mode 100644 index c5ea0c7..0000000 --- a/github_event_webhook/tests/test_github_controller.py +++ /dev/null @@ -1,85 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from collections import OrderedDict -from odoo.addons.test_http_request.common import mock_odoo_request -from odoo.tests import common -from uuid import uuid4 -from werkzeug.urls import url_encode -import json -from ..controllers.github import ( - GithubEvent, - GITHUB_EVENT_SECRET_PARAM, - GITHUB_SIGNATURE_HEADER, - make_github_signature, -) - - -class TestPullRequest(common.SavepointCase): - - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.env['github.event'].search([]).unlink() - cls.token = str(uuid4()) - cls.env['ir.config_parameter'].set_param( - GITHUB_EVENT_SECRET_PARAM, cls.token) - - def setUp(self): - super().setUp() - self.controller = GithubEvent() - self.payload = OrderedDict([ - ('number', 1), - ('action', 'created'), - ]) - self.data = {'payload': json.dumps(self.payload)} - encoded_data = url_encode(self.data) - signature = make_github_signature(encoded_data, self.token) - self.headers = {GITHUB_SIGNATURE_HEADER: signature} - - def _get_created_event(self): - return self.env['github.event'].search([]) - - def test_after_called__event_created(self): - with mock_odoo_request(self.env, headers=self.headers, data=self.data): - response = self.controller.new_github_event(**self.data) - - assert response.status_code == 201 - assert len(self._get_created_event()) == 1 - - def test_event_created_with_payload(self): - with mock_odoo_request(self.env, headers=self.headers, data=self.data): - self.controller.new_github_event(**self.data) - - event = self._get_created_event() - assert event.payload - assert json.loads(event.payload) == self.payload - - def test_if_token_not_passed__return_error_401(self): - del self.headers[GITHUB_SIGNATURE_HEADER] - - with mock_odoo_request(self.env, headers=self.headers, data=self.data): - response = self.controller.new_github_event(**self.data) - - assert response.status_code == 401 - assert not self._get_created_event() - - def test_if_wrong_token_passed__return_error_401(self): - self.headers[GITHUB_SIGNATURE_HEADER] = 'sha1={}'.format(str(uuid4())) - - with mock_odoo_request(self.env, headers=self.headers, data=self.data): - response = self.controller.new_github_event(**self.data) - - assert response.status_code == 401 - assert not self._get_created_event() - - def test_after_called__queue_job_created(self): - with mock_odoo_request(self.env, headers=self.headers, data=self.data): - self.controller.new_github_event(**self.data) - - event = self._get_created_event() - job = self.env['queue.job'].search([ - ('model_name', '=', 'github.event'), - ('method_name', '=', 'process_job'), - ]).filtered(lambda j: j.record_ids == [event.id]) - assert len(job) == 1 diff --git a/github_pull_request/__init__.py b/github_pull_request/__init__.py index 22b7d41..ac4a686 100644 --- a/github_pull_request/__init__.py +++ b/github_pull_request/__init__.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). from . import models diff --git a/github_pull_request/__manifest__.py b/github_pull_request/__manifest__.py index f638c3a..1e5ff99 100644 --- a/github_pull_request/__manifest__.py +++ b/github_pull_request/__manifest__.py @@ -1,23 +1,23 @@ -# © 2023 - Today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - Today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). { - 'name': 'Github Pull Request', - 'version': "14.0.1.0.0", - 'author': 'Numigi', - 'maintainer': 'Numigi', - 'website': 'https://bit.ly/numigi-com', - 'license': 'LGPL-3', - 'category': 'Connector', - 'summary': 'Define what is a github Pull Request as an odoo object.', - 'depends': [ - 'github_event', + "name": "Github Pull Request", + "version": "16.0.1.0.0", + "author": "Numigi", + "maintainer": "Numigi", + "website": "https://bit.ly/numigi-com", + "license": "LGPL-3", + "category": "Connector", + "summary": "Define what is a github Pull Request as an odoo object.", + "depends": [ + "github_event", ], - 'data': [ - 'security/ir.model.access.csv', - 'views/github_event.xml', - 'views/github_pull_request.xml', - 'views/menu.xml', + "data": [ + "security/ir.model.access.csv", + "views/github_event.xml", + "views/github_pull_request.xml", + "views/menu.xml", ], - 'installable': True, + "installable": True, } diff --git a/github_pull_request/i18n/fr.po b/github_pull_request/i18n/fr.po index 3d5bae9..d6c4e49 100644 --- a/github_pull_request/i18n/fr.po +++ b/github_pull_request/i18n/fr.po @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-12-04 19:31+0000\n" "PO-Revision-Date: 2019-12-04 14:33-0500\n" diff --git a/github_pull_request/models/__init__.py b/github_pull_request/models/__init__.py index 4983ac6..de7eb95 100644 --- a/github_pull_request/models/__init__.py +++ b/github_pull_request/models/__init__.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). from . import ( diff --git a/github_pull_request/models/common.py b/github_pull_request/models/common.py index 4f8a656..485bfb7 100644 --- a/github_pull_request/models/common.py +++ b/github_pull_request/models/common.py @@ -1,13 +1,13 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -OPEN = 'open' -MERGED = 'merged' -CLOSED = 'closed' +OPEN = "open" +MERGED = "merged" +CLOSED = "closed" PULL_REQUEST_STATES = [ - (OPEN, 'Open'), - (MERGED, 'Merged'), - (CLOSED, 'Closed'), + (OPEN, "Open"), + (MERGED, "Merged"), + (CLOSED, "Closed"), ] diff --git a/github_pull_request/models/github_event.py b/github_pull_request/models/github_event.py index 5176e36..37d64f2 100644 --- a/github_pull_request/models/github_event.py +++ b/github_pull_request/models/github_event.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). import dateutil.parser @@ -9,12 +9,12 @@ class GithubEvent(models.Model): - _inherit = 'github.event' + _inherit = "github.event" pull_request_id = fields.Many2one( - 'github.pull_request', - 'Pull Request', - ondelete='restrict', + "github.pull_request", + "Pull Request", + ondelete="restrict", index=True, copy=False, ) @@ -25,28 +25,30 @@ class GithubEvent(models.Model): ) def _find_existing_pull_request(self, url): - return self.env['github.pull_request'].search([ - ('source', '=', url), - ]) + return self.env["github.pull_request"].search( + [ + ("source", "=", url), + ] + ) def _make_pull_request(self, url): - return self.env['github.pull_request'].create({'source': url}) + return self.env["github.pull_request"].create({"source": url}) def _get_pull_request(self): - url = self._get_value_from_payload('pull_request.html_url') + url = self._get_value_from_payload("pull_request.html_url") existing_pull_request = self._find_existing_pull_request(url) return existing_pull_request or self._make_pull_request(url) def _get_pull_request_state(self): - is_merged = self._get_value_from_payload('pull_request.merged_at') - return MERGED if is_merged else self._get_value_from_payload('pull_request.state') + is_merged = self._get_value_from_payload("pull_request.merged_at") + return ( + MERGED if is_merged else self._get_value_from_payload("pull_request.state") + ) def _get_pull_request_updated_at(self): - datetime_string = self._get_value_from_payload( - 'pull_request.updated_at') + datetime_string = self._get_value_from_payload("pull_request.updated_at") datetime_obj = dateutil.parser.parse(datetime_string) - naive_datetime_string = datetime_obj.strftime( - DEFAULT_SERVER_DATETIME_FORMAT) + naive_datetime_string = datetime_obj.strftime(DEFAULT_SERVER_DATETIME_FORMAT) return naive_datetime_string def _get_pull_request_title(self): @@ -54,17 +56,19 @@ def _get_pull_request_title(self): def _update_from_pull_request_fields(self): """Update the event's data related to pull requests from its payload.""" - self.write({ - 'pull_request_id': self._get_pull_request().id, - 'pull_request_state': self._get_pull_request_state(), - 'pull_request_updated_at': self._get_pull_request_updated_at(), - 'pull_request_title': self._get_pull_request_title(), - }) + self.write( + { + "pull_request_id": self._get_pull_request().id, + "pull_request_state": self._get_pull_request_state(), + "pull_request_updated_at": self._get_pull_request_updated_at(), + "pull_request_title": self._get_pull_request_title(), + } + ) def process(self): super().process() - is_pull_request_event = 'pull_request' in self.payload_serialized + is_pull_request_event = "pull_request" in self.payload_serialized if is_pull_request_event: self._update_from_pull_request_fields() diff --git a/github_pull_request/models/github_pull_request.py b/github_pull_request/models/github_pull_request.py index 3919fbb..56e8d33 100644 --- a/github_pull_request/models/github_pull_request.py +++ b/github_pull_request/models/github_pull_request.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). import re @@ -7,18 +7,18 @@ regex_github_source = re.compile( - r'https:\/\/(?P[\w\.]+)/' - r'(?P\w+)/' - r'(?P[\w\-_]+)/' - r'pull/' - r'(?P\d+)' + r"https:\/\/(?P[\w\.]+)/" + r"(?P\w+)/" + r"(?P[\w\-_]+)/" + r"pull/" + r"(?P\d+)" ) class GithubPullRequest(models.Model): _name = "github.pull_request" _description = "Github Pull Request" - _rec_name = 'title' + _rec_name = "title" title = fields.Char() source = fields.Char(required=True) @@ -27,23 +27,24 @@ class GithubPullRequest(models.Model): default=OPEN, ) developer_id = fields.Many2one( - 'res.partner', 'Developer', ondelete='restrict', index=True) + "res.partner", "Developer", ondelete="restrict", index=True + ) host = fields.Char(readonly=True) organization = fields.Char(readonly=True) repository = fields.Char(readonly=True) pull_request_number = fields.Integer(readony=True) _sql_constraints = [ - ('source', 'UNIQUE (source)', 'A Pull Request already exists for this source'), + ("source", "UNIQUE (source)", "A Pull Request already exists for this source"), ] @api.model def create(self, vals): - updated_vals = update_according_to_source(vals['source'], vals) + updated_vals = update_according_to_source(vals["source"], vals) return super().create(updated_vals) def write(self, vals): - updated_vals = update_according_to_source(vals.get('source', ''), vals) + updated_vals = update_according_to_source(vals.get("source", ""), vals) super().write(updated_vals) @@ -56,11 +57,13 @@ def update_according_to_source(source: str, vals: dict) -> dict: class GithubPullRequestWithEvents(models.Model): - _inherit = 'github.pull_request' + _inherit = "github.pull_request" latest_update = fields.Datetime() event_ids = fields.One2many( - 'github.event', 'pull_request_id', 'Events', + "github.event", + "pull_request_id", + "Events", ) def is_latest_event(self, event): @@ -69,7 +72,10 @@ def is_latest_event(self, event): :ptype event: github.event :rtype: bool """ - return not self.latest_update or event.pull_request_updated_at >= self.latest_update + return ( + not self.latest_update + or event.pull_request_updated_at >= self.latest_update + ) def update_from_event(self, event): """Update the pull request from the given event. diff --git a/github_pull_request/static/description/menu_technical_pull_requests.png b/github_pull_request/static/description/menu_technical_pull_requests.png index 0d727d2..cce8aa0 100644 Binary files a/github_pull_request/static/description/menu_technical_pull_requests.png and b/github_pull_request/static/description/menu_technical_pull_requests.png differ diff --git a/github_pull_request/static/description/pull_request_event_form.png b/github_pull_request/static/description/pull_request_event_form.png index 06700ec..71a0d30 100644 Binary files a/github_pull_request/static/description/pull_request_event_form.png and b/github_pull_request/static/description/pull_request_event_form.png differ diff --git a/github_pull_request/static/description/pull_request_event_list.png b/github_pull_request/static/description/pull_request_event_list.png index 990346f..aca107b 100644 Binary files a/github_pull_request/static/description/pull_request_event_list.png and b/github_pull_request/static/description/pull_request_event_list.png differ diff --git a/github_pull_request/static/description/pull_request_form.png b/github_pull_request/static/description/pull_request_form.png index d2f8190..8335871 100644 Binary files a/github_pull_request/static/description/pull_request_form.png and b/github_pull_request/static/description/pull_request_form.png differ diff --git a/github_pull_request/static/description/pull_request_tree.png b/github_pull_request/static/description/pull_request_tree.png index 54d2f3e..7a45765 100644 Binary files a/github_pull_request/static/description/pull_request_tree.png and b/github_pull_request/static/description/pull_request_tree.png differ diff --git a/github_pull_request/tests/__init__.py b/github_pull_request/tests/__init__.py index 7fa1774..6a24851 100644 --- a/github_pull_request/tests/__init__.py +++ b/github_pull_request/tests/__init__.py @@ -1,2 +1,2 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). diff --git a/github_pull_request/tests/test_github_event.py b/github_pull_request/tests/test_github_event.py index 6c020df..c0f2aa5 100644 --- a/github_pull_request/tests/test_github_event.py +++ b/github_pull_request/tests/test_github_event.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). from odoo.addons.github_event.tests.common import GithubEventCase @@ -7,29 +7,26 @@ @ddt class TestGithubEvent(GithubEventCase): - def test_if_not_pull_request_event__no_pull_request_created(self): - self.event_1.payload = self._read_payload('check_run_completed.json') + self.event_1.payload = self._read_payload("check_run_completed.json") self.event_1.process() assert not self.event_1.pull_request_id def test_if_not_existing_pull_request__new_pull_request_created(self): - self.event_1.payload = self._read_payload( - 'pull_request_2_reopened.json') + self.event_1.payload = self._read_payload("pull_request_2_reopened.json") self.event_1.process() assert self.event_1.pull_request_id def test_if_existing_pull_request__event_attached_to_same_pull_request(self): - self.event_1.payload = self._read_payload('pull_request_2_closed.json') - self.event_2.payload = self._read_payload( - 'pull_request_2_reopened.json') + self.event_1.payload = self._read_payload("pull_request_2_closed.json") + self.event_2.payload = self._read_payload("pull_request_2_reopened.json") self.event_1.process() self.event_2.process() assert self.event_1.pull_request_id assert self.event_1.pull_request_id == self.event_2.pull_request_id def test_event_can_be_processed_twice(self): - self.event_1.payload = self._read_payload('pull_request_2_closed.json') + self.event_1.payload = self._read_payload("pull_request_2_closed.json") self.event_1.process() initial_pull_request = self.event_1.pull_request_id @@ -38,9 +35,9 @@ def test_event_can_be_processed_twice(self): assert self.event_1.pull_request_id == initial_pull_request @data( - ('pull_request_1_merged.json', 'merged'), - ('pull_request_2_closed.json', 'closed'), - ('pull_request_2_reopened.json', 'open'), + ("pull_request_1_merged.json", "merged"), + ("pull_request_2_closed.json", "closed"), + ("pull_request_2_reopened.json", "open"), ) @unpack def test_status(self, filename, expected_state): @@ -49,11 +46,13 @@ def test_status(self, filename, expected_state): assert self.event_1.pull_request_id.state == expected_state @data( - ('pull_request_2_closed.json', 'pull_request_2_reopened.json'), - ('pull_request_2_reopened.json', 'pull_request_2_closed.json'), + ("pull_request_2_closed.json", "pull_request_2_reopened.json"), + ("pull_request_2_reopened.json", "pull_request_2_closed.json"), ) @unpack - def test_if_not_last_event__pull_request_not_updated(self, first_event, second_event): + def test_if_not_last_event__pull_request_not_updated( + self, first_event, second_event + ): """Test that the pull request is only updated by the latest event. The event pull_request_closed is updated at: 2023-11-22T17:12:05Z @@ -69,11 +68,11 @@ def test_if_not_last_event__pull_request_not_updated(self, first_event, second_e self.event_1.process() self.event_2.process() assert self.event_1.pull_request_id == self.event_2.pull_request_id - assert self.event_1.pull_request_id.state == 'open' + assert self.event_1.pull_request_id.state == "open" @data( - ('pull_request_1_merged.json', 'Add module account_show_full_features'), - ('pull_request_2_closed.json', 'Add better logging'), + ("pull_request_1_merged.json", "Add module account_show_full_features"), + ("pull_request_2_closed.json", "Add better logging"), ) @unpack def test_title(self, filename, expected_title): diff --git a/github_pull_request/tests/test_github_pull_request.py b/github_pull_request/tests/test_github_pull_request.py index 9a72531..7ae6a2c 100644 --- a/github_pull_request/tests/test_github_pull_request.py +++ b/github_pull_request/tests/test_github_pull_request.py @@ -1,4 +1,4 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) +# Copyright 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). @@ -6,24 +6,51 @@ from ddt import ddt, data, unpack test_data = ( - ("https://github.com/Numigi/odoo_git_addons/pull/108693", "organization", "Numigi",), - ("https://github.com/OCA/odoo_git_addons/pull/108693", "organization", "OCA",), - ("https://www.github.com/Numigi/odoo_git_addons/pull/108693", - "host", "www.github.com", ), - ("https://github.com/Numigi/odoo_git_addons/pull/108693", "host", "github.com",), - ("https://github.com/Numigi/odoo-git-addons/pull/108693", - "repository", "odoo-git-addons",), - ("https://github.com/Numigi/odoo_git_addons/pull/108693", - "repository", "odoo_git_addons",), - ("https://github.com/Numigi/odoo_git_addons/pull/1", "pull_request_number", 1,), - ("https://github.com/Numigi/odoo_git_addons/pull/108693", - "pull_request_number", 108693,), + ( + "https://github.com/Numigi/odoo_git_addons/pull/108693", + "organization", + "Numigi", + ), + ( + "https://github.com/OCA/odoo_git_addons/pull/108693", + "organization", + "OCA", + ), + ( + "https://www.github.com/Numigi/odoo_git_addons/pull/108693", + "host", + "www.github.com", + ), + ( + "https://github.com/Numigi/odoo_git_addons/pull/108693", + "host", + "github.com", + ), + ( + "https://github.com/Numigi/odoo-git-addons/pull/108693", + "repository", + "odoo-git-addons", + ), + ( + "https://github.com/Numigi/odoo_git_addons/pull/108693", + "repository", + "odoo_git_addons", + ), + ( + "https://github.com/Numigi/odoo_git_addons/pull/1", + "pull_request_number", + 1, + ), + ( + "https://github.com/Numigi/odoo_git_addons/pull/108693", + "pull_request_number", + 108693, + ), ) @ddt class TestPullRequest(common.SavepointCase): - @classmethod def setUpClass(cls): super().setUpClass() @@ -33,14 +60,14 @@ def setUpClass(cls): @data(*test_data) @unpack def test_whenPrIsCreatedFromURL_thenFieldsAreFilled(self, url, field, expected): - pr = self.github_pull_request_pool.create({'source': url}) + pr = self.github_pull_request_pool.create({"source": url}) assert pr[field] == expected @data(*test_data) @unpack def test_whenPrIsUpdatedFromURL_thenFieldsAreUpdated(self, url, field, expected): pr = self.github_pull_request_pool.create( - {'source': "https://github.com/Numigi/odoo-public/pull/666"} + {"source": "https://github.com/Numigi/odoo-public/pull/666"} # fake url, does not matter ) pr.source = url diff --git a/github_pull_request/views/github_event.xml b/github_pull_request/views/github_event.xml index 48ece7c..f286f1f 100644 --- a/github_pull_request/views/github_event.xml +++ b/github_pull_request/views/github_event.xml @@ -4,14 +4,14 @@ Github Event Form: add fields related to pull requests github.event - + - - - - + + + + @@ -20,10 +20,10 @@ Github Event Form: add fields related to pull requests github.event - + - + diff --git a/github_pull_request/views/github_pull_request.xml b/github_pull_request/views/github_pull_request.xml index 3d7d994..6675786 100644 --- a/github_pull_request/views/github_pull_request.xml +++ b/github_pull_request/views/github_pull_request.xml @@ -6,9 +6,9 @@ Default tree view for github.pull_request - - - + + + @@ -20,28 +20,28 @@

- +

- - - - - + + + + + - - - + + + - - + + @@ -56,17 +56,17 @@ Default search view for github.pull_request - - - - + + + + - - - + + + - - + + diff --git a/github_pull_request/views/menu.xml b/github_pull_request/views/menu.xml index b683fd1..84cf13e 100644 --- a/github_pull_request/views/menu.xml +++ b/github_pull_request/views/menu.xml @@ -4,6 +4,6 @@ + action="pull_requests_action_window" /> diff --git a/github_pull_request_project/README.rst b/github_pull_request_project/README.rst deleted file mode 100644 index d734a9a..0000000 --- a/github_pull_request_project/README.rst +++ /dev/null @@ -1,19 +0,0 @@ -Github Pull Request Project -=========================== - -This modules adds a relation between tasks and github pull request. - - -Tasks in Pull Request Form view -------------------------------- - - .. image:: static/description/pull_request_form_tasks.png - -Pull Requests in Tasks Form View --------------------------------- - - .. image:: static/description/.project_task_pull_request.png - -Contributors ------------- -* Numigi (tm) and all its contributors (https://bit.ly/numigiens) diff --git a/github_pull_request_project/__init__.py b/github_pull_request_project/__init__.py deleted file mode 100644 index 22b7d41..0000000 --- a/github_pull_request_project/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import models diff --git a/github_pull_request_project/__manifest__.py b/github_pull_request_project/__manifest__.py deleted file mode 100644 index 1c37d8f..0000000 --- a/github_pull_request_project/__manifest__.py +++ /dev/null @@ -1,23 +0,0 @@ -# © 2023 - Today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -{ - 'name': 'Github Pull Request Project', - 'version': "14.0.1.0.0", - 'author': 'Numigi', - 'maintainer': 'Numigi', - 'website': 'https://bit.ly/numigi-com', - 'license': 'LGPL-3', - 'category': 'Project', - 'summary': 'Create a relation between tasks and github.pull_request models.', - 'depends': ['project', 'github_pull_request'], - 'data': [ - 'data/project_tags.xml', - 'views/ir_actions_act_window.xml', - 'views/ir_ui_menu.xml', - 'views/github_pull_request.xml', - 'views/project_task.xml', - ], - 'auto_install': True, - 'installable': True, -} diff --git a/github_pull_request_project/data/project_tags.xml b/github_pull_request_project/data/project_tags.xml deleted file mode 100644 index 4ef2c2c..0000000 --- a/github_pull_request_project/data/project_tags.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - PR: Open - - - - - PR: Merged - - - - - PR: Closed - - - - diff --git a/github_pull_request_project/i18n/fr.po b/github_pull_request_project/i18n/fr.po deleted file mode 100644 index a29dc80..0000000 --- a/github_pull_request_project/i18n/fr.po +++ /dev/null @@ -1,50 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * github_pull_request_project -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-11-14 19:48+0000\n" -"PO-Revision-Date: 2019-11-14 19:48+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: github_pull_request_project -#: model:ir.model,name:github_pull_request_project.model_github_pull_request -msgid "Github Pull Request" -msgstr "" - -#. module: github_pull_request_project -#: model:ir.model.fields,field_description:github_pull_request_project.field_project_task__no_pull_request_open -msgid "No Pull Request Open" -msgstr "Aucune pull request d'ouverte" - -#. module: github_pull_request_project -#: model:ir.model.fields,field_description:github_pull_request_project.field_project_task__pull_request_qty -msgid "Pull Request Qty" -msgstr "Quantité de pull request" - -#. module: github_pull_request_project -#: model:ir.actions.act_window,name:github_pull_request_project.pull_requests_action_window_context -#: model:ir.model.fields,field_description:github_pull_request_project.field_project_task__pull_request_ids -#: model:ir.ui.menu,name:github_pull_request_project.project_pull_request_menu -#: model_terms:ir.ui.view,arch_db:github_pull_request_project.project_task_form_pull_requests -msgid "Pull Requests" -msgstr "" - -#. module: github_pull_request_project -#: model:ir.model,name:github_pull_request_project.model_project_task -msgid "Task" -msgstr "Tâche" - -#. module: github_pull_request_project -#: model:ir.model.fields,field_description:github_pull_request_project.field_github_pull_request__task_ids -msgid "Tasks" -msgstr "Tâches" - diff --git a/github_pull_request_project/models/__init__.py b/github_pull_request_project/models/__init__.py deleted file mode 100644 index ed476b7..0000000 --- a/github_pull_request_project/models/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import ( - github_pull_request -) diff --git a/github_pull_request_project/models/github_pull_request.py b/github_pull_request_project/models/github_pull_request.py deleted file mode 100644 index b177bb5..0000000 --- a/github_pull_request_project/models/github_pull_request.py +++ /dev/null @@ -1,112 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from odoo import fields, models, api - - -class GithubPullRequestTask(models.Model): - - _inherit = "github.pull_request" - - task_ids = fields.Many2many( - 'project.task', - 'pull_request_task_ref', - 'pull_request_id', - 'task_id', - string='Tasks' - ) - - @api.model - def create(self, vals): - pr = super().create(vals) - pr.task_ids._update_pull_request_tags() - return pr - - def write(self, vals): - must_update_tags_on_tasks = 'task_ids' in vals or 'state' in vals - - if must_update_tags_on_tasks: - tasks_to_update = self.mapped('task_ids') - - super().write(vals) - - if must_update_tags_on_tasks: - tasks_to_update |= self.mapped('task_ids') - tasks_to_update._update_pull_request_tags() - - return True - - -def has_pull_request_at_state(task: 'project.task', state: str) -> bool: - """Return True if the task has at least one PR at the given state.""" - return task.pull_request_ids.filtered(lambda pr: pr.state == state) - - -class ProjectTaskPullRequest(models.Model): - - _inherit = "project.task" - - pull_request_ids = fields.Many2many( - 'github.pull_request', - 'pull_request_task_ref', - 'task_id', - 'pull_request_id', - string='Pull Requests', - copy=False, - ) - - def _compute_pull_request_qty(self): - for record in self: - record.pull_request_qty = len(record.pull_request_ids) - - pull_request_qty = fields.Integer(compute="_compute_pull_request_qty") - - def _check_all_pull_request_state(self): - for record in self: - record.no_pull_request_open = is_no_pull_request_open(record) - - @api.model - def create(self, vals): - task = super().create(vals) - task._update_pull_request_tags() - return task - - def write(self, vals): - super().write(vals) - - if 'pull_request_ids' in vals: - self._update_pull_request_tags() - - return True - - def _update_pull_request_tags(self): - tag_open = self.env.ref( - 'github_pull_request_project.tag_pull_request_open') - tag_merged = self.env.ref( - 'github_pull_request_project.tag_pull_request_merged') - tag_closed = self.env.ref( - 'github_pull_request_project.tag_pull_request_closed') - - for task in self: - show_open_tag = ( - has_pull_request_at_state(task, 'open') - ) - show_merged_tag = ( - has_pull_request_at_state(task, 'merged') and - not show_open_tag - ) - show_closed_tag = ( - has_pull_request_at_state(task, 'closed') and - not show_open_tag and - not show_merged_tag - ) - - task.update({'tag_ids': [ - (4 if show_open_tag else 3, tag_open.id), - (4 if show_merged_tag else 3, tag_merged.id), - (4 if show_closed_tag else 3, tag_closed.id), - ]}) - - @api.onchange('pull_request_ids') - def _onchange_pull_requests_update_tags(self): - self._update_pull_request_tags() diff --git a/github_pull_request_project/static/description/icon.png b/github_pull_request_project/static/description/icon.png deleted file mode 100644 index 92a86b1..0000000 Binary files a/github_pull_request_project/static/description/icon.png and /dev/null differ diff --git a/github_pull_request_project/static/description/project_task_pull_requests.png b/github_pull_request_project/static/description/project_task_pull_requests.png deleted file mode 100644 index 04b2b2a..0000000 Binary files a/github_pull_request_project/static/description/project_task_pull_requests.png and /dev/null differ diff --git a/github_pull_request_project/static/description/pull_request_form_tasks.png b/github_pull_request_project/static/description/pull_request_form_tasks.png deleted file mode 100644 index 19c1477..0000000 Binary files a/github_pull_request_project/static/description/pull_request_form_tasks.png and /dev/null differ diff --git a/github_pull_request_project/tests/__init__.py b/github_pull_request_project/tests/__init__.py deleted file mode 100644 index 2c7675f..0000000 --- a/github_pull_request_project/tests/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import test_project_task diff --git a/github_pull_request_project/tests/test_project_task.py b/github_pull_request_project/tests/test_project_task.py deleted file mode 100644 index 175eaf4..0000000 --- a/github_pull_request_project/tests/test_project_task.py +++ /dev/null @@ -1,135 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - - -from odoo.tests import common - - -class TestProjectTask(common.SavepointCase): - - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.pull_request_open = cls.env["github.pull_request"].create({ - "source": "https://github.com/Numigi/odoo-git-addons/pull/1", - "state": "open" - }) - cls.pull_request_closed = cls.env["github.pull_request"].create({ - "source": "https://github.com/Numigi/odoo-git-addons/pull/2", - "state": "closed" - }) - cls.pull_request_merged = cls.env["github.pull_request"].create({ - "source": "https://github.com/Numigi/odoo-git-addons/pull/3", - "state": "merged" - }) - - cls.tag_open = cls.env.ref( - 'github_pull_request_project.tag_pull_request_open') - cls.tag_merged = cls.env.ref( - 'github_pull_request_project.tag_pull_request_merged') - cls.tag_closed = cls.env.ref( - 'github_pull_request_project.tag_pull_request_closed') - - # Simple cases - def test_whenNoPR_thenNoTag(self): - task = self.env["project.task"].create({ - "name": "ttask", "pull_request_ids": [(5, False, False)] - }) - assert not task.tag_ids - - def test_whenPrAreMerged_thenTaskMerged(self): - task = self.env["project.task"].create({ - "name": "ttask", "pull_request_ids": [(6, False, (self.pull_request_merged.id,))] - }) - assert task.tag_ids == self.tag_merged - - def test_whenPrAreClosed_thenTaskClosed(self): - task = self.env["project.task"].create({ - "name": "ttask", "pull_request_ids": [(6, False, (self.pull_request_closed.id,))] - }) - assert task.tag_ids == self.tag_closed - - def test_whenPrAreOpen_thenTaskOpen(self): - task = self.env["project.task"].create({ - "name": "ttask", "pull_request_ids": [(6, False, (self.pull_request_open.id,))] - }) - assert task.tag_ids == self.tag_open - - # Mixing cases - def test_whenAllStates_thenTaskOpen(self): - task = self.env["project.task"].create({ - "name": "ttask", - "pull_request_ids": [( - 6, False, - ( - self.pull_request_open.id, - self.pull_request_closed.id, - self.pull_request_merged.id - ) - )] - }) - assert task.tag_ids == self.tag_open - - def test_whenClosedAndMerged_thenTaskMerged(self): - task = self.env["project.task"].create({ - "name": "ttask", - "pull_request_ids": [( - 6, False, (self.pull_request_closed.id, - self.pull_request_merged.id) - )] - }) - assert task.tag_ids == self.tag_merged - - def test_whenMergedAndOpen_thenTaskOpen(self): - task = self.env["project.task"].create({ - "name": "ttask", - "pull_request_ids": [( - 6, False, (self.pull_request_merged.id, - self.pull_request_open.id) - )] - }) - assert task.tag_ids == self.tag_open - - def test_whenClosedAndOpen_thenTaskOpen(self): - task = self.env["project.task"].create({ - "name": "ttask", - "pull_request_ids": [( - 6, False, (self.pull_request_closed.id, - self.pull_request_open.id) - )] - }) - assert task.tag_ids == self.tag_open - - def test_onTaskWrite_tagsUpdated(self): - task = self.env["project.task"].create({ - "name": "ttask", - }) - task.pull_request_ids = self.pull_request_open - assert task.tag_ids == self.tag_open - - def test_onPullRequestStateChange_tagsUpdated(self): - task = self.env["project.task"].create({ - "name": "ttask", - "pull_request_ids": [(4, self.pull_request_open.id)], - }) - assert task.tag_ids == self.tag_open - self.pull_request_open.state = 'merged' - assert task.tag_ids == self.tag_merged - - def test_onPullRequestTaskIdsChange_tagsUpdated(self): - task = self.env["project.task"].create({ - "name": "ttask", - }) - self.pull_request_open.task_ids = task - assert task.tag_ids == self.tag_open - - def test_onPullRequestCreate_tagsUpdated(self): - task = self.env["project.task"].create({ - "name": "ttask", - }) - self.env["github.pull_request"].create({ - "source": "https://github.com/Numigi/odoo-git-addons/pull/999", - "state": "open", - "task_ids": [(4, task.id)], - }) - assert task.tag_ids == self.tag_open diff --git a/github_pull_request_project/views/github_pull_request.xml b/github_pull_request_project/views/github_pull_request.xml deleted file mode 100644 index b492473..0000000 --- a/github_pull_request_project/views/github_pull_request.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - github.pull_request - Github Pull Request: task ids - form - - - - - - - - - - - github.pull_request - Github Pull Request: task ids - 16 - search - - diff --git a/github_pull_request_project/views/ir_actions_act_window.xml b/github_pull_request_project/views/ir_actions_act_window.xml deleted file mode 100644 index 00a7120..0000000 --- a/github_pull_request_project/views/ir_actions_act_window.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - Pull Requests - github.pull_request - current - ir.actions.act_window - tree,form - { - 'search_default_task_ids': [active_id], - } - - diff --git a/github_pull_request_project/views/ir_ui_menu.xml b/github_pull_request_project/views/ir_ui_menu.xml deleted file mode 100644 index 62ba878..0000000 --- a/github_pull_request_project/views/ir_ui_menu.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - Pull Requests - - 10 - - diff --git a/github_pull_request_project/views/project_task.xml b/github_pull_request_project/views/project_task.xml deleted file mode 100644 index c98cf65..0000000 --- a/github_pull_request_project/views/project_task.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - -
- -
- - - - - -
- - project.task - Project Task: pull request fields - 99 -
- -
diff --git a/gitoo.yml b/gitoo.yml index 53e7ad7..0d2df58 100644 --- a/gitoo.yml +++ b/gitoo.yml @@ -1,9 +1,4 @@ -- url: https://{{GIT_TOKEN}}@github.com/Numigi/odoo-base-addons - branch: "14.0" - includes: - - test_http_request - - url: https://github.com/OCA/queue - branch: "14.0" + branch: "16.0" includes: - queue_job