Monorepo for Tangled
Something went wrong. Try again.
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173package pulls
import ( "fmt" "net/http" "time"
"golang.org/x/sync/errgroup" "tangled.org/core/api/tangled" "tangled.org/core/appview/db" "tangled.org/core/appview/knotcompat" "tangled.org/core/appview/models" "tangled.org/core/appview/oauth" "tangled.org/core/appview/reporesolver" "tangled.org/core/tid"
comatproto "github.com/bluesky-social/indigo/api/atproto" "github.com/bluesky-social/indigo/atproto/syntax" indigoxrpc "github.com/bluesky-social/indigo/xrpc")
func (s *Pulls) handlePull( w http.ResponseWriter, r *http.Request, userDid syntax.DID, targetRepo *models.Repo, targetBranch string, sourceRepo *models.Repo, sourceBranch string, title, body string,) { l := s.logger.With("handler", "handlePull", "user", userDid) ctx := r.Context()
client, err := s.oauth.AuthorizedClient(r) if err != nil { l.Error("failed to get authorized client", "err", err) s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") return }
// 1. fetch heads of source & target branches var base, head string { xrpcc := &indigoxrpc.Client{Host: s.config.KnotMirror.Url} g, gctx := errgroup.WithContext(ctx) g.Go(func() error { // find merge-base between targetBranch & sourceBranch out, err := tangled.GitTempGetMergeBase(gctx, xrpcc, targetBranch, sourceBranch, sourceRepo.RepoDid) if err != nil { return err } base = out.Commit return nil }) g.Go(func() error { out, err := tangled.GitTempGetBranch(gctx, xrpcc, sourceBranch, sourceRepo.RepoDid) if err != nil { return err } head = out.Hash return nil }) if err := g.Wait(); err != nil { l.Error("failed to fetch branch heads", "err", err) s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") return } }
created := time.Now() pull := &models.Pull{ ID: -1, // uninitialized OwnerDid: userDid, Rkey: syntax.RecordKey(tid.TID()), Cid: "", // uninitialized RepoDid: syntax.DID(targetRepo.RepoDid), PullId: 0, // uninitialized
Title: title, Body: body, TargetBranch: targetBranch, SourceRepo: syntax.DID(sourceRepo.RepoDid), SourceBranch: &sourceBranch, Versions: []models.PullVersion{ { ID: 0, Base: base, Head: head, Created: created, }, }, Created: created, State: models.PullOpen,
Repo: targetRepo, }
// 2. call git.keepCommit { client, err := s.oauth.ServiceClient( r, oauth.WithService(sourceRepo.Knot), oauth.WithLxm(tangled.GitKeepCommitNSID), oauth.WithDev(s.config.Core.Dev), ) if err != nil { l.Error("failed to comment to knot", "err", err) s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") return }
_, err = tangled.GitKeepCommit(ctx, client, &tangled.GitKeepCommit_Input{ Repo: sourceRepo.RepoDid, Record: pull.AtUri().String(), Source: &tangled.GitKeepCommit_Input_Source{ GitKeepCommit_Commit: &tangled.GitKeepCommit_Commit{ Repo: sourceRepo.RepoDid, Oid: head, }, }, }) if err != nil { l.Error("failed to keep commit", "err", err) s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") return } }
// 3. create PR record record := pull.AsRecord() out, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ Collection: tangled.RepoPullNSID, Repo: userDid.String(), Rkey: pull.Rkey.String(), Record: knotcompat.Pull(&record), }) pull.Cid = syntax.CID(out.Cid)
tx, err := s.db.BeginTx(r.Context(), nil) if err != nil { l.Error("failed to start tx", "err", err) s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") return } defer tx.Rollback()
var references []syntax.ATURI if pull.Body != "" { _, references = s.mentionsResolver.Resolve(ctx, pull.Body) }
if err := db.PutPull(r.Context(), tx, pull, references); err != nil { l.Error("failed to create pull request in database", "err", err) s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") return }
if err = tx.Commit(); err != nil { l.Error("failed to commit transaction for pull request", "err", err) s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.") return }
s.notifier.NewPull(r.Context(), pull)
s.applyCreationLabels(r.Context(), client, userDid, pull, r.Form, targetRepo)
ownerSlashRepo := reporesolver.GetBaseRepoPath(r, targetRepo) s.pages.HxRedirect(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pull.PullId))}