diff --git a/appview/pipelines/pipelines.go b/appview/pipelines/pipelines.go --- a/appview/pipelines/pipelines.go +++ b/appview/pipelines/pipelines.go @@ -96,12 +96,43 @@ // no filters otherwise, default to "all" filterKind = "all" } + if f.Spindle == "" { + p.pages.Pipelines(w, pages.PipelinesParams{ + BaseParams: pages.BaseParamsFromContext(r.Context()), + RepoInfo: p.repoResolver.GetRepoInfo(r, user), + Pipelines: nil, + FilterKind: filterKind, + Total: 0, + }) + return + } + + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) + if err != nil { + l.Error("invalid spindle host", "host", f.Spindle, "err", err) + p.pages.Pipelines(w, pages.PipelinesParams{ + BaseParams: pages.BaseParamsFromContext(r.Context()), + RepoInfo: p.repoResolver.GetRepoInfo(r, user), + Pipelines: nil, + FilterKind: filterKind, + Total: 0, + }) + return + } + // sh.tangled.ci.queryPipelines(repo, kind, limit=30) - xrpcc := indigoxrpc.Client{Host: f.Spindle} + xrpcc := indigoxrpc.Client{Host: spindleUrl} out, err := tangled.CiQueryPipelines(r.Context(), &xrpcc, nil, "", 1, f.RepoDid) if err != nil { l.Error("failed to fetch pipelines", "err", err) - panic("unimplemented") // spindle failure, appview should not fail. + p.pages.Pipelines(w, pages.PipelinesParams{ + BaseParams: pages.BaseParamsFromContext(r.Context()), + RepoInfo: p.repoResolver.GetRepoInfo(r, user), + Pipelines: nil, + FilterKind: filterKind, + Total: 0, + }) + return } p.pages.Pipelines(w, pages.PipelinesParams{ @@ -143,7 +174,19 @@ // TODO: change url path to: // /{owner}/{slug}/pipelines/{spindle-did}/{pipeline-id}/workflow/{workflow-id} - xrpcc := &indigoxrpc.Client{Host: f.Spindle} + if f.Spindle == "" { + p.pages.Error404(w) + return + } + + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) + if err != nil { + l.Error("invalid spindle host", "host", f.Spindle, "err", err) + p.pages.Error404(w) + return + } + + xrpcc := &indigoxrpc.Client{Host: spindleUrl} out, err := tangled.CiGetPipeline(r.Context(), xrpcc, pipelineId.String()) if err != nil { // TODO(boltless): change behavior based on error @@ -237,10 +280,16 @@ ctx, cancel := context.WithCancel(r.Context()) defer cancel() + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) + if err != nil { + l.Error("invalid spindle host", "host", f.Spindle, "err", err) + return + } + evChan := make(chan *tangled.CiPipelineSubscribeLogs_Event, 100) done := make(chan error, 1) sched := &webLogScheduler{ch: evChan} - xrpcc := &lexutil.Client{Client: indigoxrpc.Client{Host: f.Spindle}} + xrpcc := &lexutil.Client{Client: indigoxrpc.Client{Host: spindleUrl}} go func() { done <- tangled.CiPipelineSubscribeLogs(ctx, xrpcc, pipelineId.String(), []string{workflowName}, sched) }() diff --git a/appview/pulls/list.go b/appview/pulls/list.go --- a/appview/pulls/list.go +++ b/appview/pulls/list.go @@ -15,6 +15,7 @@ "tangled.org/core/orm" "github.com/bluesky-social/indigo/atproto/syntax" indigoxrpc "github.com/bluesky-social/indigo/xrpc" + "tangled.org/core/hostutil" ) func (s *Pulls) RepoPulls(w http.ResponseWriter, r *http.Request) { @@ -264,13 +265,21 @@ } // commitId -> latest pipeline pipelines := func(ctx context.Context, shas []string) map[string]tangled.CiDefs_Pipeline { - xrpcc := &indigoxrpc.Client{Host: f.Spindle} + m := make(map[string]tangled.CiDefs_Pipeline) + if f.Spindle == "" { + return m + } + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) + if err != nil { + l.Error("invalid spindle host", "host", f.Spindle, "err", err) + return m + } + xrpcc := &indigoxrpc.Client{Host: spindleUrl} out, err := tangled.CiQueryPipelines(ctx, xrpcc, shas, "", 0, f.RepoDid) if err != nil { l.Error("failed to fetch pipelines", "err", err) + return m } - - m := make(map[string]tangled.CiDefs_Pipeline) for _, pipeline := range out.Pipelines { if pipeline == nil { diff --git a/appview/pulls/single.go b/appview/pulls/single.go --- a/appview/pulls/single.go +++ b/appview/pulls/single.go @@ -18,6 +18,7 @@ "github.com/bluesky-social/indigo/atproto/syntax" indigoxrpc "github.com/bluesky-social/indigo/xrpc" "github.com/go-chi/chi/v5" + "tangled.org/core/hostutil" ) // htmx fragment @@ -161,13 +162,21 @@ } // commitId -> latest pipeline pipelines := func(ctx context.Context) map[string]tangled.CiDefs_Pipeline { - xrpcc := &indigoxrpc.Client{Host: f.Spindle} + m := make(map[string]tangled.CiDefs_Pipeline) + if f.Spindle == "" { + return m + } + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) + if err != nil { + l.Error("invalid spindle host", "host", f.Spindle, "err", err) + return m + } + xrpcc := &indigoxrpc.Client{Host: spindleUrl} out, err := tangled.CiQueryPipelines(ctx, xrpcc, shas, "", 0, f.RepoDid) if err != nil { l.Error("failed to fetch pipelines", "err", err) + return m } - - m := make(map[string]tangled.CiDefs_Pipeline) for _, pipeline := range out.Pipelines { if pipeline == nil { diff --git a/appview/repo/repo_util.go b/appview/repo/repo_util.go --- a/appview/repo/repo_util.go +++ b/appview/repo/repo_util.go @@ -10,6 +10,7 @@ indigoxrpc "github.com/bluesky-social/indigo/xrpc" "tangled.org/core/api/tangled" "tangled.org/core/appview/models" + "tangled.org/core/hostutil" "tangled.org/core/types" ) @@ -87,9 +88,7 @@ return } -// grab pipelines from DB and munge that into a hashmap with commit sha as key -// -// golang is so blessed that it requires 35 lines of imperative code for this +// fetch pipelines from DB and map by commit sha func getPipelineStatuses( ctx context.Context, repo *models.Repo, @@ -101,7 +100,16 @@ if len(shas) == 0 { return m, nil } - xrpcc := &indigoxrpc.Client{Host: repo.Spindle} + if repo.Spindle == "" { + return m, nil + } + + spindleUrl, err := hostutil.EnsureHttpScheme(repo.Spindle) + if err != nil { + return m, nil // Don't block repo rendering on bad spindle configuration + } + + xrpcc := &indigoxrpc.Client{Host: spindleUrl} out, err := tangled.CiQueryPipelines(ctx, xrpcc, shas, "", 0, repo.RepoDid) if err != nil { return nil, err