Files
zeekayandHanzo Dev 1ab6e799c1 cd: the module is github.com/hanzoai/cd, where it is actually hosted
go.mod still declared `module github.com/hanzoai/deploy` after the repo was
renamed. A Go module path is not cosmetic — it is the resolvable location. So
`go get github.com/hanzoai/cd` could not work, and anything importing this
module had to spell a name that no longer exists at that address. The build log
of v3.6.0 is where it surfaced: the compiler was still emitting
github.com/hanzoai/deploy/cmd/cd/commands.

3541 import paths across 690 .go, 19 .proto, 4 .yaml, 3 .sh, 2 .mod, Procfile
and Makefile. Plus the 62 ghcr.io/hanzoai/deploy image references, moved to
ghcr.io/hanzoai/cd to match hanzo.yml's build target — a distinct string from
the module path, replaced separately so neither could clobber the other.

go mod tidy clean, CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ./... clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 21:16:24 -07:00

126 lines
3.0 KiB
Go

package generator
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/hanzoai/cd/hack/gen-resources/util"
"k8s.io/client-go/kubernetes"
)
type Repo struct {
Id int `json:"id"`
Url string `json:"html_url"` //nolint:revive //FIXME(var-naming)
}
type RepoGenerator struct {
clientSet *kubernetes.Clientset
bar *util.Bar
}
func NewRepoGenerator(clientSet *kubernetes.Clientset) Generator {
return &RepoGenerator{clientSet: clientSet, bar: &util.Bar{}}
}
func fetchRepos(ctx context.Context, token string, page int) ([]Repo, error) {
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://api.github.com/repos/argoproj/argocd-example-apps/forks?per_page=100&page=%v", page), http.NoBody)
req.Header.Set("Authorization", token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var repos []Repo
err = json.Unmarshal(body, &repos)
if err != nil {
return nil, errors.New("failed to retrieve repos, reason: " + string(body))
}
return repos, nil
}
func FetchRepos(token string, samples int) ([]Repo, error) {
log.Print("Fetch repos started")
var (
ctx = context.Background()
repos []Repo
page = 1
)
for {
if page%10 == 0 {
log.Printf("Fetch repos, page: %v", page)
}
fetchedRepos, err := fetchRepos(ctx, token, page)
if err != nil {
return nil, err
}
if len(fetchedRepos) == 0 {
break
}
if len(repos)+len(fetchedRepos) > samples {
repos = append(repos, fetchedRepos[0:samples-len(repos)]...)
break
}
repos = append(repos, fetchedRepos...)
page++
}
return repos, nil
}
func (rg *RepoGenerator) Generate(opts *util.GenerateOpts) error {
repos, err := FetchRepos(opts.GithubToken, opts.RepositoryOpts.Samples)
if err != nil {
return err
}
secrets := rg.clientSet.CoreV1().Secrets(opts.Namespace)
rg.bar.NewOption(0, int64(len(repos)))
for _, repo := range repos {
_, err = secrets.Create(context.TODO(), &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "repo-",
Namespace: opts.Namespace,
Labels: map[string]string{
"app.kubernetes.io/generated-by": "cd-generator",
"cd.hanzo.ai/secret-type": "repository",
},
Annotations: map[string]string{
"managed-by": "cd.hanzo.ai",
},
},
Data: map[string][]byte{
"type": []byte("git"),
"url": []byte(repo.Url),
"project": []byte("default"),
},
}, metav1.CreateOptions{})
rg.bar.Increment()
rg.bar.Play()
}
rg.bar.Finish()
if err != nil {
return err
}
return nil
}
func (rg *RepoGenerator) Clean(opts *util.GenerateOpts) error {
log.Print("Clean repos")
secrets := rg.clientSet.CoreV1().Secrets(opts.Namespace)
return secrets.DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: "app.kubernetes.io/generated-by=cd-generator",
})
}