feat: [CODE-4589]: support for fork repo delete (#4644)
* c8c800 support for fork repo delete
This commit is contained in:
parent
8663ae2061
commit
0aac751751
|
|
@ -252,7 +252,7 @@ func (c *Controller) reportTagEvent(
|
|||
// TODO: If it is a new branch, or an update on a branch without any PR, it also sends out an SSE for pr creation.
|
||||
func (c *Controller) handlePRMessaging(
|
||||
ctx context.Context,
|
||||
repo *types.Repository,
|
||||
sourceRepo *types.Repository,
|
||||
in hook.PostReceiveInput,
|
||||
out *hook.Output,
|
||||
) {
|
||||
|
|
@ -266,14 +266,14 @@ func (c *Controller) handlePRMessaging(
|
|||
// for now we only care about first branch that was pushed.
|
||||
branchName := in.RefUpdates[0].Ref[len(gitReferenceNamePrefixBranch):]
|
||||
|
||||
c.suggestPullRequest(ctx, repo, branchName, out)
|
||||
c.suggestPullRequest(ctx, sourceRepo, branchName, out)
|
||||
|
||||
// TODO: store latest pushed branch for user in cache and send out SSE
|
||||
}
|
||||
|
||||
func (c *Controller) suggestPullRequest(
|
||||
ctx context.Context,
|
||||
repo *types.Repository,
|
||||
sourceRepo *types.Repository,
|
||||
branchName string,
|
||||
out *hook.Output,
|
||||
) {
|
||||
|
|
@ -281,7 +281,7 @@ func (c *Controller) suggestPullRequest(
|
|||
prs, err := c.pullreqStore.List(ctx, &types.PullReqFilter{
|
||||
Page: 1,
|
||||
Size: 10,
|
||||
SourceRepoID: repo.ID,
|
||||
SourceRepoID: sourceRepo.ID,
|
||||
SourceBranch: branchName,
|
||||
// we only care about open PRs - merged/closed will lead to "create new PR" message
|
||||
States: []enum.PullReqState{enum.PullReqStateOpen},
|
||||
|
|
@ -294,7 +294,7 @@ func (c *Controller) suggestPullRequest(
|
|||
log.Ctx(ctx).Warn().Err(err).Msgf(
|
||||
"failed to find pullrequests for branch '%s' originating from repo '%s'",
|
||||
branchName,
|
||||
repo.Path,
|
||||
sourceRepo.Path,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
|
@ -302,7 +302,7 @@ func (c *Controller) suggestPullRequest(
|
|||
slices.Reverse(prs) // Use ascending order for message output.
|
||||
|
||||
// For already existing PRs, print them to users terminal for easier access.
|
||||
msgs, err := c.getOpenPRsMessages(ctx, repo, branchName, prs)
|
||||
msgs, err := c.getOpenPRsMessages(ctx, sourceRepo, branchName, prs)
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Warn().Err(err).Msg("failed to get messages for open pull request")
|
||||
return
|
||||
|
|
@ -312,7 +312,7 @@ func (c *Controller) suggestPullRequest(
|
|||
return
|
||||
}
|
||||
|
||||
if branchName == repo.DefaultBranch {
|
||||
if branchName == sourceRepo.DefaultBranch {
|
||||
// Don't suggest a pull request if this is a push to the default branch.
|
||||
return
|
||||
}
|
||||
|
|
@ -320,13 +320,13 @@ func (c *Controller) suggestPullRequest(
|
|||
// This is a new PR!
|
||||
out.Messages = append(out.Messages,
|
||||
fmt.Sprintf("Create a pull request for %q by visiting:", branchName),
|
||||
" "+c.urlProvider.GenerateUICompareURL(ctx, repo.Path, repo.DefaultBranch, branchName),
|
||||
" "+c.urlProvider.GenerateUICompareURL(ctx, sourceRepo.Path, sourceRepo.DefaultBranch, branchName),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Controller) getOpenPRsMessages(
|
||||
ctx context.Context,
|
||||
repo *types.Repository,
|
||||
sourceRepo *types.Repository,
|
||||
branchName string,
|
||||
prs []*types.PullReq,
|
||||
) ([]string, error) {
|
||||
|
|
@ -343,8 +343,8 @@ func (c *Controller) getOpenPRsMessages(
|
|||
}
|
||||
|
||||
for i, pr := range prs {
|
||||
path := repo.Path
|
||||
if pr.TargetRepoID != pr.SourceRepoID {
|
||||
path := sourceRepo.Path
|
||||
if pr.TargetRepoID != *pr.SourceRepoID {
|
||||
targetRepo, err := c.repoFinder.FindByID(ctx, pr.TargetRepoID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find target repo by ID: %w", err)
|
||||
|
|
|
|||
|
|
@ -64,9 +64,10 @@ func (c *Controller) ChangeTargetBranch(ctx context.Context,
|
|||
if pr.TargetBranch == in.BranchName {
|
||||
return pr, nil
|
||||
}
|
||||
if pr.TargetRepoID == pr.SourceRepoID && pr.SourceBranch == in.BranchName {
|
||||
|
||||
if pr.SourceRepoID != nil && pr.TargetRepoID == *pr.SourceRepoID && pr.SourceBranch == in.BranchName {
|
||||
return nil,
|
||||
errors.InvalidArgument("source branch %q is same as new target branch", pr.SourceBranch)
|
||||
errors.InvalidArgument("Source branch %q is same as new target branch", pr.SourceBranch)
|
||||
}
|
||||
|
||||
readParams := git.CreateReadParams(repo)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/harness/gitness/git"
|
||||
gitenum "github.com/harness/gitness/git/enum"
|
||||
"github.com/harness/gitness/git/sha"
|
||||
gitness_store "github.com/harness/gitness/store"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
|
|
@ -204,18 +205,28 @@ func (c *Controller) Merge(
|
|||
return nil, nil, fmt.Errorf("failed to create RPC write params: %w", err)
|
||||
}
|
||||
|
||||
sourceRepo := targetRepo
|
||||
sourceWriteParams := targetWriteParams
|
||||
if pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceWriteParams, err = controller.CreateRPCInternalWriteParams(ctx, c.urlProvider, session, sourceRepo)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to create RPC write params: %w", err)
|
||||
}
|
||||
var sourceRepo *types.RepositoryCore
|
||||
var sourceWriteParams git.WriteParams
|
||||
|
||||
sourceRepo, err = c.repoFinder.FindByID(ctx, pr.SourceRepoID)
|
||||
if err != nil {
|
||||
switch {
|
||||
case pr.SourceRepoID == nil:
|
||||
// the source repo is purged
|
||||
case *pr.SourceRepoID != pr.TargetRepoID:
|
||||
// if the source repo is nil, it's soft deleted
|
||||
sourceRepo, err = c.repoFinder.FindByID(ctx, *pr.SourceRepoID)
|
||||
if err != nil && !errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||
return nil, nil, fmt.Errorf("failed to get source repository: %w", err)
|
||||
}
|
||||
|
||||
if sourceRepo != nil {
|
||||
sourceWriteParams, err = controller.CreateRPCInternalWriteParams(ctx, c.urlProvider, session, sourceRepo)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to create RPC write params: %w", err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
sourceRepo = targetRepo
|
||||
sourceWriteParams = targetWriteParams
|
||||
}
|
||||
|
||||
getHeadRef, err := c.git.GetRef(ctx, git.GetRefParams{
|
||||
|
|
@ -243,7 +254,7 @@ func (c *Controller) Merge(
|
|||
return nil, nil, fmt.Errorf("failed to list status checks: %w", err)
|
||||
}
|
||||
|
||||
codeOwnerWithApproval, err := c.codeOwners.Evaluate(ctx, sourceRepo, pr, reviewers)
|
||||
codeOwnerWithApproval, err := c.codeOwners.Evaluate(ctx, targetRepo, pr, reviewers)
|
||||
// check for error and ignore if it is codeowners file not found else throw error
|
||||
if err != nil && !errors.Is(err, codeowners.ErrNotFound) {
|
||||
return nil, nil, fmt.Errorf("CODEOWNERS evaluation failed: %w", err)
|
||||
|
|
@ -267,7 +278,9 @@ func (c *Controller) Merge(
|
|||
return nil, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
||||
}
|
||||
|
||||
deleteSourceBranch := pr.TargetRepoID == pr.SourceRepoID && (in.DeleteSourceBranch || ruleOut.DeleteSourceBranch)
|
||||
// only delete the source branch if it's the source repository is the same as the target repository.
|
||||
deleteSourceBranch := pr.SourceRepoID != nil && pr.TargetRepoID == *pr.SourceRepoID &&
|
||||
(in.DeleteSourceBranch || ruleOut.DeleteSourceBranch)
|
||||
|
||||
if in.DryRunRules {
|
||||
err := c.backfillApprovalInfo(ctx, ruleOut.DefaultReviewerApprovals)
|
||||
|
|
@ -472,7 +485,13 @@ func (c *Controller) Merge(
|
|||
if in.Title == "" {
|
||||
switch in.Method {
|
||||
case enum.MergeMethodMerge:
|
||||
in.Title = fmt.Sprintf("Merge branch '%s' of %s (#%d)", pr.SourceBranch, sourceRepo.Path, pr.Number)
|
||||
if sourceRepo == nil {
|
||||
in.Title = fmt.Sprintf("Merge branch '%s' of unknown repository (#%d)",
|
||||
pr.SourceBranch, pr.Number)
|
||||
} else {
|
||||
in.Title = fmt.Sprintf("Merge branch '%s' of %s (#%d)", pr.SourceBranch,
|
||||
sourceRepo.Path, pr.Number)
|
||||
}
|
||||
case enum.MergeMethodSquash:
|
||||
in.Title = fmt.Sprintf("%s (#%d)", pr.Title, pr.Number)
|
||||
case enum.MergeMethodRebase, enum.MergeMethodFastForward:
|
||||
|
|
@ -681,9 +700,9 @@ func (c *Controller) Merge(
|
|||
session.Principal,
|
||||
audit.NewResource(
|
||||
audit.ResourceTypeRepository,
|
||||
sourceRepo.Identifier,
|
||||
targetRepo.Identifier,
|
||||
audit.RepoPath,
|
||||
sourceRepo.Path,
|
||||
targetRepo.Path,
|
||||
audit.BypassedResourceType,
|
||||
audit.BypassedResourceTypePullRequest,
|
||||
audit.BypassedResourceName,
|
||||
|
|
@ -691,17 +710,17 @@ func (c *Controller) Merge(
|
|||
audit.ResourceName,
|
||||
fmt.Sprintf(
|
||||
audit.BypassPullReqLabelFormat,
|
||||
sourceRepo.Identifier,
|
||||
targetRepo.Identifier,
|
||||
strconv.FormatInt(pr.Number, 10),
|
||||
),
|
||||
audit.BypassAction,
|
||||
audit.BypassActionMerged,
|
||||
),
|
||||
audit.ActionBypassed,
|
||||
paths.Parent(sourceRepo.Path),
|
||||
paths.Parent(targetRepo.Path),
|
||||
audit.WithNewObject(audit.PullRequestObject{
|
||||
PullReq: *pr,
|
||||
RepoPath: sourceRepo.Path,
|
||||
RepoPath: targetRepo.Path,
|
||||
RuleViolations: violations,
|
||||
}),
|
||||
)
|
||||
|
|
@ -713,10 +732,10 @@ func (c *Controller) Merge(
|
|||
err = c.instrumentation.Track(ctx, instrument.Event{
|
||||
Type: instrument.EventTypeMergePullRequest,
|
||||
Principal: session.Principal.ToPrincipalInfo(),
|
||||
Path: sourceRepo.Path,
|
||||
Path: targetRepo.Path,
|
||||
Properties: map[instrument.Property]any{
|
||||
instrument.PropertyRepositoryID: sourceRepo.ID,
|
||||
instrument.PropertyRepositoryName: sourceRepo.Identifier,
|
||||
instrument.PropertyRepositoryID: targetRepo.ID,
|
||||
instrument.PropertyRepositoryName: targetRepo.Identifier,
|
||||
instrument.PropertyPullRequestID: pr.Number,
|
||||
instrument.PropertyMergeStrategy: in.Method,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ func (c *Controller) Create(
|
|||
IsDraft: in.IsDraft,
|
||||
Title: in.Title,
|
||||
Description: in.Description,
|
||||
SourceRepoID: sourceRepo.ID,
|
||||
SourceRepoID: &sourceRepo.ID,
|
||||
SourceBranch: in.SourceBranch,
|
||||
SourceSHA: sourceSHA.String(),
|
||||
TargetRepoID: targetRepo.ID,
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@ import (
|
|||
"github.com/harness/gitness/app/api/usererror"
|
||||
"github.com/harness/gitness/app/auth"
|
||||
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
||||
"github.com/harness/gitness/errors"
|
||||
"github.com/harness/gitness/git"
|
||||
gitenum "github.com/harness/gitness/git/enum"
|
||||
"github.com/harness/gitness/git/sha"
|
||||
gitness_store "github.com/harness/gitness/store"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
|
|
@ -78,14 +80,17 @@ func (c *Controller) State(ctx context.Context,
|
|||
|
||||
id := pr.ID
|
||||
|
||||
sourceRepo := targetRepo
|
||||
if pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err = c.repoFinder.FindByID(ctx, pr.SourceRepoID)
|
||||
if err != nil {
|
||||
var sourceRepo *types.RepositoryCore
|
||||
|
||||
if pr.SourceRepoID != nil && *pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err = c.repoFinder.FindByID(ctx, *pr.SourceRepoID)
|
||||
if err != nil && !errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||
return nil, fmt.Errorf("failed to get source repo by id: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = apiauth.CheckRepo(ctx, c.authorizer, session, sourceRepo, enum.PermissionRepoView); err != nil {
|
||||
if sourceRepo != nil {
|
||||
if err = apiauth.CheckRepo(ctx, c.authorizer, session, sourceRepo, enum.PermissionRepoPush); err != nil {
|
||||
return nil, fmt.Errorf("failed to acquire access to source repo: %w", err)
|
||||
}
|
||||
} else if err = apiauth.CheckRepo(ctx, c.authorizer, session, targetRepo, enum.PermissionRepoPush); err != nil {
|
||||
|
|
@ -121,6 +126,10 @@ func (c *Controller) State(ctx context.Context,
|
|||
|
||||
//nolint:nestif // refactor if needed
|
||||
if pr.State != enum.PullReqStateOpen && in.State == enum.PullReqStateOpen {
|
||||
if sourceRepo == nil {
|
||||
return nil, usererror.BadRequest("Source repository doesn't exists.")
|
||||
}
|
||||
|
||||
if sourceSHA, err = c.verifyBranchExistence(ctx, sourceRepo, pr.SourceBranch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -129,7 +138,7 @@ func (c *Controller) State(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
err = c.checkIfAlreadyExists(ctx, pr.TargetRepoID, pr.SourceRepoID, pr.TargetBranch, pr.SourceBranch)
|
||||
err = c.checkIfAlreadyExists(ctx, pr.TargetRepoID, *pr.SourceRepoID, pr.TargetBranch, pr.SourceBranch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import (
|
|||
apiauth "github.com/harness/gitness/app/api/auth"
|
||||
"github.com/harness/gitness/app/auth"
|
||||
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
||||
"github.com/harness/gitness/errors"
|
||||
gitness_store "github.com/harness/gitness/store"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
|
|
@ -66,15 +68,17 @@ func (c *Controller) Update(ctx context.Context,
|
|||
return nil, fmt.Errorf("failed to get pull request by number: %w", err)
|
||||
}
|
||||
|
||||
if pr.SourceRepoID != pr.TargetRepoID {
|
||||
var sourceRepo *types.RepositoryCore
|
||||
var sourceRepo *types.RepositoryCore
|
||||
|
||||
sourceRepo, err = c.repoFinder.FindByID(ctx, pr.SourceRepoID)
|
||||
if err != nil {
|
||||
if pr.SourceRepoID != nil && *pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err = c.repoFinder.FindByID(ctx, *pr.SourceRepoID)
|
||||
if err != nil && !errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||
return nil, fmt.Errorf("failed to get source repo by id: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = apiauth.CheckRepo(ctx, c.authorizer, session, sourceRepo, enum.PermissionRepoView); err != nil {
|
||||
if sourceRepo != nil {
|
||||
if err = apiauth.CheckRepo(ctx, c.authorizer, session, sourceRepo, enum.PermissionRepoPush); err != nil {
|
||||
return nil, fmt.Errorf("failed to acquire access to source repo: %w", err)
|
||||
}
|
||||
} else if err = apiauth.CheckRepo(ctx, c.authorizer, session, targetRepo, enum.PermissionRepoPush); err != nil {
|
||||
|
|
|
|||
|
|
@ -209,10 +209,9 @@ func (c *Controller) CreateFork(
|
|||
return fmt.Errorf("failed to create fork repository: %w", err)
|
||||
}
|
||||
|
||||
repoUpstream.NumForks++
|
||||
err = c.repoStore.Update(ctx, repoUpstream)
|
||||
err = c.repoStore.UpdateNumForks(ctx, repoUpstream.ID, 1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update upstream repository: %w", err)
|
||||
return fmt.Errorf("failed to increment number of forks in upstream repository: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -77,7 +77,24 @@ func (c *Controller) PurgeNoAuth(
|
|||
}
|
||||
}
|
||||
|
||||
if err := c.repoStore.Purge(ctx, repo.ID, repo.Deleted); err != nil {
|
||||
err := c.tx.WithTx(ctx, func(ctx context.Context) error {
|
||||
if err := c.repoStore.ClearForkID(ctx, repo.ID); err != nil {
|
||||
return fmt.Errorf("failed to clear fork ID of forks: %w", err)
|
||||
}
|
||||
|
||||
if repo.ForkID != 0 {
|
||||
if err := c.repoStore.UpdateNumForks(ctx, repo.ForkID, -1); err != nil {
|
||||
return fmt.Errorf("failed to decrement number of forks of the upstream repository: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.repoStore.Purge(ctx, repo.ID, repo.Deleted); err != nil {
|
||||
return fmt.Errorf("failed to delete repo from db: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete repo from db: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
package events
|
||||
|
||||
type Base struct {
|
||||
PullReqID int64 `json:"pullreq_id"`
|
||||
SourceRepoID int64 `json:"source_repo_id"`
|
||||
TargetRepoID int64 `json:"repo_id"`
|
||||
PrincipalID int64 `json:"principal_id"`
|
||||
Number int64 `json:"number"`
|
||||
PullReqID int64 `json:"pullreq_id"`
|
||||
SourceRepoID *int64 `json:"source_repo_id"`
|
||||
TargetRepoID int64 `json:"repo_id"`
|
||||
PrincipalID int64 `json:"principal_id"`
|
||||
Number int64 `json:"number"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,13 +39,17 @@ func (s *Service) handleEventPullReqCreated(
|
|||
sourceBranch := payload.SourceBranch
|
||||
pullReqID := payload.PullReqID
|
||||
|
||||
if sourceRepoID == nil {
|
||||
return events.NewDiscardEventErrorf("pullreq %d event missing sourceRepoID", pullReqID)
|
||||
}
|
||||
|
||||
logger := log.Ctx(ctx).With().
|
||||
Int64("source_repo_id", sourceRepoID).
|
||||
Int64("source_repo_id", *sourceRepoID).
|
||||
Str("source_branch", sourceBranch).
|
||||
Int64("pullreq_id", pullReqID).
|
||||
Logger()
|
||||
|
||||
err := s.branchStore.UpdateLastPR(ctx, sourceRepoID, sourceBranch, &pullReqID)
|
||||
err := s.branchStore.UpdateLastPR(ctx, *sourceRepoID, sourceBranch, &pullReqID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update last PR: %w", err)
|
||||
}
|
||||
|
|
@ -63,8 +67,13 @@ func (s *Service) handleEventPullReqClosed(
|
|||
if payload == nil {
|
||||
return fmt.Errorf("payload is nil")
|
||||
}
|
||||
|
||||
if payload.SourceRepoID == nil {
|
||||
return events.NewDiscardEventErrorf("pullreq %d event missing sourceRepoID", payload.PullReqID)
|
||||
}
|
||||
|
||||
logger := log.Ctx(ctx).With().
|
||||
Int64("source_repo_id", payload.SourceRepoID).
|
||||
Int64("source_repo_id", *payload.SourceRepoID).
|
||||
Int64("pullreq_id", payload.PullReqID).
|
||||
Str("source_branch", payload.SourceBranch).
|
||||
Logger()
|
||||
|
|
@ -72,7 +81,7 @@ func (s *Service) handleEventPullReqClosed(
|
|||
sourceRepoID := payload.SourceRepoID
|
||||
sourceBranch := payload.SourceBranch
|
||||
|
||||
err := s.branchStore.UpdateLastPR(ctx, sourceRepoID, sourceBranch, nil)
|
||||
err := s.branchStore.UpdateLastPR(ctx, *sourceRepoID, sourceBranch, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update last PR: %w", err)
|
||||
}
|
||||
|
|
@ -90,8 +99,13 @@ func (s *Service) handleEventPullReqReopened(
|
|||
if payload == nil {
|
||||
return fmt.Errorf("payload is nil")
|
||||
}
|
||||
|
||||
if payload.SourceRepoID == nil {
|
||||
return events.NewDiscardEventErrorf("pullreq %d event missing sourceRepoID", payload.PullReqID)
|
||||
}
|
||||
|
||||
logger := log.Ctx(ctx).With().
|
||||
Int64("source_repo_id", payload.SourceRepoID).
|
||||
Int64("source_repo_id", *payload.SourceRepoID).
|
||||
Int64("pullreq_id", payload.PullReqID).
|
||||
Str("source_branch", payload.SourceBranch).
|
||||
Logger()
|
||||
|
|
@ -100,7 +114,7 @@ func (s *Service) handleEventPullReqReopened(
|
|||
sourceBranch := payload.SourceBranch
|
||||
pullReqID := payload.PullReqID
|
||||
|
||||
err := s.branchStore.UpdateLastPR(ctx, sourceRepoID, sourceBranch, &pullReqID)
|
||||
err := s.branchStore.UpdateLastPR(ctx, *sourceRepoID, sourceBranch, &pullReqID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update last PR: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ import (
|
|||
"github.com/harness/gitness/app/services/publicaccess"
|
||||
"github.com/harness/gitness/app/services/refcache"
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/errors"
|
||||
"github.com/harness/gitness/events"
|
||||
gitness_store "github.com/harness/gitness/store"
|
||||
"github.com/harness/gitness/stream"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
|
@ -556,13 +558,17 @@ func fillPullReqProps(
|
|||
return nil, fmt.Errorf("failed to fill repo data for target repo: %w", err)
|
||||
}
|
||||
|
||||
if pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err := repoFinder.FindByID(ctx, pr.SourceRepoID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find source repo: %w", err)
|
||||
}
|
||||
var sourceRepo *types.RepositoryCore
|
||||
|
||||
props[prSourceRepoID] = pr.SourceRepoID
|
||||
if pr.SourceRepoID != nil && *pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err = repoFinder.FindByID(ctx, *pr.SourceRepoID)
|
||||
if err != nil && !errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||
return nil, fmt.Errorf("failed to get source repo by id: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if sourceRepo != nil {
|
||||
props[prSourceRepoID] = sourceRepo.ID
|
||||
props[prSourceRepoName] = sourceRepo.Identifier
|
||||
props[prSourceRepoPath] = sourceRepo.Path
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ func (r *repoImportState) convertPullReq(
|
|||
UnresolvedCount: 0,
|
||||
Title: extPullReq.Title,
|
||||
Description: extPullReq.Body,
|
||||
SourceRepoID: repo.ID,
|
||||
SourceRepoID: &repo.ID,
|
||||
SourceBranch: extPullReq.Head.Name,
|
||||
SourceSHA: extPullReq.Head.SHA,
|
||||
TargetRepoID: repo.ID,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/harness/gitness/git"
|
||||
gitenum "github.com/harness/gitness/git/enum"
|
||||
"github.com/harness/gitness/git/sha"
|
||||
gitness_store "github.com/harness/gitness/store"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
|
|
@ -115,9 +116,15 @@ func (s *Service) updatePullReqOnBranchUpdate(ctx context.Context,
|
|||
|
||||
// Pull git objects from the source repo into the target repo if this is a cross repo pull request.
|
||||
|
||||
if pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err := s.repoFinder.FindByID(ctx, pr.SourceRepoID)
|
||||
if err != nil {
|
||||
if pr.SourceRepoID == nil {
|
||||
return events.NewDiscardEventError(fmt.Errorf("pull request ID=%d has no source repo ID", pr.ID))
|
||||
}
|
||||
|
||||
if *pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err := s.repoFinder.FindByID(ctx, *pr.SourceRepoID)
|
||||
if errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||
return events.NewDiscardEventError(fmt.Errorf("pull request ID=%d source repo not found ID", pr.ID))
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to get source repo git info: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -384,9 +384,13 @@ func (c *ListService) BackfillMetadata(
|
|||
options types.PullReqMetadataOptions,
|
||||
) error {
|
||||
for _, entry := range list {
|
||||
if entry.PullRequest.SourceRepoID != entry.PullRequest.TargetRepoID {
|
||||
sourceRepo, err := c.repoFinder.FindByID(ctx, entry.PullRequest.SourceRepoID)
|
||||
if err != nil {
|
||||
if entry.PullRequest.SourceRepoID == nil {
|
||||
entry.PullRequest.SourceRepo = deletedSourceRepo
|
||||
} else if *entry.PullRequest.SourceRepoID != entry.PullRequest.TargetRepoID {
|
||||
sourceRepo, err := c.repoFinder.FindByID(ctx, *entry.PullRequest.SourceRepoID)
|
||||
if errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||
sourceRepo = deletedSourceRepo
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to fetch source repository: %w", err)
|
||||
}
|
||||
|
||||
|
|
@ -447,3 +451,8 @@ func (c *ListService) BackfillMetadataForPullReq(
|
|||
|
||||
return c.BackfillMetadata(ctx, list, options)
|
||||
}
|
||||
|
||||
var deletedSourceRepo = &types.RepositoryCore{
|
||||
Identifier: "<deleted-repo>",
|
||||
Path: "<deleted-repo>",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func (s *Service) handleEventPullReqCreated(ctx context.Context,
|
|||
if err != nil {
|
||||
return fmt.Errorf("could not augment pull request info: %w", err)
|
||||
}
|
||||
return s.trigger(ctx, event.Payload.SourceRepoID, enum.TriggerActionPullReqCreated, hook)
|
||||
return s.trigger(ctx, event.Payload.TargetRepoID, enum.TriggerActionPullReqCreated, hook)
|
||||
}
|
||||
|
||||
func (s *Service) handleEventPullReqReopened(ctx context.Context,
|
||||
|
|
@ -52,7 +52,7 @@ func (s *Service) handleEventPullReqReopened(ctx context.Context,
|
|||
if err != nil {
|
||||
return fmt.Errorf("could not augment pull request info: %w", err)
|
||||
}
|
||||
return s.trigger(ctx, event.Payload.SourceRepoID, enum.TriggerActionPullReqReopened, hook)
|
||||
return s.trigger(ctx, event.Payload.TargetRepoID, enum.TriggerActionPullReqReopened, hook)
|
||||
}
|
||||
|
||||
func (s *Service) handleEventPullReqBranchUpdated(ctx context.Context,
|
||||
|
|
@ -67,7 +67,7 @@ func (s *Service) handleEventPullReqBranchUpdated(ctx context.Context,
|
|||
if err != nil {
|
||||
return fmt.Errorf("could not augment pull request info: %w", err)
|
||||
}
|
||||
return s.trigger(ctx, event.Payload.SourceRepoID, enum.TriggerActionPullReqBranchUpdated, hook)
|
||||
return s.trigger(ctx, event.Payload.TargetRepoID, enum.TriggerActionPullReqBranchUpdated, hook)
|
||||
}
|
||||
|
||||
func (s *Service) handleEventPullReqClosed(ctx context.Context,
|
||||
|
|
@ -82,7 +82,7 @@ func (s *Service) handleEventPullReqClosed(ctx context.Context,
|
|||
if err != nil {
|
||||
return fmt.Errorf("could not augment pull request info: %w", err)
|
||||
}
|
||||
return s.trigger(ctx, event.Payload.SourceRepoID, enum.TriggerActionPullReqClosed, hook)
|
||||
return s.trigger(ctx, event.Payload.TargetRepoID, enum.TriggerActionPullReqClosed, hook)
|
||||
}
|
||||
|
||||
func (s *Service) handleEventPullReqMerged(
|
||||
|
|
@ -99,7 +99,7 @@ func (s *Service) handleEventPullReqMerged(
|
|||
if err != nil {
|
||||
return fmt.Errorf("could not augment pull request info: %w", err)
|
||||
}
|
||||
return s.trigger(ctx, event.Payload.SourceRepoID, enum.TriggerActionPullReqMerged, hook)
|
||||
return s.trigger(ctx, event.Payload.TargetRepoID, enum.TriggerActionPullReqMerged, hook)
|
||||
}
|
||||
|
||||
// augmentPullReqInfo adds in information into the hook pertaining to the pull request
|
||||
|
|
|
|||
|
|
@ -96,9 +96,13 @@ func (s *Service) triggerForEventWithPullReq(
|
|||
return fmt.Errorf("failed to get pr target repo: %w", err)
|
||||
}
|
||||
|
||||
if pr.SourceRepoID == nil {
|
||||
return events.NewDiscardEventErrorf("source repo for PR id '%d' doesn't exist anymore", pr.ID)
|
||||
}
|
||||
|
||||
sourceRepo := targetRepo
|
||||
if pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err = s.findRepositoryForEvent(ctx, pr.SourceRepoID)
|
||||
if *pr.SourceRepoID != pr.TargetRepoID {
|
||||
sourceRepo, err = s.findRepositoryForEvent(ctx, *pr.SourceRepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get pr source repo: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func (s *Service) handleEventPullReqCreated(
|
|||
return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqCreated,
|
||||
event.ID, event.Payload.PrincipalID, event.Payload.PullReqID,
|
||||
func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) {
|
||||
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, sourceRepo.Path,
|
||||
commitInfo, err := s.fetchCommitInfoForEvent(ctx, targetRepo.GitUID, targetRepo.Path,
|
||||
event.Payload.SourceSHA, s.urlProvider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ func (r RepositoryInfo) MarshalJSON() ([]byte, error) {
|
|||
|
||||
// repositoryInfoFrom gets the RepositoryInfo from a types.Repository.
|
||||
func repositoryInfoFrom(ctx context.Context, repo *types.Repository, urlProvider url.Provider) RepositoryInfo {
|
||||
if repo == nil {
|
||||
return RepositoryInfo{}
|
||||
}
|
||||
return RepositoryInfo{
|
||||
ID: repo.ID,
|
||||
Path: repo.Path,
|
||||
|
|
@ -158,7 +161,7 @@ type PullReqInfo struct {
|
|||
IsDraft bool `json:"is_draft"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
SourceRepoID int64 `json:"source_repo_id"`
|
||||
SourceRepoID *int64 `json:"source_repo_id"`
|
||||
SourceBranch string `json:"source_branch"`
|
||||
TargetRepoID int64 `json:"target_repo_id"`
|
||||
TargetBranch string `json:"target_branch"`
|
||||
|
|
|
|||
|
|
@ -315,6 +315,12 @@ type (
|
|||
|
||||
// ListSizeInfos returns a list of all active repo sizes.
|
||||
ListSizeInfos(ctx context.Context) ([]*types.RepositorySizeInfo, error)
|
||||
|
||||
// UpdateNumForks increases or decreases number of forks of the repository.
|
||||
UpdateNumForks(ctx context.Context, repoID int64, delta int64) error
|
||||
|
||||
// ClearForkID clears fork ID of all repositories that have this fork ID.
|
||||
ClearForkID(ctx context.Context, repoUpstreamID int64) error
|
||||
}
|
||||
|
||||
// SettingsStore defines the settings storage.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
DROP INDEX pullreqs_source_repo_branch_target_repo_branch;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
DROP CONSTRAINT fk_pullreq_source_repo_id;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
ALTER COLUMN pullreq_source_repo_id SET NOT NULL;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
ALTER COLUMN pullreq_activity_seq DROP NOT NULL;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
ALTER COLUMN pullreq_merge_check_status DROP DEFAULT;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
ADD CONSTRAINT fk_pullreq_source_repo_id FOREIGN KEY (pullreq_source_repo_id)
|
||||
REFERENCES repositories (repo_id) MATCH SIMPLE
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE CASCADE;
|
||||
|
||||
CREATE UNIQUE INDEX pullreqs_source_repo_branch_target_repo_branch
|
||||
ON pullreqs (pullreq_source_repo_id, pullreq_source_branch, pullreq_target_repo_id, pullreq_target_branch)
|
||||
WHERE pullreq_state = 'open';
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
DROP INDEX pullreqs_source_repo_branch_target_repo_branch;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
DROP CONSTRAINT fk_pullreq_source_repo_id;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
ALTER COLUMN pullreq_source_repo_id DROP NOT NULL;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
ALTER COLUMN pullreq_activity_seq SET NOT NULL;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
ALTER COLUMN pullreq_merge_check_status SET DEFAULT 'unchecked'::text;
|
||||
|
||||
ALTER TABLE pullreqs
|
||||
ADD CONSTRAINT fk_pullreq_source_repo_id FOREIGN KEY (pullreq_source_repo_id)
|
||||
REFERENCES repositories (repo_id) MATCH SIMPLE
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE SET NULL;
|
||||
|
||||
CREATE UNIQUE INDEX pullreqs_source_repo_branch_target_repo_branch
|
||||
ON pullreqs (pullreq_source_repo_id, pullreq_source_branch, pullreq_target_repo_id, pullreq_target_branch)
|
||||
WHERE pullreq_state = 'open' and pullreq_source_repo_id IS NOT NULL;
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
DROP INDEX pullreqs_source_repo_branch_target_repo_branch;
|
||||
DROP INDEX pullreqs_target_repo_id_number;
|
||||
|
||||
CREATE TABLE pullreqs_tmp(
|
||||
pullreq_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,pullreq_version INTEGER DEFAULT 0 NOT NULL
|
||||
,pullreq_created_by INTEGER NOT NULL
|
||||
,pullreq_created BIGINT NOT NULL
|
||||
,pullreq_updated BIGINT NOT NULL
|
||||
,pullreq_edited BIGINT NOT NULL
|
||||
,pullreq_number INTEGER NOT NULL
|
||||
,pullreq_state TEXT NOT NULL
|
||||
,pullreq_is_draft TEXT DEFAULT FALSE NOT NULL
|
||||
,pullreq_comment_count INTEGER DEFAULT 0 NOT NULL
|
||||
,pullreq_title TEXT NOT NULL
|
||||
,pullreq_description TEXT NOT NULL
|
||||
,pullreq_source_repo_id INTEGER NOT NULL
|
||||
,pullreq_source_branch TEXT NOT NULL
|
||||
,pullreq_source_sha TEXT NOT NULL
|
||||
,pullreq_target_repo_id INTEGER NOT NULL
|
||||
,pullreq_target_branch TEXT NOT NULL
|
||||
,pullreq_activity_seq INTEGER DEFAULT 0
|
||||
,pullreq_merged_by INTEGER
|
||||
,pullreq_merged BIGINT
|
||||
,pullreq_merge_method TEXT
|
||||
,pullreq_merge_check_status TEXT NOT NULL
|
||||
,pullreq_merge_target_sha TEXT
|
||||
,pullreq_merge_sha TEXT
|
||||
,pullreq_merge_conflicts TEXT
|
||||
,pullreq_merge_base_sha TEXT DEFAULT '' NOT NULL
|
||||
,pullreq_unresolved_count INTEGER DEFAULT 0 NOT NULL
|
||||
,pullreq_commit_count INTEGER
|
||||
,pullreq_file_count INTEGER
|
||||
,pullreq_closed BIGINT
|
||||
,pullreq_additions INTEGER
|
||||
,pullreq_deletions INTEGER
|
||||
,pullreq_rebase_check_status TEXT DEFAULT 'unchecked' NOT NULL
|
||||
,pullreq_rebase_conflicts TEXT
|
||||
,pullreq_merge_violations_bypassed BOOLEAN default NULL
|
||||
,CONSTRAINT fk_pullreq_created_by FOREIGN KEY (pullreq_created_by)
|
||||
REFERENCES principals
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE NO ACTION
|
||||
,CONSTRAINT fk_pullreq_source_repo_id FOREIGN KEY (pullreq_source_repo_id)
|
||||
REFERENCES repositories
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE SET NULL
|
||||
,CONSTRAINT fk_pullreq_target_repo_id FOREIGN KEY (pullreq_target_repo_id)
|
||||
REFERENCES repositories
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE CASCADE
|
||||
,CONSTRAINT fk_pullreq_merged_by FOREIGN KEY (pullreq_merged_by)
|
||||
REFERENCES principals
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE NO ACTION
|
||||
);
|
||||
|
||||
INSERT INTO pullreqs_tmp(
|
||||
pullreq_id,
|
||||
pullreq_version,
|
||||
pullreq_created_by,
|
||||
pullreq_created,
|
||||
pullreq_updated,
|
||||
pullreq_edited,
|
||||
pullreq_number,
|
||||
pullreq_state,
|
||||
pullreq_is_draft,
|
||||
pullreq_comment_count,
|
||||
pullreq_title,
|
||||
pullreq_description,
|
||||
pullreq_source_repo_id,
|
||||
pullreq_source_branch,
|
||||
pullreq_source_sha,
|
||||
pullreq_target_repo_id,
|
||||
pullreq_target_branch,
|
||||
pullreq_activity_seq,
|
||||
pullreq_merged_by,
|
||||
pullreq_merged,
|
||||
pullreq_merge_method,
|
||||
pullreq_merge_check_status,
|
||||
pullreq_merge_target_sha,
|
||||
pullreq_merge_sha,
|
||||
pullreq_merge_conflicts,
|
||||
pullreq_merge_base_sha,
|
||||
pullreq_unresolved_count,
|
||||
pullreq_commit_count,
|
||||
pullreq_file_count,
|
||||
pullreq_closed,
|
||||
pullreq_additions,
|
||||
pullreq_deletions,
|
||||
pullreq_rebase_check_status,
|
||||
pullreq_rebase_conflicts,
|
||||
pullreq_merge_violations_bypassed
|
||||
)
|
||||
SELECT
|
||||
pullreq_id,
|
||||
pullreq_version,
|
||||
pullreq_created_by,
|
||||
pullreq_created,
|
||||
pullreq_updated,
|
||||
pullreq_edited,
|
||||
pullreq_number,
|
||||
pullreq_state,
|
||||
pullreq_is_draft,
|
||||
pullreq_comment_count,
|
||||
pullreq_title,
|
||||
pullreq_description,
|
||||
pullreq_source_repo_id,
|
||||
pullreq_source_branch,
|
||||
pullreq_source_sha,
|
||||
pullreq_target_repo_id,
|
||||
pullreq_target_branch,
|
||||
pullreq_activity_seq,
|
||||
pullreq_merged_by,
|
||||
pullreq_merged,
|
||||
pullreq_merge_method,
|
||||
pullreq_merge_check_status,
|
||||
pullreq_merge_target_sha,
|
||||
pullreq_merge_sha,
|
||||
pullreq_merge_conflicts,
|
||||
pullreq_merge_base_sha,
|
||||
pullreq_unresolved_count,
|
||||
pullreq_commit_count,
|
||||
pullreq_file_count,
|
||||
pullreq_closed,
|
||||
pullreq_additions,
|
||||
pullreq_deletions,
|
||||
pullreq_rebase_check_status,
|
||||
pullreq_rebase_conflicts,
|
||||
pullreq_merge_violations_bypassed
|
||||
FROM pullreqs;
|
||||
|
||||
DROP TABLE pullreqs;
|
||||
|
||||
ALTER TABLE pullreqs_tmp RENAME TO pullreqs;
|
||||
|
||||
CREATE UNIQUE INDEX pullreqs_target_repo_id_number
|
||||
on pullreqs (pullreq_target_repo_id, pullreq_number);
|
||||
|
||||
CREATE UNIQUE INDEX pullreqs_source_repo_branch_target_repo_branch
|
||||
ON pullreqs (pullreq_source_repo_id, pullreq_source_branch, pullreq_target_repo_id, pullreq_target_branch)
|
||||
WHERE pullreq_state = 'open';
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
DROP INDEX pullreqs_source_repo_branch_target_repo_branch;
|
||||
DROP INDEX pullreqs_target_repo_id_number;
|
||||
|
||||
CREATE TABLE pullreqs_tmp(
|
||||
pullreq_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,pullreq_version INTEGER DEFAULT 0 NOT NULL
|
||||
,pullreq_created_by INTEGER NOT NULL
|
||||
,pullreq_created BIGINT NOT NULL
|
||||
,pullreq_updated BIGINT NOT NULL
|
||||
,pullreq_edited BIGINT NOT NULL
|
||||
,pullreq_number INTEGER NOT NULL
|
||||
,pullreq_state TEXT NOT NULL
|
||||
,pullreq_is_draft TEXT DEFAULT FALSE NOT NULL
|
||||
,pullreq_comment_count INTEGER DEFAULT 0 NOT NULL
|
||||
,pullreq_title TEXT NOT NULL
|
||||
,pullreq_description TEXT NOT NULL
|
||||
,pullreq_source_repo_id INTEGER
|
||||
,pullreq_source_branch TEXT NOT NULL
|
||||
,pullreq_source_sha TEXT NOT NULL
|
||||
,pullreq_target_repo_id INTEGER NOT NULL
|
||||
,pullreq_target_branch TEXT NOT NULL
|
||||
,pullreq_activity_seq INTEGER NOT NULL DEFAULT 0
|
||||
,pullreq_merged_by INTEGER
|
||||
,pullreq_merged BIGINT
|
||||
,pullreq_merge_method TEXT
|
||||
,pullreq_merge_check_status TEXT DEFAULT 'unchecked' NOT NULL
|
||||
,pullreq_merge_target_sha TEXT
|
||||
,pullreq_merge_sha TEXT
|
||||
,pullreq_merge_conflicts TEXT
|
||||
,pullreq_merge_base_sha TEXT DEFAULT '' NOT NULL
|
||||
,pullreq_unresolved_count INTEGER DEFAULT 0 NOT NULL
|
||||
,pullreq_commit_count INTEGER
|
||||
,pullreq_file_count INTEGER
|
||||
,pullreq_closed BIGINT
|
||||
,pullreq_additions INTEGER
|
||||
,pullreq_deletions INTEGER
|
||||
,pullreq_rebase_check_status TEXT DEFAULT 'unchecked' NOT NULL
|
||||
,pullreq_rebase_conflicts TEXT
|
||||
,pullreq_merge_violations_bypassed BOOLEAN default NULL
|
||||
,CONSTRAINT fk_pullreq_created_by FOREIGN KEY (pullreq_created_by)
|
||||
REFERENCES principals
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE NO ACTION
|
||||
,CONSTRAINT fk_pullreq_source_repo_id FOREIGN KEY (pullreq_source_repo_id)
|
||||
REFERENCES repositories
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE SET NULL
|
||||
,CONSTRAINT fk_pullreq_target_repo_id FOREIGN KEY (pullreq_target_repo_id)
|
||||
REFERENCES repositories
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE CASCADE
|
||||
,CONSTRAINT fk_pullreq_merged_by FOREIGN KEY (pullreq_merged_by)
|
||||
REFERENCES principals
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE NO ACTION
|
||||
);
|
||||
|
||||
INSERT INTO pullreqs_tmp(
|
||||
pullreq_id,
|
||||
pullreq_version,
|
||||
pullreq_created_by,
|
||||
pullreq_created,
|
||||
pullreq_updated,
|
||||
pullreq_edited,
|
||||
pullreq_number,
|
||||
pullreq_state,
|
||||
pullreq_is_draft,
|
||||
pullreq_comment_count,
|
||||
pullreq_title,
|
||||
pullreq_description,
|
||||
pullreq_source_repo_id,
|
||||
pullreq_source_branch,
|
||||
pullreq_source_sha,
|
||||
pullreq_target_repo_id,
|
||||
pullreq_target_branch,
|
||||
pullreq_activity_seq,
|
||||
pullreq_merged_by,
|
||||
pullreq_merged,
|
||||
pullreq_merge_method,
|
||||
pullreq_merge_check_status,
|
||||
pullreq_merge_target_sha,
|
||||
pullreq_merge_sha,
|
||||
pullreq_merge_conflicts,
|
||||
pullreq_merge_base_sha,
|
||||
pullreq_unresolved_count,
|
||||
pullreq_commit_count,
|
||||
pullreq_file_count,
|
||||
pullreq_closed,
|
||||
pullreq_additions,
|
||||
pullreq_deletions,
|
||||
pullreq_rebase_check_status,
|
||||
pullreq_rebase_conflicts,
|
||||
pullreq_merge_violations_bypassed
|
||||
)
|
||||
SELECT
|
||||
pullreq_id,
|
||||
pullreq_version,
|
||||
pullreq_created_by,
|
||||
pullreq_created,
|
||||
pullreq_updated,
|
||||
pullreq_edited,
|
||||
pullreq_number,
|
||||
pullreq_state,
|
||||
pullreq_is_draft,
|
||||
pullreq_comment_count,
|
||||
pullreq_title,
|
||||
pullreq_description,
|
||||
pullreq_source_repo_id,
|
||||
pullreq_source_branch,
|
||||
pullreq_source_sha,
|
||||
pullreq_target_repo_id,
|
||||
pullreq_target_branch,
|
||||
pullreq_activity_seq,
|
||||
pullreq_merged_by,
|
||||
pullreq_merged,
|
||||
pullreq_merge_method,
|
||||
pullreq_merge_check_status,
|
||||
pullreq_merge_target_sha,
|
||||
pullreq_merge_sha,
|
||||
pullreq_merge_conflicts,
|
||||
pullreq_merge_base_sha,
|
||||
pullreq_unresolved_count,
|
||||
pullreq_commit_count,
|
||||
pullreq_file_count,
|
||||
pullreq_closed,
|
||||
pullreq_additions,
|
||||
pullreq_deletions,
|
||||
pullreq_rebase_check_status,
|
||||
pullreq_rebase_conflicts,
|
||||
pullreq_merge_violations_bypassed
|
||||
FROM pullreqs;
|
||||
|
||||
DROP TABLE pullreqs;
|
||||
|
||||
ALTER TABLE pullreqs_tmp RENAME TO pullreqs;
|
||||
|
||||
CREATE UNIQUE INDEX pullreqs_target_repo_id_number
|
||||
on pullreqs (pullreq_target_repo_id, pullreq_number);
|
||||
|
||||
CREATE UNIQUE INDEX pullreqs_source_repo_branch_target_repo_branch
|
||||
ON pullreqs (pullreq_source_repo_id, pullreq_source_branch, pullreq_target_repo_id, pullreq_target_branch)
|
||||
WHERE pullreq_state = 'open' and pullreq_source_repo_id IS NOT NULL;
|
||||
|
|
@ -74,11 +74,11 @@ type pullReq struct {
|
|||
Title string `db:"pullreq_title"`
|
||||
Description string `db:"pullreq_description"`
|
||||
|
||||
SourceRepoID int64 `db:"pullreq_source_repo_id"`
|
||||
SourceBranch string `db:"pullreq_source_branch"`
|
||||
SourceSHA string `db:"pullreq_source_sha"`
|
||||
TargetRepoID int64 `db:"pullreq_target_repo_id"`
|
||||
TargetBranch string `db:"pullreq_target_branch"`
|
||||
SourceRepoID null.Int `db:"pullreq_source_repo_id"`
|
||||
SourceBranch string `db:"pullreq_source_branch"`
|
||||
SourceSHA string `db:"pullreq_source_sha"`
|
||||
TargetRepoID int64 `db:"pullreq_target_repo_id"`
|
||||
TargetBranch string `db:"pullreq_target_branch"`
|
||||
|
||||
ActivitySeq int64 `db:"pullreq_activity_seq"`
|
||||
|
||||
|
|
@ -868,7 +868,7 @@ func mapPullReq(pr *pullReq) *types.PullReq {
|
|||
UnresolvedCount: pr.UnresolvedCount,
|
||||
Title: pr.Title,
|
||||
Description: pr.Description,
|
||||
SourceRepoID: pr.SourceRepoID,
|
||||
SourceRepoID: pr.SourceRepoID.Ptr(),
|
||||
SourceBranch: pr.SourceBranch,
|
||||
SourceSHA: pr.SourceSHA,
|
||||
TargetRepoID: pr.TargetRepoID,
|
||||
|
|
@ -918,7 +918,7 @@ func mapInternalPullReq(pr *types.PullReq) *pullReq {
|
|||
UnresolvedCount: pr.UnresolvedCount,
|
||||
Title: pr.Title,
|
||||
Description: pr.Description,
|
||||
SourceRepoID: pr.SourceRepoID,
|
||||
SourceRepoID: null.IntFromPtr(pr.SourceRepoID),
|
||||
SourceBranch: pr.SourceBranch,
|
||||
SourceSHA: pr.SourceSHA,
|
||||
TargetRepoID: pr.TargetRepoID,
|
||||
|
|
|
|||
|
|
@ -303,7 +303,6 @@ func (s *RepoStore) Update(ctx context.Context, repo *types.Repository) error {
|
|||
,repo_description = :repo_description
|
||||
,repo_default_branch = :repo_default_branch
|
||||
,repo_pullreq_seq = :repo_pullreq_seq
|
||||
,repo_num_forks = :repo_num_forks
|
||||
,repo_num_pulls = :repo_num_pulls
|
||||
,repo_num_closed_pulls = :repo_num_closed_pulls
|
||||
,repo_num_open_pulls = :repo_num_open_pulls
|
||||
|
|
@ -813,6 +812,35 @@ func (s *RepoStore) ListAll(
|
|||
return s.mapToRepos(ctx, dst)
|
||||
}
|
||||
|
||||
func (s *RepoStore) UpdateNumForks(ctx context.Context, repoID int64, delta int64) error {
|
||||
query := "UPDATE repositories SET repo_num_forks = repo_num_forks + $1 WHERE repo_id = $2"
|
||||
|
||||
if _, err := dbtx.GetAccessor(ctx, s.db).ExecContext(ctx, query, delta, repoID); err != nil {
|
||||
return database.ProcessSQLErrorf(ctx, err, "failed updating number of forks")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *RepoStore) ClearForkID(ctx context.Context, repoUpstreamID int64) error {
|
||||
stmt := database.Builder.Update("repositories").
|
||||
Set("repo_fork_id", nil).
|
||||
Where("repo_fork_id = ?", repoUpstreamID)
|
||||
|
||||
sql, args, err := stmt.ToSql()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to convert query to sql")
|
||||
}
|
||||
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
_, err = db.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return database.ProcessSQLErrorf(ctx, err, "failed to clear fork ID")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *RepoStore) mapToRepo(
|
||||
ctx context.Context,
|
||||
in *repository,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ type PullReq struct {
|
|||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
|
||||
SourceRepoID int64 `json:"source_repo_id"`
|
||||
SourceRepoID *int64 `json:"source_repo_id"`
|
||||
SourceBranch string `json:"source_branch"`
|
||||
SourceSHA string `json:"source_sha"`
|
||||
TargetRepoID int64 `json:"target_repo_id"`
|
||||
|
|
|
|||
Loading…
Reference in New Issue