abra/cli/recipe/release.go

210 lines
4.5 KiB
Go
Raw Normal View History

2021-09-22 14:03:56 +00:00
package recipe
import (
"fmt"
"path"
"strconv"
"strings"
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/tagcmp"
2021-09-22 14:03:56 +00:00
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
2021-09-23 16:52:21 +00:00
var Push bool
var PushFlag = &cli.BoolFlag{
Name: "push",
Value: false,
Destination: &Push,
}
2021-09-22 14:03:56 +00:00
var Dry bool
var DryFlag = &cli.BoolFlag{
Name: "dry-run",
Value: false,
Aliases: []string{"d"},
2021-09-22 14:03:56 +00:00
Destination: &Dry,
}
var Major bool
var MajorFlag = &cli.BoolFlag{
Name: "major",
Value: false,
Aliases: []string{"ma", "x"},
Destination: &Major,
}
var Minor bool
var MinorFlag = &cli.BoolFlag{
Name: "minor",
Value: false,
Aliases: []string{"mi", "y"},
Destination: &Minor,
}
var Patch bool
var PatchFlag = &cli.BoolFlag{
Name: "patch",
Value: false,
Aliases: []string{"p", "z"},
Destination: &Patch,
}
2021-09-22 14:03:56 +00:00
var recipeReleaseCommand = &cli.Command{
Name: "release",
Usage: "tag a recipe",
Aliases: []string{"rl"},
ArgsUsage: "<recipe> [<tag>]",
Flags: []cli.Flag{
DryFlag,
PatchFlag,
MinorFlag,
MajorFlag,
2021-09-23 16:52:21 +00:00
PushFlag,
2021-09-22 14:03:56 +00:00
},
Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipe(c)
directory := path.Join(config.APPS_DIR, recipe.Name)
tagstring := c.Args().Get(1)
imagesTmp := getImageVersions(recipe)
repo, err := git.PlainOpen(directory)
if err != nil {
logrus.Fatal(err)
}
head, err := repo.Head()
if err != nil {
logrus.Fatal(err)
}
if tagstring != "" {
if Dry {
logrus.Info(fmt.Sprintf("Dry run only. NOT creating tag %s at %s", tagstring, head.Hash()))
return nil
}
repo.CreateTag(tagstring, head.Hash(), nil) /* &git.CreateTagOptions{
Message: tag,
})*/
logrus.Info(fmt.Sprintf("Created tag %s at %s.", tagstring, head.Hash()))
2021-09-23 16:52:21 +00:00
if Push {
if err := repo.Push(&git.PushOptions{}); err != nil {
logrus.Fatal(err)
}
logrus.Info(fmt.Sprintf("Pushed tag %s to remote.", tagstring))
}
2021-09-22 14:03:56 +00:00
return nil
}
// bumpType is used to decide what part of the tag should be incremented
bumpType := btoi(Major)*4 + btoi(Minor)*2 + btoi(Patch)
if bumpType != 0 {
// a bitwise check if the number is a power of 2
if (bumpType & (bumpType - 1)) != 0 {
logrus.Fatal("you can only use one of: --major, --minor, --patch.")
2021-09-22 14:03:56 +00:00
}
}
// get the latest tag with its hash, name etc
var lastGitTag *object.Tag
iter, err := repo.Tags()
2021-09-22 14:03:56 +00:00
if err != nil {
logrus.Fatal(err)
}
if err := iter.ForEach(func(ref *plumbing.Reference) error {
obj, err := repo.TagObject(ref.Hash())
if err == nil {
lastGitTag = obj
return nil
}
return err
}); err != nil {
logrus.Fatal(err)
}
newTag, err := tagcmp.Parse(lastGitTag.Name)
2021-09-22 14:03:56 +00:00
if err != nil {
logrus.Fatal(err)
}
var newTagString string
if bumpType > 0 {
if Patch {
now, err := strconv.Atoi(newTag.Patch)
if err != nil {
logrus.Fatal(err)
}
newTag.Patch = strconv.Itoa(now + 1)
} else if Minor {
now, err := strconv.Atoi(newTag.Minor)
if err != nil {
logrus.Fatal(err)
}
newTag.Minor = strconv.Itoa(now + 1)
} else if Major {
now, err := strconv.Atoi(newTag.Major)
if err != nil {
logrus.Fatal(err)
}
newTag.Major = strconv.Itoa(now + 1)
2021-09-22 14:03:56 +00:00
}
newTagString = newTag.String()
} else {
// calculate the new tag
var images = make(map[string]tagcmp.Tag)
for name, version := range imagesTmp {
t, err := tagcmp.Parse(version)
if err != nil {
2021-09-22 14:03:56 +00:00
logrus.Fatal(err)
}
images[name] = t
2021-09-22 14:03:56 +00:00
}
}
if Dry {
logrus.Info(fmt.Sprintf("Dry run only. NOT creating tag %s at %s", newTagString, head.Hash()))
2021-09-22 14:03:56 +00:00
return nil
}
repo.CreateTag(newTagString, head.Hash(), nil) /* &git.CreateTagOptions{
2021-09-22 14:03:56 +00:00
Message: tag,
})*/
logrus.Info(fmt.Sprintf("Created tag %s at %s.", newTagString, head.Hash()))
2021-09-23 16:52:21 +00:00
if Push {
if err := repo.Push(&git.PushOptions{}); err != nil {
logrus.Fatal(err)
}
logrus.Info(fmt.Sprintf("Pushed tag %s to remote.", newTagString))
}
2021-09-22 14:03:56 +00:00
return nil
2021-09-22 14:03:56 +00:00
},
}
func getImageVersions(recipe recipe.Recipe) map[string]string {
var services = make(map[string]string)
for _, service := range recipe.Config.Services {
srv := strings.Split(service.Image, ":")
services[srv[0]] = srv[1]
}
return services
}
func btoi(b bool) int {
if b {
return 1
2021-09-22 14:03:56 +00:00
}
return 0
2021-09-22 14:03:56 +00:00
}