From c3171a269093708f2622101b4beae7f2826bcdc0 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Tue, 14 Oct 2014 15:46:35 -0400 Subject: [PATCH] Redo the UI for the trigger setup dialog and add the ability for github triggers to be filtered using a regex on their branch name. --- endpoints/api/trigger.py | 10 +- endpoints/index.py | 2 +- endpoints/trigger.py | 39 ++- static/css/quay.css | 62 +++- static/directives/setup-trigger-dialog.html | 152 +++++---- static/directives/step-view-step.html | 9 + static/directives/step-view.html | 3 + static/directives/trigger-description.html | 25 +- static/directives/trigger-setup-github.html | 161 +++++++-- static/js/app.js | 360 ++++++++++++++------ 10 files changed, 597 insertions(+), 226 deletions(-) create mode 100644 static/directives/step-view-step.html create mode 100644 static/directives/step-view.html diff --git a/endpoints/api/trigger.py b/endpoints/api/trigger.py index 081641e00..be119499d 100644 --- a/endpoints/api/trigger.py +++ b/endpoints/api/trigger.py @@ -317,7 +317,7 @@ class BuildTriggerAnalyze(RepositoryParamResource): if not found_repository: return { 'status': 'error', - 'message': 'Repository "%s" was not found' % (base_image) + 'message': 'Repository "%s" referenced by the Dockerfile was not found' % (base_image) } # If the repository is private and the user cannot see that repo, then @@ -326,7 +326,7 @@ class BuildTriggerAnalyze(RepositoryParamResource): if found_repository.visibility.name != 'public' and not can_read: return { 'status': 'error', - 'message': 'Repository "%s" was not found' % (base_image) + 'message': 'Repository "%s" referenced by the Dockerfile was not found' % (base_image) } # Check to see if the repository is public. If not, we suggest the @@ -450,18 +450,18 @@ class BuildTriggerFieldValues(RepositoryParamResource): """ Custom verb to fetch a values list for a particular field name. """ @require_repo_admin @nickname('listTriggerFieldValues') - def get(self, namespace, repository, trigger_uuid, field_name): + def post(self, namespace, repository, trigger_uuid, field_name): """ List the field values for a custom run field. """ try: trigger = model.get_build_trigger(namespace, repository, trigger_uuid) except model.InvalidBuildTriggerException: raise NotFound() + config = request.get_json() or json.loads(trigger.config) user_permission = UserAdminPermission(trigger.connected_user.username) if user_permission.can(): trigger_handler = BuildTriggerBase.get_trigger_for_service(trigger.service.name) - values = trigger_handler.list_field_values(trigger.auth_token, json.loads(trigger.config), - field_name) + values = trigger_handler.list_field_values(trigger.auth_token, config, field_name) if values is None: raise NotFound() diff --git a/endpoints/index.py b/endpoints/index.py index eb52971cf..648cf6cf9 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -70,7 +70,7 @@ def create_user(): abort(400, 'User creation is disabled. Please speak to your administrator.') user_data = request.get_json() - if not 'username' in user_data: + if not user_data or not 'username' in user_data: abort(400, 'Missing username') username = user_data['username'] diff --git a/endpoints/trigger.py b/endpoints/trigger.py index c7c47db79..0ff6f76df 100644 --- a/endpoints/trigger.py +++ b/endpoints/trigger.py @@ -3,6 +3,7 @@ import io import os.path import tarfile import base64 +import re from github import Github, UnknownObjectException, GithubException from tempfile import SpooledTemporaryFile @@ -229,13 +230,35 @@ class GithubBuildTrigger(BuildTrigger): return repos_by_org + def matches_branch(self, branch_name, regex): + if not regex: + return False + + m = regex.match(branch_name) + if not m: + return False + + return len(m.group(0)) == len(branch_name) + def list_build_subdirs(self, auth_token, config): gh_client = self._get_client(auth_token) source = config['build_source'] - try: + try: repo = gh_client.get_repo(source) - default_commit = repo.get_branch(repo.default_branch or 'master').commit + + # Find the first matching branch. + branches = None + if 'branch_regex' in config: + try: + regex = re.compile(config['branch_regex']) + branches = [branch.name for branch in repo.get_branches() + if self.matches_branch(branch.name, regex)] + except: + pass + + branches = branches or [repo.default_branch or 'master'] + default_commit = repo.get_branch(branches[0]).commit commit_tree = repo.get_git_tree(default_commit.sha, recursive=True) return [os.path.dirname(elem.path) for elem in commit_tree.tree @@ -330,7 +353,7 @@ class GithubBuildTrigger(BuildTrigger): payload = request.get_json() if not payload or payload.get('head_commit') is None: raise SkipRequestException() - + if 'zen' in payload: raise ValidationRequestException() @@ -339,6 +362,16 @@ class GithubBuildTrigger(BuildTrigger): commit_sha = payload['head_commit']['id'] commit_message = payload['head_commit'].get('message', '') + if 'branch_regex' in config: + try: + regex = re.compile(config['branch_regex']) + except: + regex = re.compile('.*') + + branch = ref.split('/')[-1] + if not self.matches_branch(branch, regex): + raise SkipRequestException() + if should_skip_commit(commit_message): raise SkipRequestException() diff --git a/static/css/quay.css b/static/css/quay.css index 08d55c970..2cc21f610 100644 --- a/static/css/quay.css +++ b/static/css/quay.css @@ -4105,6 +4105,27 @@ pre.command:before { border-bottom-left-radius: 0px; } +.trigger-setup-github-element .branch-reference.not-match { + color: #ccc !important; +} + +.trigger-setup-github-element .branch-reference.not-match a { + color: #ccc !important; + text-decoration: line-through; +} + +.trigger-setup-github-element .branch-filter { + white-space: nowrap; +} + +.trigger-setup-github-element .branch-filter span { + display: inline-block; +} + +.trigger-setup-github-element .selected-info { + margin-bottom: 20px; +} + .trigger-setup-github-element .github-org-icon { width: 20px; margin-right: 8px; @@ -4120,6 +4141,45 @@ pre.command:before { padding-left: 6px; } +.trigger-setup-github-element .matching-branches { + margin: 0px; + padding: 0px; + margin-left: 10px; + display: inline-block; +} + +.trigger-setup-github-element .matching-branches li:before { + content: "\f126"; + font-family: FontAwesome; +} + +.trigger-setup-github-element .matching-branches li { + list-style: none; + display: inline-block; + margin-left: 10px; +} + +.setup-trigger-directive-element .dockerfile-found-content { + margin-left: 32px; +} + +.setup-trigger-directive-element .dockerfile-found-content:before { + content: "\f071"; + font-family: FontAwesome; + color: rgb(255, 194, 0); + position: absolute; + top: 0px; + left: 0px; + font-size: 20px; +} + +.setup-trigger-directive-element .dockerfile-found { + position: relative; + margin-bottom: 16px; + padding-bottom: 16px; + border-bottom: 1px solid #eee; +} + .slideinout { -webkit-transition:0.5s all; transition:0.5s linear all; @@ -4127,7 +4187,7 @@ pre.command:before { position: relative; - height: 75px; + height: 32px; opacity: 1; } diff --git a/static/directives/setup-trigger-dialog.html b/static/directives/setup-trigger-dialog.html index dd384c808..a44893c68 100644 --- a/static/directives/setup-trigger-dialog.html +++ b/static/directives/setup-trigger-dialog.html @@ -8,102 +8,110 @@ -