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?
Supposing you have the following configuration with project project-template-1
in subgroup sub-group-project-templates
:
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 :
sub-group-projects
main-group/sub-group-project-templates/project-template-1
to namespace with id $namespace_id
& get the project id of the created project$project_id
from project-template-1
to : johndoe_project-template-1
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 curl & jq :
#!/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
)