├── image1.png ├── image2.png ├── README.md └── main.go /image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorentzca/alfred-circleci-workflow/HEAD/image1.png -------------------------------------------------------------------------------- /image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorentzca/alfred-circleci-workflow/HEAD/image2.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Alfred CircleCI Workflow 2 | 3 | Show CircleCI Build Status. 4 | 5 | ![](./image1.png) 6 | 7 | ![](./image2.png) 8 | 9 | ## Install 10 | 11 | Download and double-click. 12 | 13 | - https://github.com/lorentzca/alfred-circleci-workflow/releases/latest 14 | 15 | ## Usage 16 | 17 | Register CircleCI Token. 18 | 19 | - `apikey` saved in your `Keychain Access.app` 20 | 21 | ``` 22 | circleci token 23 | ``` 24 | 25 | Search and show build status. 26 | 27 | - filterable word is repository or branch or build status or username 28 | 29 | ``` 30 | circleci 31 | ``` 32 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "flag" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | "strings" 10 | ) 11 | 12 | type Recentbuild struct { 13 | Branch string `json:"branch"` 14 | BuildUrl string `json:"build_url"` 15 | StartTime string `json:"start_time"` 16 | BuildTimeMillis int `json:"build_time_millis"` 17 | Status string `json:"status"` 18 | BuildNum int `json:"build_num"` 19 | UserName string `json:"username"` 20 | RepoName string `json:"reponame"` 21 | } 22 | 23 | type Items struct { 24 | Item []Item `json:"items"` 25 | } 26 | 27 | type Item struct { 28 | Title string `json:"title"` 29 | Subtitle string `json:"subtitle"` 30 | Arg string `json:"arg"` 31 | Icon icon `json:"icon"` 32 | } 33 | 34 | type icon struct { 35 | Path string `json:"path"` 36 | } 37 | 38 | func circleci() { 39 | var token *string = flag.String("t", "secret", "CirclCI Token") 40 | var filter *string = flag.String("f", "reponame, branch, username, status...", "Search Filter") 41 | flag.Parse() 42 | 43 | url := "https://circleci.com/api/v1.1/recent-builds?circle-token=" + *token 44 | 45 | client := &http.Client{} 46 | req, _ := http.NewRequest("GET", url, nil) 47 | req.Header.Add("Accept", "application/json") 48 | res, _ := client.Do(req) 49 | defer res.Body.Close() 50 | 51 | body, _ := ioutil.ReadAll(res.Body) 52 | 53 | var r []Recentbuild 54 | json.Unmarshal(body, &r) 55 | 56 | var items []Item 57 | for _, v := range r { 58 | if strings.Contains(v.RepoName+v.Branch+v.Status+v.UserName, *filter) { 59 | title := "#" + fmt.Sprint(v.BuildNum) + 60 | " / " + v.RepoName + 61 | " / " + v.Branch 62 | 63 | sec := v.BuildTimeMillis / 1000 64 | subtitle := "user: " + v.UserName + 65 | " / start: " + v.StartTime + 66 | " / buildtime: " + fmt.Sprint(sec) + "sec" 67 | 68 | var color string 69 | if v.Status == "no_tests" || v.Status == "not_run" || v.Status == "not_running" { 70 | color = "gray" 71 | } else if v.Status == "fixed" || v.Status == "success" { 72 | color = "green" 73 | } else if v.Status == "queued" || v.Status == "scheduled" { 74 | color = "purple" 75 | } else if v.Status == "canceled" || v.Status == "failed" || v.Status == "infrastructure_fail" || v.Status == "timeout" { 76 | color = "red" 77 | } else if v.Status == "retried" || v.Status == "running" { 78 | color = "blue" 79 | } 80 | 81 | items = append(items, Item{ 82 | Title: title, 83 | Subtitle: subtitle, 84 | Arg: v.BuildUrl, 85 | Icon: icon{Path: color + ".png"}}) 86 | } 87 | } 88 | 89 | j, _ := json.Marshal(Items{Item: items}) 90 | fmt.Println(string(j)) 91 | } 92 | 93 | func main() { 94 | circleci() 95 | } 96 | --------------------------------------------------------------------------------