mirror of
https://github.com/veggiemonk/awesome-docker.git
synced 2026-04-01 07:05:38 +02:00
Harden health checks and refresh GitHub health cache
This commit is contained in:
@@ -200,6 +200,12 @@ func healthCmd() *cobra.Command {
|
|||||||
for _, e := range errs {
|
for _, e := range errs {
|
||||||
fmt.Printf(" error: %v\n", e)
|
fmt.Printf(" error: %v\n", e)
|
||||||
}
|
}
|
||||||
|
if len(infos) == 0 {
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return fmt.Errorf("failed to fetch GitHub metadata for all repositories (%d errors); check network/DNS and GITHUB_TOKEN", len(errs))
|
||||||
|
}
|
||||||
|
return fmt.Errorf("no GitHub repositories found in README")
|
||||||
|
}
|
||||||
|
|
||||||
scored := scorer.ScoreAll(infos)
|
scored := scorer.ScoreAll(infos)
|
||||||
cacheEntries := scorer.ToCacheEntries(scored)
|
cacheEntries := scorer.ToCacheEntries(scored)
|
||||||
|
|||||||
2122
config/health_cache.yaml
Normal file
2122
config/health_cache.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -27,21 +27,35 @@ type RepoInfo struct {
|
|||||||
|
|
||||||
// ExtractGitHubRepo extracts owner/name from a GitHub URL.
|
// ExtractGitHubRepo extracts owner/name from a GitHub URL.
|
||||||
// Returns false for non-repo URLs (issues, wiki, apps, etc.).
|
// Returns false for non-repo URLs (issues, wiki, apps, etc.).
|
||||||
func ExtractGitHubRepo(url string) (owner, name string, ok bool) {
|
func ExtractGitHubRepo(rawURL string) (owner, name string, ok bool) {
|
||||||
if !strings.HasPrefix(url, "https://github.com/") {
|
u, err := url.Parse(rawURL)
|
||||||
|
if err != nil {
|
||||||
return "", "", false
|
return "", "", false
|
||||||
}
|
}
|
||||||
path := strings.TrimPrefix(url, "https://github.com/")
|
|
||||||
path = strings.TrimRight(path, "/")
|
host := strings.ToLower(u.Hostname())
|
||||||
|
if host != "github.com" && host != "www.github.com" {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
path := strings.Trim(u.Path, "/")
|
||||||
parts := strings.Split(path, "/")
|
parts := strings.Split(path, "/")
|
||||||
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
||||||
return "", "", false
|
return "", "", false
|
||||||
}
|
}
|
||||||
// Skip non-repo paths
|
|
||||||
if parts[0] == "apps" || parts[0] == "features" || parts[0] == "topics" {
|
// Skip known non-repository top-level routes.
|
||||||
|
switch parts[0] {
|
||||||
|
case "apps", "features", "topics":
|
||||||
return "", "", false
|
return "", "", false
|
||||||
}
|
}
|
||||||
return parts[0], parts[1], true
|
|
||||||
|
name = strings.TrimSuffix(parts[1], ".git")
|
||||||
|
if name == "" {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts[0], name, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func isHTTPURL(raw string) bool {
|
func isHTTPURL(raw string) bool {
|
||||||
@@ -52,6 +66,16 @@ func isHTTPURL(raw string) bool {
|
|||||||
return u.Scheme == "http" || u.Scheme == "https"
|
return u.Scheme == "http" || u.Scheme == "https"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isGitHubAuthError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
s := strings.ToLower(err.Error())
|
||||||
|
return strings.Contains(s, "401 unauthorized") ||
|
||||||
|
strings.Contains(s, "bad credentials") ||
|
||||||
|
strings.Contains(s, "resource not accessible by integration")
|
||||||
|
}
|
||||||
|
|
||||||
// PartitionLinks separates URLs into GitHub repos and external HTTP(S) links.
|
// PartitionLinks separates URLs into GitHub repos and external HTTP(S) links.
|
||||||
func PartitionLinks(urls []string) (github, external []string) {
|
func PartitionLinks(urls []string) (github, external []string) {
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
@@ -134,6 +158,9 @@ func (gc *GitHubChecker) CheckRepos(ctx context.Context, urls []string, batchSiz
|
|||||||
info, err := gc.CheckRepo(ctx, owner, name)
|
info, err := gc.CheckRepo(ctx, owner, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
|
if isGitHubAuthError(err) {
|
||||||
|
break
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
results = append(results, info)
|
results = append(results, info)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package checker
|
package checker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,6 +15,10 @@ func TestExtractGitHubRepo(t *testing.T) {
|
|||||||
{"https://github.com/docker/compose", "docker", "compose", true},
|
{"https://github.com/docker/compose", "docker", "compose", true},
|
||||||
{"https://github.com/moby/moby", "moby", "moby", true},
|
{"https://github.com/moby/moby", "moby", "moby", true},
|
||||||
{"https://github.com/user/repo/", "user", "repo", true},
|
{"https://github.com/user/repo/", "user", "repo", true},
|
||||||
|
{"https://github.com/user/repo?tab=readme-ov-file", "user", "repo", true},
|
||||||
|
{"https://github.com/user/repo#readme", "user", "repo", true},
|
||||||
|
{"https://github.com/user/repo.git", "user", "repo", true},
|
||||||
|
{"https://www.github.com/user/repo", "user", "repo", true},
|
||||||
{"https://github.com/user/repo/issues", "", "", false},
|
{"https://github.com/user/repo/issues", "", "", false},
|
||||||
{"https://github.com/user/repo/wiki", "", "", false},
|
{"https://github.com/user/repo/wiki", "", "", false},
|
||||||
{"https://github.com/apps/dependabot", "", "", false},
|
{"https://github.com/apps/dependabot", "", "", false},
|
||||||
@@ -52,3 +57,22 @@ func TestPartitionLinks(t *testing.T) {
|
|||||||
t.Errorf("external links = %d, want 2", len(ext))
|
t.Errorf("external links = %d, want 2", len(ext))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsGitHubAuthError(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
err error
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{errors.New("non-200 OK status code: 401 Unauthorized body: \"Bad credentials\""), true},
|
||||||
|
{errors.New("Resource not accessible by integration"), true},
|
||||||
|
{errors.New("dial tcp: lookup api.github.com: no such host"), false},
|
||||||
|
{errors.New("context deadline exceeded"), false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
got := isGitHubAuthError(tt.err)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("isGitHubAuthError(%q) = %v, want %v", tt.err, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user