Skip to content

Instantly share code, notes, and snippets.

@ohartwig
Created May 25, 2024 09:01
Show Gist options
  • Select an option

  • Save ohartwig/108390c11e12b100675b2c100f6ccb3e to your computer and use it in GitHub Desktop.

Select an option

Save ohartwig/108390c11e12b100675b2c100f6ccb3e to your computer and use it in GitHub Desktop.
Pull alle you Repos from GitLab and build folder structure by groups and subgroups.
#!/bin/bash
# Pull alle you Repos from gitlab and build folder structure by groups and subgroups.
# Copyright (C) 2024 Moselwal Digitalagentur GmbH, Kai Ole Hartwig <support@moselwal.de>
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
# Configuration
# export GITLAB_URL="https://gitlab.com"
# export OP_TOKEN_PATH="op://your_vault_name/your_item_name/your_field_name"
#
# Usage
# group_id INT
# ./cur.sh <group_id>
# Configuration
GITLAB_URL="${GITLAB_URL}" # GITLAB URL from ENV
GROUP_ID="$1"
OP_TOKEN_PATH="${OP_TOKEN_PATH}" # 1Password Path from ENV
get_pat_from_1password() {
op read "$OP_TOKEN_PATH"
}
get_group_name() {
local group_id="$1"
local url="$GITLAB_URL/api/v4/groups/$group_id"
echo "Fetching group name from: $url" >&2
response=$(curl --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$url" 2>/dev/null)
#echo "Response from GitLab API (group name): $response" >&2
if echo "$response" | jq -e . >/dev/null 2>&1; then
group_name=$(echo "$response" | jq -r '.full_path')
if [ "$group_name" != "null" ]; then
echo "Parsed group name: $group_name" >&2
echo "$group_name"
else
echo "Error: Group name not found in response" >&2
exit 1
fi
else
echo "Error: Invalid JSON response" >&2
exit 1
fi
}
get_repos() {
local group_id="$1"
local url="$GITLAB_URL/api/v4/groups/$group_id/projects?per_page=100"
echo "Fetching repos from: $url" >&2
repos=$(curl --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$url" 2>/dev/null)
#echo "Repos response: $repos" >&2
if echo "$repos" | jq -e . >/dev/null 2>&1; then
echo "$repos"
else
echo "Error: Invalid JSON response" >&2
exit 1
fi
}
get_subgroups() {
local group_id="$1"
local url="$GITLAB_URL/api/v4/groups/$group_id/subgroups?per_page=100"
echo "Fetching subgroups from: $url" >&2
subgroups=$(curl --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$url" 2>/dev/null)
echo "Subgroups response: $subgroups" >&2
if echo "$subgroups" | jq -e . >/dev/null 2>&1; then
echo "$subgroups"
else
echo "Error: Invalid JSON response" >&2
exit 1
fi
}
process_repo() {
local repo_url="$1"
local repo_path="$2"
echo "Processing repo: $repo_url -> $repo_path"
if [ -d "$repo_path" ]; then
cd "$repo_path"
# Überprüfen, ob das Repo clean ist
if [ -n "$(git status --porcelain)" ]; then
echo "Repository $repo_path is not clean. Skipping pull operation."
cd - > /dev/null
return
fi
current_branch=$(git branch --show-current)
if [ "$current_branch" = "main" ]; then
git pull
else
git checkout main && git pull
fi
cd - > /dev/null
else
git clone "$repo_url" "$repo_path"
fi
}
process_group() {
local group_id="$1"
local base_path="$2"
mkdir -p "$base_path"
echo "Processing group: $group_id -> $base_path"
repos=$(get_repos "$group_id")
echo "Repositories JSON: $repos"
echo "$repos" | jq -r '.[] | "\(.http_url_to_repo) \(.path_with_namespace)"' | while read -r repo_url repo_path; do
repo_dir="$base_path/$(basename "$repo_path")"
echo "Repo URL: $repo_url, Repo Path: $repo_path, Repo Dir: $repo_dir"
process_repo "$repo_url" "$repo_dir"
done
subgroups=$(get_subgroups "$group_id")
echo "Subgroups JSON: $subgroups"
echo "$subgroups" | jq -r '.[] | "\(.id) \(.full_path)"' | while read -r subgroup_id subgroup_path; do
subgroup_dir="$base_path/$(basename "$subgroup_path")"
echo "Subgroup ID: $subgroup_id, Subgroup Path: $subgroup_path, Subgroup Dir: $subgroup_dir"
process_group "$subgroup_id" "$subgroup_dir"
done
}
main() {
if [ -z "$GROUP_ID" ]; then
echo "Usage: $0 <group_id>"
exit 1
fi
if [ -z "$OP_TOKEN_PATH" ]; then
echo "Error: OP_TOKEN_PATH environment variable is not set."
exit 1
fi
PRIVATE_TOKEN=$(get_pat_from_1password)
if [ -z "$PRIVATE_TOKEN" ]; then
echo "Error: Could not retrieve GitLab PAT from 1Password."
exit 1
fi
echo "Using PAT: $PRIVATE_TOKEN"
group_name=$(get_group_name "$GROUP_ID")
if [ -z "$group_name" ]; then
echo "Group not found: $GROUP_ID"
exit 1
fi
echo "Group name: $group_name"
process_group "$GROUP_ID" "$group_name"
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment