diff --git a/cli/catalogue/catalogue.go b/cli/catalogue/catalogue.go index 8bb74c01..6138d3b1 100644 --- a/cli/catalogue/catalogue.go +++ b/cli/catalogue/catalogue.go @@ -14,6 +14,7 @@ import ( "coopcloud.tech/abra/pkg/limit" "coopcloud.tech/abra/pkg/recipe" "github.com/AlecAivazis/survey/v2" + "github.com/go-git/go-git/v5" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" ) @@ -154,6 +155,7 @@ If you have a Hub account you can have Abra log you in to avoid this. Pass catl[recipeMeta.Name] = recipe.RecipeMeta{ Name: recipeMeta.Name, Repository: recipeMeta.CloneURL, + SSHURL: recipeMeta.SSHURL, Icon: recipeMeta.AvatarURL, DefaultBranch: recipeMeta.DefaultBranch, Description: recipeMeta.Description, @@ -212,7 +214,17 @@ If you have a Hub account you can have Abra log you in to avoid this. Pass } if internal.Push { - if err := gitPkg.Push(cataloguePath, false); err != nil { + repo, err := git.PlainOpen(cataloguePath) + if err != nil { + logrus.Fatal(err) + } + + sshURL := fmt.Sprintf(config.SSH_URL_TEMPLATE, "recipes") + if err := gitPkg.CreateRemote(repo, "origin-ssh", sshURL, internal.Dry); err != nil { + logrus.Fatal(err) + } + + if err := gitPkg.Push(cataloguePath, "origin-ssh", false, internal.Dry); err != nil { logrus.Fatal(err) } } diff --git a/cli/recipe/release.go b/cli/recipe/release.go index dbda67e4..723a4052 100644 --- a/cli/recipe/release.go +++ b/cli/recipe/release.go @@ -213,7 +213,7 @@ func createReleaseFromTag(recipe recipe.Recipe, tagString, mainAppVersion string logrus.Fatal(err) } - if err := pushRelease(recipe.Dir()); err != nil { + if err := pushRelease(recipe); err != nil { logrus.Fatal(err) } @@ -308,7 +308,7 @@ func tagRelease(tagString string, repo *git.Repository) error { return nil } -func pushRelease(recipeDir string) error { +func pushRelease(recipe recipe.Recipe) error { if internal.Dry { logrus.Info("dry run: no changes pushed") return nil @@ -325,7 +325,7 @@ func pushRelease(recipeDir string) error { } if internal.Push { - if err := gitPkg.Push(recipeDir, true); err != nil { + if err := recipe.Push(internal.Dry); err != nil { return err } } @@ -403,7 +403,7 @@ func createReleaseFromPreviousTag(tagString, mainAppVersion string, recipe recip logrus.Fatal(err) } - if err := pushRelease(recipe.Dir()); err != nil { + if err := pushRelease(recipe); err != nil { logrus.Fatal(err) } diff --git a/pkg/config/env.go b/pkg/config/env.go index 6cc8a208..00e7c45c 100644 --- a/pkg/config/env.go +++ b/pkg/config/env.go @@ -20,6 +20,7 @@ var RECIPES_DIR = path.Join(ABRA_DIR, "apps") var VENDOR_DIR = path.Join(ABRA_DIR, "vendor") var RECIPES_JSON = path.Join(ABRA_DIR, "catalogue", "recipes.json") var REPOS_BASE_URL = "https://git.coopcloud.tech/coop-cloud" +var SSH_URL_TEMPLATE = "ssh://git@git.coopcloud.tech:2222/coop-cloud/%s.git" // GetServers retrieves all servers. func GetServers() ([]string, error) { diff --git a/pkg/git/push.go b/pkg/git/push.go index cb8378f5..d0eeae9d 100644 --- a/pkg/git/push.go +++ b/pkg/git/push.go @@ -1,36 +1,41 @@ package git import ( - "path" - - configPkg "coopcloud.tech/abra/pkg/config" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" "github.com/sirupsen/logrus" ) -// Push pushes the latest changes -func Push(recipeName string, tags bool) error { - recipeDir := path.Join(configPkg.RECIPES_DIR, recipeName) - commitRepo, err := git.PlainOpen(recipeDir) +// Push pushes the latest changes & optionally tags to the default remote +func Push(repoDir string, remote string, tags bool, dryRun bool) error { + if dryRun { + logrus.Infof("dry run: no git changes pushed in %s", repoDir) + return nil + } + + commitRepo, err := git.PlainOpen(repoDir) if err != nil { return err } - if err := commitRepo.Push(&git.PushOptions{}); err != nil { + opts := &git.PushOptions{} + if remote != "" { + opts.RemoteName = remote + } + + if err := commitRepo.Push(opts); err != nil { return err } + logrus.Info("git changes pushed") if tags { - pushOpts := &git.PushOptions{ - RefSpecs: []config.RefSpec{ - config.RefSpec("+refs/tags/*:refs/tags/*"), - }, - } - if err := commitRepo.Push(pushOpts); err != nil { + opts.RefSpecs = append(opts.RefSpecs, config.RefSpec("+refs/tags/*:refs/tags/*")) + + if err := commitRepo.Push(opts); err != nil { return err } + logrus.Info("git tags pushed") } diff --git a/pkg/git/remote.go b/pkg/git/remote.go new file mode 100644 index 00000000..81659816 --- /dev/null +++ b/pkg/git/remote.go @@ -0,0 +1,28 @@ +package git + +import ( + "strings" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + "github.com/sirupsen/logrus" +) + +// CreateRemote creates a new git remote in a repository +func CreateRemote(repo *git.Repository, name, url string, dryRun bool) error { + if dryRun { + logrus.Infof("dry run: remote %s (%s) not created", name, url) + return nil + } + + if _, err := repo.CreateRemote(&config.RemoteConfig{ + Name: name, + URLs: []string{url}, + }); err != nil { + if !strings.Contains(err.Error(), "remote already exists") { + return err + } + } + + return nil +} diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index 2ea5ac6b..eff3d971 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -56,6 +56,7 @@ type RecipeMeta struct { Icon string `json:"icon"` Name string `json:"name"` Repository string `json:"repository"` + SSHURL string `json:"ssh_url"` Versions RecipeVersions `json:"versions"` Website string `json:"website"` } @@ -128,6 +129,25 @@ type Recipe struct { Meta RecipeMeta } +// Push pushes the latest changes to a SSH URL remote. You need to have your +// local SSH configuration for git.coopcloud.tech working for this to work +func (r Recipe) Push(dryRun bool) error { + repo, err := git.PlainOpen(r.Dir()) + if err != nil { + return err + } + + if err := gitPkg.CreateRemote(repo, "origin-ssh", r.Meta.SSHURL, dryRun); err != nil { + return err + } + + if err := gitPkg.Push(r.Dir(), "origin-ssh", true, dryRun); err != nil { + return err + } + + return nil +} + // Dir retrieves the recipe repository path func (r Recipe) Dir() string { return path.Join(config.RECIPES_DIR, r.Name)