guireleaser/prepareRelease.go

320 lines
8.8 KiB
Go
Raw Normal View History

package main
import (
"errors"
2025-02-08 06:32:37 -06:00
"fmt"
"os"
"path/filepath"
2025-01-19 10:48:16 -06:00
"time"
2025-01-19 10:48:16 -06:00
"go.wit.com/lib/gui/shell"
2024-12-16 00:19:03 -06:00
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log"
)
2024-12-17 23:59:08 -06:00
func forceReleaseVersion(repo *gitpb.Repo) {
if argv.Minor {
// if v1.2.3 change to v.1.3.0
repo.IncrementTargetMinor()
} else {
// if v1.2.3 change to v.1.2.4
repo.IncrementTargetRevision()
2024-12-17 23:59:08 -06:00
}
}
func checkpkgcache(repo *gitpb.Repo) error {
homedir, err := os.UserHomeDir()
if err != nil {
return err
}
rver := repo.GetLastTag()
if rver == "" {
return errors.New("could not get master version")
}
moddir := filepath.Join(homedir, "go/pkg/mod", repo.GetGoPath()+"@"+rver)
if shell.IsDir(moddir) {
return nil
}
getpath := repo.GetGoPath() + "@" + repo.GetLastTag()
2025-01-30 01:15:00 -06:00
log.Info("MISSING:", getpath)
_, err = me.startRepo.RunVerboseOnError([]string{"go", "get", getpath})
return err
}
2025-01-30 01:15:00 -06:00
var rillcount int
2025-02-08 06:32:37 -06:00
func rillPurge(repo *gitpb.Repo) error {
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
return nil
}
if me.forge.Config.IsPrivate(repo.GetGoPath()) {
return nil
}
_, err := repo.RunQuiet([]string{"go-mod-clean", "--purge"})
rillcount += 1
if err != nil {
log.Info("go-mod-clean --smart failed", repo.GetGoPath(), err)
return err
}
return nil
}
func rillRestore(repo *gitpb.Repo) error {
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
return nil
}
if me.forge.Config.IsPrivate(repo.GetGoPath()) {
return nil
}
2025-01-30 01:15:00 -06:00
2025-02-07 11:21:51 -06:00
_, err := repo.RunQuiet([]string{"go-mod-clean", "--smart"})
2025-01-30 01:15:00 -06:00
rillcount += 1
if err != nil {
2025-02-07 11:21:51 -06:00
log.Info("go-mod-clean --smart failed", repo.GetGoPath(), err)
return err
}
return nil
2025-01-19 10:48:16 -06:00
}
2024-12-17 23:59:08 -06:00
func rePrepareRelease() {
// reload the config
2025-01-29 21:24:08 -06:00
// me.forge = forgepb.Init()
2024-12-17 23:59:08 -06:00
me.found = new(gitpb.Repos)
2025-02-07 11:21:51 -06:00
log.Printf("rePrepareRelease() START rill go-mod-clean --smart (11 seconds?)")
2025-01-30 01:15:00 -06:00
rillcount = 0
2025-01-20 08:14:18 -06:00
now := time.Now()
me.forge.RillFuncError(rillRestore)
2025-01-30 01:15:00 -06:00
log.Printf("showRestore() (%d total repos) took:%s\n", rillcount, shell.FormatDuration(time.Since(now)))
log.Sleep(1)
all2 := me.forge.Repos.SortByFullPath()
for all2.Scan() {
check := all2.Next()
if me.forge.Config.IsReadOnly(check.GetGoPath()) {
continue
}
if me.forge.Config.IsPrivate(check.GetGoPath()) {
continue
}
// this should be rare? nonexistant?
if err := checkpkgcache(check); err != nil {
log.Info("go get checks failed here.", err, check.GetGoPath())
}
}
2024-12-18 20:24:28 -06:00
2025-01-19 10:48:16 -06:00
all := me.forge.Repos.SortByFullPath()
2024-12-12 02:05:47 -06:00
for all.Scan() {
check := all.Next()
2024-12-02 08:45:13 -06:00
if alreadyDone(check) {
// means it was already published
// protects against logic errors that might result
// in an infinite loop
2025-01-29 21:24:08 -06:00
log.Info("WARNING alreadyDone rePrepareRelease()", check.GetGoPath())
continue
}
2024-12-17 07:03:17 -06:00
if me.forge.Config.IsReadOnly(check.GetGoPath()) {
2024-12-13 02:21:39 -06:00
// can't release readonly repos
continue
}
2025-02-08 06:32:37 -06:00
if !me.forge.Config.IsPrivate(check.GetGoPath()) {
if err := checkPublishedGodeps(check); err != nil {
// this means the published godeps are no longer up to date
forceReleaseVersion(check)
me.found.AppendByGoPath(check)
log.Info("checkPublishedGodeps failed with err", check.GetGoPath(), err)
continue
} else {
// log.Info("checkPublishedGodeps is ok", check.GetGoPath())
}
}
2024-12-12 02:05:47 -06:00
// if master != lastTag, always increment
master := check.GetMasterVersion()
lastTag := check.GetLastTag()
if master != lastTag {
newmhash := check.GetTagHash(master)
oldlhash := check.GetTagHash(lastTag)
if newmhash == oldlhash {
// they are actually equal
continue
}
b1 := check.CountDiffObjects(oldlhash, newmhash)
b2 := check.CountDiffObjects(newmhash, oldlhash)
if b1 != 0 {
log.Printf("HASH ERROR %-50s tag %s < %s\n", check.GetGoPath(), newmhash, oldlhash)
log.Info("old vs new count", b1, b2, "git merge", oldlhash)
}
if b1 == 0 && b2 == 0 {
log.Info("got to identical repo", check.GetGoPath(), b1, b2)
log.Info("got to identical repo", check.GetGoPath(), oldlhash, newmhash)
// actually identical. do nothing
continue
}
if b1 == 0 && b2 == 1 {
if ok, err := me.forge.ValidGoVersion(master); ok {
log.Info("GO version valid", check.GetGoPath(), master, lastTag)
} else {
log.Info("GO version invalid", check.GetGoPath(), master, lastTag, err)
forceReleaseVersion(check)
me.found.AppendByGoPath(check)
continue
}
// if check.GetGoPath() == "go.wit.com/log" {
log.Info("edge case. don't retag.", check.GetGoPath(), b1, b2)
log.Info("edge case. don't retag.", check.GetGoPath(), oldlhash, newmhash)
// }
// actually identical. do nothing
continue
}
if check.GetGoPath() == "go.wit.com/log" {
log.Info("got to log", b1, b2)
log.Info("got to log", oldlhash, newmhash)
os.Exit(-1)
}
if gitpb.IsGoTagVersionGreater(lastTag, master) {
// this function is not right really. the hash error above should catch it correctly
// log.Printf("PROBABLY NOT NEE %-50s tag %s < %s\n", check.GetGoPath(), lastTag, master)
}
log.Printf("NEED RELEASE FOR %-50s tag %s != %s\n", check.GetGoPath(), master, lastTag)
2024-12-16 00:19:03 -06:00
forceReleaseVersion(check)
2025-01-13 08:11:43 -06:00
me.found.AppendByGoPath(check)
2024-12-16 00:19:03 -06:00
continue
}
2025-01-30 01:15:00 -06:00
if me.forge.Config.IsPrivate(check.GetGoPath()) {
// only checks after this are GO dep related which don't matter for private repos
continue
}
2025-01-17 06:20:55 -06:00
if argv.Quick != nil {
// if argv has 'quick' don't do anything
// that doesn't actually have a patch
if master == lastTag {
continue
}
}
2024-12-17 07:03:17 -06:00
if argv.Protobuf && check.GetRepoType() == "protobuf" {
log.Printf("NEED RELEASE FOR %s err: %v\n", check.GetGoPath(), "because --protobuf")
2024-12-16 00:19:03 -06:00
// if --protobuf, this will force upgrade each one
forceReleaseVersion(check)
2025-01-13 08:11:43 -06:00
me.found.AppendByGoPath(check)
2024-12-12 02:05:47 -06:00
continue
2024-12-02 08:45:13 -06:00
}
2024-12-12 02:05:47 -06:00
if check.GetGoPath() == "go.wit.com/log" {
log.Info("got to log")
os.Exit(-1)
}
// if the repo is a go binary or plugin for a new release for
// any library version change
2025-01-20 07:58:39 -06:00
// if check.GetRepoType() == "binary" || check.GetRepoType() == "plugin" {
// check if the package dependancies changed, if so, re-publish
if err := me.forge.FinalGoDepsCheckOk(check, false); err == nil {
// log.Printf("go.sum is perfect! %s\n", check.GetGoPath())
2025-01-20 07:58:39 -06:00
continue
} else {
log.Printf("NEED RELEASE FOR %-50s err: %v\n", check.GetGoPath(), err)
forceReleaseVersion(check)
me.found.AppendByGoPath(check)
}
}
2025-01-17 05:13:11 -06:00
me.forge.PrintHumanTable(me.found)
2024-12-16 00:19:03 -06:00
}
2025-01-17 14:19:26 -06:00
2025-01-18 05:52:41 -06:00
func printDone() {
for _, gopath := range me.done {
2025-01-20 05:09:28 -06:00
log.Info("printDone() THESE WERE PUBLISHED", gopath)
2025-01-18 05:52:41 -06:00
}
2025-01-20 05:09:28 -06:00
log.Sleep(1)
2025-01-18 05:52:41 -06:00
}
2025-01-17 14:19:26 -06:00
func alreadyDone(repo *gitpb.Repo) bool {
for _, gopath := range me.done {
2025-01-18 07:30:11 -06:00
// log.Info("WARNING already done", gopath, repo.GetGoPath())
// log.Info("WARNING already done", gopath, repo.GetGoPath())
// log.Info("WARNING already done", gopath, repo.GetGoPath())
2025-01-17 14:19:26 -06:00
if repo.GetGoPath() == gopath {
2025-01-18 07:30:11 -06:00
log.Info("FOUND. RETURN TRUE. already done", gopath, repo.GetGoPath())
2025-01-17 14:19:26 -06:00
return true
}
}
return false
}
2025-02-08 06:32:37 -06:00
func checkPublishedGodeps(repo *gitpb.Repo) error {
godepsOld, err := repo.GoSumFromPkgDir()
if err != nil {
return err
}
if godepsOld != nil {
if err := me.forge.TestGoDepsCheckOk(godepsOld, argv.Verbose); err != nil {
return err
}
/*
all := godepsOld.All()
for all.Scan() {
dep := all.Next()
// log.Info(repo.GetGoPath(), dep.GoPath, dep.Version)
// check if the package in question is waiting for another package to publish
found := me.forge.FindByGoPath(dep.GoPath)
if found == nil {
return fmt.Errorf("%s has godep %s which can not be found", repo.GetGoPath(), dep.GoPath)
}
if found.GetLastTag() != dep.Version {
return fmt.Errorf("%s with godep %s version mismatch %s vs %s", repo.GetGoPath(), dep.GoPath, found.GetLastTag(), dep.Version)
}
}
*/
}
godepsNew, err := repo.GoSumFromRepo()
if err != nil {
return err
}
if godepsOld == nil {
if godepsNew == nil {
log.Printf("%s published godeps == nil && real == nil\n", repo.GetGoPath())
return nil
} else {
return fmt.Errorf("published godeps == nil vs real != nil")
}
}
if err := me.forge.TestGoDepsCheckOk(godepsNew, argv.Verbose); err != nil {
return err
}
return nil
}
/*
func checkGodeps(repo *gitpb.Repo, godeps *gitpb.GoDeps) error {
if godeps == nil {
}
return nil
all := godeps.All()
for all.Scan() {
dep := all.Next()
// log.Info(repo.GetGoPath(), dep.GoPath, dep.Version)
// check if the package in question is waiting for another package to publish
found := me.forge.FindByGoPath(dep.GoPath)
if found == nil {
return fmt.Errorf("%s has godep %s which can not be found", repo.GetGoPath(), dep.GoPath)
}
if found.GetLastTag() != dep.Version {
return fmt.Errorf("%s with godep %s version mismatch %s vs %s", repo.GetGoPath(), dep.GoPath, found.GetLastTag(), dep.Version)
}
log.Printf("%s with godep %s version match %s vs %s\n", repo.GetGoPath(), dep.GoPath, found.GetLastTag(), dep.Version)
}
return nil
}
*/