summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-10-30 16:14:41 -0500
committerJeff Carr <[email protected]>2025-10-30 16:14:41 -0500
commit78212e63806da6528b56a1c9f678d3ae59e8ebc2 (patch)
tree4db2fb223588e971b6cc230bfebfc4a47899cdc4
parent7787400035d2e764caac766dc75111e1683e5537 (diff)
actually published a repo using this code
-rw-r--r--argv.go6
-rw-r--r--doPublish.go41
-rw-r--r--doRelease.go244
-rw-r--r--findNext.go86
4 files changed, 370 insertions, 7 deletions
diff --git a/argv.go b/argv.go
index 61ab8f5..6779cf4 100644
--- a/argv.go
+++ b/argv.go
@@ -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
+}