hooks: add create PR message on git push #612

Respond to a successful push with a URL to create a PR pointing to the default branch. This behavior is made to mimic other Git forges.

Signed-off-by: Samuel Shuert me@thecoded.prof

Changed files
+27
knotserver
+27
knotserver/internal.go
··· 15 "github.com/go-chi/chi/v5/middleware" 16 "tangled.org/core/api/tangled" 17 "tangled.org/core/hook" 18 "tangled.org/core/knotserver/config" 19 "tangled.org/core/knotserver/db" 20 "tangled.org/core/knotserver/git" ··· 111 Messages: make([]string, 0), 112 } 113 114 for _, line := range lines { 115 err := h.insertRefUpdate(line, gitUserDid, repoDid, repoName) 116 if err != nil { ··· 118 // non-fatal 119 } 120 121 err = h.triggerPipeline(&resp.Messages, line, gitUserDid, repoDid, repoName, pushOptions) 122 if err != nil { 123 l.Error("failed to trigger pipeline", "err", err, "line", line, "did", gitUserDid, "repo", gitRelativeDir)
··· 15 "github.com/go-chi/chi/v5/middleware" 16 "tangled.org/core/api/tangled" 17 "tangled.org/core/hook" 18 + "tangled.org/core/idresolver" 19 "tangled.org/core/knotserver/config" 20 "tangled.org/core/knotserver/db" 21 "tangled.org/core/knotserver/git" ··· 112 Messages: make([]string, 0), 113 } 114 115 + userIdent, err := idresolver.DefaultResolver().ResolveIdent(r.Context(), gitUserDid) 116 + user := gitUserDid 117 + if err != nil { 118 + l.Error("Failed to fetch user identity", "err", err) 119 + // non-fatal 120 + } else { 121 + user = userIdent.Handle.String() 122 + } 123 + gr, err := git.PlainOpen(gitRelativeDir) 124 + if err != nil { 125 + l.Error("Failed to open git repository", "err", err) 126 + return 127 + } 128 + defaultBranch, err := gr.FindMainBranch() 129 + if err != nil { 130 + l.Error("Failed to fetch default branch", "err", err) 131 + return 132 + } 133 + 134 for _, line := range lines { 135 err := h.insertRefUpdate(line, gitUserDid, repoDid, repoName) 136 if err != nil { ··· 138 // non-fatal 139 } 140 141 + if (line.NewSha.String() != line.OldSha.String()) && line.OldSha.IsZero() && (line.Ref != fmt.Sprint("refs/heads/", defaultBranch)) { 142 + resp.Messages = append(resp.Messages, "​") 143 + resp.Messages = append(resp.Messages, fmt.Sprintf("Create a PR pointing to %s", defaultBranch)) 144 + resp.Messages = append(resp.Messages, fmt.Sprintf("\t%s/@%s/%s/compare/%s...%s", h.c.AppViewEndpoint, user, repoName, defaultBranch, strings.TrimPrefix(line.Ref, "refs/heads/"))) 145 + resp.Messages = append(resp.Messages, "​") 146 + } 147 + 148 err = h.triggerPipeline(&resp.Messages, line, gitUserDid, repoDid, repoName, pushOptions) 149 if err != nil { 150 l.Error("failed to trigger pipeline", "err", err, "line", line, "did", gitUserDid, "repo", gitRelativeDir)