-
-
Save bjtitus/8851816 to your computer and use it in GitHub Desktop.
A shell script to backup your Github organization's repos.
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
#!/bin/bash | |
# A simple script to backup an organization's GitHub repositories. | |
GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"github-backups"} # where to place the backup files | |
GHBU_ORG=${GHBU_ORG-"<CHANGE-ME>"} # the GitHub organization whose repos will be backed up | |
GHBU_API=${GHBU_API-"https://api.github.com"} # base URI for the GitHub API | |
GHBU_GITHOST=${GHBU_GITHOST-"<CHANGE-ME>.github.com"} # the GitHub hostname (see comments) | |
# I recommend using an API token so it is easily trackable and removable. | |
# Note that you MUST have SSH keys for a user with the access to all repos set up | |
GHBU_TOKEN=${GHBU_TOKEN-"<CHANGE-ME>"} # the token to use for API Authentication | |
GHBU_GIT_CLONE_CMD="git clone --quiet --mirror git@${GHBU_GITHOST}:" # base command to use to clone GitHub repos | |
GHBU_APIOPTS="access_token=${GHBU_TOKEN}&" | |
# You can use Username + Password if you would like | |
# UNAME+PASSWD must be used if you don't have ssh keys set up | |
# GHBU_UNAME=${GHBU_UNAME-"<CHANGE-ME>"} # the username of a GitHub account (to use with the GitHub API) | |
# GHBU_PASSWD=${GHBU_PASSWD-"<CHANGE-ME>"} # the password for that account | |
# GHBU_GIT_CLONE_CMD="git clone --quiet --mirror https://${GHBU_UNAME}:${GHBU_PASSWD}@${GHBU_GITHOST}/" # base command to use to clone GitHub repos | |
# GHBU_CURLOPTS="-u ${GHBU_UNAME}:${GHBU_PASSWD}" | |
GHBU_PRUNE_OLD=${GHBU_PRUNE_OLD-true} # when `true`, old backups will be deleted | |
GHBU_PRUNE_AFTER_N_DAYS=${GHBU_PRUNE_AFTER_N_DAYS-3} # the min age (in days) of backup files to delete | |
GHBU_SILENT=${GHBU_SILENT-false} # when `true`, only show error messages | |
TSTAMP=`date "+%Y%m%d-%H%M"` | |
# The function `check` will exit the script if the given command fails. | |
function check { | |
"$@" | |
status=$? | |
if [ $status -ne 0 ]; then | |
echo "ERROR: Encountered error (${status}) while running the following:" >&2 | |
echo " $@" >&2 | |
echo " (at line ${BASH_LINENO[0]} of file $0.)" >&2 | |
echo " Aborting." >&2 | |
exit $status | |
fi | |
} | |
# The function `tgz` will create a gzipped tar archive of the specified file ($1) and then remove the original | |
function tgz { | |
check tar zcf $1.tar.gz $1 && check rm -rf $1 | |
} | |
$GHBU_SILENT || (echo "" && echo "=== INITIALIZING ===" && echo "") | |
$GHBU_SILENT || echo "Using backup directory $GHBU_BACKUP_DIR" | |
check mkdir -p $GHBU_BACKUP_DIR | |
$GHBU_SILENT || echo "Fetching list of repositories for ${GHBU_ORG}..." | |
REPOURL="${GHBU_API}/orgs/${GHBU_ORG}/repos?${GHBU_APIOPTS}per_page=2" | |
REPOLIST="" | |
while [ $REPOURL ]; do | |
REPOREQCONTENT=`curl --silent -i $GHBU_CURLOPTS $REPOURL -q` | |
REPOURL=`check echo "${REPOREQCONTENT}" | grep "\"next\"" | check awk -F'<' '{print $2}' | check sed -e 's/>;.*//g'` | |
REPOLIST=$REPOLIST`check echo "${REPOREQCONTENT}" | grep "\"name\"" | check awk -F': "' '{print $2}' | check sed -e 's/",//g'`$'\n' | |
done | |
$GHBU_SILENT || echo "found `echo $REPOLIST | wc -w` repositories." | |
$GHBU_SILENT || (echo "" && echo "=== BACKING UP ===" && echo "") | |
for REPO in $REPOLIST; do | |
$GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO}" | |
check ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.git ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP}.git && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}-${TSTAMP}.git | |
$GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO}.wiki (if any)" | |
${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.wiki.git ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP}.git 2>/dev/null && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.wiki-${TSTAMP}.git | |
$GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO} issues" | |
check curl --silent $GHBU_CURLOPTS ${GHBU_API}/repos/${GHBU_ORG}/${REPO}/issues?${GHBU_APIOPTS} -q > ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP} && tgz ${GHBU_BACKUP_DIR}/${GHBU_ORG}-${REPO}.issues-${TSTAMP} | |
done | |
if $GHBU_PRUNE_OLD; then | |
$GHBU_SILENT || (echo "" && echo "=== PRUNING ===" && echo "") | |
$GHBU_SILENT || echo "Pruning backup files ${GHBU_PRUNE_AFTER_N_DAYS} days old or older." | |
$GHBU_SILENT || echo "Found `find $GHBU_BACKUP_DIR -name '*.tar.gz' -mtime +$GHBU_PRUNE_AFTER_N_DAYS | wc -l` files to prune." | |
find $GHBU_BACKUP_DIR -name '*.tar.gz' -mtime +$GHBU_PRUNE_AFTER_N_DAYS -exec rm -fv {} > /dev/null \; | |
fi | |
$GHBU_SILENT || (echo "" && echo "=== DONE ===" && echo "") | |
$GHBU_SILENT || (echo "GitHub backup completed." && echo "") |
@reggi It's a fork... https://gist.github.com/rodw/3073987
Hi, It is working fine for me. Thanks :)
This fetches 2 repos per page. Line 50 needs modified to
REPOURL="${GHBU_API}/orgs/${GHBU_ORG}/repos?${GHBU_APIOPTS}per_page=100"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'd love to see some usage of this script
sh ./backup-github.sh
doesn't do anything.