Last active
February 20, 2023 00:03
-
-
Save paulmallon/57c046d2ed54974bc4a9c67b315ff0ce to your computer and use it in GitHub Desktop.
Powershell script for Gitlab REST API - A quick solution to clone selected (by id or name) or all repositories from the projects returned by API and setup git to track all remote branches. References: Gitlab Projects API: https://docs.gitlab.com/ee/api/projects.html Git doc: https://docs.gitlab.com/ee/api/projects.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Gitlab clone script | |
# | |
# Author: PM | |
# Date: 2019-10-18# | |
# | |
[CmdletBinding(DefaultParameterSetName = 'all')] | |
param ( | |
[Alias('ID')] | |
[Parameter(ParameterSetName="id")] | |
[int]$ProjectID = -1, | |
[Alias('name')] | |
[Parameter(ParameterSetName="search")] | |
[string]$projectName = $null, | |
[Parameter(ParameterSetName="all")] | |
[switch]$all, | |
[Switch]$force, | |
[string]$basePath = "c:\gitlab", | |
[string]$token= "secret-token", | |
[string]$apiUrl = "https://git.server.url/api/v4/projects" | |
) | |
# Begin script | |
$ErrorActionPreference = "Stop" | |
# Accept older TLS versions | |
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' | |
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols | |
# Get the ID and security principal of the current user account | |
# Check to see if we are currently running "as Administrator" | |
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent() | |
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID) | |
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator | |
if (-not $myWindowsPrincipal.IsInRole($adminRole)){ | |
Write-host "This script needs to be run As Admin"; | |
exit; | |
} | |
# Set API url from input arguments | |
if($all.IsPresent) { | |
$url = $apiUrl + "?per_page=500" | |
} elseif($ProjectID -ne -1) { | |
$url = $apiUrl+"/"+$ProjectID | |
}elseif( $projectName -ne $null) { | |
$url = $apiUrl + "?search=" +$projectName | |
} | |
# Call API | |
try { | |
write-host "Calling url '$url'" | |
$projects = (Invoke-WebRequest $url -Headers @{"Private-Token"=$token} ).content | ConvertFrom-Json | |
} | |
catch [System.Net.WebException] { | |
if($_.Exception.Response.StatusCode.value__ -eq 404) { | |
write-host "Project with id '$ProjectID' not found!" | |
} else { | |
write-host $_.Exception.Message | |
} | |
exit | |
} | |
# Verify result | |
if($projects -is [array] -and $projects.count -le 0) { | |
write-host "Search for '$projectName' returned no projects!" | |
exit; | |
} | |
# Process each project | |
$projects | ForEach-Object { | |
if($_.empty_repo -or $_.archived) { | |
Write-host "Skipping empty/archived repository '$name'" | |
return; | |
} | |
$name = $_.name | |
$namespace= $_.path_with_namespace.Replace('`\','/') | |
$url = $_.ssh_url_to_repo | |
$destination = join-path $basePath $namespace | |
if( (Test-Path $destination) ) { | |
if(-not $force.IsPresent) { | |
$yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', "Delete directory" | |
$no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', "Keep directory and skipp cloning" | |
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) | |
$result = $host.ui.PromptForChoice("Destination directory '$destination' already exists.", 'Would you like delete and continue with clone?', $options, 0) | |
if ($result -eq 0) { | |
Remove-Item $destination -Recurse -Force | out-null | |
} else { | |
write-host "Cloning of repository '$name' skipped.`n" | |
return; | |
} | |
} else { | |
Remove-Item $destination -Recurse -Force | out-null | |
} | |
} | |
write-host "Cloning '$name' into '$destination'...." -NoNewline | |
git clone $url $destination -q; | |
write-host "Done!" | |
$currentBranch = git -C $destination rev-parse --abbrev-ref HEAD | |
git -C $destination branch -r | ForEach-Object { | |
if( $_ -match "^\s*([a-zA-Z\/]*)$") { | |
$branch = $_.replace("origin/","").Trim(); | |
if($branch -ne $currentBranch) { | |
git -C $destination branch --track $branch origin/$branch | |
} else { | |
write-host "Branch '$currentBranch' set up to track remote branch '$branch' from 'origin'." | |
} | |
} | |
} | |
git -C $destination fetch --all -q | |
write-host "Current branch is $currentBranch`n" | |
} | |
#EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment