Skip to content
Snippets Groups Projects
Commit e593bd1b authored by Ronald Jäpel's avatar Ronald Jäpel
Browse files

Add GitLab API integration

parent 002cd7f0
No related branches found
No related tags found
No related merge requests found
......@@ -5,4 +5,5 @@ results
__pycache__
tests/test_repo*
.coverage
dist
\ No newline at end of file
dist
.token
\ No newline at end of file
import gitlab
def load_token():
"""
Read the API token from the .token file
:return:
"""
with open("../.token", "r") as file_handle:
token = file_handle.readline()
return token
def create_gitlab_remote(url, namespace, name):
token = load_token()
gl = gitlab.Gitlab(url, private_token=token)
namespace_id = gl.namespaces.list(get_all=True, search=namespace)[0].id
response = gl.projects.create({"name": name, "namespace_id": namespace_id})
return response
def delete_gitlab_remote(url, namespace, name):
token = load_token()
gl = gitlab.Gitlab(url, private_token=token)
potential_projects = gl.projects.list(get_all=True, search=[namespace, name])
for project in potential_projects:
if project.name != name:
pass
if project.namespace["name"] != namespace:
pass
gl.projects.delete(project.id)
......@@ -18,6 +18,7 @@ import pandas as pd
from cadetrdm.io_utils import recursive_chmod, write_lines_to_file, wait_for_user
from cadetrdm.jupyter_functionality import Notebook
from cadetrdm.remote_integration import create_gitlab_remote
from cadetrdm.version import version as cadetrdm_version
try:
......@@ -128,10 +129,24 @@ class BaseRepo:
with open(self.data_json_path, "r") as handle:
rdm_data = json.load(handle)
if rdm_data["is_project_repo"]:
pass
# This folder is a project repo. Use a project repo class to easily access the output repo.
output_repo = ProjectRepo(self.working_dir).output_repo
if output_repo.active_branch != "master":
if output_repo.exist_uncomitted_changes:
output_repo.stash_all_changes()
output_repo.checkout("master")
output_repo.add_list_of_remotes_in_readme_file("project_repo", self.remote_urls)
output_repo.commit("Add remote for project repo")
if rdm_data["is_output_repo"]:
# This folder is an output repo
project_repo = ProjectRepo(self.working_dir.parent)
project_repo.update_output_remotes_json()
project_repo.add_list_of_remotes_in_readme_file("output_repo", self.remote_urls)
project_repo.commit("Add remote for output repo")
def import_remote_repo(self, source_repo_location, source_repo_branch, target_repo_location=None):
"""
......@@ -634,6 +649,21 @@ class ProjectRepo(BaseRepo):
jupytext_lines = ['# Pair ipynb notebooks to py:percent text notebooks', 'formats: "ipynb,py:percent"']
write_lines_to_file(Path(path_root) / "jupytext.yml", lines=jupytext_lines, open_type="w")
def create_gitlab_remotes(self, url, namespace, name):
"""
Create project in gitlab and add the projects as remotes to the project and output repositories
:param url:
:param namespace:
:param name:
:return:
"""
response_project = create_gitlab_remote(url, namespace, name)
response_output = create_gitlab_remote(url, namespace, name + "_output")
self.add_remote(response_project.ssh_url_to_repo)
self.output_repo.add_remote(response_output.ssh_url_to_repo)
self.push(push_all=True)
def get_new_output_branch_name(self):
"""
Construct a name for the new branch in the output repository.
......
......@@ -18,3 +18,20 @@ initialize_repo(path_to_repo)
```
The `output_folder_name` can be given optionally. It defaults to `output`.
## Creating and adding remotes
You can create remotes for both the project and the output repository with one command, using the GitLab API.
Support for the GitHub API will be added in the future.
This requires you to have created a
[GitLab Personal Access Token (PAT)](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html)
and to store it in the `.token` file in the project's root. Then you can run:
```python
repo.create_gitlab_remotes(
url="e.g. https://jugit.fz-juelich.de/",
namespace="e.g. r.jaepel",
name="e.g. API_test_project"
)
```
......@@ -19,6 +19,7 @@ packages = find:
python_requires = >=3.8
install_requires =
gitpython>=3.1
python-gitlab
git-lfs
click
tabulate
......
from time import sleep
import git
import pytest
from cadetrdm import initialize_repo, ProjectRepo
from cadetrdm.io_utils import delete_path
from cadetrdm.remote_integration import delete_gitlab_remote, create_gitlab_remote
def test_gitlab_create():
url = "https://jugit.fz-juelich.de/"
namespace = "r.jaepel"
name = "API_test_project"
# ensure remote does not exist
delete_gitlab_remote(url=url, namespace=namespace, name=name)
try:
delete_path("test_repo_remote")
except FileNotFoundError:
pass
sleep(3)
response = create_gitlab_remote(url=url, namespace=namespace, name=name)
git.Repo.clone_from(response.ssh_url_to_repo, "test_repo_remote")
delete_path("test_repo_remote")
delete_gitlab_remote(url=url, namespace=namespace, name=name)
with pytest.raises(git.exc.GitCommandError):
git.Repo.clone_from(response.ssh_url_to_repo, "test_repo_remote")
def test_repo_gitlab_integration():
url = "https://jugit.fz-juelich.de/"
namespace = "r.jaepel"
name = "API_test_project"
repo_name = "test_repo_remote"
# Clean up
delete_gitlab_remote(url=url, namespace=namespace, name=name)
delete_gitlab_remote(url=url, namespace=namespace, name=name + "_output")
try:
delete_path("test_repo_remote")
except FileNotFoundError:
pass
initialize_repo(repo_name)
repo = ProjectRepo(repo_name)
repo.create_gitlab_remotes(url=url, namespace=namespace, name=name)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment