Commit 0a3e0ac8 authored by Tom Pillot's avatar Tom Pillot
Browse files

Sync github to gitlab working

parent 3492c7d3
......@@ -28,6 +28,26 @@ def check_suite(request: HttpRequest, rep: str) -> HttpResponse:
return HttpResponse(rep)
def push_to_gitlab(project: Project, namespace: Namespace, commit: str, branch: str, force: bool):
"""Push project repo to Gitlab on given branch."""
git_repo = project.git()
# Update branch to the latest commit
if branch in git_repo.branches:
git_repo.heads[branch].commit = commit
else:
git_repo.create_head(branch, commit=commit)
# Create a gitlab remote if it doesn't exist
gl_remote_name = f'gitlab/{namespace.slug}'
if gl_remote_name not in git_repo.remotes:
git_repo.create_remote(gl_remote_name, url=project.remote_url_gitlab())
# Push the changes to gitlab
print(f'Pushing {commit} on {branch} on gitlab')
git_repo.git.push(gl_remote_name, branch, force=force)
def pull_request(request: HttpRequest, rep: str) -> HttpResponse:
"""Manage Github's Pull Requests."""
data = loads(request.body.decode())
......@@ -60,20 +80,11 @@ def pull_request(request: HttpRequest, rep: str) -> HttpResponse:
remote.fetch()
commit = data['pull_request']['head']['sha']
if branch in git_repo.branches:
git_repo.heads[branch] = commit
else:
git_repo.create_head(branch, commit=commit)
print(f'pushing {commit} on {branch} on gitlab')
gl_remote_name = f'gitlab/{namespace.slug}'
# gl_remote = git_repo.remotes[f'gitlab/{namespace.slug}']
# gl_remote.push(branch)
try:
git_repo.push(gl_remote_name, branch)
push_to_gitlab(project, namespace, commit, branch, force=False)
except git.exc.GitCommandError:
print('Push failed, trying to force push')
git_repo.push(gl_remote_name, branch, force=True)
print(f'Failed to push on {branch}, trying to force push.')
push_to_gitlab(project, namespace, commit, branch, force=True)
# The pull request was closed, delete the branch pr/XX on Gitlab
elif event == 'closed':
......@@ -93,49 +104,38 @@ def push(request: HttpRequest, rep: str) -> HttpResponse:
namespace = get_object_or_404(Namespace, slug='tpillot')
project = get_object_or_404(Project, main_namespace=namespace, slug=slugify(data['repository']['name']))
branch = data['ref'][11:] # strip 'refs/heads/'
commit = data['after']
gh_remote_name = f'github/{namespace.slug}'
gl_remote_name = f'gitlab/{namespace.slug}'
git_repo = project.git()
print(f'Push detected on github: {branch}')
# TODO: hard reset if necessary ?
# Fetch the changes from github
if gh_remote_name in git_repo.remotes:
gh_remote = git_repo.remote(gh_remote_name)
else:
gh_remote = git_repo.create_remote(gh_remote_name, url=project.url_github())
gh_remote = git_repo.create_remote(gh_remote_name, url=project.remote_url_github())
gh_remote.fetch()
# The branch was deleted, delete the branch on Gitlab
if data['after'] == "0000000000000000000000000000000000000000":
if commit == "0000000000000000000000000000000000000000":
print("Branch deleted")
if branch in git_repo.branches:
git_repo.delete_head(branch, force=True)
project.gitlab().branches.delete(branch)
return HttpResponse(rep)
# Make sure we fetched the latest commit
gh_ref = gh_remote.refs[branch]
if str(gh_ref.commit) != data['after']:
fail = f'Push: wrong commit: {gh_ref.commit} vs {data["after"]}'
if str(gh_ref.commit) != commit:
fail = f'Push: wrong commit: {gh_ref.commit} vs {commit}'
print(fail)
return HttpResponseBadRequest(fail)
# Update branch to the last commit
if branch in git_repo.branches:
git_repo.branches[branch].commit = data['after']
if data['forced']:
print('Force push detected, sync canceled.')
# TODO: Send mail to admins
else:
git_repo.create_head(branch, commit=data['after'])
if gl_remote_name in git_repo.remotes:
gl_remote = git_repo.remote(gl_remote_name)
else:
gl_remote = git_repo.create_remote(gl_remote_name, url=project.url_gitlab())
# Push the changes to gitlab
# TODO: Force push
gl_remote.fetch()
if branch not in gl_remote.refs or str(gl_remote.refs[branch].commit) != data['after']:
print(f'pushing {data["after"]} on {branch} on gitlab')
gl_remote.push(branch)
push_to_gitlab(project, namespace, commit, branch, force=False)
return HttpResponse(rep)
......@@ -157,9 +157,8 @@ def pipeline(request: HttpRequest, rep: str) -> HttpResponse:
gh_status = gl_status if gl_status != 'failed' else 'failure'
if branch.startswith('pr/'):
pr_number = int(branch[3:])
pr_commit_sha = gh_repo.get_pull(pr_number).head.sha
gh_repo.get_commit(sha=pr_commit_sha).create_status(state=gh_status, target_url=ci_web_url,
context='gitlab-ci')
gh_repo.get_commit(sha=commit).create_status(state=gh_status, target_url=ci_web_url,
context='gitlab-ci')
else:
gh_commit = gh_repo.get_branch(branch).commit
gh_commit.create_status(state=gh_status, target_url=ci_web_url, context='gitlab-ci')
......
import json
import logging
import re
from subprocess import check_output
......@@ -8,7 +7,6 @@ import requests
from django.conf import settings
from django.db import models
from django.db.models import Q
from django.db.models.functions import Length
from django.db.utils import DataError
from django.template.loader import get_template
from django.utils import timezone
......@@ -216,13 +214,13 @@ class Project(Links, NamedModel, TimeStampedModel):
def github(self):
github_forge = Forge.objects.get(slug='github')
gh = Github(github_forge.token)
return gh.get_repo(f'{self.main_namespace.slug}/{self.slug}')
# return gh.get_repo(f'{self.main_namespace.slug}/{self.slug}')
return gh.get_repo(f'Ozon2/{self.slug}')
def gitlab(self):
gitlab_forge = Forge.objects.get(slug='gitlab')
gl = Gitlab(gitlab_forge.url, private_token=gitlab_forge.token)
gl_repo = gl.projects.get(f'{self.main_namespace.slug}/{self.slug}')
gl_repo.branches.get('master').unprotect() # Allow force pushing on master
return gl_repo
def main_repo(self):
......@@ -407,10 +405,18 @@ class Project(Links, NamedModel, TimeStampedModel):
def url_gitlab(self):
return f'https://gitlab.laas.fr/{self.main_namespace.slug}/{self.slug}'
def remote_url_gitlab(self):
gitlab_forge = Forge.objects.get(source=SOURCES.gitlab)
return self.url_gitlab().replace('://', f'://gitlab-ci-token:{gitlab_forge.token}@')
def url_github(self):
# return f'https://github.com/{self.main_namespace.slug}/{self.slug}'
return f'https://github.com/Ozon2/{self.slug}'
def remote_url_github(self):
github_forge = Forge.objects.get(source=SOURCES.github)
return self.url_github().replace('://', f'://{settings.GITHUB_USER}:{github_forge.token}@')
def badge(self, link, img, alt):
return mark_safe(f'<a href="{link}"><img src="{img}" alt="{alt}" /></a> ')
......
......@@ -13,8 +13,8 @@ class RainboardTests(TestCase):
self.assertEqual(test_count, 5)
def test_models(self):
self.assertEqual(models.License.objects.count(), 0)
self.assertEqual(models.Project.objects.count(), 0)
license_count = models.License.objects.count()
project_count = models.Project.objects.count()
models.License.objects.create(name='BSD 2-Clause "Simplified" License',
spdx_id='BSD-2-Clause',
url='http://spdx.org/licenses/BSD-2-Clause.json')
......@@ -22,8 +22,8 @@ class RainboardTests(TestCase):
main_namespace=models.Namespace.objects.get(slug='gepetto'),
main_forge=models.Forge.objects.get(source=utils.SOURCES.github),
license=models.License.objects.first())
self.assertEqual(models.License.objects.count(), 1)
self.assertEqual(models.Project.objects.count(), 1)
self.assertEqual(models.License.objects.count(), license_count+1)
self.assertEqual(models.Project.objects.count(), project_count+1)
project = models.Project.objects.first()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment