bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/build/release/githubRelease.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "log" 7 "net/http" 8 "os" 9 "path/filepath" 10 "strings" 11 "sync" 12 13 "github.com/google/go-github/github" 14 ) 15 16 type myRoundTripper struct { 17 accessToken string 18 } 19 20 func (rt myRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { 21 r.Header.Set("Authorization", fmt.Sprintf("token %s", rt.accessToken)) 22 return http.DefaultTransport.RoundTrip(r) 23 } 24 25 var ( 26 client *github.Client 27 number string 28 binDir string 29 sha string 30 ) 31 32 func init() { 33 accessToken := os.Getenv("GITHUB_ACCESS_TOKEN") 34 if accessToken == "" { 35 log.Fatal("GITHUB_ACCESS_TOKEN env required") 36 } 37 if number = os.Getenv("BUILD_NUMBER"); number == "" { 38 log.Fatal("BUILD_NUMBER env required") 39 } 40 if sha = os.Getenv("GIT_SHA"); sha == "" { 41 log.Fatal("GIT_SHA env required") 42 } 43 binDir = os.Getenv("OUTPUTDIR") 44 hClient := &http.Client{Transport: myRoundTripper{accessToken}} 45 client = github.NewClient(hClient) 46 } 47 48 func checkError(err error) { 49 if err != nil { 50 log.Fatal(err) 51 } 52 } 53 54 func main() { 55 fmt.Printf("Releasing to github %s.\n", number) 56 57 fmt.Println("Fetching latest release") 58 latest, _, err := client.Repositories.GetLatestRelease("bosun-monitor", "bosun") 59 checkError(err) 60 61 fmt.Println("Getting all prs since last release to build release notes...") 62 opts := &github.PullRequestListOptions{} 63 opts.Base = "master" 64 opts.Direction = "desc" 65 opts.State = "closed" 66 opts.Sort = "updated" 67 opts.PerPage = 100 68 reqs, _, err := client.PullRequests.List("bosun-monitor", "bosun", opts) 69 checkError(err) 70 71 // group pr titles if they are prefaced by `cmd/scollector:` or similar. 72 groups := make(map[string][]*github.PullRequest) 73 for _, pr := range reqs { 74 p := pr 75 if pr.ClosedAt.Before((*latest.CreatedAt).Time) { 76 continue 77 } 78 if pr.MergedAt == nil { 79 continue 80 } 81 titleParts := strings.SplitN(*pr.Title, ":", 2) 82 if len(titleParts) == 1 { 83 titleParts = []string{"other", titleParts[0]} 84 } 85 group := titleParts[0] 86 group = strings.Replace(group, "cmd/", "", -1) 87 *pr.Title = titleParts[1] 88 groups[group] = append(groups[group], &p) 89 } 90 91 body := "" 92 for key, prs := range groups { 93 body += fmt.Sprintf("\n### %s: ###\n", key) 94 for _, pr := range prs { 95 body += fmt.Sprintf(" - %s [#%d](%s)\n", *pr.Title, *pr.Number, *pr.HTMLURL) 96 } 97 } 98 99 fmt.Println("Creating the release...") 100 release := &github.RepositoryRelease{} 101 release.TagName = &number 102 release.TargetCommitish = &sha 103 release.Name = &number 104 isDraft := true 105 release.Draft = &isDraft 106 release.Body = &body 107 release, _, err = client.Repositories.CreateRelease("bosun-monitor", "bosun", release) 108 checkError(err) 109 110 fmt.Println("Uploading artifacts...") 111 files, err := ioutil.ReadDir(binDir) 112 checkError(err) 113 wg := sync.WaitGroup{} 114 for _, file := range files { 115 if file.IsDir() { 116 return 117 } 118 wg.Add(1) 119 filename := file.Name() 120 go func() { 121 uploadArtifact(filename, *release.ID) 122 wg.Done() 123 }() 124 } 125 wg.Wait() 126 127 fmt.Printf("Done. %s\n", *release.HTMLURL) 128 } 129 130 func uploadArtifact(filename string, id int) { 131 fmt.Println("\t", filename) 132 f, err := os.Open(filepath.Join(binDir, filename)) 133 checkError(err) 134 defer f.Close() 135 opts := &github.UploadOptions{} 136 opts.Name = filename 137 _, _, err = client.Repositories.UploadReleaseAsset("bosun-monitor", "bosun", id, opts, f) 138 checkError(err) 139 }