diff --git a/pkg/lint/recipe.go b/pkg/lint/recipe.go index ee9a15c1..3c6d6c5e 100644 --- a/pkg/lint/recipe.go +++ b/pkg/lint/recipe.go @@ -11,6 +11,8 @@ import ( recipePkg "coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/tagcmp" "github.com/docker/distribution/reference" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" "github.com/sirupsen/logrus" ) @@ -151,6 +153,13 @@ var LintRules = map[string][]LintRule{ HowToResolve: "vendor config versions in an abra.sh", Function: LintAbraShVendors, }, + { + Ref: "R014", + Level: "error", + Description: "invalid lightweight tag used for recipe version", + HowToResolve: "replace tag with annotated version, see operator docs", + Function: LintValidTags, + }, }, } @@ -391,3 +400,34 @@ func LintHasRecipeRepo(recipe recipe.Recipe) (bool, error) { return true, nil } + +func LintValidTags(recipe recipe.Recipe) (bool, error) { + recipeDir := path.Join(config.RECIPES_DIR, recipe.Name) + + repo, err := git.PlainOpen(recipeDir) + if err != nil { + return false, fmt.Errorf("unable to open %s: %s", recipeDir, err) + } + + iter, err := repo.Tags() + if err != nil { + logrus.Fatalf("unable to list local tags for %s", recipe.Name) + } + + if err := iter.ForEach(func(ref *plumbing.Reference) error { + _, err := repo.TagObject(ref.Hash()) + if err != nil { + switch err { + case plumbing.ErrObjectNotFound: + return fmt.Errorf("invalid lightweight tag detected") + default: + return err + } + } + return nil + }); err != nil { + return false, nil + } + + return true, nil +}