Mirroring to Gitlab

So you run a project on GitHub (actually on GitHub) and you want to mirror it to your local GitLab install.

Here we

  1. Mirror to GitLab
  2. Send status updates back

This should be fun.

  1. First, create a system user: gitmirror
  2. Second, create a gitlab user: gitmirror
  3. Install github2gitlab from pip
  4. Create a /home/gitmirror/sync-project.sh with

    #!/bin/bash
    /usr/local/bin/github2gitlab --gitlab-url https://code.sealedabstract.com --gitlab-token 'YOURTOKEN' --github-repo AnarchyTools/atbuild --gitlab-repo AnarchyTools/atbuild
    
  5. Install webhook

  6. I use this for /etc/init.d/webhook. I made it via https://gist.github.com/naholyr/4275302/

    #!/bin/sh
    ### BEGIN INIT INFO
    # Provides:          webhooks
    # Required-Start:    $local_fs $network $named $time $syslog
    # Required-Stop:     $local_fs $network $named $time $syslog
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Description:       Webhooks\ daemon
    ### END INIT INFO
    
    SCRIPT="/usr/local/bin/webhook -hooks /etc/hooks.json --verbose=true"
    RUNAS=gitmirror
    
    PIDFILE=/var/run/webhooks.pid
    LOGFILE=/var/log/webhooks.log
    
    start() {
      if [ -f /var/run/$PIDNAME ] && kill -0 $(cat /var/run/$PIDNAME); then
        echo 'Service already running' >&2
        return 1
      fi
      echo 'Starting serviceā€¦' >&2
      local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
      su -c "$CMD" $RUNAS > "$PIDFILE"
      echo 'Service started' >&2
    }
    
    stop() {
      if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
        echo 'Service not running' >&2
        return 1
      fi
      echo 'Stopping serviceā€¦' >&2
      kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
      echo 'Service stopped' >&2
    }
    
    uninstall() {
      echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
      local SURE
      read SURE
      if [ "$SURE" = "yes" ]; then
        stop
        rm -f "$PIDFILE"
        echo "Notice: log file is not be removed: '$LOGFILE'" >&2
        update-rc.d -f webhooks remove
        rm -fv "$0"
      fi
    }
    
    case "$1" in
      start)
        start
        ;;
      stop)
        stop
        ;;
      uninstall)
        uninstall
        ;;
      retart)
        stop
        start
        ;;
      *)
        echo "Usage: $0 {start|stop|restart|uninstall}"
    esac
    
  7. update-rc.d webhooks defaults

  8. Now we need our /etc/hooks.json:

    [
      {
        "id": "mirror-anarchy",
        "execute-command": "/home/gitmirror/sync-anarchy.sh",
        "command-working-directory": "/home/gitmirror"
      },
      {
        "id":"status-anarchy",
        "execute-command":"/home/gitmirror/status-anarchy.sh",
        "command-working-directory": "/home/gitmirror",
        "pass-arguments-to-command": [
            {"source": "payload", "name": "build_status"},
            {"source": "payload", "name": "build_id"},
            {"source": "payload", "name": "sha"},
            {"source": "payload", "name": "build_name"}
        ]
      }
    ]
    
  9. (Remember to let 9000 through your firewall)

  10. You may need to change /home/gitmirror/{repo}'s remote to use an SSH url to avoid an authentication prompt. Try it and see.

  11. Now we need that second script, status-project.sh:

    #!/bin/bash
    set -e
    GITLAB_STATE="$1"
    BUILDNO="$2"
    SHA="$3"
    NAME="$4"
    
    GITLAB_PROJECT="AnarchyTools/atbuild"
    GITHUB_PROJECT=$GITLAB_PROJECT
    GITLAB_URL="https://code.sealedabstract.com/"
    
    BUILD_URL=${GITLAB_URL}${GITLAB_PROJECT}/builds/${BUILDNO}
    
    #calculate github state
    if [ "$GITLAB_STATE" = "running" ]; then
            GITHUB_STATE="pending"
    elif [ "$GITLAB_STATE" = "success" ]; then
            GITHUB_STATE="success"
    elif [ "$GITLAB_STATE" = "failed" ]; then
            GITHUB_STATE="failure"
    else
            echo "unknown gitlab state $GITLAB_STATE"
            exit 1
    fi
    
    PAYLOAD="{\"state\":\"${GITHUB_STATE}\",\"target_url\":\"${BUILD_URL}\",\"context\":\"$NAME\"}"
    curl -d "$PAYLOAD" -u glados:YOURTOKENHERE https://api.github.com/repos/${GITHUB_PROJECT}/statuses/${SHA}
    
  12. This assumes glados is your GitHub user.

  13. Finally, we config the webhooks themselves: hook1 hook2


Want me to build your app / consult for your company / speak at your event? Good news! I'm an iOS developer for hire.