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
+27 -24
Interdiff #0 โ†’ #1
-24
hook/hook.go
··· 10 10 "strings" 11 11 12 12 "github.com/urfave/cli/v3" 13 - "tangled.org/core/idresolver" 14 - "tangled.org/core/knotserver/git" 15 13 ) 16 14 17 15 type HookResponse struct { ··· 70 68 71 69 client := &http.Client{} 72 70 73 - gr, err := git.PlainOpen(gitDir) 74 - defaultBranch, err := gr.FindMainBranch() 75 - if err != nil { 76 - fmt.Fprintln(os.Stderr, "failed to retrieve default branch") 77 - return nil 78 - } 79 - gitPath := strings.Split(gitDir, "/") 80 - repoName := gitPath[len(gitPath)-1] 81 - userIdent, err := idresolver.DefaultResolver().ResolveIdent(ctx, userDid) 82 - lines, err := git.ParsePostReceive(strings.NewReader(payload)) 83 - if err != nil { 84 - return fmt.Errorf("failed to parse post-receive payload: %w", err) 85 - } 86 - for _, line := range lines { 87 - if line.OldSha.IsZero() && line.OldSha != line.NewSha { 88 - fmt.Fprintln(os.Stderr, "โ€‹") 89 - fmt.Fprintf(os.Stderr, "Create a PR pointing to %s\n", defaultBranch) 90 - fmt.Fprintf(os.Stderr, "\thttps://tangled.org/@%s/%s/compare/%s...%s\n", userIdent.Handle.String(), repoName, defaultBranch, strings.TrimPrefix(line.Ref, "refs/heads/")) 91 - fmt.Fprintln(os.Stderr, "โ€‹") 92 - } 93 - } 94 - 95 71 req, err := http.NewRequest("POST", "http://"+endpoint+"/hooks/post-receive", strings.NewReader(payload)) 96 72 if err != nil { 97 73 return fmt.Errorf("failed to create request: %w", err)
+27
knotserver/internal.go
··· 15 15 "github.com/go-chi/chi/v5/middleware" 16 16 "tangled.org/core/api/tangled" 17 17 "tangled.org/core/hook" 18 + "tangled.org/core/idresolver" 18 19 "tangled.org/core/knotserver/config" 19 20 "tangled.org/core/knotserver/db" 20 21 "tangled.org/core/knotserver/git" ··· 111 112 Messages: make([]string, 0), 112 113 } 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 + 114 134 for _, line := range lines { 115 135 err := h.insertRefUpdate(line, gitUserDid, repoDid, repoName) 116 136 if err != nil { ··· 118 138 // non-fatal 119 139 } 120 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 + 121 148 err = h.triggerPipeline(&resp.Messages, line, gitUserDid, repoDid, repoName, pushOptions) 122 149 if err != nil { 123 150 l.Error("failed to trigger pipeline", "err", err, "line", line, "did", gitUserDid, "repo", gitRelativeDir)

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.