forked from bsteciuk/kismatic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
release.go
141 lines (130 loc) · 3.94 KB
/
release.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
)
const (
linuxArtifact string = "./artifact/linux/kismatic.tar.gz"
darwinArtifact string = "./artifact/darwin/kismatic.tar.gz"
)
var tag = flag.String("tag", "", "the name of the git tag")
func main() {
// 0. Validate/get all the pre-reqs we need for creating the release
flag.Parse()
if *tag == "" {
exit("tag cannot be empty")
}
// For safety, this script creates a temporary release
*tag = *tag + "-CI"
fmt.Printf("Creating release for tag %q\n", *tag)
authToken := os.Getenv("GITHUB_TOKEN")
if authToken == "" {
exit("GITHUB_TOKEN environment variable is empty.")
}
// Look for the linux and darwin tarballs
if _, err := os.Stat(linuxArtifact); err != nil {
exit(fmt.Sprintf("%v", err))
}
if _, err := os.Stat(darwinArtifact); err != nil {
exit(fmt.Sprintf("%v", err))
}
// 1. Create the release with the given tag name
url := "https://api.github.com/repos/apprenda/kismatic/releases"
createBody := struct {
TagName string `json:"tag_name"`
Name string `json:"name"`
Draft bool `json:"draft"`
}{
TagName: *tag,
Name: *tag,
Draft: true,
}
createData, err := json.Marshal(createBody)
if err != nil {
exit(fmt.Sprintf("error marshaling body: %s", err))
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(createData))
if err != nil {
exit(fmt.Sprintf("error creating request: %s", err))
}
req.Header.Add("Authorization", fmt.Sprintf("token %s", authToken))
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
exit(fmt.Sprintf("error doing HTTP request: %v", err))
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
exit(fmt.Sprintf("got unexpected response code from server: %v", resp.Status))
}
createResp := struct {
WebURL string `json:"html_url"`
UploadURL string `json:"upload_url"`
}{}
if err = json.NewDecoder(resp.Body).Decode(&createResp); err != nil {
exit(fmt.Sprintf("error unmarshaling response: %v", err))
}
// 2. Upload the artifacts that are part of the release
//
// Gotta clean up the URL we get from GitHub
// e.g. https://uploads.github.com/repos/alexbrand/kurl/releases/5014109/assets{?name,label}
uploadURL := createResp.UploadURL[0:strings.Index(createResp.UploadURL, "{")]
fmt.Println("Uploading linux artifact")
artifactName := fmt.Sprintf("kismatic-%s-linux-amd64.tar.gz", *tag)
if err := uploadArtifact(artifactName, linuxArtifact, uploadURL, authToken); err != nil {
exit(fmt.Sprintf("error uploading linux artifact: %v", err))
}
fmt.Println("Uploading darwin artifact")
artifactName = fmt.Sprintf("kismatic-%s-darwin-amd64.tar.gz", *tag)
if err := uploadArtifact(artifactName, darwinArtifact, uploadURL, authToken); err != nil {
exit(fmt.Sprintf("error uploading darwin artifact: %v", err))
}
fmt.Println("New release draft is up!")
fmt.Println(createResp.WebURL)
}
func uploadArtifact(name, file, uploadURL, authToken string) error {
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()
stat, err := f.Stat()
if err != nil {
return err
}
// Create request
req, err := http.NewRequest(http.MethodPost, uploadURL, f)
q := req.URL.Query()
q.Add("name", name)
req.URL.RawQuery = q.Encode()
if err != nil {
return err
}
req.Header.Add("Content-Type", "application/x-gzip")
req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("token %s", authToken))
req.ContentLength = stat.Size()
// Issue request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
return fmt.Errorf("got unexpected response code from server: %s", resp.Status)
}
return nil
}
func exit(msg string) {
fmt.Fprintf(os.Stderr, msg+"\n")
os.Exit(1)
}