-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
201 lines (173 loc) · 4.44 KB
/
main.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
package main
import (
"flag"
"fmt"
"github.com/leibowitz/gojenkins"
"os"
"regexp"
"time"
)
func main() {
var url, name, regex string
var tail bool
// Wait max X minutes for the build to finish
maxWait := time.Duration(2 * time.Minute)
flag.StringVar(&url, "jenkins", "", "Your jenkins url")
flag.StringVar(&name, "job", "", "Your job name")
flag.StringVar(®ex, "regex", "", "Regex for job name")
flag.BoolVar(&tail, "tail", tail, "Tail output to console")
flag.DurationVar(&maxWait, "maxwait", maxWait, "Maximum time to wait for a build")
flag.Parse()
if url == "" {
flag.Usage()
os.Exit(1)
}
fmt.Printf("Using jenkins URL %s\n", url)
jenkins := gojenkins.CreateJenkins(url).Init()
if jenkins == nil {
fmt.Printf("Unable to connect to: %s\n", url)
os.Exit(1)
}
if name == "" && regex == "" {
flag.Usage()
os.Exit(1)
} else if regex != "" {
var names []string
var nameMatch = regexp.MustCompile(regex)
for _, job := range jenkins.GetAllJobNames() {
if nameMatch.MatchString(job.Name) {
names = append(names, job.Name)
}
}
if len(names) == 0 {
fmt.Printf("No matching job name found\n")
os.Exit(1)
} else if len(names) > 1 {
fmt.Printf("More than one job name found: %v\n", names)
os.Exit(1)
}
// use the matched name
name = names[0]
}
job := jenkins.GetJob(name)
if job == nil {
fmt.Printf("No job found\n")
os.Exit(1)
}
fmt.Printf("Found job %s\n", job.GetName())
fmt.Printf("Next build number: %d\n", job.GetDetails().NextBuildNumber)
var paramNames []string
var buildParams flag.FlagSet
for _, property := range job.GetDetails().Property {
for _, param := range property.ParameterDefinitions {
//fmt.Printf("%s\n", param.Name)
var value string
buildParams.StringVar(&value, param.Name, "", "")
paramNames = append(paramNames, param.Name)
}
}
params := make(map[string]string)
if len(paramNames) > 0 {
err := buildParams.Parse(args())
if err != nil {
fmt.Printf("Couldn't parse the build arguments: %s\n", err.Error())
os.Exit(1)
}
for _, name := range paramNames {
f := buildParams.Lookup(name)
fmt.Printf("%s: %s\n", f.Name, f.Value)
params[f.Name] = f.Value.String()
}
}
fmt.Printf("Triggering build with params: %+v\n", params)
status := "FAILED"
rsp, err := job.Build(params)
if err == nil && job.Successful(rsp) {
status = "OK"
}
fmt.Printf("%s\n", status)
if !job.Successful(rsp) {
os.Exit(1)
}
fmt.Printf("%s\n", rsp.Header.Get("Location"))
// Stop now if we are not tailing build output to console
if !tail {
os.Exit(0)
}
start := time.Now()
var build *gojenkins.Build
// Wait for build to exist
for {
//fmt.Printf("1.Waiting for build: %d\n", job.GetDetails().NextBuildNumber)
build = job.GetBuild(job.GetDetails().NextBuildNumber)
if build != nil {
fmt.Printf("\nBuild found:\n%s\n", build.GetUrl())
break
}
if time.Now().Sub(start) > maxWait {
fmt.Printf("\nGiving up waiting for build to exist\n")
os.Exit(1)
}
fmt.Printf(".")
time.Sleep(3 * time.Second)
}
go func(build *gojenkins.Build) {
if build == nil {
fmt.Printf("Can't stream output with no build to stream from")
return
}
err := build.StreamOutput()
if err != nil {
fmt.Printf("Couldn't stream output: %s\n", err.Error())
return
}
}(build)
if build.GetResult() == "" {
// Wait for build to start
for {
//fmt.Printf("2.Result: %s\n", build.GetResult())
if build.IsRunning() || build.GetResult() != "" {
fmt.Printf("\nJob is Running\n")
break
}
if time.Now().Sub(start) > maxWait {
fmt.Printf("\nGiving up waiting for build to start\n")
os.Exit(1)
}
fmt.Printf(".")
time.Sleep(3 * time.Second)
}
}
// Waiting for build to finish
for {
build.Poll()
//fmt.Printf("3.Result: %s\n", build.GetResult())
if build.GetResult() != "" {
fmt.Printf("\nJob is Finished\n")
break
}
if time.Now().Sub(start) > maxWait {
fmt.Printf("\nGiving up waiting for build to finish\n")
os.Exit(1)
}
fmt.Printf(".")
time.Sleep(3 * time.Second)
}
if build.GetResult() == "SUCCESS" {
if build.Raw.Description != nil {
fmt.Printf("Result: %v\n", build.Raw.Description.(string))
}
} else {
fmt.Printf("Job %s\n", build.GetResult())
}
}
// get list of command-line arguments pre-prended with "-"
// so we can parse them using flag.Parse()
func args() []string {
args := flag.Args()
var nArgs []string
for _, s := range args {
nArgs = append(nArgs, "-"+s)
}
return nArgs
}