UI and code improvements to make working with the multiple SCMs easier
This commit is contained in:
parent
f091aaa07e
commit
d07f9f04e9
10 changed files with 70 additions and 114 deletions
|
@ -48,14 +48,19 @@ def user_view(user):
|
|||
def trigger_view(trigger, can_read=False, can_admin=False):
|
||||
if trigger and trigger.uuid:
|
||||
build_trigger = BuildTriggerHandler.get_handler(trigger)
|
||||
build_source = build_trigger.config.get('build_source')
|
||||
|
||||
repo_url = build_trigger.get_repository_url() if build_source else None
|
||||
|
||||
return {
|
||||
'service': trigger.service.name,
|
||||
'build_source': build_trigger.config.get('build_source') if can_read else None,
|
||||
'build_source': build_source if can_read else None,
|
||||
'config': build_trigger.config if can_admin else {},
|
||||
'id': trigger.uuid,
|
||||
'connected_user': trigger.connected_user.username,
|
||||
'is_active': build_trigger.is_active(),
|
||||
'pull_robot': user_view(trigger.pull_robot) if trigger.pull_robot else None
|
||||
'pull_robot': user_view(trigger.pull_robot) if trigger.pull_robot else None,
|
||||
'repository_url': repo_url if can_read else None,
|
||||
}
|
||||
|
||||
return None
|
||||
|
|
|
@ -367,8 +367,7 @@ class BuildTriggerAnalyze(RepositoryParamResource):
|
|||
'name': base_repository,
|
||||
'is_public': found_repository.visibility.name == 'public',
|
||||
'robots': read_robots,
|
||||
'status': 'analyzed',
|
||||
'dockerfile_url': handler.dockerfile_url()
|
||||
'status': 'analyzed'
|
||||
}
|
||||
|
||||
except RepositoryReadException as rre:
|
||||
|
|
|
@ -120,12 +120,6 @@ class BuildTriggerHandler(object):
|
|||
""" Returns the auth token for the trigger. """
|
||||
return self.trigger.auth_token
|
||||
|
||||
def dockerfile_url(self):
|
||||
"""
|
||||
Returns the URL at which the Dockerfile for the trigger is found or None if none/not applicable.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def load_dockerfile_contents(self):
|
||||
"""
|
||||
Loads the Dockerfile found for the trigger's config and returns them or None if none could
|
||||
|
@ -188,6 +182,11 @@ class BuildTriggerHandler(object):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_repository_url(self):
|
||||
""" Returns the URL of the current trigger's repository. Note that this operation
|
||||
can be called in a loop, so it should be as fast as possible. """
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def service_name(cls):
|
||||
"""
|
||||
|
@ -212,6 +211,18 @@ class BuildTriggerHandler(object):
|
|||
""" Sets the auth token for the trigger, saving it to the DB. """
|
||||
model.update_build_trigger(self.trigger, self.config, auth_token=auth_token)
|
||||
|
||||
def get_dockerfile_path(self):
|
||||
""" Returns the normalized path to the Dockerfile found in the subdirectory
|
||||
in the config. """
|
||||
subdirectory = self.config.get('subdir', '')
|
||||
if subdirectory == '/':
|
||||
subdirectory = ''
|
||||
else:
|
||||
if not subdirectory.endswith('/'):
|
||||
subdirectory = subdirectory + '/'
|
||||
|
||||
return subdirectory + 'Dockerfile'
|
||||
|
||||
|
||||
class BitbucketBuildTrigger(BuildTriggerHandler):
|
||||
"""
|
||||
|
@ -371,24 +382,9 @@ class BitbucketBuildTrigger(BuildTriggerHandler):
|
|||
|
||||
return []
|
||||
|
||||
def dockerfile_url(self):
|
||||
repository = self._get_repository_client()
|
||||
subdirectory = self.config.get('subdir', '')
|
||||
path = subdirectory + '/Dockerfile' if subdirectory else 'Dockerfile'
|
||||
|
||||
master_branch = 'master'
|
||||
(result, data, _) = repository.get_main_branch()
|
||||
if result:
|
||||
master_branch = data['name']
|
||||
|
||||
return 'https://bitbucket.org/%s/%s/src/%s/%s' % (repository.namespace,
|
||||
repository.repository_name,
|
||||
master_branch, path)
|
||||
|
||||
def load_dockerfile_contents(self):
|
||||
repository = self._get_repository_client()
|
||||
subdirectory = self.config.get('subdir', '/')[1:]
|
||||
path = subdirectory + '/Dockerfile' if subdirectory else 'Dockerfile'
|
||||
path = self.get_dockerfile_path()
|
||||
|
||||
(result, data, err_msg) = repository.get_raw_path_contents(path, revision='master')
|
||||
if not result:
|
||||
|
@ -539,6 +535,11 @@ class BitbucketBuildTrigger(BuildTriggerHandler):
|
|||
|
||||
return self._prepare_build(commit_sha, ref, True)
|
||||
|
||||
def get_repository_url(self):
|
||||
source = self.config['build_source']
|
||||
(namespace, name) = source.split('/')
|
||||
return 'https://bitbucket.org/%s/%s' % (namespace, name)
|
||||
|
||||
|
||||
class GithubBuildTrigger(BuildTriggerHandler):
|
||||
"""
|
||||
|
@ -696,30 +697,13 @@ class GithubBuildTrigger(BuildTriggerHandler):
|
|||
|
||||
raise RepositoryReadException(message)
|
||||
|
||||
def dockerfile_url(self):
|
||||
config = self.config
|
||||
|
||||
source = config['build_source']
|
||||
subdirectory = config.get('subdir', '')
|
||||
path = subdirectory + '/Dockerfile' if subdirectory else 'Dockerfile'
|
||||
gh_client = self._get_client()
|
||||
|
||||
try:
|
||||
repo = gh_client.get_repo(source)
|
||||
master_branch = repo.default_branch or 'master'
|
||||
return 'https://github.com/%s/blob/%s/%s' % (source, master_branch, path)
|
||||
except GithubException:
|
||||
logger.exception('Could not load repository for Dockerfile.')
|
||||
return None
|
||||
|
||||
def load_dockerfile_contents(self):
|
||||
config = self.config
|
||||
gh_client = self._get_client()
|
||||
|
||||
source = config['build_source']
|
||||
subdirectory = config.get('subdir', '')
|
||||
path = subdirectory + '/Dockerfile' if subdirectory else 'Dockerfile'
|
||||
|
||||
path = self.get_dockerfile_path()
|
||||
try:
|
||||
repo = gh_client.get_repo(source)
|
||||
file_info = repo.get_file_contents(path)
|
||||
|
@ -922,6 +906,12 @@ class GithubBuildTrigger(BuildTriggerHandler):
|
|||
|
||||
return None
|
||||
|
||||
def get_repository_url(self):
|
||||
from app import github_trigger
|
||||
source = self.config['build_source']
|
||||
return github_trigger.get_public_url(source)
|
||||
|
||||
|
||||
class CustomBuildTrigger(BuildTriggerHandler):
|
||||
payload_schema = {
|
||||
'type': 'object',
|
||||
|
@ -1084,6 +1074,9 @@ class CustomBuildTrigger(BuildTriggerHandler):
|
|||
self.config = config
|
||||
return config
|
||||
|
||||
def get_repository_url(self):
|
||||
return None
|
||||
|
||||
|
||||
class GitLabBuildTrigger(BuildTriggerHandler):
|
||||
"""
|
||||
|
@ -1221,35 +1214,9 @@ class GitLabBuildTrigger(BuildTriggerHandler):
|
|||
|
||||
return []
|
||||
|
||||
def dockerfile_url(self):
|
||||
gl_client = self._get_authorized_client()
|
||||
subdir = self.config.get('subdir', '')
|
||||
path = subdir + '/Dockerfile' if subdir else 'Dockerfile'
|
||||
|
||||
repository = gl_client.getproject(self.config['build_source'])
|
||||
if repository is False:
|
||||
return None
|
||||
|
||||
branches = self.list_field_values('branch_name')
|
||||
branches = find_matching_branches(self.config, branches)
|
||||
if branches == []:
|
||||
return None
|
||||
branch_name = branches[0]
|
||||
if repository['default_branch'] in branches:
|
||||
branch_name = repository['default_branch']
|
||||
|
||||
return '%s/%s/blob/%s/%s' % (gl_client.host,
|
||||
repository['path_with_namespace'],
|
||||
branch_name,
|
||||
path)
|
||||
|
||||
def load_dockerfile_contents(self):
|
||||
gl_client = self._get_authorized_client()
|
||||
subdir = self.config.get('subdir', '')
|
||||
if subdir == '/':
|
||||
subdir = ''
|
||||
|
||||
path = subdir + 'Dockerfile' if subdir else 'Dockerfile'
|
||||
path = self.get_dockerfile_path()
|
||||
|
||||
repository = gl_client.getproject(self.config['build_source'])
|
||||
if repository is False:
|
||||
|
@ -1394,3 +1361,12 @@ class GitLabBuildTrigger(BuildTriggerHandler):
|
|||
ref = 'refs/heads/%s' % branch_name
|
||||
|
||||
return self._prepare_build(commit, ref, True)
|
||||
|
||||
def get_repository_url(self):
|
||||
gl_client = self._get_authorized_client()
|
||||
repository = gl_client.getproject(self.config['build_source'])
|
||||
if repository is False:
|
||||
return None
|
||||
|
||||
return '%s/%s' % (gl_client.host, repository['path_with_namespace'])
|
||||
|
||||
|
|
|
@ -13,29 +13,17 @@
|
|||
<div class="modal-body" ng-show="currentView != 'activating'">
|
||||
<!-- Trigger-specific setup -->
|
||||
<div class="trigger-description-element trigger-option-section" ng-switch on="trigger.service">
|
||||
<div ng-switch-when="github">
|
||||
<div class="trigger-setup-githost" repository="repository" trigger="trigger"
|
||||
kind="github"
|
||||
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
|
||||
analyze="checkAnalyze(isValid)"></div>
|
||||
</div>
|
||||
<div ng-switch-when="bitbucket">
|
||||
<div class="trigger-setup-githost" repository="repository" trigger="trigger"
|
||||
kind="bitbucket"
|
||||
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
|
||||
analyze="checkAnalyze(isValid)"></div>
|
||||
</div>
|
||||
<div ng-switch-when="gitlab">
|
||||
<div class="trigger-setup-githost" repository="repository" trigger="trigger"
|
||||
kind="gitlab"
|
||||
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
|
||||
analyze="checkAnalyze(isValid)"></div>
|
||||
</div>
|
||||
<div ng-switch-when="custom-git">
|
||||
<div class="trigger-setup-custom" repository="repository" trigger="trigger"
|
||||
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
|
||||
analyze="checkAnalyze(isValid)"></div>
|
||||
</div>
|
||||
<div ng-switch-default>
|
||||
<div class="trigger-setup-githost" repository="repository" trigger="trigger"
|
||||
kind="{{ trigger.service }}"
|
||||
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
|
||||
analyze="checkAnalyze(isValid)"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading pull information -->
|
||||
|
@ -57,14 +45,8 @@
|
|||
</div>
|
||||
<div class="dockerfile-found" ng-if="pullInfo.analysis.is_public === false">
|
||||
<div class="dockerfile-found-content">
|
||||
A robot account is <strong>required</strong> for this build trigger because
|
||||
|
||||
the
|
||||
<a href="{{ pullInfo.analysis.dockerfile_url }}" ng-if="pullInfo.analysis.dockerfile_url" target="_blank">
|
||||
Dockerfile found
|
||||
</a>
|
||||
<span ng-if="!pullInfo.analysis.dockerfile_url">Dockerfile found</span>
|
||||
|
||||
A robot account is <strong>required</strong> for this build trigger because the
|
||||
Dockerfile found
|
||||
pulls from the private <span class="registry-name"></span> repository
|
||||
|
||||
<a href="/repository/{{ pullInfo.analysis.namespace }}/{{ pullInfo.analysis.name }}" target="_blank">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<span>
|
||||
<i class="fa fa-bitbucket fa-lg" style="margin-right: 6px" data-title="BitBucket" bs-tooltip="tooltip.title"></i>
|
||||
Push to BitBucket repository
|
||||
<a href="https://bitbucket.org/{{ trigger.config.build_source }}" target="_new">
|
||||
<a href="{{ trigger.repository_url }}" target="_new">
|
||||
{{ trigger.config.build_source }}
|
||||
</a>
|
||||
<div style="margin-top: 4px; margin-left: 26px; font-size: 12px; color: gray;" ng-if="!short">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<span>
|
||||
<i class="fa fa-github fa-lg" style="margin-right: 6px" data-title="GitHub" bs-tooltip="tooltip.title"></i>
|
||||
Push to GitHub <span ng-if="KeyService.isEnterprise('github-trigger')">Enterprise</span> repository
|
||||
<a href="{{ KeyService['githubTriggerEndpoint'] }}{{ trigger.config.build_source }}" target="_new">
|
||||
<a href="{{ trigger.repository_url }}" target="_new">
|
||||
{{ trigger.config.build_source }}
|
||||
</a>
|
||||
<div style="margin-top: 4px; margin-left: 26px; font-size: 12px; color: gray;" ng-if="!short">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<span>
|
||||
<i class="fa fa-git-square fa-lg" style="margin-right: 6px" data-title="GitLab" bs-tooltip="tooltip.title"></i>
|
||||
Push to GitLab repository
|
||||
<a href="https://gitlab.com/{{ trigger.config.build_source }}" target="_new">
|
||||
<a ng-href="{{ trigger.repository_url }}" target="_new">
|
||||
{{ trigger.config.build_source }}
|
||||
</a>
|
||||
<div style="margin-top: 4px; margin-left: 26px; font-size: 12px; color: gray;" ng-if="!short">
|
||||
|
|
|
@ -55,9 +55,6 @@ angular.module('quay').factory('TriggerService', ['UtilService', '$sanitize', 'K
|
|||
'credentials': '/static/directives/trigger/githost/credentials.html',
|
||||
'trigger-description': '/static/directives/trigger/github/trigger-description.html'
|
||||
},
|
||||
'repository_url': function(build) {
|
||||
return KeyService['githubTriggerEndpoint'] + build.trigger.build_source;
|
||||
},
|
||||
'link_templates': {
|
||||
'commit': '/commit/{sha}',
|
||||
'branch': '/tree/{branch}',
|
||||
|
@ -94,9 +91,6 @@ angular.module('quay').factory('TriggerService', ['UtilService', '$sanitize', 'K
|
|||
'credentials': '/static/directives/trigger/githost/credentials.html',
|
||||
'trigger-description': '/static/directives/trigger/bitbucket/trigger-description.html'
|
||||
},
|
||||
'repository_url': function(build) {
|
||||
return 'https://bitbucket.org/' + build.trigger.build_source;
|
||||
},
|
||||
'link_templates': {
|
||||
'commit': '/commits/{sha}',
|
||||
'branch': '/branch/{branch}',
|
||||
|
@ -137,9 +131,6 @@ angular.module('quay').factory('TriggerService', ['UtilService', '$sanitize', 'K
|
|||
'credentials': '/static/directives/trigger/githost/credentials.html',
|
||||
'trigger-description': '/static/directives/trigger/gitlab/trigger-description.html'
|
||||
},
|
||||
'repository_url': function(build) {
|
||||
return 'https://bitbucket.org/' + build.trigger.build_source;
|
||||
},
|
||||
'link_templates': {
|
||||
'commit': '/commit/{sha}',
|
||||
'branch': '/tree/{branch}',
|
||||
|
@ -191,8 +182,8 @@ angular.module('quay').factory('TriggerService', ['UtilService', '$sanitize', 'K
|
|||
return null;
|
||||
}
|
||||
|
||||
var repositoryUrl = type.repository_url;
|
||||
if (!repositoryUrl || !repositoryUrl(build)) {
|
||||
var repositoryUrl = build.trigger.repository_url;
|
||||
if (!repositoryUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -201,7 +192,7 @@ angular.module('quay').factory('TriggerService', ['UtilService', '$sanitize', 'K
|
|||
return null;
|
||||
}
|
||||
|
||||
return repositoryUrl(build) + linkTemplate[templateName];
|
||||
return repositoryUrl + linkTemplate[templateName];
|
||||
};
|
||||
|
||||
triggerService.supportsFullListing = function(name) {
|
||||
|
|
|
@ -2478,8 +2478,8 @@ class FakeBuildTrigger(BuildTriggerHandler):
|
|||
prepared.is_manual = True
|
||||
return prepared
|
||||
|
||||
def dockerfile_url(self):
|
||||
return 'http://some/url'
|
||||
def get_repository_url(self):
|
||||
return 'http://foo/' + self.config['build_source']
|
||||
|
||||
def load_dockerfile_contents(self):
|
||||
if not 'dockerfile' in self.config:
|
||||
|
|
|
@ -78,6 +78,9 @@ class GithubOAuthConfig(OAuthConfig):
|
|||
|
||||
return [org.lower() for org in allowed]
|
||||
|
||||
def get_public_url(self, suffix):
|
||||
return '%s%s' % (self._endpoint(), suffix)
|
||||
|
||||
def _endpoint(self):
|
||||
endpoint = self.config.get('GITHUB_ENDPOINT', 'https://github.com')
|
||||
if not endpoint.endswith('/'):
|
||||
|
|
Reference in a new issue