Update gitea project creation to only use the REST API
Setting gitea project settings like wiki and issue tracker settings was previously done via hijacking web ui requests. We now have a REST API that is capable of setting things items. Using this API should be more reliable as the API is versioned. Update the gitea project creation code to use this API for more stability. As a nice side effect the code is simplified quite a bit as we can combine a few actions that were previously separate like updating descriptions and default branches. As a side note this fixes a bug where we hardcoded setting master as the default branch despite making that configurable. Change-Id: I101dd8f81a2cb91655f6de878bc94350aeb1fc0c
This commit is contained in:
parent
8a85c1dce1
commit
004cf7645a
@ -117,11 +117,7 @@ class Gitea(object):
|
||||
return [x['full_name'] for x in
|
||||
self.get_paginated('/api/v1/orgs/{org}/repos'.format(org=org))]
|
||||
|
||||
def get_csrf_token(self):
|
||||
resp = self.get('/')
|
||||
return urllib.parse.unquote(self.session.cookies.get('_csrf'))
|
||||
|
||||
def make_gitea_project(self, project, csrf_token):
|
||||
def make_gitea_project(self, project):
|
||||
org, repo = project['project'].split('/', 1)
|
||||
repo_properties = {
|
||||
'auto_init': True,
|
||||
@ -142,8 +138,18 @@ class Gitea(object):
|
||||
json=repo_properties)
|
||||
self.log("Created repo:", project['project'])
|
||||
|
||||
def update_gitea_project_settings(self, project, csrf_token):
|
||||
def update_gitea_project_settings(self, project):
|
||||
org, repo = project['project'].split('/', 1)
|
||||
|
||||
settings = {}
|
||||
settings['default_branch'] = project.get('default-branch', 'master')
|
||||
description = project.get('description', '')[:255]
|
||||
if description:
|
||||
settings['description'] = description
|
||||
settings['has_pull_requests'] = False
|
||||
settings['has_projects'] = False
|
||||
settings['has_wiki'] = False
|
||||
settings['external_wiki'] = {'external_wiki_url': ''}
|
||||
if project.get('use-storyboard'):
|
||||
external_tracker_url = SB_REPO.format(org=org, repo=repo)
|
||||
tracker_url_format = SB_FORMAT
|
||||
@ -153,78 +159,25 @@ class Gitea(object):
|
||||
else:
|
||||
external_tracker_url = LP_REPO.format(repo=repo)
|
||||
tracker_url_format = LP_FORMAT.format(repo=repo)
|
||||
# We enable issues so that the external tracker works
|
||||
settings['has_issues'] = True
|
||||
settings['external_tracker'] = {
|
||||
'external_tracker_url': external_tracker_url,
|
||||
'external_tracker_format': tracker_url_format,
|
||||
'external_tracker_style': 'numeric',
|
||||
}
|
||||
for count in range(0, 5):
|
||||
try:
|
||||
self.post(
|
||||
'/{org}/{repo}/settings'.format(org=org, repo=repo),
|
||||
data=dict(
|
||||
_csrf=csrf_token,
|
||||
action='advanced',
|
||||
# enable_pulls is not provided, which disables it
|
||||
# enable_wiki is not provided, which disables it
|
||||
enable_external_wiki=False,
|
||||
external_wiki_url='',
|
||||
# enable_issues is on so that issue links work
|
||||
enable_issues='on',
|
||||
enable_external_tracker=True,
|
||||
external_tracker_url=external_tracker_url,
|
||||
tracker_url_format=tracker_url_format,
|
||||
tracker_issue_style='numeric',
|
||||
),
|
||||
allow_redirects=False)
|
||||
# Set allow_redirects to false because gitea returns
|
||||
# with a 302 on success, and we don't need to follow
|
||||
# that.
|
||||
self.log("Updated tracker url:", external_tracker_url)
|
||||
return
|
||||
except requests.exceptions.HTTPError as e:
|
||||
time.sleep(3)
|
||||
raise Exception("Could not update tracker url")
|
||||
|
||||
def update_gitea_project_branches(self, project, csrf_token):
|
||||
org, repo = project['project'].split('/', 1)
|
||||
for count in range(0, 5):
|
||||
try:
|
||||
self.post(
|
||||
'/{org}/{repo}/settings/branches'.format(
|
||||
org=org, repo=repo),
|
||||
data=dict(
|
||||
_csrf=csrf_token,
|
||||
action='default_branch',
|
||||
branch='master',
|
||||
),
|
||||
allow_redirects=False)
|
||||
# Set allow_redirects to false because gitea returns
|
||||
# with a 302 on success, and we don't need to follow
|
||||
# that.
|
||||
self.log("Set master branch:", project['project'])
|
||||
return
|
||||
except requests.exceptions.HTTPError as e:
|
||||
time.sleep(3)
|
||||
raise Exception("Could not update branch settings")
|
||||
|
||||
def update_gitea_project_description(self, project, csrf_token):
|
||||
org, repo = project['project'].split('/', 1)
|
||||
description = project.get('description', '')[:255]
|
||||
if description:
|
||||
description_update = {
|
||||
'description': description,
|
||||
}
|
||||
try:
|
||||
resp = self.patch(
|
||||
self.patch(
|
||||
'/api/v1/repos/{org}/{repo}'.format(org=org, repo=repo),
|
||||
json=description_update)
|
||||
# Commented out as there is no good way to log only those
|
||||
# projects which have an updated description and as a result
|
||||
# this is noisy.
|
||||
#self.log("Set description for:", project['project'])
|
||||
except Exception as e:
|
||||
# Updating descriptions is best effort as we may fail due to
|
||||
# gitea bugs, but such a failure isn't critical.
|
||||
self.log("Failed to set desciption for:",
|
||||
project['project'], str(e))
|
||||
json=settings)
|
||||
self.log("Updated settings:", project['project'])
|
||||
return
|
||||
except requests.exceptions.HTTPError as e:
|
||||
time.sleep(3)
|
||||
raise Exception("Could not update settings")
|
||||
|
||||
def make_projects(self, projects, gitea_repos, csrf_token,
|
||||
def make_projects(self, projects, gitea_repos,
|
||||
settings_thread_pool, branches_thread_pool, futures):
|
||||
for project in projects:
|
||||
create = False
|
||||
@ -242,20 +195,11 @@ class Gitea(object):
|
||||
if create:
|
||||
# TODO: use threadpool when we're running with
|
||||
# https://github.com/go-gitea/gitea/pull/7493
|
||||
self.make_gitea_project(project, csrf_token)
|
||||
self.make_gitea_project(project)
|
||||
if create or self.always_update:
|
||||
futures.append(settings_thread_pool.submit(
|
||||
self.update_gitea_project_settings,
|
||||
project, csrf_token))
|
||||
futures.append(branches_thread_pool.submit(
|
||||
self.update_gitea_project_branches,
|
||||
project, csrf_token))
|
||||
if self.always_update:
|
||||
# If we are not creating, but are trying to always update
|
||||
# then we update the project description.
|
||||
futures.append(settings_thread_pool.submit(
|
||||
self.update_gitea_project_description,
|
||||
project, csrf_token))
|
||||
project))
|
||||
|
||||
def run(self):
|
||||
futures = []
|
||||
@ -266,7 +210,6 @@ class Gitea(object):
|
||||
self.make_gitea_org(org)
|
||||
self.ensure_gitea_teams(org)
|
||||
gitea_repos.extend(self.get_org_repo_list(org))
|
||||
csrf_token = self.get_csrf_token()
|
||||
|
||||
# We can create repos in parallel, as long as all the repos
|
||||
# for the same org are in series (due to database contention,
|
||||
@ -291,7 +234,7 @@ class Gitea(object):
|
||||
for task_list in org_task_lists:
|
||||
while task_list:
|
||||
project = task_list.pop(0)
|
||||
self.make_projects([project], gitea_repos, csrf_token,
|
||||
self.make_projects([project], gitea_repos,
|
||||
settings_thread_pool, branches_thread_pool,
|
||||
futures)
|
||||
if len(futures) > 1:
|
||||
@ -310,7 +253,7 @@ class Gitea(object):
|
||||
for projects in sorted_task_lists:
|
||||
futures.append(org_thread_pool.submit(
|
||||
self.make_projects,
|
||||
projects, gitea_repos, csrf_token, settings_thread_pool,
|
||||
projects, gitea_repos, settings_thread_pool,
|
||||
branches_thread_pool, futures))
|
||||
self.wait_for_futures(futures)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user