diff options
| author | Jeff Carr <[email protected]> | 2025-10-30 16:14:41 -0500 | 
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-10-30 16:14:41 -0500 | 
| commit | 78212e63806da6528b56a1c9f678d3ae59e8ebc2 (patch) | |
| tree | 4db2fb223588e971b6cc230bfebfc4a47899cdc4 | |
| parent | 7787400035d2e764caac766dc75111e1683e5537 (diff) | |
actually published a repo using this code
| -rw-r--r-- | argv.go | 6 | ||||
| -rw-r--r-- | doPublish.go | 41 | ||||
| -rw-r--r-- | doRelease.go | 244 | ||||
| -rw-r--r-- | findNext.go | 86 | 
4 files changed, 370 insertions, 7 deletions
@@ -82,9 +82,9 @@ type UpgradeCmd struct {  }  type PublishCmd struct { -	Protobuf bool `arg:"--protobuf"                    help:"force all protobufs to be republished"` -	Doit     bool `arg:"--doit"                        help:"actually publish"` -	// Gomod    bool `arg:"--keep-gomod"                  help:"don't really do anything"` +	Protobuf  bool `arg:"--protobuf"                    help:"force all protobufs to be republished"` +	Doit      bool `arg:"--doit"                        help:"actually publish"` +	KeepGomod bool `arg:"--keep-gomod"                  help:"don't really do anything"`  }  type InstallCmd struct { diff --git a/doPublish.go b/doPublish.go index efa8af2..9b11ddd 100644 --- a/doPublish.go +++ b/doPublish.go @@ -9,6 +9,7 @@ import (  	"go.wit.com/lib/env"  	"go.wit.com/lib/protobuf/argvpb" +	"go.wit.com/log"  )  func doPublish() error { @@ -16,11 +17,43 @@ func doPublish() error {  	// publish := me.forge.RunOnReposNewDumb(me.forge.Repos, rePrepareReleaseNew) // doesn't use Rill()  	publish := me.forge.RunOnReposNew(me.forge.Repos, rePrepareReleaseNew) -	if publish != nil { -		publish = publish.SortActual() -		footer := publish.PrintPublishNewTB() -		fmt.Printf("publish.len(%d) PrintPublishTable() footer: %s\n", publish.Len(), footer) +	if publish == nil { +		return errors.New("nothing to publish. you actually have to write code first")  	} + +	for repo := range publish.IterAll() { +		// update the target version +		// repo.IncrementTargetMinor() +		repo.IncrementTargetRevision() +	} + +	publish = publish.SortActual() +	footer := publish.PrintPublishNewTB() +	fmt.Printf("publish.len(%d) PrintPublishTable() footer: %s\n", publish.Len(), footer) + +	tryme := findNext(publish) +	if len(tryme) == 0 { +		return errors.New("can't find something safe to publish") +	} + +	startRepo := me.forge.Repos.FindByNamespace("go.wit.com/lib/xgb") +	if startRepo == nil { +		return errors.New("a startRepo can't be found") +	} + +	releaseReason := "new attempt" + +	for i, repo := range tryme { +		log.Info("tryme:", i, repo.FullPath) +		if env.True("--doit") { +			err := doRelease(repo, startRepo, releaseReason) +			if err != nil { +				return err +			} +		} +		log.Printf("WOULD HAVE RUN: doRelease(%s, %s, %s) %s\n", repo.Namespace, startRepo.Namespace, releaseReason, repo.GetTargetVersion()) +	} +  	if !env.True("--doit") {  		return errors.New("run with --doit to actually try to publish")  	} diff --git a/doRelease.go b/doRelease.go new file mode 100644 index 0000000..d5a203c --- /dev/null +++ b/doRelease.go @@ -0,0 +1,244 @@ +// This is a simple example +package main + +import ( +	"errors" +	"fmt" +	"os" +	"strings" +	"time" + +	"go.wit.com/lib/gui/shell" +	"go.wit.com/lib/protobuf/argvpb" +	"go.wit.com/lib/protobuf/gitpb" +	"go.wit.com/log" +) + +func doRelease(current *gitpb.Repo, startRepo *gitpb.Repo, releaseReason string) error { +	releaseVersion := current.GetTargetVersion() +	log.Info("doRelease() on", current.GetGoPath(), releaseVersion) +	// double check release version logic + +	if shell.Exists("go.mod") { +		log.Info("go.mod exists ok") +	} else { +		pwd, _ := os.Getwd() +		log.Info("go.mod missing in working dir", pwd) +		return fmt.Errorf("go.mod missing %s", current.GetGoPath()) +	} + +	curName := current.GetCurrentBranchName() +	mName := current.GetMasterBranchName() +	if curName != mName { +		log.Info("\trepo is not working from main branch", curName, "!=", mName) +		return fmt.Errorf("not on main branch %s", current.GetGoPath()) +	} + +	// check if the git tag already exists somehow +	testtag := releaseVersion +	if t := current.IfRefExists(testtag); t != nil { +		log.Info("TAG ALREADY EXISTS", testtag) +		return log.Errorf("%s TAG ALREADY EXISTS %s", current.FullPath, testtag) +	} else { +		log.Info("TAG IS NEW", testtag) +	} + +	if me.forge.Config.IsPrivate(current.GetGoPath()) { +		// do not self update private repos +		log.Info("This is a private repo.") +		var retag [][]string +		retag = append(retag, []string{"git", "tag", "-m", releaseReason, releaseVersion}) +		retag = append(retag, []string{"git", "push", "origin", releaseVersion}) +		if !current.RunAll(retag) { +			log.Info("retag failed") +			return fmt.Errorf("RETAG FAILED %s", current.GetGoPath()) +		} +		return nil +	} +	// me.done = append(me.done, current.GetGoPath()) +	if err := finalGoDepsCheckOk(current); err != nil { +		msg := fmt.Sprint("the go.mod file is wrong. fix it here?", current.GetGoPath()) +		return errors.New(msg) +	} +	if current.GetGoPath() == startRepo.GetGoPath() { +		log.Info("CAN NOT SELF UPDATE.", current.GetGoPath(), "is the same as os.Getwd()") +		log.Info("go get must be run from somewhere else other than startRepo") +		log.Info("chdir to autotypist if it exists") +		msg := fmt.Sprint("CAN NOT SELF UPDATE.", current.GetGoPath(), "is the same as os.Getwd()") +		return errors.New(msg) +	} +	if !startRepo.Exists("go.mod") { +		log.Info("go.sum missing in", startRepo.GetGoPath()) +		log.Info("pick a different repo here") +		log.Info("todo: error out earlier knowing this will upgrade") +		log.Info("versions", startRepo.GetTargetVersion(), startRepo.GetMasterVersion()) +		panic("redo go.sum") +	} + +	log.Info("\ttag and push", curName, releaseVersion, releaseReason) + +	if err := current.ValidGoSum(); err != nil { +		log.Info("ValidGoSum() error", current.GetGoPath(), err) +		msg := fmt.Sprint("ValidGoSum() error", current.GetGoPath(), err) +		return errors.New(msg) +	} + +	// TODO: re-add this and double check again (?) +	// _, err := current.RunVerboseOnError([]string{"go-mod-clean", "strict"}) +	// if err != nil { +	// 	return err +	// } + +	var all [][]string +	var autogen []string +	all = append(all, []string{"git", "add", "-f", "go.mod"}) +	autogen = append(autogen, "go.mod") +	if current.GoInfo.GoPrimitive { +		// don't add go.sum here. TODO: check for go.sum file and fail +	} else { +		all = append(all, []string{"git", "add", "-f", "go.sum"}) +		autogen = append(autogen, "go.sum") +	} +	if ok, compiled, err := current.ScanProtobuf(); ok { +		log.Info("\tIsProtobuf() == true") +		if err != nil { +			log.Info("\tERROR: There are protobuf files, but they are not compiled") +			log.Info("\tERROR: can not continue") +			msg := fmt.Sprint("ERROR: There are protobuf files, but they are not compiled") +			return errors.New(msg) +		} +		log.Info("\tshould add the protobuf files here") +		log.Info("\tcompiled files found:", compiled) +		for _, s := range compiled { +			log.Info("\tcompiled file found:", s) +			all = append(all, []string{"git", "add", "-f", s}) +			autogen = append(autogen, s) +		} +	} else { +		log.Info("\tIsProtobuf() == false") +	} +	all = append(all, []string{"git", "commit", "-m", releaseReason}) +	all = append(all, []string{"git", "push"}) +	all = append(all, []string{"git", "tag", "-m", releaseReason, releaseVersion}) +	all = append(all, []string{"git", "push", "origin", releaseVersion}) + +	// save the autogenerated files in git metadata (aka: notes) +	cname := current.GetCurrentBranchName() +	if err := current.AutogenSave(autogen, cname, true); err != nil { +		log.Info("AutogenSave() error", err) +		msg := fmt.Sprint("AutogenSave() error", err) +		return errors.New(msg) +	} + +	if !current.RunAll(all) { +		log.Info("failed to make new release", releaseVersion) +		return fmt.Errorf("setting findOK = false %s", current.GetGoPath()) +	} +	log.Info("RELEASE OK") + +	// 'publish' the version to the golang package versioning system +	if err := doPublishVersion(current, startRepo, releaseVersion); err != nil { +		time.Sleep(3 * time.Second) +		// this can fail to update, try it again after sleep(3s) +		if err := doPublishVersion(current, startRepo, releaseVersion); err != nil { +			log.Info("PUBLISH FAILED gopath=%s", current.GetGoPath()) +			return err +		} +	} + +	log.Info("PUBLISH OK") +	// current.SetGoState("RELEASED") + +	if argv.Publish.KeepGomod { +		log.Info("TRY THE CRAZY THING HERE") + +		// delete tag +		var retag [][]string +		retag = append(retag, []string{"git", "tag", "--delete", releaseVersion}) +		retag = append(retag, []string{"git", "push", "--delete", "origin", releaseVersion}) +		if !current.RunAll(retag) { +			log.Info("delete failed") +			argvpb.BadExit("--keep-gomod testing", fmt.Errorf("DELETE TAG FAILED %s", current.GetGoPath())) +		} + +		// switch to devel branch ? +		if current.CheckoutDevel() { +			// ok? +		} else { +			// holy crap. die here +			argvpb.BadExit("CheckoutDevel() failed", nil) +		} +		retag = append(retag, []string{"git", "tag", "-m", releaseReason, releaseVersion}) +		retag = append(retag, []string{"git", "push", "origin", releaseVersion}) + +		if !current.RunAll(retag) { +			log.Info("retag failed") +			argvpb.BadExit("--keep-gomod testing", fmt.Errorf("RETAG FAILED %s", current.GetGoPath())) +		} +		argvpb.BadExit("did --keep-gomod work?", nil) // MUST FAIL HERE +	} else { +		// unwind and re-tag. Now that the go.mod and go.sum are published, revert +		// to the development branch +		if !current.RevertMasterToDevel() { +			log.Info("Revert Failed") +			return fmt.Errorf("REVERT FAILED %s", current.GetGoPath()) +		} + +		// update tag +		var retag [][]string +		retag = append(retag, []string{"git", "tag", "--delete", releaseVersion}) +		retag = append(retag, []string{"git", "push", "--delete", "origin", releaseVersion}) +		retag = append(retag, []string{"git", "tag", "-m", releaseReason, releaseVersion}) +		retag = append(retag, []string{"git", "push", "origin", releaseVersion}) + +		if !current.RunAll(retag) { +			log.Info("retag failed") +			return fmt.Errorf("RETAG FAILED %s", current.GetGoPath()) +		} +	} +	log.Info("EVERYTHING OK. RERELEASED", current.GetGoPath()) + +	return nil +} + +// this pulls the new tag from the golang package repository +// to insert the new version +func doPublishVersion(current *gitpb.Repo, startRepo *gitpb.Repo, releaseVersion string) error { +	gopath := current.GetGoPath() +	docmd := []string{"go", "get", "-v", gopath + "@" + releaseVersion} +	log.Info("SHOULD RUN cmd HERE:", docmd) + +	if me.forge.Config.IsPrivate(current.GetGoPath()) { +		// do not self update private repos +		return errors.New("This is a private repo and can not be self checked") +	} + +	// try to pull from google +	if gopath == startRepo.GetGoPath() { +		log.Info("CAN NOT SELF UPDATE. cmd =", docmd) +		log.Info("go get must be run from somewhere else other than startRepo") +		log.Info("chdir to autotypist if it exists") +		msg := fmt.Sprint("CAN NOT SELF UPDATE. cmd =", docmd) +		return errors.New(msg) +	} +	// publish go.mod & go.sum for use with go +	os.Unsetenv("GO111MODULE") +	log.Info("TRYING TO SELF UPDATE HERE. cmd =", docmd) +	result := startRepo.Run(docmd) + +	if result.Error != nil { +		log.Info("SELF UPDATE FAILED. error =", result.Error) +		log.Info("SELF UPDATE FAILED. exit =", result.Exit) +		log.Info("SELF UPDATE FAILED. out =", result.Stdout) +		return errors.New("SELF UPDATE FAILED") +	} +	if result.Exit != 0 { +		log.Info("SELF UPDATE FAILED. error =", result.Error) +		log.Info("SELF UPDATE FAILED. exit =", result.Exit) +		log.Info("SELF UPDATE FAILED. out =", result.Stdout) +		return errors.New("SELF UPDATE FAILED") +	} +	log.Info("SELF UPDATE OK. out =", strings.Join(result.Stdout, "\n")) +	log.Info("SELF UPDATE WORKED") +	return nil +} diff --git a/findNext.go b/findNext.go new file mode 100644 index 0000000..b1c23f9 --- /dev/null +++ b/findNext.go @@ -0,0 +1,86 @@ +package main + +import ( +	"fmt" +	"os" + +	"go.wit.com/log" + +	"go.wit.com/lib/cobol" +	"go.wit.com/lib/protobuf/gitpb" +) + +// trys to figure out if there is still something to update +// todo: redo this logic as it is terrible +// rename this findNext() +func findNext(found *gitpb.Repos) []*gitpb.Repo { +	var trythese []*gitpb.Repo +	// findCounter = 0 +	var simpletable [][]string +	simpletable = append(simpletable, []string{"namespace", "function", "err reason"}) +	for check := range found.IterAll() { +		if check.GetMasterBranchName() != check.GetCurrentBranchName() { +			log.Info("FIND NEXT: YOU MUST BE ON THE MASTER BRANCH", check.GetNamespace()) +			continue +		} +		if check.IsDirty() { +			// log.Info("FIND NEXT: CAN NOT RELEASE DIRTY REPO", check.GetNamespace()) +			simpletable = append(simpletable, []string{check.GetNamespace(), "CAN NOT RELEASE DIRTY REPO"}) +			continue +		} +		/* +			if alreadyDone(check) { +				log.Info("FIND NEXT: findNext() alreadyDone. WHY IS THIS STILL CHECKING?", check.GetNamespace()) +				continue +			} +		*/ +		// log.Info("FIND NEXT: CHECKING START:", check.GetNamespace()) + +		if me.forge.Config.IsPrivate(check.GetNamespace()) { +			log.Info("FIND NEXT: GOOD TO GO ON PRIVATE REPO", check.GetNamespace()) +			trythese = append(trythese, check) +			continue +		} + +		godepsNew, err := check.GoSumFromRepo() +		if err != nil { +			errs := fmt.Sprintf("%v", err) +			simpletable = append(simpletable, []string{check.GetNamespace(), "check.GoSumFromRepo()", errs}) +			continue + +		} +		if godepsNew == nil { +			// don't check godepsNew, but check to make sure go mod tidy actually ran without error +			os.Unsetenv("GO111MODULE") +			cmd := []string{"go", "mod", "tidy"} +			err := check.RunVerbose(cmd) +			if err != nil { +				log.Info("FIND NEXT: go mod tidy failed. this go package needs to be examined by hand as it doesn't appear to be primitive") +				log.Info("FIND NEXT:", check.FullPath, cmd) +				os.Exit(-1) +			} +			// if godepsNew == nil, then this go package is a primitive and there is no go.sum file +		} else { +			if err := testGoDepsCheckOk(godepsNew); err != nil { +				log.Info("FIND NEXT: CHECKING current repo deps failed", err) +				continue +			} +		} + +		if err := finalGoDepsCheckOk(check); err != nil { +			// if err := me.forge.FinalGoDepsCheckOk(check, false); err != nil { +			// log.Info("FIND NEXT: FinalGoDepsCheckOk() repo=", check.GetNamespace(), "err:", err) +			// log.Info("FIND NEXT: CHECKING END:", check.GetNamespace()) +			// log.Info("FIND NEXT: ") +			simpletable = append(simpletable, []string{check.GetNamespace(), fmt.Sprintf("FinalGoDepsCheckOk() err(%v)", err)}) +			continue +		} +		log.Info("FIND NEXT: GOOD TO GO ON", check.GetNamespace()) +		// setCurrentRepo(check, "should be good to release", "pretty sure") +		trythese = append(trythese, check) +	} + +	footer := cobol.SimpleTable(simpletable) +	log.Info("reasons against publishing:", footer) +	return trythese +}  | 
