···2020 <div class="col-span-1 md:col-span-2">2121 <h2 class="text-sm pb-2 uppercase font-bold">Spindle</h2>2222 <p class="text-gray-500 dark:text-gray-400">2323- Choose a spindle to execute your workflows on. Spindles can be2424- selfhosted,2323+ Choose a spindle to execute your workflows on. Only repository owners2424+ can configure spindles. Spindles can be selfhosted,2525 <a class="text-gray-500 dark:text-gray-400 underline" href="https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md">2626 click to learn more.2727 </a>2828 </p>2929 </div>3030- <form hx-post="/{{ $.RepoInfo.FullName }}/settings/spindle" class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch">3131- <select3232- id="spindle" 3333- name="spindle"3434- required 3535- class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"3636- {{ if not $.RepoInfo.Roles.IsOwner }}disabled{{ end }}>3737- <option value="" disabled selected >3838- Choose a spindle3939- </option>4040- {{ range $.Spindles }}4141- <option value="{{ . }}" class="py-1" {{ if eq . $.CurrentSpindle }}selected{{ end }}>4242- {{ . }}3030+ {{ if not $.RepoInfo.Roles.IsOwner }}3131+ <div class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch">3232+ {{ or $.CurrentSpindle "No spindle configured" }}3333+ </div>3434+ {{ else }}3535+ <form hx-post="/{{ $.RepoInfo.FullName }}/settings/spindle" class="col-span-1 md:col-span-1 md:justify-self-end group flex gap-2 items-stretch">3636+ <select3737+ id="spindle" 3838+ name="spindle"3939+ required 4040+ class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700">4141+ <option value="" disabled>4242+ Choose a spindle4343 </option>4444- {{ end }}4545- </select>4646- <button class="btn flex gap-2 items-center" type="submit" {{ if not $.RepoInfo.Roles.IsOwner }}disabled{{ end }}>4747- {{ i "check" "size-4" }}4848- {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}4949- </button>5050- </form>4444+ {{ range $.Spindles }}4545+ <option value="{{ . }}" class="py-1" {{ if eq . $.CurrentSpindle }}selected{{ end }}>4646+ {{ . }}4747+ </option>4848+ {{ end }}4949+ </select>5050+ <button class="btn flex gap-2 items-center" type="submit" {{ if not $.RepoInfo.Roles.IsOwner }}disabled{{ end }}>5151+ {{ i "check" "size-4" }}5252+ {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}5353+ </button>5454+ </form>5555+ {{ end }}5156 </div>5257{{ end }}5358
+2-2
appview/repo/repo.go
···12251225 f, err := rp.repoResolver.Resolve(r)12261226 user := rp.oauth.GetUser(r)1227122712281228- // all spindles that this user is a member of12291229- spindles, err := rp.enforcer.GetSpindlesForUser(user.Did)12281228+ // all spindles that the repo owner is a member of12291229+ spindles, err := rp.enforcer.GetSpindlesForUser(f.OwnerDid())12301230 if err != nil {12311231 log.Println("failed to fetch spindles", err)12321232 return
-1
knotserver/ingester.go
···316316 defer func() {317317 eventTime := event.TimeUS318318 lastTimeUs := eventTime + 1319319- fmt.Println("lastTimeUs", lastTimeUs)320319 if err := h.db.SaveLastTimeUs(lastTimeUs); err != nil {321320 err = fmt.Errorf("(deferred) failed to save last time us: %w", err)322321 }
+19-3
spindle/ingester.go
···33import (44 "context"55 "encoding/json"66+ "errors"67 "fmt"77- "path/filepath"8899 "tangled.sh/tangled.sh/core/api/tangled"1010 "tangled.sh/tangled.sh/core/eventconsumer"···100100 return nil101101}102102103103-func (s *Spindle) ingestRepo(_ context.Context, e *models.Event) error {103103+func (s *Spindle) ingestRepo(ctx context.Context, e *models.Event) error {104104 var err error105105+ did := e.Did106106+ resolver := idresolver.DefaultResolver()105107106108 l := s.l.With("component", "ingester", "record", tangled.RepoNSID)107109···139137 return fmt.Errorf("failed to add repo: %w", err)140138 }141139140140+ didSlashRepo, err := securejoin.SecureJoin(record.Owner, record.Name)141141+ if err != nil {142142+ return err143143+ }144144+142145 // add repo to rbac143143- if err := s.e.AddRepo(record.Owner, rbac.ThisServer, filepath.Join(record.Owner, record.Name)); err != nil {146146+ if err := s.e.AddRepo(record.Owner, rbac.ThisServer, didSlashRepo); err != nil {144147 l.Error("failed to add repo to enforcer", "error", err)145148 return fmt.Errorf("failed to add repo: %w", err)149149+ }150150+151151+ // add collaborators to rbac152152+ owner, err := resolver.ResolveIdent(ctx, did)153153+ if err != nil || owner.Handle.IsInvalidHandle() {154154+ return err155155+ }156156+ if err := s.fetchAndAddCollaborators(ctx, owner, didSlashRepo); err != nil {157157+ return err146158 }147159148160 // add this knot to the event consumer