Monorepo for Tangled tangled.org

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

Labels
enhancement
assignee

None yet.

Participants 2
AT URI
at://did:plc:k2zmz2l3hvfr44tmlhewol2j/sh.tangled.repo.pull/3lzwhi232k322
+42 -24
Interdiff #1 โ†’ #2
+42 -24
knotserver/internal.go
··· 112 112 Messages: make([]string, 0), 113 113 } 114 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 115 for _, line := range lines { 135 116 err := h.insertRefUpdate(line, gitUserDid, repoDid, repoName) 136 117 if err != nil { ··· 138 119 // non-fatal 139 120 } 140 121 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, "โ€‹") 122 + if (line.NewSha.String() != line.OldSha.String()) && line.OldSha.IsZero() { 123 + msg, err := h.replyCompare(line, gitUserDid, gitRelativeDir, repoName, r.Context()) 124 + if err != nil { 125 + l.Error("failed to reply with compare link", "err", err, "line", line, "did", gitUserDid, "repo", gitRelativeDir) 126 + // non-fatal 127 + } else { 128 + for msgLine := range msg { 129 + resp.Messages = append(resp.Messages, msg[msgLine]) 130 + } 131 + } 146 132 } 147 133 148 134 err = h.triggerPipeline(&resp.Messages, line, gitUserDid, repoDid, repoName, pushOptions) ··· 153 139 154 140 155 141 writeJSON(w, resp) 142 + } 143 + 144 + func (h *InternalHandle) replyCompare(line git.PostReceiveLine, gitUserDid string, gitRelativeDir string, repoName string, ctx context.Context) ([]string, error) { 145 + l := h.l.With("handler", "replyCompare") 146 + userIdent, err := idresolver.DefaultResolver().ResolveIdent(ctx, gitUserDid) 147 + user := gitUserDid 148 + if err != nil { 149 + l.Error("Failed to fetch user identity", "err", err) 150 + // non-fatal 151 + } else { 152 + user = userIdent.Handle.String() 153 + } 154 + gr, err := git.PlainOpen(gitRelativeDir) 155 + if err != nil { 156 + l.Error("Failed to open git repository", "err", err) 157 + return []string{}, err 158 + } 159 + defaultBranch, err := gr.FindMainBranch() 160 + if err != nil { 161 + l.Error("Failed to fetch default branch", "err", err) 162 + return []string{}, err 163 + } 164 + if line.Ref == fmt.Sprintf("refs/heads/%s", defaultBranch) { 165 + return []string{}, nil 166 + } 167 + ZWS := "โ€‹" 168 + var msg []string 169 + msg = append(msg, ZWS) 170 + msg = append(msg, fmt.Sprintf("Create a PR pointing to %s", defaultBranch)) 171 + msg = append(msg, fmt.Sprintf("\t%s/%s/%s/compare/%s...%s", h.c.AppViewEndpoint, user, repoName, defaultBranch, strings.TrimPrefix(line.Ref, "refs/heads/"))) 172 + msg = append(msg, ZWS) 173 + return msg, nil 156 174 } 157 175 158 176 func (h *InternalHandle) insertRefUpdate(line git.PostReceiveLine, gitUserDid, repoDid, repoName string) error {

History

5 rounds 3 comments
sign up or login to add to the discussion
1 commit
expand
knotserver/internal: add create PR message on git push
expand 1 comment

lgtm thanks!

pull request successfully merged
1 commit
expand
knotserver/internal: add create PR message on git push
expand 0 comments
1 commit
expand
knotserver/internal: add create PR message on git push
expand 0 comments
1 commit
expand
knotserver: add create PR message on git push
expand 1 comment

this looks pretty good now! the only thing i'd want from this is for this handler to be separated out, just like how insertRefUpdate and triggerPipeline are split up.

this is because we don't want errors here to end the function, even the userIdent fails to resolve, we want to continue with the rest of the post-receive handler.

1 commit
expand
hooks: add create PR message on git push
expand 1 comment

i would prefer if this addition were made to knotserver/internal.go along side the other post-recieve handlers (insertRefUpdate and triggerPipeline). the way to return strings to the user in this handler are via the HookResponse struct.

there is an example of this in triggerPipeline which conditionally returns pipeline compilation status back to the user, by writing messages into resp.Messages. we could do something similar here.

that being said, the change largely looks good to me! thanks for working on this.