To automatically create backups of all GitHub repositories, git and SSH must already be configured and able to work with GitHub.

Generate an API key, also known as a personal access token

Go to GitHub and follow this path:

GitHub home page -> Settings -> Developer settings -> Personal access token -> Fine-grained tokens -> Generate new token

For Repository access, select “All repositories”, because we will back up not only public repositories but also private ones.

In Repository permissions, select only one item: “Metadata”, and set it to Read-only.

Choose the token name, description, and expiration date at your discretion.

Next, make sure to copy and save the token. It will not be shown again. Otherwise, you will have to repeat the procedure.

You can leave the tab open and paste the token directly into the script in the next step.

Prepare the directory and files

As an example, use the directory “/home/github”.

Create the file “github_backuper.sh” there and paste the following:

#!/bin/bash

API_TOKEN=""
BACKUP_DIR=""

PAGE=1

while : ; do
    REPOS=$(curl -s -H "Authorization: Bearer $API_TOKEN" \
        "https://api.github.com/user/repos?per_page=100&page=$PAGE&affiliation=owner")

    COUNT=$(echo "$REPOS" | grep -o '"ssh_url"' | wc -l)
    [ "$COUNT" -eq 0 ] && break

    echo "$REPOS" | grep '"ssh_url"' | awk -F'"' '{print $4}' | while read -r SSH_URL; do
        SSH_URL=$(echo "$SSH_URL" | sed 's/github\.com/github/')
        REPO_NAME=$(basename "$SSH_URL" .git)
        REPO_PATH="$BACKUP_DIR/$REPO_NAME"

        if [ -d "$REPO_PATH/.git" ]; then
            git -C "$REPO_PATH" pull --quiet
        else
            git clone --quiet "$SSH_URL" "$REPO_PATH"
        fi
    done

    PAGE=$((PAGE + 1))
done

Configure the cron scheduler

The next step is to run the script using the cron scheduler.

Several lines must be adjusted in /etc/crontab.

Add our storage directory to the PATH variable. It should be added after the “:” character.

In this case it will look like this:

PATH=/bin:/sbin:/home/github

Then add the schedule to the end of the file.

To create backups every day at 00:00, add this line:

00 00 * * * user /home/github/github_backuper.sh >> /home/github/log_github_backuper.log

The part >> /home/github/log_github_backuper.log is needed for logging the script output. If this information is not required, it can be omitted.

user is the user under which the script will be launched.

To simplify schedule generation, you can use this excellent service.