Skip to content

Instantly share code, notes, and snippets.

@mvanholsteijn
Created December 22, 2022 12:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mvanholsteijn/4ee1c43ec0fd3a5182770144bd7b7f9b to your computer and use it in GitHub Desktop.
Save mvanholsteijn/4ee1c43ec0fd3a5182770144bd7b7f9b to your computer and use it in GitHub Desktop.
bulk update of gitlab repositories. search desired repositories, checkout, update and push to origin as merge request
#!/bin/bash
CHECKOUT_DIR=/tmp/checkout
COMMIT_MESSAGE=
BRANCH_NAME=
UPDATE_SCRIPT=
SEARCH=
GROUP_NAME=
PUSH=no
find_all_projects() {
local match project_id project ssh_url_to_repo search group
group=$1 ; shift; search="$@"
glab api "groups/$group/search?scope=blobs&search=$search" | jq -c '.[]'| \
while read match; do
project_id=$(jq -r .project_id <<< "$match")
project=$(glab api projects/$project_id)
ssh_url_to_repo=$(jq -r .ssh_url_to_repo <<< "$project")
echo $ssh_url_to_repo
return
done
}
checkout() {
local url directory
url=$1
directory=$CHECKOUT_DIR/$(basename $url .git)
if [[ -d $directory ]] ; then
echo "ERROR: $directory already exists" >&2
exit 1
fi
git clone $url $directory
(cd $directory && git switch --create $BRANCH_NAME)
}
update() {
local url directory
url=$1
directory=$CHECKOUT_DIR/$(basename $url .git)
(
cd $directory
$UPDATE_SCRIPT
)
}
create_pull_request() {
local url directory
url=$1
directory=$CHECKOUT_DIR/$(basename $url .git)
(
cd $directory
if [[ -n $(git status -s .) ]] ; then
echo "INFO: updated" >&2
git add .
git commit -m "$COMMIT_MESSAGE"
if [[ $PUSH == yes ]] ; then
git push -omerge_request.create
fi
else
echo "INFO: no changes for $url" >&2
fi
)
}
usage() {
echo "Usage: $(basename $0) [-p] -g <group> -b <branch-name> -c <commit-message> -u <update-script> -s <search>" >&2
echo "$@">&2
exit 1
}
parse_command_line_options() {
while getopts pg:s:b:c:u: option
do
case "${option}"
in
p) PUSH=yes;;
b) BRANCH_NAME=${OPTARG};;
c) COMMIT_MESSAGE=${OPTARG};;
u) UPDATE_SCRIPT="$(cd "$(dirname "${OPTARG}")"; pwd)/$(basename "${OPTARG}")";;
s) SEARCH=${OPTARG};;
g) GROUP=${OPTARG};;
esac
done
# Check if all required options were specified
if [[ -z $BRANCH_NAME || -z $COMMIT_MESSAGE || -z $UPDATE_SCRIPT || -z $SEARCH || -z $GROUP ]]
then
usage "ERROR: not all required options specified."
fi
if [[ ! -x $UPDATE_SCRIPT ]]; then
usage" ERROR: $UPDATE_SCRIPT is not an executable script"
fi
}
main() {
parse_command_line_options "$@"
find_all_projects "$GROUP" "$SEARCH" | while read url; do
checkout $url
update $url
create_pull_request $url
exit 0
done
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment