Skip to content

Commit d94272f

Browse files
authored
Merge pull request #44 from infinityworks/chore/tests
Adds blackbox behavioural test to validate metrics endpoint.
2 parents efe556f + 68c7609 commit d94272f

File tree

10 files changed

+516
-27
lines changed

10 files changed

+516
-27
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.sequence

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.PHONY: install test build
2+
13
install:
24
@go mod download
35

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,14 @@ github-exporter:
6060
Metrics will be made available on port 9171 by default
6161
An example of these metrics can be found in the `METRICS.md` markdown file in the root of this repository
6262

63+
## Tests
64+
65+
There is a set of blackbox behavioural tests which validate metrics endpoint in the `test` directory.
66+
Run as follows
67+
68+
```bash
69+
make test
70+
```
71+
6372
## Metadata
6473
[![](https://images.microbadger.com/badges/image/infinityworks/github-exporter.svg)](http://microbadger.com/images/infinityworks/github-exporter "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/version/infinityworks/github-exporter.svg)](http://microbadger.com/images/infinityworks/github-exporter "Get your own version badge on microbadger.com")

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ go 1.12
55
require (
66
github.com/fatih/structs v1.1.0
77
github.com/infinityworks/go-common v0.0.0-20170820165359-7f20a140fd37
8-
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
9-
github.com/modern-go/reflect2 v1.0.1 // indirect
108
github.com/prometheus/client_golang v0.9.2
119
github.com/sirupsen/logrus v1.4.2
10+
github.com/steinfletcher/apitest v1.3.8
1211
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
1312
)

go.sum

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
22
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
3+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
35
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
46
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
57
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
68
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
79
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
810
github.com/infinityworks/go-common v0.0.0-20170820165359-7f20a140fd37 h1:Lm6kyC3JBiJQvJrus66He0E4viqDc/m5BdiFNSkIFfU=
911
github.com/infinityworks/go-common v0.0.0-20170820165359-7f20a140fd37/go.mod h1:+OaHNKQvQ9oOCr+DgkF95PkiDx20fLHpzMp8SmRPQTg=
12+
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
1013
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
1114
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
1215
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
13-
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
14-
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
16+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1517
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1618
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
1719
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
@@ -23,11 +25,18 @@ github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nL
2325
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
2426
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
2527
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
28+
github.com/steinfletcher/apitest v1.3.8 h1:Q5CrFWbXSo9ocx9pb0IgPw38FKPKfkfEF+3+V35n4M8=
29+
github.com/steinfletcher/apitest v1.3.8/go.mod h1:LOVbGzWvWCiiVE4PZByfhRnA5L00l5uZQEx403xQ4K8=
30+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
2631
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
32+
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
2733
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
34+
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
35+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
2836
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y=
2937
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE=
3038
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
39+
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
3140
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
3241
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
3342
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

http/server.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package http
2+
3+
import (
4+
"github.com/infinityworks/github-exporter/exporter"
5+
"github.com/prometheus/client_golang/prometheus"
6+
"github.com/prometheus/client_golang/prometheus/promhttp"
7+
"log"
8+
"net/http"
9+
)
10+
11+
type Server struct {
12+
Handler http.Handler
13+
exporter exporter.Exporter
14+
}
15+
16+
func NewServer(exporter exporter.Exporter) *Server {
17+
r := http.NewServeMux()
18+
19+
// Register Metrics from each of the endpoints
20+
// This invokes the Collect method through the prometheus client libraries.
21+
prometheus.MustRegister(&exporter)
22+
23+
r.Handle(exporter.MetricsPath(), promhttp.Handler())
24+
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
25+
_, _ = w.Write([]byte(`<html>
26+
<head><title>Github Exporter</title></head>
27+
<body>
28+
<h1>GitHub Prometheus Metrics Exporter</h1>
29+
<p>For more information, visit <a href=https://github.com/infinityworks/github-exporter>GitHub</a></p>
30+
<p><a href='` + exporter.MetricsPath() + `'>Metrics</a></p>
31+
</body>
32+
</html>
33+
`))
34+
})
35+
36+
return &Server{Handler: r, exporter: exporter}
37+
}
38+
39+
func (s *Server) Start() {
40+
log.Fatal(http.ListenAndServe(":"+s.exporter.ListenPort(), s.Handler))
41+
}

main.go

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package main
22

33
import (
4-
"net/http"
5-
64
"github.com/fatih/structs"
75
conf "github.com/infinityworks/github-exporter/config"
86
"github.com/infinityworks/github-exporter/exporter"
7+
"github.com/infinityworks/github-exporter/http"
98
"github.com/infinityworks/go-common/logger"
109
"github.com/prometheus/client_golang/prometheus"
11-
"github.com/prometheus/client_golang/prometheus/promhttp"
1210
"github.com/sirupsen/logrus"
1311
)
1412

@@ -25,30 +23,12 @@ func init() {
2523
}
2624

2725
func main() {
28-
2926
log.WithFields(structs.Map(applicationCfg)).Info("Starting Exporter")
3027

31-
exporter := exporter.Exporter{
28+
exp := exporter.Exporter{
3229
APIMetrics: mets,
3330
Config: applicationCfg,
3431
}
3532

36-
// Register Metrics from each of the endpoints
37-
// This invokes the Collect method through the prometheus client libraries.
38-
prometheus.MustRegister(&exporter)
39-
40-
// Setup HTTP handler
41-
http.Handle(applicationCfg.MetricsPath(), promhttp.Handler())
42-
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
43-
w.Write([]byte(`<html>
44-
<head><title>Github Exporter</title></head>
45-
<body>
46-
<h1>GitHub Prometheus Metrics Exporter</h1>
47-
<p>For more information, visit <a href=https://github.com/infinityworks/github-exporter>GitHub</a></p>
48-
<p><a href='` + applicationCfg.MetricsPath() + `'>Metrics</a></p>
49-
</body>
50-
</html>
51-
`))
52-
})
53-
log.Fatal(http.ListenAndServe(":"+applicationCfg.ListenPort(), nil))
33+
http.NewServer(exp).Start()
5434
}

test/github_exporter_test.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package test
2+
3+
import (
4+
"fmt"
5+
"github.com/infinityworks/github-exporter/config"
6+
"github.com/infinityworks/github-exporter/exporter"
7+
web "github.com/infinityworks/github-exporter/http"
8+
"github.com/prometheus/client_golang/prometheus"
9+
"github.com/steinfletcher/apitest"
10+
"io/ioutil"
11+
"net/http"
12+
"os"
13+
"strings"
14+
"testing"
15+
)
16+
17+
func TestHomepage(t *testing.T) {
18+
test, collector := apiTest(withConfig("a/b"))
19+
defer prometheus.Unregister(&collector)
20+
21+
test.Get("/").
22+
Expect(t).
23+
Assert(bodyContains("GitHub Prometheus Metrics Exporter")).
24+
Status(http.StatusOK).
25+
End()
26+
}
27+
28+
func TestGithubExporter(t *testing.T) {
29+
test, collector := apiTest(withConfig("myOrg/myRepo"))
30+
defer prometheus.Unregister(&collector)
31+
32+
test.Mocks(
33+
githubRepos(),
34+
githubRateLimit(),
35+
githubReleases(),
36+
).
37+
Get("/metrics").
38+
Expect(t).
39+
Assert(bodyContains(`github_rate_limit 60`)).
40+
Assert(bodyContains(`github_rate_remaining 60`)).
41+
Assert(bodyContains(`github_rate_reset 1.566853865e+09`)).
42+
Assert(bodyContains(`github_repo_forks{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 10`)).
43+
Assert(bodyContains(`github_repo_open_issues{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 2`)).
44+
Assert(bodyContains(`github_repo_size_kb{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 946`)).
45+
Assert(bodyContains(`github_repo_stars{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 120`)).
46+
Assert(bodyContains(`github_repo_watchers{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 5`)).
47+
Assert(bodyContains(`github_repo_release_downloads{created_at="2019-02-28T08:25:53Z",name="myRepo_1.3.0_checksums.txt",release="1.3.0",repo="myRepo",user="myOrg"} 7292`)).
48+
Assert(bodyContains(`github_repo_release_downloads{created_at="2019-02-28T08:25:53Z",name="myRepo_1.3.0_windows_amd64.tar.gz",release="1.3.0",repo="myRepo",user="myOrg"} 21`)).
49+
Assert(bodyContains(`github_repo_release_downloads{created_at="2019-05-02T15:22:16Z",name="myRepo_2.0.0_checksums.txt",release="2.0.0",repo="myRepo",user="myOrg"} 14564`)).
50+
Assert(bodyContains(`github_repo_release_downloads{created_at="2019-05-02T15:22:16Z",name="myRepo_2.0.0_windows_amd64.tar.gz",release="2.0.0",repo="myRepo",user="myOrg"} 55`)).
51+
Status(http.StatusOK).
52+
End()
53+
}
54+
55+
func apiTest(conf config.Config) (*apitest.APITest, exporter.Exporter) {
56+
exp := exporter.Exporter{
57+
APIMetrics: exporter.AddMetrics(),
58+
Config: conf,
59+
}
60+
server := web.NewServer(exp)
61+
62+
return apitest.New().
63+
Report(apitest.SequenceDiagram()).
64+
Handler(server.Handler), exp
65+
}
66+
67+
func withConfig(repos string) config.Config {
68+
_ = os.Setenv("REPOS", repos)
69+
_ = os.Setenv("GITHUB_TOKEN", "12345")
70+
return config.Init()
71+
}
72+
73+
func githubRepos() *apitest.Mock {
74+
return apitest.NewMock().
75+
Get("https://api.github.com/repos/myOrg/myRepo").
76+
Header("Authorization", "token 12345").
77+
Query("per_page", "100").
78+
RespondWith().
79+
Times(2).
80+
Body(readFile("testdata/my_repo_response.json")).
81+
Status(200).
82+
End()
83+
}
84+
85+
func githubRateLimit() *apitest.Mock {
86+
return apitest.NewMock().
87+
Get("https://api.github.com/rate_limit").
88+
Header("Authorization", "token 12345").
89+
RespondWith().
90+
Header("X-RateLimit-Limit", "60").
91+
Header("X-RateLimit-Remaining", "60").
92+
Header("X-RateLimit-Reset", "1566853865").
93+
Status(http.StatusOK).
94+
End()
95+
}
96+
97+
func githubReleases() *apitest.Mock {
98+
return apitest.NewMock().
99+
Get("https://api.github.com/repos/myOrg/myRepo/releases").
100+
Header("Authorization", "token 12345").
101+
RespondWith().
102+
Times(2).
103+
Body(readFile("testdata/releases_response.json")).
104+
Status(http.StatusOK).
105+
End()
106+
}
107+
108+
func readFile(path string) string {
109+
bytes, err := ioutil.ReadFile(path)
110+
if err != nil {
111+
panic(err)
112+
}
113+
return string(bytes)
114+
}
115+
116+
func bodyContains(substr string) func(*http.Response, *http.Request) error {
117+
return func(res *http.Response, req *http.Request) error {
118+
bytes, err := ioutil.ReadAll(res.Body)
119+
if err != nil {
120+
panic(err)
121+
}
122+
response := string(bytes)
123+
if !strings.Contains(response, substr) {
124+
return fmt.Errorf("response did not contain substring '%s'", substr)
125+
}
126+
return nil
127+
}
128+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
{
2+
"id": 163222413,
3+
"node_id": "MDEwOlJlcG9zaXRvcnkxNjMyMjI0MTM=",
4+
"name": "myRepo",
5+
"full_name": "myOrg/myRepo",
6+
"private": false,
7+
"owner": {
8+
"login": "myOrg",
9+
"id": 1219157,
10+
"node_id": "MDQ6VXNlcjEyMTkxNTc=",
11+
"avatar_url": "https://avatars1.githubusercontent.com/u/1219157?v=4",
12+
"gravatar_id": "",
13+
"url": "https://api.github.com/users/myOrg",
14+
"html_url": "https://github.com/myOrg",
15+
"followers_url": "https://api.github.com/users/myOrg/followers",
16+
"following_url": "https://api.github.com/users/myOrg/following{/other_user}",
17+
"gists_url": "https://api.github.com/users/myOrg/gists{/gist_id}",
18+
"starred_url": "https://api.github.com/users/myOrg/starred{/owner}{/repo}",
19+
"subscriptions_url": "https://api.github.com/users/myOrg/subscriptions",
20+
"organizations_url": "https://api.github.com/users/myOrg/orgs",
21+
"repos_url": "https://api.github.com/users/myOrg/repos",
22+
"events_url": "https://api.github.com/users/myOrg/events{/privacy}",
23+
"received_events_url": "https://api.github.com/users/myOrg/received_events",
24+
"type": "User",
25+
"site_admin": false
26+
},
27+
"html_url": "https://github.com/myOrg/myRepo",
28+
"description": "A simple and extensible behavioural testing library written in golang. You can use api test to simplify REST API, HTTP handler and e2e tests.",
29+
"fork": false,
30+
"url": "https://api.github.com/repos/myOrg/myRepo",
31+
"forks_url": "https://api.github.com/repos/myOrg/myRepo/forks",
32+
"keys_url": "https://api.github.com/repos/myOrg/myRepo/keys{/key_id}",
33+
"collaborators_url": "https://api.github.com/repos/myOrg/myRepo/collaborators{/collaborator}",
34+
"teams_url": "https://api.github.com/repos/myOrg/myRepo/teams",
35+
"hooks_url": "https://api.github.com/repos/myOrg/myRepo/hooks",
36+
"issue_events_url": "https://api.github.com/repos/myOrg/myRepo/issues/events{/number}",
37+
"events_url": "https://api.github.com/repos/myOrg/myRepo/events",
38+
"assignees_url": "https://api.github.com/repos/myOrg/myRepo/assignees{/user}",
39+
"branches_url": "https://api.github.com/repos/myOrg/myRepo/branches{/branch}",
40+
"tags_url": "https://api.github.com/repos/myOrg/myRepo/tags",
41+
"blobs_url": "https://api.github.com/repos/myOrg/myRepo/git/blobs{/sha}",
42+
"git_tags_url": "https://api.github.com/repos/myOrg/myRepo/git/tags{/sha}",
43+
"git_refs_url": "https://api.github.com/repos/myOrg/myRepo/git/refs{/sha}",
44+
"trees_url": "https://api.github.com/repos/myOrg/myRepo/git/trees{/sha}",
45+
"statuses_url": "https://api.github.com/repos/myOrg/myRepo/statuses/{sha}",
46+
"languages_url": "https://api.github.com/repos/myOrg/myRepo/languages",
47+
"stargazers_url": "https://api.github.com/repos/myOrg/myRepo/stargazers",
48+
"contributors_url": "https://api.github.com/repos/myOrg/myRepo/contributors",
49+
"subscribers_url": "https://api.github.com/repos/myOrg/myRepo/subscribers",
50+
"subscription_url": "https://api.github.com/repos/myOrg/myRepo/subscription",
51+
"commits_url": "https://api.github.com/repos/myOrg/myRepo/commits{/sha}",
52+
"git_commits_url": "https://api.github.com/repos/myOrg/myRepo/git/commits{/sha}",
53+
"comments_url": "https://api.github.com/repos/myOrg/myRepo/comments{/number}",
54+
"issue_comment_url": "https://api.github.com/repos/myOrg/myRepo/issues/comments{/number}",
55+
"contents_url": "https://api.github.com/repos/myOrg/myRepo/contents/{+path}",
56+
"compare_url": "https://api.github.com/repos/myOrg/myRepo/compare/{base}...{head}",
57+
"merges_url": "https://api.github.com/repos/myOrg/myRepo/merges",
58+
"archive_url": "https://api.github.com/repos/myOrg/myRepo/{archive_format}{/ref}",
59+
"downloads_url": "https://api.github.com/repos/myOrg/myRepo/downloads",
60+
"issues_url": "https://api.github.com/repos/myOrg/myRepo/issues{/number}",
61+
"pulls_url": "https://api.github.com/repos/myOrg/myRepo/pulls{/number}",
62+
"milestones_url": "https://api.github.com/repos/myOrg/myRepo/milestones{/number}",
63+
"notifications_url": "https://api.github.com/repos/myOrg/myRepo/notifications{?since,all,participating}",
64+
"labels_url": "https://api.github.com/repos/myOrg/myRepo/labels{/name}",
65+
"releases_url": "https://api.github.com/repos/myOrg/myRepo/releases{/id}",
66+
"deployments_url": "https://api.github.com/repos/myOrg/myRepo/deployments",
67+
"created_at": "2018-12-26T22:27:19Z",
68+
"updated_at": "2019-08-22T20:25:14Z",
69+
"pushed_at": "2019-08-22T20:25:16Z",
70+
"git_url": "git://github.com/myOrg/myRepo.git",
71+
"ssh_url": "[email protected]:myOrg/myRepo.git",
72+
"clone_url": "https://github.com/myOrg/myRepo.git",
73+
"svn_url": "https://github.com/myOrg/myRepo",
74+
"homepage": "https://myRepo.dev",
75+
"size": 946,
76+
"stargazers_count": 120,
77+
"watchers_count": 120,
78+
"language": "Go",
79+
"has_issues": true,
80+
"has_projects": true,
81+
"has_downloads": true,
82+
"has_wiki": false,
83+
"has_pages": false,
84+
"forks_count": 10,
85+
"mirror_url": null,
86+
"archived": false,
87+
"disabled": false,
88+
"open_issues_count": 2,
89+
"license": {
90+
"key": "mit",
91+
"name": "MIT License",
92+
"spdx_id": "MIT",
93+
"url": "https://api.github.com/licenses/mit",
94+
"node_id": "MDc6TGljZW5zZTEz"
95+
},
96+
"forks": 10,
97+
"open_issues": 2,
98+
"watchers": 120,
99+
"default_branch": "master",
100+
"network_count": 10,
101+
"subscribers_count": 5
102+
}

0 commit comments

Comments
 (0)