Repository: OCA/currency (language: python)

Issue:
[12.0][FIX] currency_rate_update: Fix security vulnerability from CWE-61



Discussion / hints:
hi @pedrobaeza I have created the PR to fix issue#177 but I do not know why it fails:

"ERROR: Could not find a version that satisfies the requirement pylint-plugin-utils==0.7 (from -r /home/travis/maintainer-quality-tools/travis/pylint_odoo_requirements.txt (line 1)) (from versions: 0.1, 0.1.1, 0.2, 0.2.1, 0.2.2, 0.2.3, 0.2.4, 0.2.6, 0.3, 0.4, 0.5, 0.6)
ERROR: No matching distribution found for pylint-plugin-utils==0.7 (from -r /home/travis/maintainer-quality-tools/travis/pylint_odoo_requirements.txt (line 1))
The command "travis_install_nightly" failed and exited with 1 during ."
12.0 version is too old and CI is not adapted to "new times". One option is to use copier for updating the template for getting new CI definitions. Other is to make the PR to newer versions.
> 12.0 version is too old and CI is not adapted to "new times". One option is to use copier for updating the template for getting new CI definitions. Other is to make the PR to newer versions.

I tried adding in the .travis.yml but I see that I not the correct way to do it as it still fails :( I tried to look for copier and installed it too but did not know how to make it work.

Fix patch:
diff --git a/.copier-answers.yml b/.copier-answers.yml
new file mode 100644
index 00000000..7a84c462
--- /dev/null
+++ b/.copier-answers.yml
@@ -0,0 +1,26 @@
+# Do NOT update manually; changes here will be overwritten by Copier
+_commit: v1.15.1
+_src_path: https://github.com/OCA/oca-addons-repo-template.git
+ci: GitHub
+dependency_installation_mode: PIP
+generate_requirements_txt: true
+github_check_license: false
+github_ci_extra_env: {}
+github_enable_codecov: true
+github_enable_makepot: true
+github_enable_stale_action: false
+github_enforce_dev_status_compatibility: false
+include_wkhtmltopdf: false
+odoo_test_flavor: OCB
+odoo_version: 12.0
+org_name: Odoo Community Association (OCA)
+org_slug: OCA
+rebel_module_groups: []
+repo_description: Currency related Addons (crypto currencies, rate conversion, integrations
+    with third party applications,...)
+repo_name: Currency
+repo_slug: currency
+repo_website: https://github.com/OCA/currency
+travis_apt_packages: []
+travis_apt_sources: []
+
diff --git a/.editorconfig b/.editorconfig
index 62276b0d..bfd7ac53 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -7,11 +7,11 @@ indent_style = space
 insert_final_newline = true
 trim_trailing_whitespace = true
 
-[.eslintrc,*.{json,yml,yaml,rst,md}]
+[*.{json,yml,yaml,rst,md}]
 indent_size = 2
 
 # Do not configure editor for libs and autogenerated content
-[*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst]
+[{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}]
 charset = unset
 end_of_line = unset
 indent_size = unset
diff --git a/.flake8 b/.flake8
new file mode 100644
index 00000000..6363964b
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,11 @@
+[flake8]
+# E123,E133,E226,E241,E242 are ignored by default by pep8 and flake8
+# F811 is legal in odoo 8 when we implement 2 interfaces for a method
+# F601 pylint support this case with expected tests
+# W503 changed by W504 and OCA prefers allow both
+# E203: whitespace before ':' (black behaviour and not pep8 compliant)
+ignore = E123,E133,E226,E241,E242,F811,F601,W503,W504,E203
+max-line-length = 88
+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 00000000..6d54b60f
--- /dev/null
+++ b/.github/workflows/pre-commit.yml
@@ -0,0 +1,37 @@
+name: pre-commit
+
+on:
+  pull_request:
+    branches:
+      - "12.0*"
+  push:
+    branches:
+      - "12.0"
+      - "12.0-ocabot-*"
+
+jobs:
+  pre-commit:
+    runs-on: ubuntu-20.04
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v2
+        with:
+          python-version: "3.6"
+      - 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 bad6d533..9c283fd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,8 @@
 # Byte-compiled / optimized / DLL files
 __pycache__/
 *.py[cod]
-*$py.class
+/.venv
+/.pytest_cache
 
 # C extensions
 *.so
@@ -9,13 +10,11 @@ __pycache__/
 # Distribution / packaging
 .Python
 env/
+bin/
 build/
 develop-eggs/
 dist/
-downloads/
 eggs/
-.eggs/
-lib/
 lib64/
 parts/
 sdist/
@@ -23,12 +22,7 @@ var/
 *.egg-info/
 .installed.cfg
 *.egg
-
-# PyInstaller
-#  Usually these files are written by a python script from a template
-#  before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
+*.eggs
 
 # Installer logs
 pip-log.txt
@@ -38,16 +32,12 @@ pip-delete-this-directory.txt
 htmlcov/
 .tox/
 .coverage
-.coverage.*
 .cache
 nosetests.xml
 coverage.xml
-*,cover
-.hypothesis/
 
 # Translations
 *.mo
-*.pot
 
 # Pycharm
 .idea
@@ -57,42 +47,28 @@ coverage.xml
 
 # Visual Studio cache/options directory
 .vs/
+.vscode
+
+# OSX Files
+.DS_Store
 
 # Django stuff:
 *.log
-local_settings.py
 
-# Flask stuff:
-instance/
-.webassets-cache
+# Mr Developer
+.mr.developer.cfg
+.project
+.pydevproject
 
-# Scrapy stuff:
-.scrapy
+# Rope
+.ropeproject
 
 # Sphinx documentation
 docs/_build/
 
-# PyBuilder
-target/
-
-# IPython Notebook
-.ipynb_checkpoints
-
-# pyenv
-.python-version
+# Backup files
+*~
+*.swp
 
-# celery beat schedule file
-celerybeat-schedule
-
-# dotenv
-.env
-
-# virtualenv
-venv/
-ENV/
-
-# Spyder project settings
-.spyderproject
-
-# Rope project settings
-.ropeproject
+# OCA rules
+!static/lib/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..a77de1ea
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,59 @@
+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$|
+  # You don't usually want a bot to modify your legal texts
+  (LICENSE.*|COPYING.*)
+default_language_version:
+  python: python3.6
+repos:
+  - repo: https://github.com/oca/maintainer-tools
+    rev: ab1d7f6
+    hooks:
+      # update the NOT INSTALLABLE ADDONS section above
+      - id: oca-update-pre-commit-excluded-addons
+      - id: oca-fix-manifest-website
+        args: ["https://github.com/OCA/currency"]
+  - repo: https://github.com/acsone/setuptools-odoo
+    rev: 3.1.8
+    hooks:
+      - id: setuptools-odoo-make-default
+      - id: setuptools-odoo-get-requirements
+        args:
+          - --output
+          - requirements.txt
+          - --header
+          - "# generated from manifests external_dependencies"
+  - repo: https://github.com/OCA/mirrors-flake8
+    rev: v3.4.1
+    hooks:
+      - id: flake8
+        name: flake8 excluding __init__.py
+        exclude: __init__\.py
+  - repo: https://github.com/pre-commit/mirrors-pylint
+    rev: v2.5.3
+    hooks:
+      - id: pylint
+        name: pylint with optional checks
+        args:
+          - --rcfile=.pylintrc
+          - --exit-zero
+        verbose: true
+        additional_dependencies: &pylint_deps
+          - pylint-odoo==3.5.0
+      - id: pylint
+        name: pylint with mandatory checks
+        args:
+          - --rcfile=.pylintrc-mandatory
+        additional_dependencies: *pylint_deps
+
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 00000000..d8abd712
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,156 @@
+[MASTER]
+load-plugins=pylint_odoo
+score=n
+
+[ODOOLINT]
+readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
+manifest_required_authors=Odoo Community Association (OCA)
+manifest_required_keys=license
+manifest_deprecated_keys=description,active
+license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
+valid_odoo_versions=12.0
+
+[MESSAGES CONTROL]
+disable=all
+
+# Enable message and code:
+#   anomalous-backslash-in-string - W1401
+#   assignment-from-none - W1111
+#   dangerous-default-value - W0102
+#   duplicate-key - W0109
+#   missing-import-error - W7935
+#   missing-manifest-dependency - W7936
+#   pointless-statement - W0104
+#   pointless-string-statement - W0105
+#   print-statement - E1601
+#   redundant-keyword-arg - E1124
+#   reimported - W0404
+#   relative-import - W0403
+#   return-in-init - E0101
+#   rst-syntax-error - E7901
+#   too-few-format-args - E1306
+#   unreachable - W0101
+
+
+# This .pylintrc contains optional AND mandatory checks and is meant to be
+# loaded in an IDE to have it check everything, in the hope this will make
+# optional checks more visible to contributors who otherwise never look at a
+# green travis to see optional checks that failed.
+# .pylintrc-mandatory containing only mandatory checks is used the pre-commit
+# config as a blocking check.
+
+# Beta message and code:
+#   api-one-deprecated - W8104
+#   api-one-multi-together - W8101
+#   attribute-deprecated - W8105
+#   class-camelcase - C8104
+#   create-user-wo-reset-password - W7905
+#   consider-merging-classes-inherited - R7980
+#   copy-wo-api-one - W8102
+#   dangerous-filter-wo-user - W7901
+#   dangerous-view-replace-wo-priority - W7940
+#   deprecated-module - W0402
+#   duplicate-id-csv - W7906
+#   duplicate-xml-fields - W7907
+#   duplicate-xml-record-id - W7902
+#   file-not-used - W7930
+#   incoherent-interpreter-exec-perm - W8201
+#   invalid-commit - E8102
+#   javascript-lint - W7903
+#   manifest-deprecated-key - C8103
+#   method-compute - C8108
+#   method-inverse - C8110
+#   method-required-super - W8106
+#   method-search - C8109
+#   missing-newline-extrafiles - W7908
+#   missing-readme - C7902
+#   no-utf8-coding-comment - C8201
+#   unnecessary-utf8-coding-comment - C8202
+#   odoo-addons-relative-import - W7950
+#   old-api7-method-defined - R8110
+#   openerp-exception-warning - R8101
+#   redundant-modulename-xml - W7909
+#   sql-injection - E8103
+#   too-complex - C0901
+#   translation-field - W8103
+#   translation-required - C8107
+#   use-vim-comment - W8202
+#   wrong-tabs-instead-of-spaces - W7910
+#   xml-syntax-error - E7902
+
+
+enable=anomalous-backslash-in-string,
+    assignment-from-none,
+    dangerous-default-value,
+    development-status-allowed,
+    duplicate-key,
+    duplicate-po-message-definition,
+    missing-import-error,
+    missing-manifest-dependency,
+    po-msgstr-variables,
+    po-syntax-error,
+    pointless-statement,
+    pointless-string-statement,
+    print-used,
+    redundant-keyword-arg,
+    reimported,
+    relative-import,
+    return-in-init,
+    rst-syntax-error,
+    too-few-format-args,
+    unreachable,
+    eval-used,
+    eval-referenced,
+    license-allowed,
+    manifest-author-string,
+    manifest-required-author,
+    manifest-required-key,
+    manifest-version-format,
+    api-one-deprecated,
+    api-one-multi-together,
+    attribute-deprecated,
+    class-camelcase,
+    create-user-wo-reset-password,
+    consider-merging-classes-inherited,
+    copy-wo-api-one,
+    dangerous-filter-wo-user,
+    dangerous-view-replace-wo-priority,
+    deprecated-module,
+    duplicate-id-csv,
+    duplicate-po-message-definition,
+    duplicate-xml-fields,
+    duplicate-xml-record-id,
+    file-not-used,
+    incoherent-interpreter-exec-perm,
+    invalid-commit,
+    javascript-lint,
+    manifest-deprecated-key,
+    method-compute,
+    method-inverse,
+    method-required-super,
+    method-search,
+    missing-newline-extrafiles,
+    missing-readme,
+    po-msgstr-variables,
+    po-syntax-error,
+    no-utf8-coding-comment,
+    unnecessary-utf8-coding-comment,
+    odoo-addons-relative-import,
+    old-api7-method-defined,
+    openerp-exception-warning,
+    redefined-builtin,
+    redundant-modulename-xml,
+    sql-injection,
+    too-complex,
+    translation-field,
+    translation-required,
+    use-vim-comment,
+    wrong-tabs-instead-of-spaces,
+    xml-syntax-error,
+
+
+[REPORTS]
+msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
+output-format=colorized
+reports=no
+
diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory
new file mode 100644
index 00000000..9b44956f
--- /dev/null
+++ b/.pylintrc-mandatory
@@ -0,0 +1,68 @@
+[MASTER]
+load-plugins=pylint_odoo
+score=n
+
+[ODOOLINT]
+readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
+manifest_required_authors=Odoo Community Association (OCA)
+manifest_required_keys=license
+manifest_deprecated_keys=description,active
+license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
+valid_odoo_versions=12.0
+
+[MESSAGES CONTROL]
+disable=all
+
+# Enable message and code:
+#   anomalous-backslash-in-string - W1401
+#   assignment-from-none - W1111
+#   dangerous-default-value - W0102
+#   duplicate-key - W0109
+#   missing-import-error - W7935
+#   missing-manifest-dependency - W7936
+#   pointless-statement - W0104
+#   pointless-string-statement - W0105
+#   print-statement - E1601
+#   redundant-keyword-arg - E1124
+#   reimported - W0404
+#   relative-import - W0403
+#   return-in-init - E0101
+#   rst-syntax-error - E7901
+#   too-few-format-args - E1306
+#   unreachable - W0101
+
+
+
+enable=anomalous-backslash-in-string,
+    assignment-from-none,
+    dangerous-default-value,
+    development-status-allowed,
+    duplicate-key,
+    duplicate-po-message-definition,
+    missing-import-error,
+    missing-manifest-dependency,
+    po-msgstr-variables,
+    po-syntax-error,
+    pointless-statement,
+    pointless-string-statement,
+    print-used,
+    redundant-keyword-arg,
+    reimported,
+    relative-import,
+    return-in-init,
+    rst-syntax-error,
+    too-few-format-args,
+    unreachable,
+    eval-used,
+    eval-referenced,
+    license-allowed,
+    manifest-author-string,
+    manifest-required-author,
+    manifest-required-key,
+    manifest-version-format
+
+[REPORTS]
+msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
+output-format=colorized
+reports=no
+
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 9666d81f..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-language: python
-sudo: false
-cache: pip
-
-python:
-  - "3.5"
-
-addons:
-  postgresql: "9.6"
-  apt:
-    packages:
-      - expect-dev  # provides unbuffer utility
-      - python-lxml # because pip installation is slow
-
-env:
-  global:
-  - VERSION="12.0" TESTS="0" LINT_CHECK="0" TRANSIFEX="0"
-  - TRANSIFEX_USER='transbot@odoo-community.org'
-  - secure: "L3kTv/2+8rBA5weP1YeeF45KPgbJmqY06pVSqll5C+EbRDgcx4MECQGfKSzjENLNtcryasbesEVcdbD29CBA4jey5IRcpPJmHzy3Rpv/cAqfvWWsnCZ4ilVff7VzhQgJIzj9zgw03VrF4HB4z7FPvh2NCTGJPTtUDBj+wblDyC8FPC3AeItIh8BE+0740K5ckXhqGC6ltXDDeZfLOIsMDwBYpcaAVNWwWHgwdE97Z7lVqsMKm4p22OYg49XflCrto3oZpVZtcD4jMYnElVMT40iJgBLsaN7pUnplwRjVt2K7AvgglqkYqmHhUyEL83+YoE0S4QNFBn0uCJwdrpBjHAbkodESECZK+p9DnEnYXhQxcrEYO7ryHvTHGzPBPL4w+veXz+8r80+h8tPmCqyAtqH+WOGbu99roFJpUx0ddubTmV+/gTrGbTUm3XKlcwjcm0XzmQguoO8I5X+JsjFoRO5WtKHE0JDIEn9rNVcA5wIYEntSKIU+FajaEIWieQI619CJhqhRusIIkdOZTTILMWRpAsuZlKUQq3mrEIDjAEHuwaiCPb8TmN2bKF7XtiAq2gVFCalKmb3nel3NQZjbduJh9OK4UF0UqBoWK//sMAc27lhlEoqB/m1R84zby5gqaN7f3Rj5M8Ee1onw2qlU7u2Rn3GeHtplAhoEbney6Gs="
-
-  matrix:
-  - LINT_CHECK="1"
-  - TRANSIFEX="1"
-  - TESTS="1" ODOO_REPO="OCA/OCB"
-  - TESTS="1" ODOO_REPO="odoo/odoo"
-
-install:
-  - git clone https://github.com/OCA/maintainer-quality-tools.git $HOME/maintainer-quality-tools
-  - export PATH=$HOME/maintainer-quality-tools/travis:$PATH
-  - travis_install_nightly
-
-script:
-  - travis_run_tests
-
-after_success:
-  - travis_after_tests_success
diff --git a/LICENSE b/LICENSE
index 58777e31..be3f7b28 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
-GNU AFFERO GENERAL PUBLIC LICENSE
+                    GNU AFFERO GENERAL PUBLIC LICENSE
                        Version 3, 19 November 2007
 
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
@@ -633,8 +633,8 @@ the "copyright" line and a pointer to where the full notice is found.
     Copyright (C) <year>  <name of author>
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Affero General Public License as published
-    by the Free Software Foundation, either version 3 of the License, or
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -643,7 +643,7 @@ the "copyright" line and a pointer to where the full notice is found.
     GNU Affero General Public License for more details.
 
     You should have received a copy of the GNU Affero General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 Also add information on how to contact you by electronic and paper mail.
 
@@ -658,4 +658,4 @@ specific requirements.
   You should also get your employer (if you work as a programmer) or school,
 if any, to sign a "copyright disclaimer" for the program, if necessary.
 For more information on this, and how to apply and follow the GNU AGPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
diff --git a/README.md b/README.md
index 8f9fdeba..edb41a04 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,37 @@
-![Licence](https://img.shields.io/badge/licence-AGPL--3-blue.svg)
-[![Runbot Status](https://runbot.odoo-community.org/runbot/badge/flat/259/12.0.svg)](https://runbot.odoo-community.org/runbot/repo/github-com-oca-currency-259)
-[![Build Status](https://travis-ci.org/OCA/currency.svg?branch=12.0)](https://travis-ci.org/OCA/currency)
+
+[![Runboat](https://img.shields.io/badge/runboat-Try%20me-875A7B.png)](https://runboat.odoo-community.org/builds?repo=OCA/currency&target_branch=12.0)
+[![Pre-commit Status](https://github.com/OCA/currency/actions/workflows/pre-commit.yml/badge.svg?branch=12.0)](https://github.com/OCA/currency/actions/workflows/pre-commit.yml?query=branch%3A12.0)
+[![Build Status](https://github.com/OCA/currency/actions/workflows/test.yml/badge.svg?branch=12.0)](https://github.com/OCA/currency/actions/workflows/test.yml?query=branch%3A12.0)
 [![codecov](https://codecov.io/gh/OCA/currency/branch/12.0/graph/badge.svg)](https://codecov.io/gh/OCA/currency)
+[![Translation Status](https://translation.odoo-community.org/widgets/currency-12-0/-/svg-badge.svg)](https://translation.odoo-community.org/engage/currency-12-0/?utm_source=widget)
+
+<!-- /!\ do not modify above this line -->
 
+# Currency
 
-Currency
-========
 Currency related Addons (crypto currencies, rate conversion, integrations with third party applications,...)
+
+<!-- /!\ do not modify below this line -->
+
+<!-- prettier-ignore-start -->
+
+[//]: # (addons)
+
+This part will be replaced when running the oca-gen-addons-table script from OCA/maintainer-tools.
+
+[//]: # (end addons)
+
+<!-- prettier-ignore-end -->
+
+## Licenses
+
+This repository is licensed under [AGPL-3.0](LICENSE).
+
+However, each module can have a totally different license, as long as they adhere to Odoo Community Association (OCA)
+policy. Consult each module's `__manifest__.py` file, which contains a `license` key
+that explains its license.
+
+----
+OCA, or the [Odoo Community Association](http://odoo-community.org/), is a nonprofit
+organization whose mission is to support the collaborative development of Odoo features
+and promote its widespread use.
diff --git a/currency_rate_update_oxr/__manifest__.py b/currency_rate_update_oxr/__manifest__.py
index b24bc2e1..a6412d4b 100644
--- a/currency_rate_update_oxr/__manifest__.py
+++ b/currency_rate_update_oxr/__manifest__.py
@@ -6,6 +6,7 @@
     'name': 'Currency Rate Update: OpenExchangeRates.org',
     'version': '12.0.1.0.2',
     'category': 'Financial Management/Configuration',
+    'website': 'https://github.com/OCA/currency',
     'summary': 'Update exchange rates using OpenExchangeRates.org',
     'author':
         'CorporateHub, '
diff --git a/currency_rate_update_transferwise/__manifest__.py b/currency_rate_update_transferwise/__manifest__.py
index 99752cc7..3dc3dc0f 100644
--- a/currency_rate_update_transferwise/__manifest__.py
+++ b/currency_rate_update_transferwise/__manifest__.py
@@ -10,6 +10,7 @@
     'author':
         'CorporateHub, '
         'Odoo Community Association (OCA)',
+    'website': 'https://github.com/OCA/currency',
     'license': 'AGPL-3',
     'installable': True,
     'application': False,
diff --git a/currency_rate_update_xe/__manifest__.py b/currency_rate_update_xe/__manifest__.py
index 6242a2e2..60ab509e 100644
--- a/currency_rate_update_xe/__manifest__.py
+++ b/currency_rate_update_xe/__manifest__.py
@@ -6,6 +6,7 @@
     'name': 'Currency Rate Update: XE.com',
     'version': '12.0.1.0.0',
     'category': 'Financial Management/Configuration',
+    'website': 'https://github.com/OCA/currency',
     'summary': 'Update exchange rates using XE.com',
     'author':
         'CorporateHub, '


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..af0e8244
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,69 @@
+name: tests
+
+on:
+  pull_request:
+    branches:
+      - "12.0*"
+  push:
+    branches:
+      - "12.0"
+      - "12.0-ocabot-*"
+
+jobs:
+  unreleased-deps:
+    runs-on: ubuntu-latest
+    name: Detect unreleased dependencies
+    steps:
+      - uses: actions/checkout@v3
+      - run: |
+          for reqfile in requirements.txt test-requirements.txt ; do
+              if [ -f ${reqfile} ] ; then
+                  result=0
+                  # reject non-comment lines that contain a / (i.e. URLs, relative paths)
+                  grep "^[^#].*/" ${reqfile} || result=$?
+                  if [ $result -eq 0 ] ; then
+                      echo "Unreleased dependencies found in ${reqfile}."
+                      exit 1
+                  fi
+              fi
+          done
+  test:
+    runs-on: ubuntu-20.04
+    container: ${{ matrix.container }}
+    name: ${{ matrix.name }}
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - container: ghcr.io/oca/oca-ci/py3.6-ocb12.0:latest
+            name: test with OCB
+            makepot: "true"
+    services:
+      postgres:
+        image: postgres:9.6
+        env:
+          POSTGRES_USER: odoo
+          POSTGRES_PASSWORD: odoo
+          POSTGRES_DB: odoo
+        ports:
+          - 5432:5432
+    steps:
+      - uses: actions/checkout@v3
+        with:
+          persist-credentials: false
+      - name: Install addons and dependencies
+        run: oca_install_addons
+      - name: Check licenses
+        run: manifestoo -d . check-licenses
+        continue-on-error: true
+      - name: Check development status
+        run: manifestoo -d . check-dev-status --default-dev-status=Beta
+        continue-on-error: true
+      - name: Initialize test db
+        run: oca_init_test_database
+      - name: Run tests
+        run: oca_run_tests
+      - uses: codecov/codecov-action@v1
+      - name: Update .pot files
+        run: oca_export_and_push_pot https://x-access-token:${{ secrets.GIT_PUSH_TOKEN }}@github.com/${{ github.repository }}
+        if: ${{ matrix.makepot == 'true' && github.event_name == 'push' && github.repository_owner == 'OCA' }}