Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 55 additions & 4 deletions multimod/internal/tag/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"log"
"os/exec"
"strings"

"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
Expand Down Expand Up @@ -65,8 +66,9 @@ func Run(versioningFile, moduleSetName, commitHash string, deleteModuleSetTags b

type tagger struct {
shared.ModuleSetRelease
CommitHash plumbing.Hash
Repo *git.Repository
CommitHash plumbing.Hash
Repo *git.Repository
tagsOnCommit map[string]bool
}

func newTagger(versioningFilename, modSetToUpdate, repoRoot, hash string, deleteModuleSetTags bool) (tagger, error) {
Expand All @@ -87,23 +89,67 @@ func newTagger(versioningFilename, modSetToUpdate, repoRoot, hash string, delete

modFullTagNames := modRelease.ModuleFullTagNames()

var tagsOnCommit map[string]bool

if deleteModuleSetTags {
if err = verifyTagsOnCommit(modFullTagNames, repo, fullCommitHash); err != nil {
return tagger{}, fmt.Errorf("verifyTagsOnCommit failed: %w", err)
}
tagsOnCommit = make(map[string]bool)
} else {
if err = modRelease.CheckGitTagsAlreadyExist(repo); err != nil {
return tagger{}, fmt.Errorf("CheckGitTagsAlreadyExist failed: %w", err)
var tagsOnOtherCommit []string
tagsOnCommit, tagsOnOtherCommit, err = getTagsOnCommitStatus(modFullTagNames, repo, fullCommitHash)
if err != nil {
return tagger{}, fmt.Errorf("error checking tag status: %w", err)
}

if len(tagsOnOtherCommit) > 0 {
return tagger{}, fmt.Errorf("some git tags exist on a different commit than %s:\n%s", fullCommitHash, strings.Join(tagsOnOtherCommit, "\n"))
}
}

return tagger{
ModuleSetRelease: modRelease,
CommitHash: fullCommitHash,
Repo: repo,
tagsOnCommit: tagsOnCommit,
}, nil
}

func getTagsOnCommitStatus(modFullTagNames []string, repo *git.Repository, targetCommitHash plumbing.Hash) (map[string]bool, []string, error) {
tagsOnCommit := make(map[string]bool)
var tagsOnOtherCommit []string

for _, tagName := range modFullTagNames {
tagRef, tagRefErr := repo.Tag(tagName)

if tagRefErr != nil {
if errors.Is(tagRefErr, git.ErrTagNotFound) {
continue
}
return nil, nil, fmt.Errorf("unable to fetch git tag ref for %v: %w", tagName, tagRefErr)
}

tagObj, tagObjErr := repo.TagObject(tagRef.Hash())
if tagObjErr != nil {
return nil, nil, fmt.Errorf("unable to get tag object: %w", tagObjErr)
}

tagCommit, tagCommitErr := tagObj.Commit()
if tagCommitErr != nil {
return nil, nil, fmt.Errorf("could not get tag object commit: %w", tagCommitErr)
}

if targetCommitHash == tagCommit.Hash {
tagsOnCommit[tagName] = true
} else {
tagsOnOtherCommit = append(tagsOnOtherCommit, tagName)
}
}

return tagsOnCommit, tagsOnOtherCommit, nil
}

func verifyTagsOnCommit(modFullTagNames []string, repo *git.Repository, targetCommitHash plumbing.Hash) error {
var tagsNotOnCommit []string

Expand Down Expand Up @@ -186,6 +232,11 @@ func (t tagger) tagAllModules(customTagger *object.Signature) error {
log.Printf("Tagging commit %s:\n", t.CommitHash)

for _, newFullTag := range modFullTags {
if t.tagsOnCommit[newFullTag] {
log.Printf("%v (already exists, skipping)\n", newFullTag)
continue
}

log.Printf("%v\n", newFullTag)

var err error
Expand Down
30 changes: 29 additions & 1 deletion multimod/internal/tag/tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,10 +536,38 @@
"test/v0.1.0",
"v1.0.0-doesNotExist",
},
shouldError: true,
shouldError: false, // Should succeed, skipping tags that already exist on the commit
},
}

t.Run("mod_set_3_tags_on_different_commit", func(t *testing.T) {
tmpRootDir := t.TempDir()
repo, initialHash, err := sharedtest.InitNewRepoWithCommit(tmpRootDir)
require.NoError(t, err)

createTagOptions := &git.CreateTagOptions{

Check failure on line 548 in multimod/internal/tag/tag_test.go

View workflow job for this annotation

GitHub Actions / lint (windows-latest)

shadow: declaration of "createTagOptions" shadows declaration at line 469 (govet)
Message: "test tag message",
Tagger: sharedtest.TestAuthor,
}
_, err = repo.CreateTag("v2.2.2", initialHash, createTagOptions)
require.NoError(t, err)

fullHash, err := shared.CommitChangesToNewBranch("test_commit", "commit used in a test", repo, sharedtest.TestAuthor)
require.NoError(t, err)
hashPrefix := fullHash.String()[:8]

modFiles := map[string][]byte{
filepath.Join(tmpRootDir, "go.mod"): []byte("module go.opentelemetry.io/testroot/v2\n\ngo 1.16\n"),
}

require.NoError(t, sharedtest.WriteTempFiles(modFiles), "could not create go mod file tree")

versioningFilename := filepath.Join(testDataDir, "tag_all_modules", "versions_valid.yaml")

Check failure on line 565 in multimod/internal/tag/tag_test.go

View workflow job for this annotation

GitHub Actions / lint (windows-latest)

shadow: declaration of "versioningFilename" shadows declaration at line 467 (govet)
_, err = newTagger(versioningFilename, "mod-set-3", tmpRootDir, hashPrefix, false)
assert.Error(t, err)
assert.Contains(t, err.Error(), "some git tags exist on a different commit")
})

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tmpRootDir := t.TempDir()
Expand Down
Loading