mirror of
https://github.com/harness/drone.git
synced 2025-05-05 15:32:56 +00:00
fix: [CODE-2717]: Modify Sync to take DefaultBranch as input (#2962)
This commit is contained in:
parent
4d4917eddc
commit
ccce5ad646
@ -314,16 +314,12 @@ func (r *Repository) Handle(ctx context.Context, data string, _ job.ProgressRepo
|
||||
|
||||
log.Info().Msg("sync repository")
|
||||
|
||||
defaultBranch, err := r.syncGitRepository(ctx, &systemPrincipal, repo, cloneURLWithAuth)
|
||||
err = r.syncGitRepository(ctx, &systemPrincipal, repo, cloneURLWithAuth)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to sync git repository from '%s': %w", input.CloneURL, err)
|
||||
}
|
||||
|
||||
log.Info().Msgf("successfully synced repository (returned default branch: '%s')", defaultBranch)
|
||||
|
||||
if defaultBranch == "" {
|
||||
defaultBranch = r.defaultBranch
|
||||
}
|
||||
log.Info().Msgf("successfully synced repository (with default branch: %q)", repo.DefaultBranch)
|
||||
|
||||
log.Info().Msg("update repo in DB")
|
||||
|
||||
@ -333,7 +329,6 @@ func (r *Repository) Handle(ctx context.Context, data string, _ job.ProgressRepo
|
||||
}
|
||||
|
||||
repo.GitUID = gitUID
|
||||
repo.DefaultBranch = defaultBranch
|
||||
repo.State = enum.RepoStateActive
|
||||
|
||||
return nil
|
||||
@ -463,23 +458,24 @@ func (r *Repository) syncGitRepository(ctx context.Context,
|
||||
principal *types.Principal,
|
||||
repo *types.Repository,
|
||||
sourceCloneURL string,
|
||||
) (string, error) {
|
||||
) error {
|
||||
writeParams, err := r.createRPCWriteParams(ctx, principal, repo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
|
||||
syncOut, err := r.git.SyncRepository(ctx, &git.SyncRepositoryParams{
|
||||
_, err = r.git.SyncRepository(ctx, &git.SyncRepositoryParams{
|
||||
WriteParams: writeParams,
|
||||
Source: sourceCloneURL,
|
||||
CreateIfNotExists: false,
|
||||
RefSpecs: []string{"refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"},
|
||||
DefaultBranch: repo.DefaultBranch,
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to sync repository: %w", err)
|
||||
return fmt.Errorf("failed to sync repository: %w", err)
|
||||
}
|
||||
|
||||
return syncOut.DefaultBranch, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) deleteGitRepository(ctx context.Context,
|
||||
|
@ -96,14 +96,22 @@ func (g *Git) HasBranches(
|
||||
|
||||
func (g *Git) IsBranchExist(ctx context.Context, repoPath, name string) (bool, error) {
|
||||
cmd := command.New("show-ref",
|
||||
command.WithFlag("--verify", BranchPrefix+name),
|
||||
command.WithFlag("--exists", BranchPrefix+name),
|
||||
)
|
||||
err := cmd.Run(ctx,
|
||||
command.WithDir(repoPath),
|
||||
)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to check if branch '%s' exist: %w", name, err)
|
||||
if cmdERR := command.AsError(err); cmdERR != nil && cmdERR.IsExitCode(2) {
|
||||
// git returns exit code 2 in case the ref doesn't exist.
|
||||
// On success it would be 0 and no error would be returned in the first place.
|
||||
// Any other exit code we fall through to default error handling.
|
||||
// https://git-scm.com/docs/git-show-ref#Documentation/git-show-ref.txt---exists
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, processGitErrorf(err, "failed to check if branch %q exist", name)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/harness/gitness/errors"
|
||||
"github.com/harness/gitness/git/command"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
@ -98,27 +99,28 @@ func (g *Git) SetDefaultBranch(
|
||||
ctx context.Context,
|
||||
repoPath string,
|
||||
defaultBranch string,
|
||||
allowEmpty bool,
|
||||
ignoreBranchExistance bool,
|
||||
) error {
|
||||
if repoPath == "" {
|
||||
return ErrRepositoryPathEmpty
|
||||
}
|
||||
|
||||
// if requested, error out if branch doesn't exist. Otherwise, blindly set it.
|
||||
exist, err := g.IsBranchExist(ctx, repoPath, defaultBranch)
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Err(err).Msgf("failed to set default branch")
|
||||
}
|
||||
if !allowEmpty && !exist {
|
||||
// TODO: ensure this returns not found error to caller
|
||||
return fmt.Errorf("branch '%s' does not exist", defaultBranch)
|
||||
if !ignoreBranchExistance {
|
||||
// best effort try to check for existence - technically someone else could delete it in the meanwhile.
|
||||
exist, err := g.IsBranchExist(ctx, repoPath, defaultBranch)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check if branch exists: %w", err)
|
||||
}
|
||||
if !exist {
|
||||
return errors.NotFound("branch %q does not exist", defaultBranch)
|
||||
}
|
||||
}
|
||||
|
||||
// change default branch
|
||||
cmd := command.New("symbolic-ref",
|
||||
command.WithArg("HEAD", gitReferenceNamePrefixBranch+defaultBranch),
|
||||
)
|
||||
err = cmd.Run(ctx, command.WithDir(repoPath))
|
||||
err := cmd.Run(ctx, command.WithDir(repoPath))
|
||||
if err != nil {
|
||||
return processGitErrorf(err, "failed to set new default branch")
|
||||
}
|
||||
@ -130,6 +132,26 @@ func (g *Git) SetDefaultBranch(
|
||||
func (g *Git) GetDefaultBranch(
|
||||
ctx context.Context,
|
||||
repoPath string,
|
||||
) (string, error) {
|
||||
rawBranchRef, err := g.GetSymbolicRefHeadRaw(ctx, repoPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get raw symbolic ref HEAD: %w", err)
|
||||
}
|
||||
|
||||
branchName := strings.TrimPrefix(
|
||||
strings.TrimSpace(
|
||||
rawBranchRef,
|
||||
),
|
||||
BranchPrefix,
|
||||
)
|
||||
|
||||
return branchName, nil
|
||||
}
|
||||
|
||||
// GetSymbolicRefHeadRaw returns the raw output of the symolic-ref command for HEAD.
|
||||
func (g *Git) GetSymbolicRefHeadRaw(
|
||||
ctx context.Context,
|
||||
repoPath string,
|
||||
) (string, error) {
|
||||
if repoPath == "" {
|
||||
return "", ErrRepositoryPathEmpty
|
||||
@ -144,7 +166,7 @@ func (g *Git) GetDefaultBranch(
|
||||
command.WithDir(repoPath),
|
||||
command.WithStdout(output))
|
||||
if err != nil {
|
||||
return "", processGitErrorf(err, "failed to get default branch")
|
||||
return "", processGitErrorf(err, "failed to get value of symbolic ref HEAD from git")
|
||||
}
|
||||
|
||||
return output.String(), nil
|
||||
|
63
git/repo.go
63
git/repo.go
@ -109,6 +109,10 @@ type SyncRepositoryParams struct {
|
||||
// RefSpecs [OPTIONAL] allows to override the refspecs that are being synced from the remote repository.
|
||||
// By default all references present on the remote repository will be fetched (including scm internal ones).
|
||||
RefSpecs []string
|
||||
// DefaultBranch [OPTIONAL] allows to override the default branch of the repository.
|
||||
// If empty, the default branch will be set to match the remote repository's default branch.
|
||||
// WARNING: If the remote repo is empty and no value is provided, an api.ErrNoDefaultBranch error is returned.
|
||||
DefaultBranch string
|
||||
}
|
||||
|
||||
type SyncRepositoryOutput struct {
|
||||
@ -130,7 +134,15 @@ type HashRepositoryOutput struct {
|
||||
}
|
||||
type UpdateDefaultBranchParams struct {
|
||||
WriteParams
|
||||
// BranchName is the name of the branch
|
||||
// BranchName is the name of the branch (not the full reference).
|
||||
BranchName string
|
||||
}
|
||||
|
||||
type GetDefaultBranchParams struct {
|
||||
ReadParams
|
||||
}
|
||||
type GetDefaultBranchOutput struct {
|
||||
// BranchName is the name of the branch (not the full reference).
|
||||
BranchName string
|
||||
}
|
||||
|
||||
@ -259,7 +271,7 @@ func (s *Service) SyncRepository(
|
||||
}
|
||||
|
||||
// the default branch doesn't matter for a sync,
|
||||
// we create an empty repo and the head will by updated as part of the Sync.
|
||||
// we create an empty repo and the head will by updated later.
|
||||
const syncDefaultBranch = "main"
|
||||
if err = s.createRepositoryInternal(
|
||||
ctx,
|
||||
@ -278,24 +290,22 @@ func (s *Service) SyncRepository(
|
||||
// sync repo content
|
||||
err = s.git.Sync(ctx, repoPath, params.Source, params.RefSpecs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("SyncRepository: failed to sync git repo: %w", err)
|
||||
return nil, fmt.Errorf("failed to sync from source repo: %w", err)
|
||||
}
|
||||
|
||||
// get remote default branch
|
||||
defaultBranch, err := s.git.GetRemoteDefaultBranch(ctx, params.Source)
|
||||
if errors.Is(err, api.ErrNoDefaultBranch) {
|
||||
return &SyncRepositoryOutput{
|
||||
DefaultBranch: "",
|
||||
}, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("SyncRepository: failed to get default branch from repo: %w", err)
|
||||
defaultBranch := params.DefaultBranch
|
||||
if defaultBranch == "" {
|
||||
// get default branch from remote repo (returns api.ErrNoDefaultBranch if repo is empty!)
|
||||
defaultBranch, err = s.git.GetRemoteDefaultBranch(ctx, params.Source)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get default branch from source repo: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// set default branch
|
||||
err = s.git.SetDefaultBranch(ctx, repoPath, defaultBranch, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("SyncRepository: failed to set default branch of repo: %w", err)
|
||||
return nil, fmt.Errorf("failed to set default branch of repo: %w", err)
|
||||
}
|
||||
|
||||
return &SyncRepositoryOutput{
|
||||
@ -329,7 +339,8 @@ func (s *Service) HashRepository(ctx context.Context, params *HashRepositoryPara
|
||||
}()
|
||||
|
||||
// add default branch to hash
|
||||
defaultBranch, err := s.git.GetDefaultBranch(goCtx, repoPath)
|
||||
// IMPORTANT: Has to stay as is to ensure hash consistency! (e.g. "refs/heads/main/n")
|
||||
defaultBranchRef, err := s.git.GetSymbolicRefHeadRaw(goCtx, repoPath)
|
||||
if err != nil {
|
||||
hashChan <- hash.SourceNext{
|
||||
Err: fmt.Errorf("HashRepository: failed to get default branch: %w", err),
|
||||
@ -338,7 +349,7 @@ func (s *Service) HashRepository(ctx context.Context, params *HashRepositoryPara
|
||||
}
|
||||
|
||||
hashChan <- hash.SourceNext{
|
||||
Data: hash.SerializeHead(defaultBranch),
|
||||
Data: hash.SerializeHead(defaultBranchRef),
|
||||
}
|
||||
|
||||
err = s.git.WalkReferences(goCtx, repoPath, func(wre api.WalkReferencesEntry) error {
|
||||
@ -515,6 +526,26 @@ func (s *Service) GetRepositorySize(
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetDefaultBranch returns the default branch of the repo.
|
||||
func (s *Service) GetDefaultBranch(
|
||||
ctx context.Context,
|
||||
params *GetDefaultBranchParams,
|
||||
) (*GetDefaultBranchOutput, error) {
|
||||
if err := params.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repoPath := getFullPathForRepo(s.reposRoot, params.RepoUID)
|
||||
|
||||
dfltBranch, err := s.git.GetDefaultBranch(ctx, repoPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get repo default branch: %w", err)
|
||||
}
|
||||
return &GetDefaultBranchOutput{
|
||||
BranchName: dfltBranch,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateDefaultBranch updates the default branch of the repo.
|
||||
func (s *Service) UpdateDefaultBranch(
|
||||
ctx context.Context,
|
||||
@ -531,7 +562,7 @@ func (s *Service) UpdateDefaultBranch(
|
||||
|
||||
err := s.git.SetDefaultBranch(ctx, repoPath, params.BranchName, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UpdateDefaultBranch: failed to update repo default branch %q: %w",
|
||||
return fmt.Errorf("failed to update repo default branch %q: %w",
|
||||
params.BranchName, err)
|
||||
}
|
||||
return nil
|
||||
|
@ -17,8 +17,8 @@ package git
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/harness/gitness/git/api"
|
||||
"github.com/harness/gitness/git/merge"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
@ -44,7 +44,7 @@ func (s *Service) Summary(
|
||||
if err != nil {
|
||||
return SummaryOutput{}, err
|
||||
}
|
||||
defaultBranch = strings.TrimSpace(defaultBranch)
|
||||
defaultBranchRef := api.GetReferenceFromBranchName(defaultBranch)
|
||||
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
@ -52,7 +52,7 @@ func (s *Service) Summary(
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
commitCount, err = merge.CommitCount(ctx, repoPath, "", defaultBranch)
|
||||
commitCount, err = merge.CommitCount(ctx, repoPath, "", defaultBranchRef)
|
||||
return err
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user