GithubHelp home page GithubHelp logo

bndr / gojenkins Goto Github PK

View Code? Open in Web Editor NEW
843.0 18.0 439.0 372 KB

Jenkins API Client in Go. Looking for maintainers to move this project forward.

License: Apache License 2.0

Go 99.12% Dockerfile 0.09% Makefile 0.79%
jenkins go continuous-integration api godoc

gojenkins's Introduction

Jenkins API Client for Go

GoDoc Go Report Cart Build Status

About

Jenkins is the most popular Open Source Continuous Integration system. This Library will help you interact with Jenkins in a more developer-friendly way.

These are some of the features that are currently implemented:

  • Get information on test-results of completed/failed build
  • Ability to query Nodes, and manipulate them. Start, Stop, set Offline.
  • Ability to query Jobs, and manipulate them.
  • Get Plugins, Builds, Artifacts, Fingerprints
  • Validate Fingerprints of Artifacts
  • Create and Delete Users
  • Get Current Queue, Cancel Tasks
  • Create and Revoke API Tokens
  • etc. For all methods go to GoDoc Reference.

Installation

go get github.com/bndr/gojenkins

CLI

For users that would like CLI based on gojenkins, follow the steps below:

$ cd cli/jenkinsctl
$ make

Usage

import (
  "github.com/bndr/gojenkins"
  "context"
  "time"
  "fmt"
)

ctx := context.Background()
jenkins := gojenkins.CreateJenkins(nil, "http://localhost:8080/", "admin", "admin")
// Provide CA certificate if server is using self-signed certificate
// caCert, _ := ioutil.ReadFile("/tmp/ca.crt")
// jenkins.Requester.CACert = caCert
_, err := jenkins.Init(ctx)


if err != nil {
  panic("Something Went Wrong")
}

job, err := jenkins.GetJob(ctx, "#jobname")
if err != nil {
  panic(err)
}
queueid, err := job.InvokeSimple(ctx, params) // or  jenkins.BuildJob(ctx, "#jobname", params)
if err != nil {
  panic(err)
}
build, err := jenkins.GetBuildFromQueueID(ctx, job, queueid)
if err != nil {
  panic(err)
}

// Wait for build to finish
for build.IsRunning(ctx) {
  time.Sleep(5000 * time.Millisecond)
  build.Poll(ctx)
}

fmt.Printf("build number %d with result: %v\n", build.GetBuildNumber(), build.GetResult())

API Reference: https://godoc.org/github.com/bndr/gojenkins

Examples

For all of the examples below first create a jenkins object

import "github.com/bndr/gojenkins"

jenkins, _ := gojenkins.CreateJenkins(nil, "http://localhost:8080/", "admin", "admin").Init(ctx)

or if you don't need authentication:

jenkins, _ := gojenkins.CreateJenkins(nil, "http://localhost:8080/").Init(ctx)

you can also specify your own http.Client (for instance, providing your own SSL configurations):

client := &http.Client{ ... }
jenkins, := gojenkins.CreateJenkins(client, "http://localhost:8080/").Init(ctx)

By default, gojenkins will use the http.DefaultClient if none is passed into the CreateJenkins() function.

Check Status of all nodes

nodes := jenkins.GetAllNodes(ctx)

for _, node := range nodes {

  // Fetch Node Data
  node.Poll(ctx)
	if node.IsOnline(ctx) {
		fmt.Println("Node is Online")
	}
}

Get all Builds for specific Job, and check their status

jobName := "someJob"
builds, err := jenkins.GetAllBuildIds(ctx, jobName)

if err != nil {
  panic(err)
}

for _, build := range builds {
  buildId := build.Number
  data, err := jenkins.GetBuild(ctx, jobName, buildId)

  if err != nil {
    panic(err)
  }

	if "SUCCESS" == data.GetResult(ctx) {
		fmt.Println("This build succeeded")
	}
}

// Get Last Successful/Failed/Stable Build for a Job
job, err := jenkins.GetJob(ctx, "someJob")

if err != nil {
  panic(err)
}

job.GetLastSuccessfulBuild(ctx)
job.GetLastStableBuild(ctx)

Get Current Tasks in Queue, and the reason why they're in the queue

tasks := jenkins.GetQueue(ctx)

for _, task := range tasks {
	fmt.Println(task.GetWhy(ctx))
}

Create View and add Jobs to it

view, err := jenkins.CreateView(ctx, "test_view", gojenkins.LIST_VIEW)

if err != nil {
  panic(err)
}

status, err := view.AddJob(ctx, "jobName")

if status != nil {
  fmt.Println("Job has been added to view")
}

Create nested Folders and create Jobs in them

// Create parent folder
pFolder, err := jenkins.CreateFolder(ctx, "parentFolder")
if err != nil {
  panic(err)
}

// Create child folder in parent folder
cFolder, err := jenkins.CreateFolder(ctx, "childFolder", pFolder.GetName())
if err != nil {
  panic(err)
}

// Create job in child folder
configString := `<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties/>
  <scm class="hudson.scm.NullSCM"/>
  <canRoam>true</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers class="vector"/>
  <concurrentBuild>false</concurrentBuild>
  <builders/>
  <publishers/>
  <buildWrappers/>
</project>`

job, err := jenkins.CreateJobInFolder(ctx, configString, "jobInFolder", pFolder.GetName(), cFolder.GetName())
if err != nil {
  panic(err)
}

if job != nil {
	fmt.Println("Job has been created in child folder")
}

Get All Artifacts for a Build and Save them to a folder

job, _ := jenkins.GetJob(ctx, "job")
build, _ := job.GetBuild(ctx, 1)
artifacts := build.GetArtifacts(ctx)

for _, a := range artifacts {
	a.SaveToDir("/tmp")
}

To always get fresh data use the .Poll() method

job, _ := jenkins.GetJob(ctx, "job")
job.Poll()

build, _ := job.getBuild(ctx, 1)
build.Poll()

Create and Delete Users

// Create user
user, err := jenkins.CreateUser(ctx, "username", "password", "fullname", "[email protected]")
if err != nil {
  log.Fatal(err)
}
// Delete User
err = user.Delete()
if err != nil {
  log.Fatal(err)
}
// Delete user not created by gojenkins
err = jenkins.DeleteUser("username")

Create and Revoke API Tokens

// Create a token for admin user
token, err := jenkins.GenerateAPIToken(ctx, "TestToken")
if err != nil {
  log.Fatal(err)
}

// Set Jenkins client to use new API token
jenkins.Requester.BasicAuth.Password = token.Value

// Revoke token that was just created
token.Revoke()

// Revoke all tokens for admin user
err = jenkins.RevokeAllAPITokens(ctx)
if err != nil {
  log.Fatal(err)
}

Testing

go test

Contribute

All Contributions are welcome. The todo list is on the bottom of this README. Feel free to send a pull request.

TODO

Although the basic features are implemented there are many optional features that are on the todo list.

  • Kerberos Authentication
  • Rewrite some (all?) iterators with channels

LICENSE

Apache License 2.0

gojenkins's People

Contributors

7ac avatar adnaan avatar arcticsnowman avatar arinto avatar bang88 avatar bndr avatar boopathi avatar circa10a avatar dloucasfx avatar figo avatar franta avatar frapschen avatar gmtror avatar johnmurray avatar kelwang avatar klauern avatar maxwell92 avatar mceloud avatar nergdron avatar ns3777k avatar panpan0000 avatar supereagle avatar tamalsaha avatar thomasbs avatar thomaspeitz avatar vitalyisaev2 avatar wusphinx avatar xgwang-zte avatar xkkker avatar zahiar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gojenkins's Issues

how to pass parameter

Hi, I'm use BuildJob method to pass parameter, but jenkins not received.
my code is :

params := make(map[string]string)
params["param1"] = "ssss"
params["param2"] = "bbbb"
res, err := util.Build("test_parameter",params)

the util code is :
func Build(appName string, options ...interface{}) (bool, error) {
ret, err := jenkinsClent.BuildJob(appName, options)
}

I don't know where is wrong.

Use "pretty=false" for JSON/XML gets?

Passing this along on the querystring gives a minified response and it seems like we would always prefer this. If you think this is a good idea, I'm happy to submit a PR!

get a 403 error when deleting a job

Pretty new to Go - so feel free to point me in the right direction:

When I do (simplified the code):

jenkins, err := gojenkins.CreateJenkins("http://myjenkins.com", *user, *pwd ).Init()
job, err := jenkins.GetJob(*unregJob)
success, err := job.Delete()

I get a 403 forbidden in err, but the job was deleted.

Following up on some other threads I did a tcp dump and found that the delete was working - the link was being redirected without credentials - it was this redirection that was gettin gthe 403 response. See the following TCP Dump :

POST /job/SimpleWebApp/doDelete HTTP/1.1
Host: myjenkins.com
User-Agent: Go-http-client/1.1
Content-Length: 0
Authorization: Basic YWRtaXXXXXXXXXXZBc1lWWA==
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

HTTP/1.1 302 Found
X-Content-Type-Options: nosniff
Location: http://myjenkins.com/
Content-Length: 0
Server: Jetty(winstone-2.9)

GET / HTTP/1.1
Host: myjenkins.com
User-Agent: Go-http-client/1.1
Referer: http://myjenkins.com/job/SimpleWebApp/doDelete
Accept-Encoding: gzip

HTTP/1.1 403 Forbidden
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID.042ada4c=1vsx0bsfghws9xjghpb623usa;Path=/;HttpOnly
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/html;charset=UTF-8
X-Hudson: 1.395
X-Jenkins: 1.642.2
X-Jenkins-Session: 140c17f2
X-Hudson-CLI-Port: 50000
X-Jenkins-CLI-Port: 50000
X-Jenkins-CLI2-Port: 50000
X-You-Are-Authenticated-As: anonymous
X-You-Are-In-Group: 
X-Required-Permission: hudson.model.Hudson.Read
X-Permission-Implied-By: hudson.security.Permission.GenericRead
X-Permission-Implied-By: hudson.model.Hudson.Administer
Content-Length: 793
Server: Jetty(winstone-2.9)

<html><head><meta http-equiv='refresh' content='1;url=/login?from=%2F'/><script>window.location.replace('/login?from=%2F');</script></head><body style='background-color:white; color:white;'>


Authentication required
<!--
You are authenticated as: anonymous
Groups that you are in:

Permission you need to have (but didn't): hudson.model.Hudson.Read
 ... which is implied by: hudson.security.Permission.GenericRead
 ... which is implied by: hudson.model.Hudson.Administer
-->

Any thoughts on this ? Will also keep looking.

Jenkins should be renamed to Client (remove stutter)

Per some guidance from the Go blog, it recommends removing stutter in names: https://blog.golang.org/package-names

In particular, this portion seems relevant:

Avoid stutter. Since client code uses the package name as a prefix when referring to the package contents, the names for those contents need not repeat the package name. The HTTP server provided by the http package is called Server, not HTTPServer. Client code refers to this type as http.Server, so there is no ambiguity.

This issue shows up prominently in the README:

import "github.com/bndr/gojenkins"

jenkins := gojenkins.CreateJenkins(nil, "http://localhost:8080/", "admin", "admin")
// Provide CA certificate if server is using self-signed certificate
// caCert, _ := ioutil.ReadFile("/tmp/ca.crt")
// jenkins.Requester.CACert = caCert
_, err := jenkins.Init()

Jenkins, gojenkins, CreateJenkins. I believe most, if not all, of the references to Jenkins could easily be replaced with Client and be a lot cleaner:

import "github.com/bndr/gojenkins"

client := gojenkins.CreateClient(nil, "http://localhost:8080/", "admin", "admin")
// Provide CA certificate if server is using self-signed certificate
// caCert, _ := ioutil.ReadFile("/tmp/ca.crt")
// client.Requester.CACert = caCert
_, err := client.Init()

Fail to create job whose name with the prefix 'job'

Can create the job with name sub-job, but fail to create the same job after only change the job name to job_test.
It is caused by the code:

func (j *Job) parentBase() string {
	return j.Base[:strings.LastIndex(j.Base, "/job")]
}

I think we should get the parent base url by trimming the job name at the end of url, instead of the index of const string /job.

errcheck: should check for and return errors in all cases where they can happen

There are a number of good linters out there, one of them being errcheck. This specific tool points out a number of places where error values aren't being checked for, which can make the library user have trouble finding the root cause of an error that wasn't returned to him/her at the earliest time it came up:

artifact.go:65:20:      a.validateDownload(path)
artifact.go:112:23:     defer localFile.Close()
artifact.go:114:17:     io.WriteString(h, string(buffer[0:n]))
build.go:211:28:        b.Jenkins.Requester.GetXML(url, &content, nil)
build.go:293:8: b.Poll(3)
build.go:357:17:        result[i].Poll()
folder.go:64:9: f.Poll()
jenkins.go:258:15:      jobObj.Rename(name)
jenkins_test.go:62:20:  item.InvokeSimple(map[string]string{"param1": "param1"})
jenkins_test.go:63:12:  item.Poll()
jenkins_test.go:246:22: jenkins.GetAllJobs()
jenkins_test.go:247:23: jenkins.GetAllViews()
jenkins_test.go:248:23: jenkins.GetAllNodes()
job.go:326:9:   j.Poll()
job.go:358:9:   j.Poll()
request.go:204:24:      defer fileData.Close()
request.go:207:37:      json.NewDecoder(ar.Payload).Decode(&params)
request.go:256:27:      defer response.Body.Close()
request.go:272:27:      defer response.Body.Close()
request.go:274:39:      json.NewDecoder(response.Body).Decode(responseStruct)

seems no update job method

hi! it seems no update job method, if has pls show me,if not pls let me know.Might I can post a pr to u

Performance issue with GetAllNodes redundant call to GetNode

Within GetAllNodes, after the API call to /computer is made, GetNode makes a request to /computer/{name}, which returns the same information that's in the individual nodes of the response from /computer that's already been received:

nodes := make([]*Node, len(computers.Computers))
    for i, node := range computers.Computers {
        name := node.DisplayName
        // Special Case - Master Node
        if name == "master" {
            name = "(master)"
        }
        nodes[i], _ = j.GetNode(name)
    }

https://github.com/bndr/gojenkins/blob/master/jenkins.go#L293-L301

As far as I know, this is not a new feature to Jenkins, so I was wondering if there was some extra sizzle that made this extra API call necessary. As you can imagine, as the list of nodes grows (I have a Master with 60 slaves, which makes this particular method creep along) the time to completion grows significantly because it's making 1 http request + n http requests based on the number of slaves in the response.

Happy to PR a change but before I do, I wanted to confirm there's not something I'm missing in how the implementation is supposed to work.

errors ?

How do I know if jenkins.Getjob("jobname") returned an error ?

Shouldn't it be like this ?

job, err := jenkins.Getjob("jobname")

And this applies to other APIs also.

jenkins.GetBuild cause process down

When I call jenkins.GetBuild frequently in my web project, the process would down with following error trace:

panic: Get http://XXXXXXXXXXX/job/test-JTGVV/api/json: EOF

goroutine 189 [running]:
runtime.panic(0x8a3c80, 0xc2101b4780)
/usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
github.com/bndr/gojenkins.(_Requester).Do(0xc2100c76e0, 0x975660, 0x3, 0xc2101bbcf0, 0xf, ...)
/home/yehui/go/src/github.com/bndr/gojenkins/request.go:161 +0xb57
github.com/bndr/gojenkins.(_Requester).GetJSON(0xc2100c76e0, 0xc2101bbcf0, 0xf, 0x7c58e0, 0xc210331800, ...)
/home/yehui/go/src/github.com/bndr/gojenkins/request.go:61 +0x15a
github.com/bndr/gojenkins.(_Job).Poll(0xc2101bf020, 0x5)
/home/yehui/go/src/github.com/bndr/gojenkins/job.go:323 +0x57
github.com/bndr/gojenkins.(_Job).GetParameters(0xc2101bf020, 0xc21033c800, 0x41432b, 0xaa4510)
/home/yehui/go/src/github.com/bndr/gojenkins/job.go:242 +0x35
github.com/bndr/gojenkins.(_Job).InvokeSimple(0xc2101bf020, 0x0, 0x5)
/home/yehui/go/src/github.com/bndr/gojenkins/job.go:273 +0x54
github.com/bndr/gojenkins.(_Jenkins).BuildJob(0xc210070330, 0xc2101a9140, 0xa, 0x0, 0x0, ...)
/home/yehui/go/src/github.com/bndr/gojenkins/jenkins.go:173 +0x123
rnd-github.huawei.com/paas/application-manager/util/pipelineJenkins.ExecuteJob(0xc2101a9140, 0xa, 0x24, 0x0, 0x0)

Add support for executing groovy scripts

via the jenkins API /scriptText endpoint and return the script output if any (plain text, not json).
To execute a groovy script you send a POST request to the /scriptText endpoint with Content-Type = application/x-www-form-urlencoded and a parameter named script which holds the groovy script to execute (as a string). The request returns the output of the script as a plain text. It's the same as running the script from Jenkins' Script Console

job.Invoke() and job.InvokeSimple() should return Queue Item info

job.Invoke() and job.InvokeSimple() should either return a taskResponse or a Queue Item ID.

Since when a 201 is returned, the Location: header is the URL to the Queue Item, perhaps a taskResponse is more appropriate. Otherwise you have to parse out the Queue Item ID instead.

job.Invoke() does not work

job.Invoke right now does not work under any circumstance. It also seems like the cause parameter is entirely ignored.

Downstream jobs not registering

The job.GetDownstreamJobs() function is not returning my downstream jobs. From looking at the api documentation in the UI, there is a jobs parameter under the primary job that has all the of the subjobs under it. It seems that parameter is not mapped into the struct. Thanks

go test panic on master

Hi, I'm trying to contribute with this enhancement #34 but go test is throwing a panic. I haven't changed or added any code, i just go get the project and ran the test suite. Any help is appreciated, thanks.

$ go test

--- FAIL: TestCreateJobs (0.00s)
        Error Trace:    jenkins_test.go:29
        Error:          Expected nil, but got: &errors.errorString{s:"401"}
        Error Trace:    jenkins_test.go:30
        Error:          Expected value not to be nil.
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x481521]

goroutine 18 [running]:
panic(0x68b220, 0xc42000c230)
        /usr/local/go/src/runtime/panic.go:500 +0x1a1
testing.tRunner.func1(0xc42013c0c0)
        /usr/local/go/src/testing/testing.go:579 +0x25d
panic(0x68b220, 0xc42000c230)
        /usr/local/go/src/runtime/panic.go:458 +0x243
github.com/bndr/gojenkins.TestCreateJobs(0xc42013c0c0)
        /home/bronzdoc/gocode/src/github.com/bndr/gojenkins/jenkins_test.go:31 +0x1f1
testing.tRunner(0xc42013c0c0, 0x7058e8)
        /usr/local/go/src/testing/testing.go:610 +0x81
created by testing.(*T).Run
        /usr/local/go/src/testing/testing.go:646 +0x2ec
exit status 2
FAIL    github.com/bndr/gojenkins       0.011s

go env:

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/bronzdoc/gocode"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build008091184=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
Linux version 4.9.0-0.bpo.1-amd64 ([email protected]) (gcc version 4.9.2 (Debian 4.9.2-10) ) #1 SMP Debian 4.9.2-2~bpo8+1 (2017-01-26)

Create types for APIs

For some APIs like func (j *Jenkins) CreateNode(name string, numExecutors int, description string, remoteFS string, options ...interface{}) (*Node, error), it is not good enough:

  1. Core config of node are listed as params. If want to add another core config, the API has to be changed, which will cause the build failure for codes depend on gojenkins.
  2. Use options param as map for complex configs. This param is clear enough for users, as they do not know what key are supported, and there is no a clear struct.

I think we can create a api folder for types, the above API will be clear as func (j *Jenkins) CreateNode(node *api.Node) (*Node, error). All configs needed by a node will be stored in api.Node. In order to add more config for node, just need to add them into the struct api.Node, no need to change the API.

Once I have GetMatrixRuns(), how can I get the test results within?

This may be a question the further shows how new I am to Go; however, I have tried a number of things and have not been able to access the contents of GetMatrixRuns()

               matrixRuns, err := build.GetMatrixRuns()

        if err != nil {
            fmt.Println(buildID.Number, " ", err)
            continue
        }
        for _, run := range matrixRuns {
                fmt.Println(i)
        }

Will return:

&{0xc820204600 0xc8200e9a00 0xc82000b050 1}
&{0xc820204d80 0xc8200e9a00 0xc82000b050 1}
&{0xc820204f00 0xc8200e9a00 0xc82000b050 1}

I have tried to treat these as builds; however, references like run.Number do not work.

Any example or suggestions on how best to access the contents?

Use the net/http/DefaultClient over the hand-written one

I had a lot of issues testing this, and it boiled down to a lot of idiosyncracies related to a custom-type of an http.Client that didn't work as well as the http.DefaultClient that I just used instead. A number of things that it seems to do are done for me automatically on my environment:

  • uses built-in certificate store (no need to pass in a CA)
  • handles HTTP proxy configs better
  • leverages the NO_PROXY/no_proxy as well
  • Case-insensitive proxy settings

Overall, a lot of these things worked for me OOTB with my current projects behind my corporate proxy (Yay Go!) and I think that there should be a way to simplify or leverage what's there already if possible. I ended up changing your client entirely prior to calling Init(), which should be a default unless you need the extra configuration:

func main() {
	jenkins := gojenkins.CreateJenkins(LntProdJenkins, UserName, Token)
	jenkins.Requester.Client = http.DefaultClient
	_, err := jenkins.Init()
	if err != nil {
		panic(err)
	}
	jobs, err := jenkins.GetAllJobs()
	if err != nil {
		panic(err)
	}
	for _, job := range jobs {
		fmt.Printf("%+v\n", job)
	}
}

BuildID

The BuildID of the return value in func jenkins.BuildJob can not be used as parament of the func jenkins.GetBuild(jobname,number) directly. How to use the func jenkins.BuildJob to get the parament number in func jenkins.GetBuild(jobname,number)

Duplicate struct tags for json breaks decoding

We ran into an issue after upgrading where jobs wasn't getting populated. After doing some debugging, it appears that having SubJobs and Jobs decode from the same JSON struct tag breaks the decoding.

Add support for Contexts

It would be nice to have support for Contexts; either Go 1.7's context package or the one from previous versions of Go in x/net/context.

This would allow cancelling Jenkins requests as well as setting up timeouts in specific parts of a chain of requests.

Get Job ID/URL

Using BuildJob to create a Jenkins job but not seeing a way to get the current build ID or URL. Anyway to get this data?

panic: interface conversion: interface is float64, not int64

This bit of code is resulting in this error:

builds, err := jenkins.GetAllBuildIds(jobName)

    if err != nil {
        panic(err)
    }
    fmt.Printf("Build ID\tTimeStamp\t\tResult\tIs Running\n")
    fmt.Println("------------------------------------------------------")
    for _, build := range builds {
        buildId := build.Number
        data, err := jenkins.GetBuild(jobName, buildId)

        if err != nil {
            panic(err)
        }
        upstreamBuild, _ := data.GetUpstreamBuild()
        fmt.Println(upstreamBuild)
...

panic: interface conversion: interface is float64, not int64

goroutine 1 [running]:
github.com/bndr/gojenkins.(_Build).GetUpstreamBuildNumber(0xc8200f68d0, 0xc820101ba0, 0x0, 0x0)
/home/esammons/go/src/github.com/bndr/gojenkins/build.go:305 +0x13f
github.com/bndr/gojenkins.(_Build).GetUpstreamBuild(0xc8200f68d0, 0x86e380, 0x0, 0x0)
/home/esammons/go/src/github.com/bndr/gojenkins/build.go:317 +0x97
main.main()
/home/esammons/git/getjenkinsstats/getjenkinsstats.go:50 +0x407
exit status 2

What I am trying to do is see the results of the individual tests within a given build. Our setup consists of the following:

Results Job
-- Build starts upstream project build number nn

Actual tests run, pass, and fail are reported in the project; however, I have not found a way to get to that level of detail with this library. When trying to dig into Upstream Projects I hit the error above.

Any thoughts on how I might get actual test results from a build?

Error message in job.go has missing argument

Found via govet

github.com/bndr/gojenkins/job.go:387: missing argument for Sprintf("%s"): format reads arg 2, have only 1 args
    if isRunning && skipIfRunning {
        return false, errors.New(fmt.Sprintf("%s Will not request new build because %s is already running", j.GetName()))
    }

Im not quite sure what the other arg is suppose to be, otherwise I'll send in a pull request.

Also errors.New(fmt.Sprintf( is fine but clunky. Perhapsfmt.Errorf would be better.

thanks for a fine project!

n

Add Job.GetAllBuilds() call

It would be very useful to get all builds at once with one network call instead of one by one via GetBuild as it would make iteration of all builds many times faster.

How can I create credentials when creating node used SSHLauncher?

case "SSHLauncher":
		launcher = map[string]string{
			"stapler-class":        "hudson.plugins.sshslaves.SSHLauncher",
			"$class":               "hudson.plugins.sshslaves.SSHLauncher",
			"host":                 params["host"],
			"port":                 params["port"],
			"credentialsId":        params["credentialsId"],
			"jvmOptions":           params["jvmOptions"],
			"javaPath":             params["javaPath"],
			"prefixStartSlaveCmd":  params["prefixStartSlaveCmd"],
			"suffixStartSlaveCmd":  params["suffixStartSlaveCmd"],
			"maxNumRetries":        params["maxNumRetries"],
			"retryWaitTime":        params["retryWaitTime"],
			"lanuchTimeoutSeconds": params["lanuchTimeoutSeconds"],
			"type":                 "hudson.slaves.DumbSlave",
			"stapler-class-bag":    "true"}

Why is type 'culprit' not 'Culprit'?

Why is type 'culprit' not 'Culprit'?

Seems odd to have a structure type not follow the case rules..

Also it prevent the godoc from showing it in the documentation page and you don't have a nice link from the build.GetCulprits() function definition.

Nested jobs don't work

The getBuildByType function doesn't support nested jobs because the job.GetName function only returns the direct name of the job. The following nested job

/job/containers/job/postgres

with the following code

Base:    "/job/" + j.GetName() + "/" + number

Sets the base url to /job/postgres/1 when it should be /job/containers/job/postgres/1

Support passing CACert

Hi,
We run Jenkins with a self-signed certificate. As a result, we need to provide the CACert to talk to Jenkins. Will you accept PRs to support passing additional config for CreateJenkins() ?

Thanks.

GetResultSet() returns "no result sets found" when iterating over builds

I have two programs that do exactly the same thing with one exception. Program 1 hardcodes buildId while program 2 iterates over builds and assigns buildId := build.Number.

In program 1, I get back the expected values for PassCount and FailCount, when I run Program 2, when the same buildId is encountered I get "No reset set"

Program 1:

buildId = 467

    data, _ := jenkins.GetBuild(jobName, buildId)

    //data.Poll()
    resultSet, _ := data.GetResultSet()
    if resultSet != nil {
        fmt.Println(buildId, " Pass count : ", resultSet.PassCount, " Fail count : ", resultSet.FailCount)
    }

467 Pass count : 2399 Fail count : 25

Program 2:

for _, build := range builds {
        buildId = build.Number

        data, _ := jenkins.GetBuild(jobName, buildId)
        data.Poll()
        resultSet, _ := data.GetResultSet()
        fmt.Println(buildId, " : ")
        if resultSet != nil {
            fmt.Println(buildId, " Pass count : ", resultSet.PassCount, " Fail count : ", resultSet.FailCount)
        } else {
            continue
        }
    }

470 :
469 :
468 :
467 :
466 :

I have tried numerous approaches and always the same. You'll notice I even tried data.Poll() in program 2. Nothing has worked address the issue.

No need to check the existence of the resources when create them

When call the Jenkins REST APIs to create resources, there will be error like A job already exists with the name 'Job1_test' when they do exist, there is no need to check them in advance.

In addition, there are errors for both CreateNode() and CreateView():

  • CreateNode(): There should be error when create the node if the node already exists, instead of directly return the node info.
  • CreateView(): There will be panic error when exists or exists.Raw is nil.
	if exists.Raw.Name != "" {
		return exists, errors.New("View already exists")
	}

Character encoding issue in updateConfig function

So I use a very similar approach to create and modify jobs , and it works perfectly when I try to add Chinese or Japanese character in job description while creating a new job.

However when I modify an existing job and try to add a Chinese character in job description by calling the updateConfig function, there is only unreadable code in the description area after executing the function.

Any suggestions on how to resolve this? It really baffles me for the last few days since the CreateJob function works fine but the UpdateConfig function doesn't.

BTW thanks for resolving my last issue!

Trying to assign []gojenkins.job type fails with cannot refer to unexported name gojenkins.job

I'm trying to create a function that will allow me to perform a very simple search on a slice of jobs ([]gojenkins.job) and then return the modified slice; however, in trying to assign the type as an argument in my function I get an error "cannot refer to unexported name."

Current program is just a stub, at the moment, accept the []gojenkins.job and search and return []gojenkins.job.

func SearchJobsByName(jobs []gojenkins.job, search string) []gojenkins.job {
    return jobs
}

I anticipate calling the above with something like

jobs, _ := jenkins.GetAllJobNames()
actions.SearchJobsByName(jobs, search)

Add method to wait for a Queued Item to start

Add a method to wait for a Queued Item to start (i.e. become a Build).

This would repeatedly poll the Queue Item URL for a specific Queue Item ID until it has a build number and build URL.

This makes more sense if #38 is done as well.

Typo in function name: GetRevistionBranch()

Function name in Build is called GetRevistionBranch() instead of GetRevisionBranch(), and it also is broken with:

panic: runtime error: index out of range

goroutine 34 [running]:
panic(0x86e160, 0xc82000a0b0)
        /usr/local/go/src/runtime/panic.go:481 +0x3e6
github.com/bndr/gojenkins.(*Build).GetRevistionBranch(0xc82060b200, 0x0, 0x0)
        /git/ops/src/github.com/bndr/gojenkins/build.go:403 +0x188

Gojenkins is not Goroutine safe

When making several API calls from different gorouties, I will get the following:

fatal error: concurrent map writes

goroutine 14 [running]:
runtime.throw(0x954850, 0x15)
        /usr/local/go/src/runtime/panic.go:547 +0x90 fp=0xc82062f560 sp=0xc82062f548
runtime.mapassign1(0x8a6060, 0xc8204286f0, 0xc82062f628, 0xc82062f638)
        /usr/local/go/src/runtime/hashmap.go:445 +0xb1 fp=0xc82062f608 sp=0xc82062f560
net/textproto.MIMEHeader.Set(0xc8204286f0, 0x905ae0, 0xc, 0x9539f0, 0x10)
        /usr/local/go/src/net/textproto/header.go:22 +0xc2 fp=0xc82062f658 sp=0xc82062f608
net/http.Header.Set(0xc8204286f0, 0x905ae0, 0xc, 0x9539f0, 0x10)
        /usr/local/go/src/net/http/header.go:31 +0x49 fp=0xc82062f688 sp=0xc82062f658
github.com/bndr/gojenkins.(*Requester).SetHeader(0xc8204242d0, 0x905ae0, 0xc, 0x9539f0, 0x10, 0x410a82)
        /git/ops/src/github.com/bndr/gojenkins/request.go:85 +0x4d fp=0xc82062f6b8 sp=0xc82062f688
github.com/bndr/gojenkins.(*Requester).GetJSON(0xc8204242d0, 0xc82068b920, 0x14, 0x77b2e0, 0xc820486c00, 0xc82012de30, 0x0, 0                                 x0, 0x0)
        /git/ops/src/github.com/bndr/gojenkins/request.go:68 +0x6c fp=0xc82062f770 sp=0xc82062f6b8
github.com/bndr/gojenkins.(*Build).Poll(0xc82012de00, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0)
        /git/ops/src/github.com/bndr/gojenkins/build.go:447 +0x312 fp=0xc82062f870 sp=0xc82062f770
github.com/bndr/gojenkins.(*Job).GetBuild(0xc8205bc380, 0x46d5, 0xc8205b4450, 0x0, 0x0)
        /git/ops/src/github.com/bndr/gojenkins/job.go:104 +0x202 fp=0xc82062f968 sp=0xc82062f870

Is it possible to refactor this bit so it doesn't use global state?

<help wanted>How can I get the ConsoleOutput sync with the jenkins in the best way?

I'm trying to get the ConsoleOutput sync with jenkins when the job is building , I want to find a best way to get it. Can you give me some advice ?
Otherwise, I think it's time to make a new release, as my vendor always get the latest releases , rather than the latest code of master ,it's annoying.
Last of all ,forgive my poor english.

add credentials

Add credentials to add deletion

$ cat > credential.xml <<EOF
<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
GLOBAL
deploy-key
wecoyote
secret123
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
EOF
$ curl -X POST -H content-type:application/xml -d @credential.xml
https://jenkins.example.com/job/example-folder/credentials/store/folder/\
domain/testing/createCredentials

https://github.com/jenkinsci/credentials-plugin/blob/master/docs/user.adoc#credentials-domains

panic error

If the jobname is not exist in jenkins server,use funcs that need jobname value will occur panic error.Please add protection to the value.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.