Skip to content

Instantly share code, notes, and snippets.

@dbanck
Created October 20, 2021 14:50
Show Gist options
  • Save dbanck/d58bd801711c5eed09e056ae91ae2f83 to your computer and use it in GitHub Desktop.
Save dbanck/d58bd801711c5eed09e056ae91ae2f83 to your computer and use it in GitHub Desktop.
Backup GitLab Repositories
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"time"
)
type Repository struct {
ID int `json:"id"`
Description string `json:"description"`
Name string `json:"name"`
NameWithNamespace string `json:"name_with_namespace"`
Path string `json:"path"`
PathWithNamespace string `json:"path_with_namespace"`
CreatedAt time.Time `json:"created_at"`
DefaultBranch string `json:"default_branch"`
TagList []interface{} `json:"tag_list"`
SSHURLToRepo string `json:"ssh_url_to_repo"`
HTTPURLToRepo string `json:"http_url_to_repo"`
WebURL string `json:"web_url"`
ReadmeURL string `json:"readme_url"`
AvatarURL interface{} `json:"avatar_url"`
ForksCount int `json:"forks_count"`
StarCount int `json:"star_count"`
LastActivityAt time.Time `json:"last_activity_at"`
Namespace struct {
ID int `json:"id"`
Name string `json:"name"`
Path string `json:"path"`
Kind string `json:"kind"`
FullPath string `json:"full_path"`
ParentID interface{} `json:"parent_id"`
AvatarURL interface{} `json:"avatar_url"`
WebURL string `json:"web_url"`
} `json:"namespace"`
}
func getRepositories() ([]Repository, error) {
repositories := []Repository{}
// Create client
client := &http.Client{}
url := "<DOMAIN>/api/v4/projects?archived=false&simple=true&per_page=100"
// Create request
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return repositories, err
}
// Headers
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", os.Getenv("TOKEN")))
parseFormErr := req.ParseForm()
if parseFormErr != nil {
fmt.Println(parseFormErr)
}
// Fetch Request
res, err := client.Do(req)
if err != nil {
return repositories, err
}
if res.Body != nil {
defer res.Body.Close()
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return repositories, err
}
err = json.Unmarshal(body, &repositories)
if err != nil {
return repositories, err
}
return repositories, nil
}
func main() {
repositories, err := getRepositories()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d repositories.\n", len(repositories))
for i, repository := range repositories {
fmt.Printf("%d - Backing up repository %s...\n", i+1, repository.Name)
clone := exec.Command("git", "clone", "--mirror", repository.SSHURLToRepo)
err := clone.Run()
if err != nil {
log.Fatal(err)
}
path := fmt.Sprintf("%s.git", repository.Path)
bundle := exec.Command("git",
"-C", path,
"bundle", "create", fmt.Sprintf("../backups/%s-%s.bak", repository.Namespace.Name, repository.Name), "--all")
err = bundle.Run()
if err != nil {
log.Fatal(err)
}
err = os.RemoveAll(path)
if err != nil {
log.Fatal(err)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment