guireleaser/doRelease.go

251 lines
8.6 KiB
Go

// This is a simple example
package main
import (
"errors"
"fmt"
"os"
"strings"
"time"
"go.wit.com/lib/gui/shell"
"go.wit.com/log"
)
func doRelease() error {
check := me.current
log.Info("doRelease() on", me.current.GetGoPath())
if !findOk {
log.Info("doRelease() immediately end something went wrong last time. findOk == false")
return fmt.Errorf("findOK = false %s", check.GetGoPath())
}
// double check release version logic
if me.release.releaseVersionB.String() != "release version "+me.release.version.String() {
log.Warn("something went wrong with the release.version:", me.release.version.String())
return fmt.Errorf("GUI lied %s", check.GetGoPath())
}
if strings.HasPrefix(me.release.version.String(), "v") {
log.Warn("everything is ok. version starts with v.", me.release.version.String())
} else {
log.Warn("version does not start with v.", me.release.version.String())
return fmt.Errorf("release does not start with a v %s", check.GetGoPath())
}
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", check.GetGoPath())
}
curName := me.current.GetCurrentBranchName()
mName := me.current.GetMasterBranchName()
if curName != mName {
log.Info("\trepo is not working from main branch", curName, "!=", mName)
return fmt.Errorf("not on main branch %s", check.GetGoPath())
}
if alreadyDone(check) {
// means it was already published
// protects against logic errors that might result
// in an infinite loop
log.Info("doRelease() WARNING. should have never gotten here. return true. already done", check.GetGoPath())
log.Info("doRelease() WARNING. should have never gotten here. return true. already done", check.GetGoPath())
log.Info("doRelease() WARNING. should have never gotten here. return true. already done", check.GetGoPath())
check.Reload()
return fmt.Errorf("already released %s", check.GetGoPath())
}
me.done = append(me.done, me.current.GetGoPath())
if err := me.forge.FinalGoDepsCheckOk(check, true); err != nil {
msg := fmt.Sprint("the go.mod file is wrong. fix it here?", check.GetGoPath())
badExit(errors.New(msg))
return fmt.Errorf("FinalGoDeps %s err %v", check.GetGoPath(), err)
}
if check.GetGoPath() == me.startRepo.GetGoPath() {
log.Info("CAN NOT SELF UPDATE.", check.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.", check.GetGoPath(), "is the same as os.Getwd()")
badExit(errors.New(msg))
}
if !me.startRepo.Exists("go.mod") {
log.Info("go.sum missing in", me.startRepo.GetGoPath())
log.Info("pick a different repo here")
log.Info("todo: error out earlier knowing this will upgrade")
log.Info("versions", me.startRepo.GetTargetVersion(), me.startRepo.GetMasterVersion())
panic("redo go.sum")
}
log.Info("\ttag and push", curName, me.release.version.String(), me.releaseReasonS)
if err := check.ValidGoSum(); err != nil {
log.Info("ValidGoSum() error", check.GetGoPath(), err)
msg := fmt.Sprint("ValidGoSum() error", check.GetGoPath(), err)
badExit(errors.New(msg))
}
var all [][]string
var autogen []string
all = append(all, []string{"git", "add", "-f", "go.mod"})
autogen = append(autogen, "go.mod")
if check.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 := me.current.IsProtobuf(); 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")
badExit(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", me.releaseReasonS})
all = append(all, []string{"git", "push"})
all = append(all, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()})
all = append(all, []string{"git", "push", "origin", me.release.version.String()})
// save the autogenerated files in git metadata (aka: notes)
cname := check.GetCurrentBranchName()
if err := check.AutogenSave(autogen, cname, true); err != nil {
log.Info("AutogenSave() error", err)
msg := fmt.Sprint("AutogenSave() error", err)
badExit(errors.New(msg))
}
if !me.current.RunAll(all) {
log.Info("failed to make new release", me.release.version.String())
findOk = false
return fmt.Errorf("setting findOK = false %s", check.GetGoPath())
}
log.Info("RELEASE OK")
// 'publish' the version to the golang package versioning system
if !doPublishVersion() {
time.Sleep(3 * time.Second)
// this can fail to update, try it again after sleep(3s)
if !doPublishVersion() {
log.Info("PUBLISH FAILED")
findOk = false
return fmt.Errorf("PUBLISH FAILED %s", check.GetGoPath())
}
}
log.Info("PUBLISH OK")
// me.current.SetGoState("RELEASED")
// unwind and re-tag. Now that the go.mod and go.sum are published, revert
// to the development branch
if !me.current.RevertMasterToDevel() {
log.Info("Revert Failed")
findOk = false
return fmt.Errorf("REVERT FAILED %s", check.GetGoPath())
}
// update tag
var retag [][]string
retag = append(retag, []string{"git", "tag", "--delete", me.release.version.String()})
retag = append(retag, []string{"git", "push", "--delete", "origin", me.release.version.String()})
retag = append(retag, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()})
retag = append(retag, []string{"git", "push", "origin", me.release.version.String()})
if err := check.AutogenRestore(cname); err != nil {
log.Info("AutogenRestore() failed", err)
} else {
cmd := []string{"git", "push", "origin", "refs/notes/*:refs/notes/*"}
check.Run(cmd)
}
if !me.current.RunAll(retag) {
log.Info("retag failed")
findOk = false
return fmt.Errorf("RETAG FAILED %s", check.GetGoPath())
}
log.Info("EVERYTHING OK. RERELEASED", me.current.GetGoPath())
// save autogen files under the tag version (for example: "v0.2.3")
newtag := me.release.version.String()
if err := check.AutogenSave(autogen, newtag, true); err != nil {
log.Info("AutogenSave() error", err)
msg := fmt.Sprint("AutogenSave() error", err)
badExit(errors.New(msg))
}
me.current.Reload()
me.forge.SetConfigSave(true)
me.forge.ConfigSave()
log.Info("sleep 2")
time.Sleep(2 * time.Second)
printDone()
rePrepareRelease()
findNext()
if me.current == nil {
log.Info("NOT GOOD TO RUN ANOTHER DAY")
log.Info("took out all the loop code")
setCurrentRepo(nil, "loop by hand motherfucker", "fucknuts")
return fmt.Errorf("findNext returned next repo == nil")
}
log.Info("GOOD TO RUN ANOTHER DAY ON:", me.current.GetGoPath())
return nil
}
// this pulls the new tag from the golang package repository
// to insert the new version
func doPublishVersion() bool {
gopath := me.current.GetGoPath()
docmd := []string{"go", "get", "-v", gopath + "@" + me.release.version.String()}
log.Info("SHOULD RUN cmd HERE:", docmd)
if me.forge.Config.IsPrivate(me.current.GetGoPath()) {
// do not self update private repos
log.Info("This is a private repo and can not be self checked")
return true
}
// try to pull from google
if gopath == me.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)
badExit(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 := me.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)
log.Info("SELF UPDATE FAILED")
return false
}
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)
log.Info("SELF UPDATE FAILED")
return false
}
log.Info("SELF UPDATE OK. out =", strings.Join(result.Stdout, "\n"))
log.Info("SELF UPDATE WORKED")
return true
}