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  }