From 442324659c03ecab789d5216ffebafba37b334c5 Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Wed, 23 Apr 2025 08:43:34 +0200 Subject: [PATCH] Add branches and tags creation endpoints --- api_server/blueprints/gitapi.py | 140 ++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/api_server/blueprints/gitapi.py b/api_server/blueprints/gitapi.py index 3383a53..888781a 100755 --- a/api_server/blueprints/gitapi.py +++ b/api_server/blueprints/gitapi.py @@ -533,6 +533,146 @@ class GitRepoBranchesDeleter(Resource): log.info("Branch %s of repository %s deleted", branch, repo, extra = {"repository" : repo, "branch" : branch}) return {"status": "deleted"}, 200 + def post(self, repo, branch): + """Create a given branch in a given repository + + Args: + repo (str): The name of the repository. + + Returns: + Response: A JSON response containing a list of branch names or an error message if the repository is not found. + - 200: A JSON object with a "status" key containing "deleted" + - 404: A JSON object with an "error" key containing the message "Repository not found" or "Branch not found" + - 409: A JSON object with an "error" key containing the message "Branch already exists" + """ + + repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git") + if not os.path.isdir(repo_path): + log.error("Can't get branches of repository repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path }) + return {"error": "Repository not found"}, 404 + + git_repo = git.Repo(repo_path) + git_repo.git.config('--global', '--add', 'safe.directory', repo_path) + + data = request.json + if data is None: + log.error("Can't create branch, JSON post data missing") + return {"error" : "Parameters missing"}, 400 + + if not "commit" in data: + log.error("Can't create branch, commit parameter missing") + return {"error" : "commit parameter missing"}, 400 + + + if branch in git_repo.branches: + log.error("Can't create branch %s, already found in repository %s", branch, repo, extra = {"repository" : repo, "branch" : branch}) + return {"error": "Branch already exists"}, 409 + + git_repo.create_head(branch, commit = data["commit"] ) + log.info("Branch %s of repository %s created", branch, repo, extra = {"repository" : repo, "branch" : branch}) + return {"status": "created"}, 200 + +@git_ns.route('/repositories//tags') +class GitRepoTags(Resource): + def get(self, repo): + """ + Retrieve the list of tags for a given repository. + + Args: + repo (str): The name of the repository. + + Returns: + Response: A JSON response containing a list of tags names or an error message if the repository is not found. + - 200: A JSON object with a "tags" key containing a list of tags names. + - 404: A JSON object with an "error" key containing the message "Repository not found" if the repository does not exist. + """ + repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git") + if not os.path.isdir(repo_path): + log.error("Can't get tags of repository repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path }) + return {"error": "Repository not found"}, 404 + + git_repo = git.Repo(repo_path) + git_repo.git.config('--global', '--add', 'safe.directory', repo_path) + + + tags = [] + for tag in git_repo.tags: + tags = tags + [tag.name] + + log.info("Returning %i tags", len(tags)) + return { + "tags": tags + } + +@git_ns.route('/repositories//tags/') +class GitRepoTagsDeleter(Resource): + def delete(self, repo, tag): + """Delete a given tag in a given repository + + Args: + repo (str): The name of the repository. + + Returns: + Response: A JSON response containing a list of tag names or an error message if the repository is not found. + - 200: A JSON object with a "status" key containing "deleted" + - 404: A JSON object with an "error" key containing the message "Repository not found" or "Tag not found" + """ + + repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git") + if not os.path.isdir(repo_path): + log.error("Can't get tags of repository repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path }) + return {"error": "Repository not found"}, 404 + + git_repo = git.Repo(repo_path) + git_repo.git.config('--global', '--add', 'safe.directory', repo_path) + + + if not tag in git_repo.tags: + log.error("Can't delete tag %s, not found in repository %s", tag, repo, extra = {"repository" : repo, "tag" : tag}) + return {"error": "Tag not found"}, 404 + + git_repo.delete_head(tag) + log.info("Tag %s of repository %s deleted", tag, repo, extra = {"repository" : repo, "tag" : tag}) + return {"status": "deleted"}, 200 + + def post(self, repo, tag): + """Create a given tag in a given repository + + Args: + repo (str): The name of the repository. + + Returns: + Response: A JSON response containing a creation status + - 200: A JSON object with a "status" key containing "created" + - 404: A JSON object with an "error" key containing the message "Repository not found" + - 409: A JSON object with an "error" key containing the message "Tag already exists" + """ + + repo_path = os.path.join(REPOSITORIES_BASE_PATH, repo + ".git") + if not os.path.isdir(repo_path): + log.error("Can't get tags of repository repository %s, not found. Looked in %s", repo, repo_path, extra = {"repository" : repo, "path" : repo_path }) + return {"error": "Repository not found"}, 404 + + git_repo = git.Repo(repo_path) + git_repo.git.config('--global', '--add', 'safe.directory', repo_path) + + data = request.json + if data is None: + log.error("Can't create tag, JSON post data missing") + return {"error" : "Parameters missing"}, 400 + + if not "commit" in data: + log.error("Can't create tag, commit parameter missing") + return {"error" : "commit parameter missing"}, 400 + + + if tag in git_repo.tags: + log.error("Can't create tag %s, already found in repository %s", tag, repo, extra = {"repository" : repo, "tag" : tag}) + return {"error": "Tag already exists"}, 409 + git_repo.create_tag(tag, ref = data["commit"]) + + log.info("Tag %s of repository %s created", tag, repo, extra = {"repository" : repo, "tag" : tag}) + return {"status": "created"}, 200 @git_ns.route('/health') class GitHealth(Resource):