Skip to content
This repository was archived by the owner on Jun 14, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package cmd
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should create component here. deploy branches does too much.
the command should only get the argument needed to call the components...
We should separate the ux from the business code...


import (
"bufio"
"fmt"
"os"
"os/exec"
"strings"
"time"

"github.com/fatih/color"
"github.com/rodaine/table"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var releaseInterval string
var releaseOffset string
var allowForcePush bool

func init() {
rootCmd.AddCommand(deployCmd)
deployCmd.Flags().StringVar(&releaseOffset, "releaseOffset", "1m", "Duration to wait before the first release ('5m', '1h25m', '30s')")
deployCmd.Flags().StringVar(&releaseInterval, "releaseInterval", "25m", "Duration to wait between releases. ('5m', '1h25m', '30s')")
deployCmd.Flags().BoolVar(&allowForcePush, "force", false, "Allow force push if deploy branch has diverged from base")
}

var deployCmd = &cobra.Command{
Use: "deploy",
Short: "Deploy base branch to target branches",
Long: `Deploy base branch to target branches`,
RunE: func(cmd *cobra.Command, args []string) error {
return deployBranches(
viper.GetStringMapString("release.branch-map"),
viper.GetString("release.on-deploy.body-branch-suffix-find"),
viper.GetString("release.on-deploy.body-branch-suffix-replace"),
)
},
}

func deployBranches(branchMap map[string]string, suffixFind, suffixReplace string) error {
blue := color.New(color.FgCyan)
yellow := color.New(color.FgYellow)
green := color.New(color.FgGreen)

reference := baseBranch
remote := r.GitRemote().Config().Name
releaseRepo := r.Name()
path := r.Path()
integrateGithubRelease := releaseRepo != ""

if integrateGithubRelease {
release, err := gc.LastRelease()
if err != nil {
return err
}
reference = release.GetTagName()
green.Printf("Deploying %s\n", release.GetHTMLURL())
}

blue.Printf("Release reference: %s\n", reference)
green.Println("Deployment start times are estimates.")

headerFmt := color.New(color.FgGreen, color.Underline).SprintfFunc()
columnFmt := color.New(color.FgYellow).SprintfFunc()

tbl := table.New("Branch", "Start Time")
tbl.WithHeaderFormatter(headerFmt).WithFirstColumnFormatter(columnFmt)

intervalDuration, err := time.ParseDuration(releaseInterval)
if err != nil {
return fmt.Errorf("error parsing interval: %v", err)
}
offsetDuration, err := time.ParseDuration(releaseOffset)
if err != nil {
return fmt.Errorf("error parsing offset: %v", err)
}

t := time.Now()
t = t.Add(offsetDuration)
firstRelease := t
for _, branch := range releaseBranches {
tbl.AddRow(branch, t.Format("15:04"))
t = t.Add(intervalDuration)
}

tbl.Print()
reader := bufio.NewReader(os.Stdin)
yellow.Printf("Press 'ok' to continue with Deployment:")
input, _ := reader.ReadString('\n')
text := strings.Split(input, "\n")[0]
if text != "ok" {
fmt.Printf("No deployment\n")
return nil
}
fmt.Println(text)

if firstRelease.Before(time.Now()) {
yellow.Println("\ndeployment stopped since first released time has passed. Please run again")
return nil
}

d := time.Until(firstRelease)
green.Printf("Deployment will start in %s\n", d.String())
time.Sleep(d)

for i, branch := range releaseBranches {
if i != 0 {
time.Sleep(intervalDuration)
t = t.Add(intervalDuration)
}
green.Printf("%s Deploying %s\n", time.Now().Format("15:04:05"), branch)
cmd := ""
// if reference is a branch name, use origin
pushFlag := ""
if allowForcePush {
pushFlag = "-f"
}
if reference == baseBranch {
cmd = fmt.Sprintf("cd %s && git push %s %s %s/%s:%s", path, pushFlag, remote, remote, reference, branch)
} else { // if reference is a tag don't prefix with origin
cmd = fmt.Sprintf("cd %s && git push %s %s %s:%s", path, pushFlag, remote, reference, branch)
}
green.Printf("%s Executing %s\n", time.Now().Format("15:04:05"), cmd)
out, err := exec.Command("sh", "-c", cmd).Output()

if err != nil {
return fmt.Errorf("error executing command %s:%v", cmd, err)
}
green.Printf("%s Triggered Successfully %s\n", time.Now().Format("15:04:05"), strings.TrimSpace(string(out)))

branchText, ok := branchMap[branch]
if !ok {
branchText = branch
}
if integrateGithubRelease && suffixFind != "" {
t := time.Now()
green.Printf("%s Updating release on github %s\n", time.Now().Format("15:04:05"), strings.TrimSpace(string(out)))
release, err := gc.LastRelease()
if err != nil {
return err
}

findText := fmt.Sprintf("%s ![](https://img.shields.io/badge/released%s)", branchText, suffixFind)
replaceText := fmt.Sprintf("%s ![](https://img.shields.io/badge/released-%d_%s_%d_%02d:%02d%s)", branchText, t.Day(), t.Month(), t.Year(), t.Hour(), t.Minute(), suffixReplace)
newBody := strings.Replace(*(release.Body), findText, replaceText, -1)
fmt.Println(newBody)
release.Body = &newBody
_, err = gc.EditRelease(release)
if err != nil {
return err
}

green.Printf("%s Updated release on github %s\n", time.Now().Format("15:04:05"), strings.TrimSpace(string(out)))
}
}

return nil
}
107 changes: 107 additions & 0 deletions cmd/draft.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package cmd

import (
"bufio"
"fmt"
"os"
"regexp"
"strings"
"time"

"github.com/dbaltas/ergo/github"
"github.com/dbaltas/ergo/repo"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var releaseTag string
var updateJiraFixVersions bool

func init() {
rootCmd.AddCommand(draftCmd)
draftCmd.Flags().StringVar(&releaseTag, "releaseTag", "", "Tag for the release. If empty, curent date in YYYY.MM.DD will be used")
draftCmd.Flags().BoolVar(&updateJiraFixVersions, "update-jira-fix-versions", false, "Update fix versions on Jira based on the configuration string")

}

var draftCmd = &cobra.Command{
Use: "draft",
Short: "Create a draft release [github]",
Long: `Create a draft release on github comparing one target branch with the base branch`,
RunE: func(cmd *cobra.Command, args []string) error {
return draftRelease()
},
}

func draftRelease() error {
yellow := color.New(color.FgYellow)
branchMap := viper.GetStringMapString("release.branch-map")

t := time.Now()

tagName := releaseTag
if tagName == "" {
tagName = fmt.Sprintf("%4d.%02d.%02d", t.Year(), t.Month(), t.Day())
}
name := fmt.Sprintf("%s %d %d", t.Month(), t.Day(), t.Year())

var diff []repo.DiffCommitBranch

branches := strings.Split(releaseBranchesString, ",")
for _, branch := range branches {
ahead, behind, err := r.CompareBranch(baseBranch, branch)
if err != nil {
return fmt.Errorf("error comparing %s %s:%s", baseBranch, branch, err)
}
branchCommitDiff := repo.DiffCommitBranch{
Branch: branch,
BaseBranch: baseBranch,
Ahead: ahead,
Behind: behind,
}
diff = append(diff, branchCommitDiff)
}

releaseBody := github.ReleaseBody(diff, viper.GetString("github.release-body-prefix"), branchMap)
if updateJiraFixVersions {
// Eliminate duplicates by using a map
uTasks := make(map[string]bool)
taskRegExp := viper.GetString("jira.task-regex")

re := regexp.MustCompile(fmt.Sprintf("(?m)(%v)", taskRegExp))
for _, commit := range diff[0].Behind {
res := re.FindAllStringSubmatch(commit.Message, -1)
if len(res) > 0 {
for _, task := range res {
uTasks[task[0]] = true
}
}
}

// Get all the values
tasks := make([]string, 0, len(uTasks))
for task := range uTasks {
tasks = append(tasks, task)
}
jc.UpdateIssueFixVersions(tasks)
}

fmt.Println(releaseBody)
reader := bufio.NewReader(os.Stdin)
yellow.Printf("Press 'ok' to continue with Drafting the release:")
input, _ := reader.ReadString('\n')
text := strings.Split(input, "\n")[0]
if text != "ok" {
fmt.Printf("No draft\n")
return nil
}

release, err := gc.CreateDraftRelease(name, tagName, releaseBody)

if err != nil {
return err
}
fmt.Println(release)
return nil
}
67 changes: 67 additions & 0 deletions cmd/github/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package main

import (
"context"
"fmt"

"github.com/google/go-github/github"
"github.com/spf13/viper"
"golang.org/x/oauth2"
)

func main() {
viper.AddConfigPath(".")
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
fmt.Printf("error reading config file: %v", err)
return
}

ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: viper.GetString("github.accessToken")},
)
tc := oauth2.NewClient(ctx, ts)

client := github.NewClient(tc)

// list all repositories for the authenticated user
repo, resp, err := client.Repositories.Get(ctx, "taxibeat", "rest")
if err != nil {
fmt.Printf("error list repos: %v\n", err)
return
}

fmt.Println(resp)
fmt.Println(repo.Name)

// tagName := "2018.04.19"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented code

// name := "April 19 2018"
// isDraft := true
// releaseBody := "this is a test release body created by ergo!"
// release := &github.RepositoryRelease{
// Name: &name,
// TagName: &tagName,
// Draft: &isDraft,
// Body: &releaseBody,
// }
// rel, resp, err := client.Repositories.CreateRelease(ctx, "taxibeat", "rest", release)
// if err != nil {
// fmt.Printf("error list repos: %v\n", err)
// return
// }

// fmt.Println(resp)
// fmt.Println(rel)

repos, _, err := client.Repositories.ListByOrg(ctx, "taxibeat", &github.RepositoryListByOrgOptions{
Type: "All",
})
if err != nil {
fmt.Printf("error list repos: %v\n", err)
return
}
for _, repo := range repos {
fmt.Println(*(repo.IssuesURL))
}
}
Loading