Dans mon référentiel GitLab, j'ai un groupe de 20 projets. Je veux cloner tous les projets à la fois. Est-ce possible?
Pas vraiment, à moins que:
vous avez un 21ème projet qui référence les 20 autres sous la forme submodules .
(auquel cas un clone suivi d'un git submodule update --init
suffirait pour cloner et extraire les 20 projets)
ou vous listez d'une manière ou d'une autre les projets auxquels vous avez accès ( API de GitLab pour les projets ), et effectuez une boucle sur ce résultat pour les cloner (ce qui signifie qu'ils peuvent être scriptés, puis exécutés en tant que commande "one")
Depuis 2015, Jay Gabez mentionne dans les commentaires (août 2019) l'outil gabrie30/ghorg
ghorg
vous permet de cloner rapidement toutes les organisations ou les utilisateurs dans un répertoire unique.
Usage:
$ ghorg clone someorg
$ ghorg clone someuser --clone-type=user --protocol=ssh --branch=develop
$ ghorg clone gitlab-org --scm=gitlab --namespace=gitlab-org/security-products
$ ghorg clone --help
Voici un exemple dans Python 3:
from urllib.request import urlopen
import json
import subprocess, shlex
allProjects = urlopen("http://[yourServer:port]/api/v4/projects?private_token=[yourPrivateTokenFromUserProfile]&per_page=100000")
allProjectsDict = json.loads(allProjects.read().decode())
for thisProject in allProjectsDict:
try:
thisProjectURL = thisProject['ssh_url_to_repo']
command = shlex.split('git clone %s' % thisProjectURL)
resultCode = subprocess.Popen(command)
except Exception as e:
print("Error on %s: %s" % (thisProjectURL, e.strerror))
Il existe un outil appelé myrepos , qui gère plusieurs référentiels de contrôles de version. La mise à jour de tous les référentiels nécessite simplement une commande:
mr update
Pour enregistrer tous les projets gitlab sur mr, voici un petit script python. Il nécessite le package python-gitlab installé:
import os
from subprocess import call
from gitlab import Gitlab
# Register a connection to a gitlab instance, using its URL and a user private token
gl = Gitlab('http://192.168.123.107', 'JVNSESs8EwWRx5yDxM5q')
groupsToSkip = ['aGroupYouDontWantToBeAdded']
gl.auth() # Connect to get the current user
gitBasePathRelative = "git/"
gitBasePathRelativeAbsolut = os.path.expanduser("~/" + gitBasePathRelative)
os.makedirs(gitBasePathRelativeAbsolut,exist_ok=True)
for p in gl.Project():
if not any(p.namespace.path in s for s in groupsToSkip):
pathToFolder = gitBasePathRelative + p.namespace.name + "/" + p.name
commandArray = ["mr", "config", pathToFolder, "checkout=git clone '" + p.ssh_url_to_repo + "' '" + p.name + "'"]
call(commandArray)
os.chdir(gitBasePathRelativeAbsolut)
call(["mr", "update"])
J'ai construit un script (curl, git, jq requis) juste pour ça. Nous l'utilisons et cela fonctionne très bien: https://Gist.github.com/JonasGroeger/1b5155e461036b557d0fb4b3307e1e75
Pour connaître votre espace de noms, il est préférable de vérifier l'API rapidement:
curl "https://domain.com/api/v3/projects?private_token=$GITLAB_PRIVATE_TOKEN"
Là, utilisez "namespace.name" comme NAMESPACE
pour votre groupe.
Le script fait essentiellement:
PROJECT_SEARCH_PARAM
Obtenez leurs path
et ssh_url_to_repo
2.1. Si le répertoire path
existe, insérez-le et appelez git pull
2.2. Si le répertoire path
n’existe pas, appelez git clone
Voici un autre exemple de script bash permettant de cloner toutes les mises en pension d'un groupe. La seule dépendance à installer est jq ( https://stedolan.github.io/jq/ ). Placez simplement le script dans le répertoire dans lequel vous souhaitez cloner vos projets. Puis lancez-le comme suit:
./myscript <group name> <private token> <gitlab url>
c'est à dire.
./myscript group1 abc123tyn234 http://yourserver.git.com
Scénario:
#!/bin/bash
if command -v jq >/dev/null 2>&1; then
echo "jq parser found";
else
echo "this script requires the 'jq' json parser (https://stedolan.github.io/jq/).";
exit 1;
fi
if [ -z "$1" ]
then
echo "a group name arg is required"
exit 1;
fi
if [ -z "$2" ]
then
echo "an auth token arg is required. See $3/profile/account"
exit 1;
fi
if [ -z "$3" ]
then
echo "a gitlab URL is required."
exit 1;
fi
TOKEN="$2";
URL="$3/api/v3"
PREFIX="ssh_url_to_repo";
echo "Cloning all git projects in group $1";
GROUP_ID=$(curl --header "PRIVATE-TOKEN: $TOKEN" $URL/groups?search=$1 | jq '.[].id')
echo "group id was $GROUP_ID";
curl --header "PRIVATE-TOKEN: $TOKEN" $URL/groups/$GROUP_ID/projects?per_page=100 | jq --arg p "$PREFIX" '.[] | .[$p]' | xargs -L1 git clone
Si vous êtes d'accord avec certains Sorecery Shell, cela va cloner toutes les pensions groupées par leur identifiant de groupe (vous avez besoin de jq et de parallèle)
seq 3 \
| parallel curl -s "'https://[gitlabUrl]/api/v4/projects?page={}&per_page=100&private_token=[privateToken]'
| jq '.[] | .ssh_url_to_repo, .name, .namespace.path'" \
| tr -d '"' \
| awk '{ printf "%s ", $0; if (NR % 3 == 0) print " " }' \
| parallel --colsep ' ' 'mkdir -p {2} && git clone {1} {3}/{2}'
Un script mis à jour Python 3) accomplit cette tâche de manière vraiment efficace en utilisant la dernière API et la pagination appropriée de Gitlab:
import requests
import subprocess, shlex
import os
print('Starting getrepos process..')
key = '12345678901234567890' # your gitlab key
base_url = 'https://your.gitlab.url/api/v4/projects?simple=true&per_page=10&private_token='
url = base_url + key
base_dir = os.getcwd()
while True:
print('\n\nRetrieving from ' + url)
response = requests.get(url, verify = False)
projects = response.json()
for project in projects:
project_name = project['name']
project_path = project['namespace']['full_path']
project_url = project['ssh_url_to_repo']
os.chdir(base_dir)
print('\nProcessing %s...' % project_name)
try:
print('Moving into directory: %s' % project_path)
os.makedirs(project_path, exist_ok = True)
os.chdir(project_path)
cmd = shlex.split('git clone --mirror %s' % project_url)
subprocess.run(cmd)
except Exception as e:
print('Error: ' + e.strerror)
if 'next' not in response.links:
break
url = response.links['next']['url'].replace('127.0.0.1:9999', 'your.gitlab.url')
print('\nDone')
Nécessite la bibliothèque request (pour naviguer vers les liens de page).
Une doublure avec boucle, jq, tr
for repo in $(curl "https://<your-Host>/api/v4/groups/<group_id>?private_token=<your_private_token>" | jq .projects[].ssh_url_to_repo | tr -d '"'); do git clone $repo; done;```
Vous pouvez vous référer à ce Ruby ici: https://Gist.github.com/thegauraw/da2a3429f19f603cf1c9b3b09553728b)
Mais vous devez vous assurer que vous avez le lien vers l'URL de l'organisation gitlab (qui ressemble à: https://gitlab.example.com/api/v3/ par exemple organisation) et le jeton privé ( qui ressemble à: QALWKQFAGZDWQYDGHADS et vous pouvez entrer dans: https://gitlab.example.com/profile/account une fois que vous êtes connecté). Assurez-vous également que vous avez installé httparty gem ou gem install httparty
Oui c'est possible, voici le code.
pip installer python-gitlab
#!/usr/bin/python3
import os
import sys
import gitlab
import subprocess
glab = gitlab.Gitlab(f'https://{sys.argv[1]}', f'{sys.argv[3]}')
groups = glab.groups.list()
groupname = sys.argv[2]
for group in groups:
if group.name == groupname:
projects = group.projects.list(all=True)
for repo in projects:
command = f'git clone {repo.ssh_url_to_repo}'
process = subprocess.Popen(command, stdout=subprocess.PIPE, Shell=True)
output, _ = process.communicate()
process.wait()
Une autre façon de le faire avec Windows "Git Bash" qui a des paquets limités installés:
#!/bin/bash
curl -o projects.json https://<GitLabUrl>/api/v4/projects?private_token=<YourToken>
i=0
while : ; do
echo "/$i/namespace/full_path" > jsonpointer
path=$(jsonpointer -f jsonpointer projects.json 2>/dev/null | tr -d '"')
[ -z "$path" ] && break
echo $path
if [ "${path%%/*}" == "<YourProject>" ]; then
[ ! -d "${path#*/}" ] && mkdir -p "${path#*/}"
echo "/$i/ssh_url_to_repo" > jsonpointer
url=$(jsonpointer -f jsonpointer projects.json 2>/dev/null | tr -d '"')
( cd "${path#*/}" ; git clone --mirror "$url" )
fi
let i+=1
done
rm -f projects.json jsonpointer
Une alternative basée sur la réponse de Dmitriy - dans le cas où vous deviez cloner des référentiels dans une arborescence de groupe entier de manière récursive.
#!/usr/bin/python3
import os
import sys
import gitlab
import subprocess
glab = gitlab.Gitlab(f'https://{sys.argv[1]}', f'{sys.argv[3]}')
groups = glab.groups.list()
root = sys.argv[2]
def visit(group):
name = group.name
real_group = glab.groups.get(group.id)
os.mkdir(name)
os.chdir(name)
clone(real_group.projects.list(all=True))
for child in real_group.subgroups.list():
visit(child)
os.chdir("../")
def clone(projects):
for repo in projects:
command = f'git clone {repo.ssh_url_to_repo}'
process = subprocess.Popen(command, stdout=subprocess.PIPE, Shell=True)
output, _ = process.communicate()
process.wait()
glab = gitlab.Gitlab(f'https://{sys.argv[1]}', f'{sys.argv[3]}')
groups = glab.groups.list()
root = sys.argv[2]
for group in groups:
if group.name == root:
visit(group)