Monorepo for Tangled tangled.org

knotserver: state: Sync fork without fast-forward checks

authored by brookjeynes.dev and committed by Tangled 8b6482d2 7aa0e09f

Changed files
+97 -1
appview
knotclient
state
+20
appview/knotclient/signer.go
··· 106 106 return s.client.Do(req) 107 107 } 108 108 109 + func (s *SignedClient) SyncRepoFork(ownerDid, source, name, branch string) (*http.Response, error) { 110 + const ( 111 + Method = "POST" 112 + ) 113 + endpoint := fmt.Sprintf("/repo/fork/sync/%s", branch) 114 + 115 + body, _ := json.Marshal(map[string]any{ 116 + "did": ownerDid, 117 + "source": source, 118 + "name": name, 119 + }) 120 + 121 + req, err := s.newRequest(Method, endpoint, body) 122 + if err != nil { 123 + return nil, err 124 + } 125 + 126 + return s.client.Do(req) 127 + } 128 + 109 129 func (s *SignedClient) ForkRepo(ownerDid, source, name string) (*http.Response, error) { 110 130 const ( 111 131 Method = "POST"
+76 -1
appview/state/repo.go
··· 121 121 emails := uniqueEmails(commitsTrunc) 122 122 123 123 user := s.oauth.GetUser(r) 124 + repoInfo := f.RepoInfo(s, user) 125 + 126 + secret, err := db.GetRegistrationKey(s.db, f.Knot) 127 + if err != nil { 128 + log.Printf("failed to get registration key for %s: %s", f.Knot, err) 129 + s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 130 + } 131 + 132 + // update the hidden tracking branch to latest 133 + signedClient, err := knotclient.NewSignedClient(f.Knot, secret, s.config.Core.Dev) 134 + if err != nil { 135 + log.Printf("failed to create signed client for %s: %s", f.Knot, err) 136 + s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 137 + } 138 + 139 + newHiddenRefResp, err := signedClient.NewHiddenRef(user.Did, repoInfo.Name, f.Ref, f.Ref) 140 + if err != nil || newHiddenRefResp.StatusCode != http.StatusNoContent { 141 + log.Printf("failed to update tracking branch: %s", err) 142 + s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.") 143 + } 144 + 145 + hiddenRef := fmt.Sprintf("hidden/%s/%s", f.Ref, f.Ref) 146 + comparison, err := us.Compare(user.Did, repoInfo.Name, f.Ref, hiddenRef) 147 + if err != nil { 148 + log.Printf("failed to compare branches: %s", err) 149 + s.pages.Notice(w, "resubmit-error", err.Error()) 150 + } 151 + log.Println(comparison) 152 + 124 153 s.pages.RepoIndexPage(w, pages.RepoIndexParams{ 125 154 LoggedInUser: user, 126 - RepoInfo: f.RepoInfo(s, user), 155 + RepoInfo: repoInfo, 127 156 TagMap: tagMap, 128 157 RepoIndexResponse: result, 129 158 CommitsTrunc: commitsTrunc, ··· 1801 1830 } 1802 1831 1803 1832 s.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issueId)) 1833 + return 1834 + } 1835 + } 1836 + 1837 + func (s *State) SyncRepoFork(w http.ResponseWriter, r *http.Request) { 1838 + user := s.auth.GetUser(r) 1839 + f, err := s.fullyResolvedRepo(r) 1840 + if err != nil { 1841 + log.Printf("failed to resolve source repo: %v", err) 1842 + return 1843 + } 1844 + 1845 + params := r.URL.Query() 1846 + knot := params.Get("knot") 1847 + branch := params.Get("branch") 1848 + 1849 + switch r.Method { 1850 + case http.MethodPost: 1851 + secret, err := db.GetRegistrationKey(s.db, knot) 1852 + if err != nil { 1853 + s.pages.Notice(w, "repo", fmt.Sprintf("No registration key found for knot %s.", knot)) 1854 + return 1855 + } 1856 + 1857 + client, err := NewSignedClient(knot, secret, s.config.Dev) 1858 + if err != nil { 1859 + s.pages.Notice(w, "repo", "Failed to reach knot server.") 1860 + return 1861 + } 1862 + 1863 + var uri string 1864 + if s.config.Dev { 1865 + uri = "http" 1866 + } else { 1867 + uri = "https" 1868 + } 1869 + forkName := fmt.Sprintf("%s", f.RepoName) 1870 + forkSourceUrl := fmt.Sprintf("%s://%s/%s/%s", uri, f.Knot, f.OwnerDid(), f.RepoName) 1871 + 1872 + _, err = client.SyncRepoFork(user.Did, forkSourceUrl, forkName, branch) 1873 + if err != nil { 1874 + s.pages.Notice(w, "repo", "Failed to sync repository fork.") 1875 + return 1876 + } 1877 + 1878 + s.pages.HxRefresh(w) 1804 1879 return 1805 1880 } 1806 1881 }
+1
appview/state/router.go
··· 113 113 r.Use(middleware.AuthMiddleware(s.oauth)) 114 114 r.Get("/", s.ForkRepo) 115 115 r.Post("/", s.ForkRepo) 116 + r.Post("/sync", s.SyncRepoFork) 116 117 }) 117 118 118 119 r.Route("/pulls", func(r chi.Router) {