// 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 }