├── .gitignore ├── .editorconfig ├── go-bob-status ├── docker-compose.yml ├── Dockerfile ├── README.md ├── Vagrantfile └── main.go /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | env.list -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.go] 2 | indent_style = tab 3 | indent_size = 4 4 | -------------------------------------------------------------------------------- /go-bob-status: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shell/go-bob-status/master/go-bob-status -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.2' 2 | services: 3 | cli: 4 | build: 5 | context: . 6 | env_file: env.list 7 | depends_on: 8 | - redis 9 | redis: 10 | image: redis:alpine -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:onbuild 2 | ADD . /go/src/github.com/shell/go-bob-status 3 | RUN go install github.com/shell/go-bob-status 4 | CMD ["/go/bin/go-bob-status", "-t", "$GITHUB_TOKEN", "-u", "$JENKINS_USER", "-p", "$JENKINS_PASSWORD"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go Bob Status 2 | 3 | Sync Jenkins build status with Github commit written in Golang 4 | 5 | ## Cli app 6 | 7 | Type --help to see all variables that needs to be set 8 | 9 | 10 | ## Compile binary for Linux 11 | 12 | CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o go-bob-status . -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure 5 | # configures the configuration version (we support older styles for 6 | # backwards compatibility). Please don't change it unless you know what 7 | # you're doing. 8 | 9 | Vagrant.configure("2") do |config| 10 | config.vm.box = "ubuntu/trusty64" 11 | 12 | config.vm.box_check_update = false 13 | config.vm.hostname = "go-box" 14 | config.vm.synced_folder ".", "/vagrant" 15 | config.vm.network "private_network", ip: "192.168.33.10" 16 | end 17 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "strings" 8 | "sync" 9 | "time" 10 | 11 | "github.com/bndr/gojenkins" 12 | "github.com/go-redis/redis" 13 | "github.com/google/go-github/github" 14 | flags "github.com/jessevdk/go-flags" 15 | "golang.org/x/oauth2" 16 | ) 17 | 18 | const ( 19 | gitHubOwner = "revdotcom" 20 | gitHubRepo = "revdotcom" 21 | noColor = "\033[0m" 22 | colorGreen = "\033[0;32m" 23 | colorRed = "\033[0;31m" 24 | ) 25 | 26 | type opts struct { 27 | GithubToken string `short:"t" long:"token" description:"Github Api Token" required:"true"` 28 | JenkinsUsername string `short:"u" long:"user" description:"Jenkins username" required:"true"` 29 | JenkinsPassword string `short:"p" long:"password" description:"Jenkins password" required:"true"` 30 | } 31 | 32 | func getGitHubClient(gitHubToken string) (*github.Client, *context.Context) { 33 | ctx := context.Background() 34 | tokenService := oauth2.StaticTokenSource( 35 | &oauth2.Token{AccessToken: gitHubToken}, 36 | ) 37 | tokenClient := oauth2.NewClient(ctx, tokenService) 38 | ghClient := github.NewClient(tokenClient) 39 | return ghClient, &ctx 40 | } 41 | 42 | func getJenkinsClient(jenkinsUsername, jenkinsPassword string) *gojenkins.Jenkins { 43 | client := gojenkins.CreateJenkins(nil, "https://ci.rev.com", jenkinsUsername, jenkinsPassword) 44 | 45 | if _, err := client.Init(); err != nil { 46 | panic("Something went wrong") 47 | } 48 | 49 | return client 50 | } 51 | 52 | func getRedisClient() *redis.Client { 53 | client := redis.NewClient(&redis.Options{ 54 | Addr: "localhost:6379", 55 | Password: "", // no password set 56 | DB: 0, // use default DB 57 | }) 58 | 59 | if _, err := client.Ping().Result(); err != nil { 60 | panic("can't connect to Redis") 61 | } 62 | return client 63 | } 64 | 65 | func getRedisKey(sha string) string { 66 | return "github:" + gitHubRepo + ":" + sha 67 | } 68 | 69 | func main() { 70 | args := opts{} 71 | parser := flags.NewParser(&args, flags.Default) 72 | 73 | if _, err := parser.Parse(); err != nil { 74 | os.Exit(1) 75 | } 76 | 77 | ghClient, ctx := getGitHubClient(args.GithubToken) 78 | jenkinsClient := getJenkinsClient(args.JenkinsUsername, args.JenkinsPassword) 79 | redisClient := getRedisClient() 80 | 81 | jobs, errj := jenkinsClient.GetAllJobs() 82 | 83 | if errj != nil { 84 | panic("can't fetch jobs") 85 | } 86 | 87 | var waitGroup sync.WaitGroup 88 | waitGroup.Add(len(jobs)) 89 | 90 | defer waitGroup.Wait() 91 | 92 | for _, job := range jobs { 93 | go func(j gojenkins.Job) { 94 | defer waitGroup.Done() 95 | 96 | jobName := j.GetName() 97 | 98 | if strings.HasPrefix(jobName, "Rev.com-build-feature_") { 99 | build, _ := j.GetLastBuild() 100 | sha := build.GetRevision() 101 | 102 | var status string 103 | if build.IsRunning() { 104 | status = "pending" 105 | } else { 106 | if build.IsGood() { 107 | status = "success" 108 | } else { 109 | status = "failure" 110 | } 111 | } 112 | buildURL := build.GetUrl() + "console" // Point to the console log directly 113 | 114 | statusColor := colorGreen 115 | if status != "success" { 116 | statusColor = colorRed 117 | } 118 | 119 | rStatus, rErr := redisClient.Get(getRedisKey(sha)).Result() 120 | if rErr != nil || rStatus != status { 121 | repoStatus := github.RepoStatus{ 122 | State: &status, 123 | TargetURL: &buildURL, 124 | } 125 | ghClient.Repositories.CreateStatus(*ctx, gitHubOwner, gitHubRepo, sha, &repoStatus) 126 | redisClient.Set(getRedisKey(sha), status, time.Hour*24*14) 127 | 128 | fmt.Printf("%vsha: %v with status: %v%v\n", noColor, sha, statusColor, status) 129 | } else { 130 | fmt.Printf("%vsha[Cache]: \033[1;30m%v %vwith status: %v%v\n", noColor, sha, noColor, statusColor, status) 131 | } 132 | } 133 | }(*job) 134 | } 135 | } 136 | --------------------------------------------------------------------------------