[IMP] runbot: allow custom run path per user

Adds a new setting on users to define a custom path to use when
accessing a running build.
Can be used to directly access a specific page instead of landing on the
home page from a runbot run.
This commit is contained in:
William Braeckman 2025-01-02 12:13:39 +01:00
parent e66cd93c2c
commit 9fc4f2e5db
6 changed files with 43 additions and 6 deletions

View File

@ -85,7 +85,7 @@ class Runbot(Controller):
@o_route([
'/runbot/submit'
], type='http', auth="public", methods=['GET', 'POST'], csrf=False)
def submit(self, more=False, redirect='/', keep_search=False, category=False, filter_mode=False, update_triggers=False, **kwargs):
def submit(self, more=False, redirect='/', keep_search=False, category=False, filter_mode=False, update_triggers=False, build_url_path=None, **kwargs):
assert redirect.startswith('/')
response = werkzeug.utils.redirect(redirect)
response.set_cookie('more', '1' if more else '0')
@ -101,6 +101,11 @@ class Runbot(Controller):
response.delete_cookie(key)
else:
response.set_cookie(key, '-'.join(enabled_triggers))
if build_url_path:
if request.env.user._is_public():
response.set_cookie('build_url_path', build_url_path)
else:
request.env.user.build_url_path = build_url_path
return response
@route(['/',
@ -656,6 +661,10 @@ class Runbot(Controller):
def access_running(self, build_id, db_suffix=None, **kwargs):
build = request.env['runbot.build'].browse(int(build_id)).exists()
run_url = build._get_run_url(db_suffix)
if path := request.env.user.build_url_path:
if not path.startswith('/'):
path = f'/{path}'
run_url += path
_logger.info('Redirecting to %s', run_url)
return werkzeug.utils.redirect(run_url)

View File

@ -10,4 +10,9 @@ class IrQweb(models.AbstractModel):
response = super()._prepare_frontend_environment(values)
values['s2human'] = s2human
values['s2human_long'] = s2human_long
values['build_url_path'] = (
request.httprequest.cookies.get('build_url_path', self.env.user.build_url_path)
)
return response

View File

@ -13,6 +13,7 @@ class ResUsers(models.Model):
# Add default action_id
action_id = fields.Many2one('ir.actions.actions',
default=lambda self: self.env.ref('runbot.open_view_warning_tree', raise_if_not_found=False))
build_url_path = fields.Char(related="res_users_settings_id.build_url_path", readonly=False)
_sql_constraints = [
(
@ -24,9 +25,15 @@ class ResUsers(models.Model):
@property
def SELF_WRITEABLE_FIELDS(self):
return super().SELF_WRITEABLE_FIELDS + ['github_login']
return super().SELF_WRITEABLE_FIELDS + ['github_login', 'build_url_path']
def write(self, values):
if list(values.keys()) == ['github_login'] and self.env.user.has_group('runbot.group_runbot_team_manager'):
return super(ResUsers, self.sudo()).write(values)
return super().write(values)
class ResUsersSettings(models.Model):
_inherit = 'res.users.settings'
build_url_path = fields.Char("Build run path", default='', help="Default path when entering a running build.")

View File

@ -77,19 +77,26 @@ server {
<t t-foreach="builds" t-as="build">
<t id="server_build_anchor"/>
<t t-set="re_dest" t-value="re_escape(build.dest)"/>
<t t-set="re_host" t-value="re_escape(build.host)"/>
<t t-set="token" t-value="build._get_run_token()[0]"/>
<t t-set="db_group" t-value="'(?&lt;db&gt;-[a-z0-9_-]+)?'"/>
<t t-set="fingerprint_group" t-value="'(?&lt;fingerprint&gt;-[a-z0-9_]+)'"/>
server {
listen 8080;
server_name ~^<t t-out="re_escape(build.dest)"/>(-[a-z0-9_-]+)?-<t t-out="build._get_run_token()[0]"/>(-[a-z0-9_]+)\.<t t-out="re_escape(build.host)"/>$;
server_name ~^<t t-out="re_dest"/><t t-out="db_group"/>-<t t-out="token"/><t t-out="fingerprint_group"/>\.<t t-out="re_host"/>$;
<t id="build_anchor_authenticated"/>
location / {
location ~ /(?&lt;path&gt;.*) {
<t id="build_anchor_authenticated_side_effect"/>
return 307 http://<t t-out="build.dest"/>$1.<t t-out="build.host"/>;
return 307 http://<t t-out="build.dest"/>$db.<t t-out="build.host"/>/$path;
}
}
server {
listen 8080;
server_name ~^<t t-out="re_escape(build.dest)"/>(-[a-z0-9_-]+)?\.<t t-out="re_escape(build.host)"/>$;
server_name ~^<t t-out="re_dest"/>(-[a-z0-9_-]+)?\.<t t-out="re_host"/>$;
<t id="build_anchor"/>
location / { proxy_pass http://127.0.0.1:<t t-out="build.port"/>; }
location /longpolling { proxy_pass http://127.0.0.1:<t t-out="build.port + 1"/>; }

View File

@ -139,6 +139,12 @@
<button t-attf-onclick="document.cookie = 'category={{category.id}}; expires=Thu, 1 Dec 2942 12:00:00 UTC; path=/'; location.reload();" type="button" t-attf-class="btn btn-{{'primary' if category.id == active_category_id else 'secondary'}}" t-out="category.name"/>
</t>
</div>
<hr class="separator"/>
<div class="text-nowrap input-group" title="Change this path to change the default path you will be redirected to when accessing a build.">
<span class="input-group-text">Build path</span>
<input type="text" class="form-control" name="build_url_path" t-att-value="build_url_path" placeholder="/" aria-label="Default build path"/>
</div>
<hr class="separator"/>
<div t-if="triggers">

View File

@ -7,6 +7,7 @@
<field name="arch" type="xml">
<xpath expr="//field[@name='email']" position="after">
<field name="github_login"/>
<field name="build_url_path"/>
</xpath>
</field>
</record>
@ -19,6 +20,7 @@
<xpath expr="//group[@name='phone_numbers']" position="after">
<group name="runbot">
<field name="github_login"/>
<field name="build_url_path"/>
<field name="runbot_team_ids"/>
</group>
</xpath>
@ -47,6 +49,7 @@
<page string="Runbot">
<group>
<field name="github_login"/>
<field name="build_url_path"/>
<field name="runbot_team_ids"/>
</group>
</page>