Monorepo for Tangled
0

Configure Feed

Select the types of activity you want to include in your feed.

appview: resolve spindle endpoint scheme using hostutil.EnsureHttpScheme

Signed-off-by: dawn <dawn@tangled.org>

authored by

dawn and committed by
Tangled
(Jul 4, 2026, 8:12 AM +0300) 5240ec97 67f4c805

+89 -14
+53 -4
appview/pipelines/pipelines.go
··· 96 96 filterKind = "all" 97 97 } 98 98 99 + if f.Spindle == "" { 100 + p.pages.Pipelines(w, pages.PipelinesParams{ 101 + BaseParams: pages.BaseParamsFromContext(r.Context()), 102 + RepoInfo: p.repoResolver.GetRepoInfo(r, user), 103 + Pipelines: nil, 104 + FilterKind: filterKind, 105 + Total: 0, 106 + }) 107 + return 108 + } 109 + 110 + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) 111 + if err != nil { 112 + l.Error("invalid spindle host", "host", f.Spindle, "err", err) 113 + p.pages.Pipelines(w, pages.PipelinesParams{ 114 + BaseParams: pages.BaseParamsFromContext(r.Context()), 115 + RepoInfo: p.repoResolver.GetRepoInfo(r, user), 116 + Pipelines: nil, 117 + FilterKind: filterKind, 118 + Total: 0, 119 + }) 120 + return 121 + } 122 + 99 123 // sh.tangled.ci.queryPipelines(repo, kind, limit=30) 100 - xrpcc := indigoxrpc.Client{Host: f.Spindle} 124 + xrpcc := indigoxrpc.Client{Host: spindleUrl} 101 125 out, err := tangled.CiQueryPipelines(r.Context(), &xrpcc, nil, "", 1, f.RepoDid) 102 126 if err != nil { 103 127 l.Error("failed to fetch pipelines", "err", err) 104 - panic("unimplemented") // spindle failure, appview should not fail. 128 + p.pages.Pipelines(w, pages.PipelinesParams{ 129 + BaseParams: pages.BaseParamsFromContext(r.Context()), 130 + RepoInfo: p.repoResolver.GetRepoInfo(r, user), 131 + Pipelines: nil, 132 + FilterKind: filterKind, 133 + Total: 0, 134 + }) 135 + return 105 136 } 106 137 107 138 p.pages.Pipelines(w, pages.PipelinesParams{ ··· 143 174 // TODO: change url path to: 144 175 // /{owner}/{slug}/pipelines/{spindle-did}/{pipeline-id}/workflow/{workflow-id} 145 176 146 - xrpcc := &indigoxrpc.Client{Host: f.Spindle} 177 + if f.Spindle == "" { 178 + p.pages.Error404(w) 179 + return 180 + } 181 + 182 + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) 183 + if err != nil { 184 + l.Error("invalid spindle host", "host", f.Spindle, "err", err) 185 + p.pages.Error404(w) 186 + return 187 + } 188 + 189 + xrpcc := &indigoxrpc.Client{Host: spindleUrl} 147 190 out, err := tangled.CiGetPipeline(r.Context(), xrpcc, pipelineId.String()) 148 191 if err != nil { 149 192 // TODO(boltless): change behavior based on error ··· 237 280 ctx, cancel := context.WithCancel(r.Context()) 238 281 defer cancel() 239 282 283 + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) 284 + if err != nil { 285 + l.Error("invalid spindle host", "host", f.Spindle, "err", err) 286 + return 287 + } 288 + 240 289 evChan := make(chan *tangled.CiPipelineSubscribeLogs_Event, 100) 241 290 done := make(chan error, 1) 242 291 sched := &webLogScheduler{ch: evChan} 243 - xrpcc := &lexutil.Client{Client: indigoxrpc.Client{Host: f.Spindle}} 292 + xrpcc := &lexutil.Client{Client: indigoxrpc.Client{Host: spindleUrl}} 244 293 go func() { 245 294 done <- tangled.CiPipelineSubscribeLogs(ctx, xrpcc, pipelineId.String(), []string{workflowName}, sched) 246 295 }()
+12 -3
appview/pulls/list.go
··· 15 15 16 16 "github.com/bluesky-social/indigo/atproto/syntax" 17 17 indigoxrpc "github.com/bluesky-social/indigo/xrpc" 18 + "tangled.org/core/hostutil" 18 19 ) 19 20 20 21 func (s *Pulls) RepoPulls(w http.ResponseWriter, r *http.Request) { ··· 264 265 265 266 // commitId -> latest pipeline 266 267 pipelines := func(ctx context.Context, shas []string) map[string]tangled.CiDefs_Pipeline { 267 - xrpcc := &indigoxrpc.Client{Host: f.Spindle} 268 + m := make(map[string]tangled.CiDefs_Pipeline) 269 + if f.Spindle == "" { 270 + return m 271 + } 272 + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) 273 + if err != nil { 274 + l.Error("invalid spindle host", "host", f.Spindle, "err", err) 275 + return m 276 + } 277 + xrpcc := &indigoxrpc.Client{Host: spindleUrl} 268 278 out, err := tangled.CiQueryPipelines(ctx, xrpcc, shas, "", 0, f.RepoDid) 269 279 if err != nil { 270 280 l.Error("failed to fetch pipelines", "err", err) 281 + return m 271 282 } 272 - 273 - m := make(map[string]tangled.CiDefs_Pipeline) 274 283 275 284 for _, pipeline := range out.Pipelines { 276 285 if pipeline == nil {
+12 -3
appview/pulls/single.go
··· 18 18 "github.com/bluesky-social/indigo/atproto/syntax" 19 19 indigoxrpc "github.com/bluesky-social/indigo/xrpc" 20 20 "github.com/go-chi/chi/v5" 21 + "tangled.org/core/hostutil" 21 22 ) 22 23 23 24 // htmx fragment ··· 161 162 162 163 // commitId -> latest pipeline 163 164 pipelines := func(ctx context.Context) map[string]tangled.CiDefs_Pipeline { 164 - xrpcc := &indigoxrpc.Client{Host: f.Spindle} 165 + m := make(map[string]tangled.CiDefs_Pipeline) 166 + if f.Spindle == "" { 167 + return m 168 + } 169 + spindleUrl, err := hostutil.EnsureHttpScheme(f.Spindle) 170 + if err != nil { 171 + l.Error("invalid spindle host", "host", f.Spindle, "err", err) 172 + return m 173 + } 174 + xrpcc := &indigoxrpc.Client{Host: spindleUrl} 165 175 out, err := tangled.CiQueryPipelines(ctx, xrpcc, shas, "", 0, f.RepoDid) 166 176 if err != nil { 167 177 l.Error("failed to fetch pipelines", "err", err) 178 + return m 168 179 } 169 - 170 - m := make(map[string]tangled.CiDefs_Pipeline) 171 180 172 181 for _, pipeline := range out.Pipelines { 173 182 if pipeline == nil {
+12 -4
appview/repo/repo_util.go
··· 10 10 indigoxrpc "github.com/bluesky-social/indigo/xrpc" 11 11 "tangled.org/core/api/tangled" 12 12 "tangled.org/core/appview/models" 13 + "tangled.org/core/hostutil" 13 14 "tangled.org/core/types" 14 15 ) 15 16 ··· 87 88 return 88 89 } 89 90 90 - // grab pipelines from DB and munge that into a hashmap with commit sha as key 91 - // 92 - // golang is so blessed that it requires 35 lines of imperative code for this 91 + // fetch pipelines from DB and map by commit sha 93 92 func getPipelineStatuses( 94 93 ctx context.Context, 95 94 repo *models.Repo, ··· 101 100 return m, nil 102 101 } 103 102 104 - xrpcc := &indigoxrpc.Client{Host: repo.Spindle} 103 + if repo.Spindle == "" { 104 + return m, nil 105 + } 106 + 107 + spindleUrl, err := hostutil.EnsureHttpScheme(repo.Spindle) 108 + if err != nil { 109 + return m, nil // Don't block repo rendering on bad spindle configuration 110 + } 111 + 112 + xrpcc := &indigoxrpc.Client{Host: spindleUrl} 105 113 out, err := tangled.CiQueryPipelines(ctx, xrpcc, shas, "", 0, repo.RepoDid) 106 114 if err != nil { 107 115 return nil, err