From ebf67ceb22212db163de4f5c7207a0e6db08cd32 Mon Sep 17 00:00:00 2001
From: Javier Vega <javier@vauxoo.com>
Date: Tue, 21 Jan 2020 21:28:42 -0600
Subject: [PATCH 1/2] test 1

---
 bumpversion.cfg                               |   9 +++
 xunnel_changelog/README.rst                   |   0
 xunnel_changelog/__init__.py                  |   2 +
 xunnel_changelog/__manifest__.py              |  26 +++++++
 xunnel_changelog/controllers/__init__.py      |   1 +
 .../__pycache__/__init__.cpython-36.pyc       | Bin 0 -> 206 bytes
 .../gitlab_webhooks.cpython-36.pyc            | Bin 0 -> 1462 bytes
 .../controllers/gitlab_webhooks.py            |  46 +++++++++++
 xunnel_changelog/models/__init__.py           |   1 +
 .../__pycache__/__init__.cpython-36.pyc       | Bin 0 -> 202 bytes
 .../xunnel_changelog.cpython-36.pyc           | Bin 0 -> 2403 bytes
 xunnel_changelog/models/xunnel_changelog.py   |  72 ++++++++++++++++++
 xunnel_changelog/security/ir.model.access.csv |   2 +
 13 files changed, 159 insertions(+)
 create mode 100644 bumpversion.cfg
 create mode 100644 xunnel_changelog/README.rst
 create mode 100644 xunnel_changelog/__init__.py
 create mode 100644 xunnel_changelog/__manifest__.py
 create mode 100644 xunnel_changelog/controllers/__init__.py
 create mode 100644 xunnel_changelog/controllers/__pycache__/__init__.cpython-36.pyc
 create mode 100644 xunnel_changelog/controllers/__pycache__/gitlab_webhooks.cpython-36.pyc
 create mode 100644 xunnel_changelog/controllers/gitlab_webhooks.py
 create mode 100644 xunnel_changelog/models/__init__.py
 create mode 100644 xunnel_changelog/models/__pycache__/__init__.cpython-36.pyc
 create mode 100644 xunnel_changelog/models/__pycache__/xunnel_changelog.cpython-36.pyc
 create mode 100644 xunnel_changelog/models/xunnel_changelog.py
 create mode 100644 xunnel_changelog/security/ir.model.access.csv

diff --git a/bumpversion.cfg b/bumpversion.cfg
new file mode 100644
index 0000000..3f32ba1
--- /dev/null
+++ b/bumpversion.cfg
@@ -0,0 +1,9 @@
+[bumpversion]
+commit = True
+tag = True
+current_version = 11.0.0.0.1
+parse = (?P<major>.*\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)$
+serialize = 
+	{major}.{minor}.{patch}
+
+[bumpversion:file:xunnel_changelog/__manifest__.py]
diff --git a/xunnel_changelog/README.rst b/xunnel_changelog/README.rst
new file mode 100644
index 0000000..e69de29
diff --git a/xunnel_changelog/__init__.py b/xunnel_changelog/__init__.py
new file mode 100644
index 0000000..f7209b1
--- /dev/null
+++ b/xunnel_changelog/__init__.py
@@ -0,0 +1,2 @@
+from . import models
+from . import controllers
diff --git a/xunnel_changelog/__manifest__.py b/xunnel_changelog/__manifest__.py
new file mode 100644
index 0000000..c343db8
--- /dev/null
+++ b/xunnel_changelog/__manifest__.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+
+{
+    'name': 'Xunnel changelog',
+    'version': '11.0.0.0.1',
+    'category': 'Tools',
+    'author': 'Vauxoo',
+
+    'license': 'LGPL-3',
+    'website': 'https://www.vauxoo.com',
+    'depends': [
+    ],
+    'external_dependencies': {
+    },
+    'data': [
+        # Security
+        "security/ir.model.access.csv",
+    ],
+    'demo': [
+    ],
+    'qweb': [
+    ],
+    'test': [
+    ],
+    'auto_install': False,
+}
diff --git a/xunnel_changelog/controllers/__init__.py b/xunnel_changelog/controllers/__init__.py
new file mode 100644
index 0000000..211c4ef
--- /dev/null
+++ b/xunnel_changelog/controllers/__init__.py
@@ -0,0 +1 @@
+from . import gitlab_webhooks
diff --git a/xunnel_changelog/controllers/__pycache__/__init__.cpython-36.pyc b/xunnel_changelog/controllers/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6fbf2406d94b7e6a77508566098cf01cc2a1b90e
GIT binary patch
literal 206
zcmXr!<>fkQrXDB9z`*brh~a<<$Z`PUVgVqL!jQt4!;s4u#mLBz!W7J)$^4QLD6GkN
zi$6WHBquQ`zC1N4BR@a8*iVz`7DEw8^Gb#y79a&Ceg*4i<maa9XC;<p>SyK^mn7yT
zrxxp1l;-87=IACC6ksyrlQR<Y(o=Kt)Af_{^Gb^Hb8=FPiuL2;GxIV_;^XxSDsOSv
R<mRW8=A_zz+)@n03;^hlH~0Vm

literal 0
HcmV?d00001

diff --git a/xunnel_changelog/controllers/__pycache__/gitlab_webhooks.cpython-36.pyc b/xunnel_changelog/controllers/__pycache__/gitlab_webhooks.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..11ea53f7609241bb95ce2dd6dcca9beb61673482
GIT binary patch
literal 1462
zcmZWpPmkj?6ps_<Pt#7f!@_|R5z?@9rD<8Qrxik=6|)x@Ml*{*Ijoh&o+g<z&f3ll
zQ>CZwm2bd_8()CW!P!?X@D(`moU}6|k;<=r_Ve$(_j}L&{NNz`=8q?D{`M{FFYCdF
zVg3~i`5XkbC@QTLiV-q%yR>7Q*@eUK7RBx>i#im)vnXb$@U~9uQ~Sc2y8pmQYl<|^
zl&VitqwPQN)}ud#3A18EEkJY%OcAvW+7eNhdcU~Tr@=eRc%cKp4E6X`uF7QbBU@yg
zU&;01{O6{sSUFF#q*}6)FEuVCue4V;i!x6&KKuUS^~n@#tZr+janh(v`zxk0PNl}F
z6qhO5#TCN82je9S`6mcv6{xT`s6`ZgXcf-Zf)MR3+SuKWTX=;}9nhWD7ALLUI#-T3
zp%``pGB7FR=%Pmn>$BY2;1<IPe~aojpt*n>^tc<Zbzx@!Sbk>{=GNARmEjh(e(M#(
zZhy2zpc~5r!1#@hVQ16=9)0wyy9q!$Xam3)sB!U#PTE0X#^Kg6g#!W)PuGugF-v)M
znJ-D5hy<8mV*SCgqje@(+K61;&J@35)q4EXanJYhYoo``^Ut1XmkGhe`r{ue!zCB_
zn$Z_gUR@_;P9s1NOhw)K_>eCOmMW4cCGth1m|Rc#dd=?Z<tp&av|kHujN`|3qB3%m
zgQy@pStlveL&{_-@>=D*iYF^3mW-r)waOKdS)$RisjIPIH5VhOn;3)8;RA#5iqocK
z<eCWy5bL9_ql(=`-<{9T&Z8`m(Sorm>ToIK5*^7G;gOuaCv1b{3--2QQfY@(*BZ-)
zay?iw)ibDvro;Cpe#R0CUbF)SIyi>}cqN(kq)JpH_0Y8E-Z+2~NJdsvPYfJwR`ota
z?E#UA0%8bs^^ysV^Xig|iOJ6-3AX`DR$hwtL5atC1rDl|k)HZdU(sIEm?kQT$54(3
zwTK6IMd$#v2PK3w;}EDJf~8#0-z{+j@c+j1jIY?dNUrnw-jm$jz2l^=|34*n;B#m<
zC3sl^EAw4gH@gcwt8ewLCGHOlz@z*WgyjZkggi6>8NhFZ#={W`?Fq6GMxoK|(Du;!
zqrOe|&%&&4vU|kSsiy<d^%EgFBxKhPM2`r0+a#swG(!4nyMjZjiYMT|Oa6iQ#H=|W
z%nK&XTM^hMkZx@nXv`_+yPh#s%d2JADBpG!6ecGTfzaX0J5IW@4}2KDg>j^VFZwXQ
NG!Ing4QQ}K=RYh?uO$Eg

literal 0
HcmV?d00001

diff --git a/xunnel_changelog/controllers/gitlab_webhooks.py b/xunnel_changelog/controllers/gitlab_webhooks.py
new file mode 100644
index 0000000..0f8d8ff
--- /dev/null
+++ b/xunnel_changelog/controllers/gitlab_webhooks.py
@@ -0,0 +1,46 @@
+from odoo import http
+import logging
+
+_logger = logging.getLogger(__name__)
+
+
+class GitlabWebhooks(http.Controller):
+
+    @http.route(
+        '/xunnel/changelog', type='json', auth='public', methods=['POST'],
+        csrf=False
+    )
+    def xunnel_changelog(self):
+        env = http.request.env
+        instance_token = env['ir.config_parameter'].sudo().get_param(
+            'gitlab.security.token')
+        gitlab_token = http.request.httprequest.headers.get('X-Gitlab-Token')
+        if instance_token and instance_token != gitlab_token:
+            http.Response.status = '401'
+            return {'error': 'Unauthorized: invalid secret token'}
+        data = http.request.jsonrequest or {}
+        obj_attributes = data.get('object_attributes') or {}
+        # This controller can receive requests from everything that happens to
+        # a MR/PR, we will ignore all that's not a MR/PR thas has been merged.
+        """ if (data.get('object_kind') != 'merge_request' or
+                obj_attributes.get('state') != 'merged'):
+            # This log can be removed if it causes spam
+            _logger.info(
+                'Request not from a MR/PR or has not been merged, ignoring')
+            return """
+        # TODO: we need to store the description in RST format, and we need to
+        # find a way to get the bumped version.
+        changelog = env['xunnel.changelog'].sudo()
+        title = obj_attributes.get('title')
+        values = {
+            'repo': data.get('project', {}).get('path_with_namespace'),
+            'title': title,
+            'description': changelog.parse_md(
+                obj_attributes.get('description')),
+            'commit_sha': obj_attributes.get('merge_commit_sha') or '1',
+            'module_version': changelog.get_dump_version(title)
+        }
+        new_record = changelog.create(values)
+        # This log can be removed if it causes spam
+        _logger.info('A new MR/PR has been merged in %s:\n%s',
+                     new_record.repo, new_record.title)
diff --git a/xunnel_changelog/models/__init__.py b/xunnel_changelog/models/__init__.py
new file mode 100644
index 0000000..120263c
--- /dev/null
+++ b/xunnel_changelog/models/__init__.py
@@ -0,0 +1 @@
+from . import xunnel_changelog
diff --git a/xunnel_changelog/models/__pycache__/__init__.cpython-36.pyc b/xunnel_changelog/models/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9a4b020d6a94a7e8edc2206a4607ad54489dc07e
GIT binary patch
literal 202
zcmXr!<>fkQrXDBHz`*brh~a<<$Z`PUVgVqL!jQt4!;s4u#mLBz!W7J)$^4QLD6GkN
zOQ51OFE2GGJ~<;XFFiFUKiyB0=@vr~NcT#HA{HP8CVu(pXXNLm>SraEW$I_<6_+ID
zC8rkaLp19q78GDI5k~6g=BK3Q6zj*wXXa&=#K-FuRNmsS0ScDpq}qYpQ4GWk000&?
AF8}}l

literal 0
HcmV?d00001

diff --git a/xunnel_changelog/models/__pycache__/xunnel_changelog.cpython-36.pyc b/xunnel_changelog/models/__pycache__/xunnel_changelog.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..389abcaeece667e21ef24f5fa6e01dc4bbf63e74
GIT binary patch
literal 2403
zcmai0UvJws5Eu2wmL13W+pQf|jOgYj>RPAmu$Q9f3Uo;KuyjQebgQsURYf|Mr+*>o
zCKa5g^tHo2#ejW)eHp&)sb67FJJOQldL1T%C*JXnygT0g<S&+&+rRy}^|Npd<1b_G
zv0;862Hyoj41y9PMLtSR-%KsvLP};Pc53^!o?D6IJ0P=?hTnK-5Suu!4dPHVYMxoX
zORRmvYrKWM49}8{G$%CSvN4EhLb$ZTBKDAUNhqj@Q~D@UiuE&d<#&)!!$-vMO@e%j
z+9QXU#3J?^({EIqqq!z<E@_bF8|1gD6<4pcHP_NBOM2cWOQZukbTqe2x?}~oW!fFB
zkX5qw+Bif0s^-?ohUV6QTPK_3g61|f_W}7(bDQKMgnCJ?{4mZknmibW*&$8x!*caR
z3;IzlIVkZHTIBe6NEyXq7<0V$Wase{d>nF|Qg%p*XG)jRqjAhAk@k=#Mfv$bEE0<I
z0a(zf8dfTl3!F1tjFY71`{n+3g^2SkOfaE5VzK6G+o>ZQ$C+R`8Ap`B^#6DD5QAbd
z%1<8TX&Q@p^B1q?!YD61rHsSr^?7jV<Aj!1A5y{fF)yq2a3Cntl4#5r%^;AB%8!F6
zPm8gjK@xHiOs#{;#xu1OvRUcK<(alBqH=YRvox&EQ4%m{gV)+BLRD#5@K)9J00!>^
zIoX~VUmHK+QzVQLnxGNX*_nB20%uK3VxE~36xc_N@1fA)mhJM|?!q}(<T%6yqe8q=
zVf5R$ddjulvm3qiMvvg$H+On_cY6C}tM}qMR)S}bJcl{pfpocGa7`(dOA({sd7#|a
z;(-?1Ivh*doF)TlF&eQIF#N+{>+t&f>CP}u>CPy88Slgy7hx7rzB8@88(~rWdm79t
za%b9?mCCuiU%X;Vu=y1jyaB|p+o+4m%L_H$f9De3pXU2uJuyarD8zh&PK}ekPWjbS
z1X7*y;)-hNi_mtb=EUSTkJcw9q+ca|9TM*-Bq{Ih*H!fV-O6}gmz$~@=!7U|1Wz+b
z&M#vZ;ARDGX+T9Z45l!|R9U=L1TI5%j$<)|crrmxglxQE`7x)`jEU^Nd!XESUwv9^
z6*gjPK%}h{^zBT^hFWO>xdwxGfEacMwb3TBk%`Ld|C!bI92A+#93J&nL)WsZ1Yt}N
zq!0<HVl{)bq0)OCGEO;^=pMl;GF7kN9PE9IrwwzSA%JNMyq2vrWWSL7IJ+&~dJ4^?
zqLXGy7Q&Klp$-UA@+By6)m(<{qVnQmOtsp~f2C@{(Eh7loFMKJ@S05f4^31Q=BYKY
zI9BqBH8RhjFNvjNv&&y+z(U4pfopUbusqe^B5L3aGXUE2NDlx<YmlwdfMb3KZ>eow
zetPS6|EB)k+Uny2h0@U6W0vt*XK&4`%%r>J<>?07Up>BCIdgBjf6d$ekxxGJJlU+V
z%$6pj(gD1RhO%|Y@^L}pNJ#6D3eTRV+R@%io1PR*I$CEj^{b#Bs3U8TybD?6T_8ro
zhSIW8N7E87UdE!~BkzKAgCGl28U(T()ZiP)P7oZ8!=zeqv<g$#CT;lAG2dqJMPpaB
z;6OFb(%gr~Zv$GxCnMmXdI@ycM~W!)V(R)K1>;1-8ftWZfI$6GU|4B*im1Y#Bf66m
zAT?p|>p)!7HoLlyV1`^vb(Ed~2eWFW>vosAO{Ofpmb7z{=S($^4n_N-!I)iEvMWHO
gv!^{#7IWuoca#&-y*ovPdkR0e`ao_%x?S+#AC6Io!T<mO

literal 0
HcmV?d00001

diff --git a/xunnel_changelog/models/xunnel_changelog.py b/xunnel_changelog/models/xunnel_changelog.py
new file mode 100644
index 0000000..7e475b8
--- /dev/null
+++ b/xunnel_changelog/models/xunnel_changelog.py
@@ -0,0 +1,72 @@
+from odoo import models, fields, api
+from datetime import datetime
+import markdown2
+import re
+
+
+class XunnelChangelog(models.Model):
+
+    _name = "xunnel.changelog"
+
+    repo = fields.Char(required=True, help='Repo where this MR/PR was merged')
+    title = fields.Char(
+        required=True,
+        help="Title of the merge request or pull request."
+    )
+    description = fields.Text(
+        help=("Optional description of the changes introduced in the merge"
+              " request or pull request")
+    )
+    commit_sha = fields.Char(
+        required=True,
+        help="Commit introduced by this MR/PR"
+    )
+    module_version = fields.Char(
+        help="Version of the module"
+    )
+    last_module_version = fields.Char(
+        help="Gets the version after the current one",
+        compute="_compute_last_module_version")
+    date = fields.Char(
+        compute="_compute_date",
+        help="formats the date")
+
+    @api.multi
+    def _compute_date(self):
+        """Formats the date to a pretty one.
+        """
+        for rec in self:
+            date = datetime.strptime(rec.create_date, '%Y-%m-%d %H:%M:%S')
+            rec.date = datetime.strftime(date, '%b, %d %Y')
+
+    @api.multi
+    def _compute_last_module_version(self):
+        """Sets the `module_version` of the last record created.
+        """
+        self = self.with_context(prefetch_fields=False)
+        for rec in self:
+            last = self.browse((rec.id or 0) - 1)
+            if not last:
+               continue
+            rec.last_module_version = last.module_version
+
+    @api.model
+    def parse_md(self, md):
+        """Parses a Md text to HTML format.
+        """
+        md = str(md)
+        return markdown2.markdown(md)
+
+    @api.model
+    def get_dump_version(self, title):
+        """Gets the dump version from the title of an MR.
+        The required format is: 'dumpv#12.0.0.0.1'. This returns
+        '12.0.0.0.1'.
+        """
+        if not title:
+            return False
+        expr = r'dumpv#(?P<version>(.*)(\s|$))'
+        group = re.match(expr, title)
+        if not group:
+            return False
+        return group.groupdict().get('version')
diff --git a/xunnel_changelog/security/ir.model.access.csv b/xunnel_changelog/security/ir.model.access.csv
new file mode 100644
index 0000000..234f566
--- /dev/null
+++ b/xunnel_changelog/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+xunnelchangelog,xunnel.changelog_name,model_xunnel_changelog,,1,0,0,0
-- 
GitLab


From a2fbfa85675ffcc2f82f2ff0ce788dda63c8da3c Mon Sep 17 00:00:00 2001
From: Javier Vega <javier@vauxoo.com>
Date: Tue, 21 Jan 2020 21:30:27 -0600
Subject: [PATCH 2/2] bum versin

---
 bumpversion.cfg => .bumpversion.cfg | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename bumpversion.cfg => .bumpversion.cfg (86%)

diff --git a/bumpversion.cfg b/.bumpversion.cfg
similarity index 86%
rename from bumpversion.cfg
rename to .bumpversion.cfg
index 3f32ba1..3b11455 100644
--- a/bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,7 +1,7 @@
 [bumpversion]
 commit = True
 tag = True
-current_version = 11.0.0.0.1
+current_version = 11.0.0.0.2
 parse = (?P<major>.*\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)$
 serialize = 
 	{major}.{minor}.{patch}
-- 
GitLab