Created
May 25, 2024 09:01
-
-
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.
This file contains hidden or 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
| #!/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