Created
March 26, 2014 14:49
-
-
Save shaniber/9785061 to your computer and use it in GitHub Desktop.
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 | |
| # A simple script to make live backups of an organization's GitHub repositories. | |
| # Where to store the backup files | |
| GHBU_BACKUP_DIR=${GHBU_BACKUP_DIR-"==/FULL/PATH/TO/BACKUPDIR=="} | |
| # The GitHub organization whose repos will be backed up | |
| GHBU_ORG=${GHBU_ORG-"==ORGANIZATION=="} | |
| # GitHub API token. | |
| GBHU_TOKEN=${GBHU_TOKEN-"==AUTHTOKEN=="} | |
| # the GitHub hostname. | |
| GHBU_GITHOST=${GHBU_GITHOST-"github.com"} | |
| # base URI for the GitHub API. | |
| GHBU_API=${GHBU_API-"https://api.github.com"} | |
| # Options for the API call. | |
| GHBU_API_OPTS="access_token=${GBHU_TOKEN}&" | |
| # base command to use to clone GitHub repos | |
| GHBU_GIT_CLONE_CMD="git clone --quiet --mirror git@${GHBU_GITHOST}:" | |
| # base command to use to clone GitHub repos | |
| GHBU_GIT_FETCH_CMD="git --bare fetch" | |
| # when `true`, old backups will be deleted | |
| GHBU_PRUNE_OLD=${GHBU_PRUNE_OLD-true} | |
| # the min age (in days) of backup files to delete | |
| GHBU_PRUNE_AFTER_N_DAYS=${GHBU_PRUNE_AFTER_N_DAYS-3} | |
| # when `true`, only show error messages | |
| GHBU_SILENT=${GHBU_SILENT-false} | |
| 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 -n "Fetching list of repositories for ${GHBU_ORG}..." | |
| REPOURL="${GHBU_API}/orgs/${GHBU_ORG}/repos?${GHBU_API_OPTS}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 | awk '$1=$1'` repositories." | |
| $GHBU_SILENT || (echo "" && echo "=== BACKING UP ===" && echo "") | |
| for REPO in $REPOLIST; do | |
| # if the repository exists, update it from GitHub. | |
| if [ -d ${GHBU_BACKUP_DIR}/${REPO}.git ] ; then | |
| $GHBU_SILENT || echo "Syncing existing repo ${GHBU_ORG}/${REPO}" | |
| check cd ${GHBU_BACKUP_DIR}/${REPO}.git && check ${GHBU_GIT_FETCH_CMD} | |
| # if the repository is new, clone it. | |
| else | |
| $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO}" | |
| check ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.git ${GHBU_BACKUP_DIR}/${REPO}.git | |
| fi | |
| # if the wiki exists, update it from GitHub. | |
| if [ -d ${GHBU_BACKUP_DIR}/${REPO}.wiki.git ] ; then | |
| $GHBU_SILENT || echo "Syncing existing wiki for ${GHBU_ORG}/${REPO}" | |
| check cd ${GHBU_BACKUP_DIR}/${REPO}.wiki.git && check ${GHBU_GIT_FETCH_CMD} | |
| # if the wiki is new, attempt to clone it (and ignore it if it doesn't exist). | |
| else | |
| $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO}.wiki (if any)" | |
| ${GHBU_GIT_CLONE_CMD}${GHBU_ORG}/${REPO}.wiki.git ${GHBU_BACKUP_DIR}/${REPO}.wiki.git 2>/dev/null | |
| fi | |
| # Have to read the API docs to see how to do this via the API using a token. | |
| # $GHBU_SILENT || echo "Backing up ${GHBU_ORG}/${REPO} issues" | |
| # check curl --silent -u $GHBU_UNAME:$GHBU_PASSWD ${GHBU_API}/repos/${GHBU_ORG}/${REPO}/issues -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 issues 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 "") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment