2

For the possibility that there is a better approach that I'm thinking about I would like to explain my requirement first (the question starts after the divider line).

Given I have the following GitLab group structure:

- main-group
  - sub-group-project-templates
    - project-template-1
  - sub-group-projects

In main-group/sub-group-project-templates there are multiple projects that function as starter project for a task. If there is someone who wants to do such a task I want to have a fork of the corresponding project template (e.g. project-template-1) in the group sub-group-projects with the name of the person as project name.

Given the name of the person is John Doe who wants to start the task of project-template-1 there should be a new project main-group/sub-group-projects/john_doe_project-template-1.

John Doe should only be able to see (read / write) the repository john_doe_project-template-1 and NOT the rest of the project (other forks, ...).


My solution would be to fork the template project to the sub group and then add a new contributor.

But I already fail at the first step (forking the project into the sub group with a new name).

My first shot at it was looking at:

POST http://gitlab.com/api/v4/projects/project_id/fork

But I don't know how to define the target directory and set the name of the new fork. The following isn't working:

POST http://gitlab.com/api/v4/projects/project_id/fork?namespace=main-group%2Fsub-group-projects%2Fjohn_doe_project-template-1

"message": "404 Target Namespace Not Found"

Is something like this even possible or how can I achieve this?

Spenhouet
  • 6,556
  • 12
  • 51
  • 76

1 Answers1

1

Supposing you have the following configuration with project project-template-1 in subgroup sub-group-project-templates :

enter image description here

It can be done in multiple API requests but there are some work-in-progress for the following features:

But these 2 issues have workarounds eg just perform an additionnal request to get the namespace id (1) and perform an edit project request (2) after forking

The steps are the following :

  • get namespace id for the subgroup sub-group-projects
  • fork project main-group/sub-group-project-templates/project-template-1 to namespace with id $namespace_id & get the project id of the created project
  • rename project with id $project_id from project-template-1 to : johndoe_project-template-1
  • get user id for user johndoe
  • add project member for project johndoe_project-template-1 : add user with id $user_id

Note that to add a member, you need the user id which I assume you want to search in the 4th step but you may not need this step if you already have it

Here is a bash script performing all these step, it uses & :

#!/bin/bash
set -e

gitlab_host=gitlab.your.host
access_token=YOUR_ACCESS_TOKEN

username=johndoe
project=project-template-1
user_access=30

group=main-group
namespace_src=sub-group-project-templates
namespace_dest=sub-group-projects
new_project_name=${username}_${project}

project_src=$group/$namespace_src/$project

encoded_project=$(echo $project_src | sed 's/\//%2F/g')

echo "1 - get namespace id for $namespace_dest"
#https://docs.gitlab.com/ce/api/namespaces.html
namespace_id=$(curl -s "https://$gitlab_host/api/v4/namespaces?search=$namespace_dest" \
    -H "Private-Token: $access_token" | jq -r '.[0].id')


echo "2 - fork project $project_src to namespace with id $namespace_id"
#https://docs.gitlab.com/ce/api/projects.html#fork-project
project_id=$(curl -s -X POST "https://$gitlab_host/api/v4/projects/$encoded_project/fork?namespace=$namespace_id" \
    -H "Private-Token: $access_token" | jq '.id')

if [ -z $project_id ]; then
    echo "fork failed"
    exit 1
fi

echo "3 - rename project with id $project_id from $project to : $new_project_name"
#https://docs.gitlab.com/ce/api/projects.html#edit-project
curl -s -X PUT "https://$gitlab_host/api/v4/projects/$project_id" \
    -H "Content-Type: application/json" \
    -d "{\"path\": \"$new_project_name\",\"name\": \"$new_project_name\" }" \
    -H "Private-Token: $access_token" > /dev/null

echo "4 - get user id for : $username"
#https://docs.gitlab.com/ce/api/users.html
user_id=$(curl -s "https://$gitlab_host/api/v4/users?username=johndoe" \
    -H "Private-Token: $access_token" | \
    jq -r '.[] | select(.name == "johndoe") | .id')

echo "5 - edit project member : add user with id $user_id"
#https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project
curl -s "https://$gitlab_host/api/v4/projects/$project_id/members" \
    -H "Private-Token: $access_token" \
    -d "user_id=$user_id&access_level=$user_access" > /dev/null

In the 2nd step (fork project), project source namespace is URL encoded so you may want to use a proper manner to encode it (in this case we only have to replace / with %2F)

Bertrand Martel
  • 42,756
  • 16
  • 135
  • 159