mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 23:45:44 +07:00
[ADD] runbot_merge: github identity for the mergebot
Necessary to create commits *as* the mergebot without going through the github API. Copy of the improved version from forwardport. *Not* an override, to avoid unnecessarily triggering one or the other which is confusing and weird.
This commit is contained in:
parent
86a1b5523e
commit
2fbbe3fcdb
@ -1,9 +1,11 @@
|
||||
import logging
|
||||
import re
|
||||
|
||||
import requests
|
||||
import sentry_sdk
|
||||
|
||||
from odoo import models, fields
|
||||
from odoo import models, fields, api
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
class Project(models.Model):
|
||||
@ -28,13 +30,14 @@ class Project(models.Model):
|
||||
)
|
||||
|
||||
github_token = fields.Char("Github Token", required=True)
|
||||
github_name = fields.Char(store=True, compute="_compute_identity")
|
||||
github_email = fields.Char(store=True, compute="_compute_identity")
|
||||
github_prefix = fields.Char(
|
||||
required=True,
|
||||
default="hanson", # mergebot du bot du bot du~
|
||||
help="Prefix (~bot name) used when sending commands from PR "
|
||||
"comments e.g. [hanson retry] or [hanson r+ p=1]",
|
||||
)
|
||||
github_name = fields.Char(related='github_prefix')
|
||||
|
||||
batch_limit = fields.Integer(
|
||||
default=8, group_operator=None, help="Maximum number of PRs staged together")
|
||||
@ -48,6 +51,42 @@ class Project(models.Model):
|
||||
freeze_id = fields.Many2one('runbot_merge.project.freeze', compute='_compute_freeze')
|
||||
freeze_reminder = fields.Text()
|
||||
|
||||
@api.depends('github_token')
|
||||
def _compute_identity(self):
|
||||
s = requests.Session()
|
||||
for project in self:
|
||||
if not project.github_token or (project.github_name and project.github_email):
|
||||
continue
|
||||
|
||||
r0 = s.get('https://api.github.com/user', headers={
|
||||
'Authorization': 'token %s' % project.github_token
|
||||
})
|
||||
if not r0.ok:
|
||||
_logger.error("Failed to fetch merge bot information for project %s: %s", project.name, r0.text or r0.content)
|
||||
continue
|
||||
|
||||
r0 = r0.json()
|
||||
project.github_name = r0['name'] or r0['login']
|
||||
if email := r0['email']:
|
||||
project.github_email = email
|
||||
continue
|
||||
|
||||
if 'user:email' not in set(re.split(r',\s*', r0.headers['x-oauth-scopes'])):
|
||||
raise UserError("The merge bot github token needs the user:email scope to fetch the bot's identity.")
|
||||
r1 = s.get('https://api.github.com/user/emails', headers={
|
||||
'Authorization': 'token %s' % project.github_token
|
||||
})
|
||||
if not r1.ok:
|
||||
_logger.error("Failed to fetch merge bot emails for project %s: %s", project.name, r1.text or r1.content)
|
||||
continue
|
||||
project.github_email = next((
|
||||
entry['email']
|
||||
for entry in r1.json()
|
||||
if entry['primary']
|
||||
), None)
|
||||
if not project.github_email:
|
||||
raise UserError("The merge bot needs a public or accessible primary email set up.")
|
||||
|
||||
def _check_stagings(self, commit=False):
|
||||
# check branches with an active staging
|
||||
for branch in self.env['runbot_merge.branch']\
|
||||
|
@ -25,6 +25,10 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="github_token"/>
|
||||
<field name="github_name" readonly="0"
|
||||
help="Identity when creating new commits, defaults to github name, falls back to login."/>
|
||||
<field name="github_email" readonly="0"
|
||||
help="Identity when creating new commits, defaults to public email, falls back to primary email."/>
|
||||
<field name="secret"/>
|
||||
</group>
|
||||
<group>
|
||||
|
Loading…
Reference in New Issue
Block a user