diff options
author | John Cai <jcai@gitlab.com> | 2022-07-25 17:15:41 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2022-07-25 18:10:12 +0300 |
commit | 231bf5e66916b7460902228a765b0a44025b609a (patch) | |
tree | 63c0c613ba3da5cc860bf922c394f5178f2658bc | |
parent | 17a3fc6cae47ba8b9c96250bfb38441350c9ee8b (diff) |
operations: Remove CherryPickStructuredErrors feature flagjc-remove-user-cherry-pick-ff
Now that we have been running this feature flag in production for a week
without issue, we can remove it.
-rw-r--r-- | cmd/gitaly-git2go-v15/cherry_pick.go | 17 | ||||
-rw-r--r-- | cmd/gitaly-git2go-v15/cherry_pick_test.go | 23 | ||||
-rw-r--r-- | internal/gitaly/service/operations/cherry_pick.go | 149 | ||||
-rw-r--r-- | internal/gitaly/service/operations/cherry_pick_test.go | 164 | ||||
-rw-r--r-- | internal/metadata/featureflag/ff_cherry_pick_structured_errors.go | 10 |
5 files changed, 122 insertions, 241 deletions
diff --git a/cmd/gitaly-git2go-v15/cherry_pick.go b/cmd/gitaly-git2go-v15/cherry_pick.go index ada0c3b97..5ebbb26b0 100644 --- a/cmd/gitaly-git2go-v15/cherry_pick.go +++ b/cmd/gitaly-git2go-v15/cherry_pick.go @@ -12,7 +12,6 @@ import ( git "github.com/libgit2/git2go/v33" "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go-v15/git2goutil" "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" ) type cherryPickSubcommand struct{} @@ -93,18 +92,14 @@ func (cmd *cherryPickSubcommand) cherryPick(ctx context.Context, r *git2go.Cherr } if index.HasConflicts() { - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - conflictingFiles, err := getConflictingFiles(index) - if err != nil { - return "", fmt.Errorf("getting conflicting files: %w", err) - } - - return "", git2go.ConflictingFilesError{ - ConflictingFiles: conflictingFiles, - } + conflictingFiles, err := getConflictingFiles(index) + if err != nil { + return "", fmt.Errorf("getting conflicting files: %w", err) } - return "", git2go.HasConflictsError{} + return "", git2go.ConflictingFilesError{ + ConflictingFiles: conflictingFiles, + } } tree, err := index.WriteTreeTo(repo) diff --git a/cmd/gitaly-git2go-v15/cherry_pick_test.go b/cmd/gitaly-git2go-v15/cherry_pick_test.go index 2e3ebe78e..e9b82c8db 100644 --- a/cmd/gitaly-git2go-v15/cherry_pick_test.go +++ b/cmd/gitaly-git2go-v15/cherry_pick_test.go @@ -3,7 +3,6 @@ package main import ( - "context" "testing" "time" @@ -13,7 +12,6 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/cmd/gitaly-git2go-v15/git2goutil" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" - "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" ) @@ -161,11 +159,7 @@ func TestCherryPick(t *testing.T) { } t.Run(tc.desc, func(t *testing.T) { - ctx := featureflag.ContextWithFeatureFlag( - testhelper.Context(t), - featureflag.CherryPickStructuredErrors, - true, - ) + ctx := testhelper.Context(t) committer := git.Signature{ Name: "Baz", @@ -224,12 +218,8 @@ func TestCherryPick(t *testing.T) { } func TestCherryPickStructuredErrors(t *testing.T) { - testhelper.NewFeatureSets(featureflag.CherryPickStructuredErrors).Run(t, - testCherryPickStructuredErrors, - ) -} + ctx := testhelper.Context(t) -func testCherryPickStructuredErrors(t *testing.T, ctx context.Context) { cfg, repo, repoPath := testcfg.BuildWithRepo(t) testcfg.BuildGitalyGit2Go(t, cfg) @@ -278,11 +268,6 @@ func testCherryPickStructuredErrors(t *testing.T, ctx context.Context) { Commit: commit, }) - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - require.EqualError(t, err, "cherry-pick: there are conflicting files") - require.ErrorAs(t, err, &git2go.ConflictingFilesError{}) - } else { - require.EqualError(t, err, "cherry-pick: could not apply due to conflicts") - require.ErrorAs(t, err, &git2go.HasConflictsError{}) - } + require.EqualError(t, err, "cherry-pick: there are conflicting files") + require.ErrorAs(t, err, &git2go.ConflictingFilesError{}) } diff --git a/internal/gitaly/service/operations/cherry_pick.go b/internal/gitaly/service/operations/cherry_pick.go index 23b0566fd..8732f84cb 100644 --- a/internal/gitaly/service/operations/cherry_pick.go +++ b/internal/gitaly/service/operations/cherry_pick.go @@ -11,7 +11,6 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref" "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" - "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -64,62 +63,43 @@ func (s *Server) UserCherryPick(ctx context.Context, req *gitalypb.UserCherryPic Mainline: mainline, }) if err != nil { - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - var conflictErr git2go.ConflictingFilesError - var emptyErr git2go.EmptyError - - switch { - case errors.As(err, &conflictErr): - conflictingFiles := make([][]byte, 0, len(conflictErr.ConflictingFiles)) - for _, conflictingFile := range conflictErr.ConflictingFiles { - conflictingFiles = append(conflictingFiles, []byte(conflictingFile)) - } - - detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( - helper.ErrFailedPreconditionf("cherry pick: %w", err), - &gitalypb.UserCherryPickError{ - Error: &gitalypb.UserCherryPickError_CherryPickConflict{ - CherryPickConflict: &gitalypb.MergeConflictError{ - ConflictingFiles: conflictingFiles, - }, + var conflictErr git2go.ConflictingFilesError + var emptyErr git2go.EmptyError + + switch { + case errors.As(err, &conflictErr): + conflictingFiles := make([][]byte, 0, len(conflictErr.ConflictingFiles)) + for _, conflictingFile := range conflictErr.ConflictingFiles { + conflictingFiles = append(conflictingFiles, []byte(conflictingFile)) + } + + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPreconditionf("cherry pick: %w", err), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_CherryPickConflict{ + CherryPickConflict: &gitalypb.MergeConflictError{ + ConflictingFiles: conflictingFiles, }, }, - ) - if errGeneratingDetailedErr != nil { - return nil, helper.ErrInternalf("error details: %w", err) - } - - return nil, detailedErr - case errors.As(err, &emptyErr): - detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( - helper.ErrFailedPrecondition(err), - &gitalypb.UserCherryPickError{ - Error: &gitalypb.UserCherryPickError_ChangesAlreadyApplied{}, - }, - ) - if errGeneratingDetailedErr != nil { - return nil, helper.ErrInternalf("error details: %w", err) - } - - return nil, detailedErr - case errors.Is(err, git2go.ErrInvalidArgument): - return nil, helper.ErrInvalidArgument(err) - default: - return nil, helper.ErrInternalf("cherry-pick command: %w", err) + }, + ) + if errGeneratingDetailedErr != nil { + return nil, helper.ErrInternalf("error details: %w", err) } - } - switch { - case errors.As(err, &git2go.HasConflictsError{}) || errors.As(err, &git2go.ConflictingFilesError{}): - return &gitalypb.UserCherryPickResponse{ - CreateTreeError: err.Error(), - CreateTreeErrorCode: gitalypb.UserCherryPickResponse_CONFLICT, - }, nil - case errors.As(err, &git2go.EmptyError{}): - return &gitalypb.UserCherryPickResponse{ - CreateTreeError: err.Error(), - CreateTreeErrorCode: gitalypb.UserCherryPickResponse_EMPTY, - }, nil + return nil, detailedErr + case errors.As(err, &emptyErr): + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPrecondition(err), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_ChangesAlreadyApplied{}, + }, + ) + if errGeneratingDetailedErr != nil { + return nil, helper.ErrInternalf("error details: %w", err) + } + + return nil, detailedErr case errors.Is(err, git2go.ErrInvalidArgument): return nil, helper.ErrInvalidArgument(err) default: @@ -148,57 +128,46 @@ func (s *Server) UserCherryPick(ctx context.Context, req *gitalypb.UserCherryPic return nil, err } if !ancestor { - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( - helper.ErrFailedPrecondition(errors.New("cherry-pick: branch diverged")), - &gitalypb.UserCherryPickError{ - Error: &gitalypb.UserCherryPickError_TargetBranchDiverged{ - TargetBranchDiverged: &gitalypb.NotAncestorError{ - ParentRevision: []byte(oldrev.Revision()), - ChildRevision: []byte(newrev), - }, + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPrecondition(errors.New("cherry-pick: branch diverged")), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_TargetBranchDiverged{ + TargetBranchDiverged: &gitalypb.NotAncestorError{ + ParentRevision: []byte(oldrev.Revision()), + ChildRevision: []byte(newrev), }, - }) - - if errGeneratingDetailedErr != nil { - return nil, helper.ErrInternalf("error details: %w", err) - } + }, + }) - return nil, detailedErr + if errGeneratingDetailedErr != nil { + return nil, helper.ErrInternalf("error details: %w", err) } - return &gitalypb.UserCherryPickResponse{ - CommitError: "Branch diverged", - }, nil + return nil, detailedErr } } if err := s.updateReferenceWithHooks(ctx, req.GetRepository(), req.User, quarantineDir, referenceName, newrev, oldrev); err != nil { - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - var customHookErr updateref.CustomHookError - - if errors.As(err, &customHookErr) { - detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( - helper.ErrFailedPrecondition(errors.New("access check failed")), - &gitalypb.UserCherryPickError{ - Error: &gitalypb.UserCherryPickError_AccessCheck{ - AccessCheck: &gitalypb.AccessCheckError{ - ErrorMessage: strings.TrimSuffix(customHookErr.Error(), "\n"), - }, - }, - }) + var customHookErr updateref.CustomHookError - if errGeneratingDetailedErr != nil { - return nil, helper.ErrInternalf("error details: %w", err) - } + if errors.As(err, &customHookErr) { + detailedErr, errGeneratingDetailedErr := helper.ErrWithDetails( + helper.ErrFailedPrecondition(errors.New("access check failed")), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + ErrorMessage: strings.TrimSuffix(customHookErr.Error(), "\n"), + }, + }, + }) - return nil, detailedErr + if errGeneratingDetailedErr != nil { + return nil, helper.ErrInternalf("error details: %w", err) } - return nil, fmt.Errorf("update reference with hooks: %w", err) + return nil, detailedErr } - var customHookErr updateref.CustomHookError if errors.As(err, &customHookErr) { return &gitalypb.UserCherryPickResponse{ PreReceiveError: customHookErr.Error(), diff --git a/internal/gitaly/service/operations/cherry_pick_test.go b/internal/gitaly/service/operations/cherry_pick_test.go index ccc8bc6e9..6fad1115f 100644 --- a/internal/gitaly/service/operations/cherry_pick_test.go +++ b/internal/gitaly/service/operations/cherry_pick_test.go @@ -3,7 +3,6 @@ package operations import ( - "context" "errors" "fmt" "path/filepath" @@ -16,7 +15,6 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" - "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "google.golang.org/grpc/codes" @@ -349,13 +347,7 @@ func TestServer_UserCherryPick_failedValidations(t *testing.T) { func TestServer_UserCherryPick_failedWithPreReceiveError(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.CherryPickStructuredErrors).Run(t, testServerUserCherryPickFailedWithPreReceiveError) -} - -func testServerUserCherryPickFailedWithPreReceiveError(t *testing.T, ctx context.Context) { - t.Parallel() - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -380,37 +372,27 @@ func testServerUserCherryPickFailedWithPreReceiveError(t *testing.T, ctx context gittest.WriteCustomHook(t, repoPath, hookName, hookContent) response, err := client.UserCherryPick(ctx, request) - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - require.Nil(t, response) - testhelper.RequireGrpcError(t, errWithDetails(t, - helper.ErrFailedPrecondition( - errors.New("access check failed"), - ), - &gitalypb.UserCherryPickError{ - Error: &gitalypb.UserCherryPickError_AccessCheck{ - AccessCheck: &gitalypb.AccessCheckError{ - ErrorMessage: "GL_ID=user-123", - }, + require.Nil(t, response) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrFailedPrecondition( + errors.New("access check failed"), + ), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_AccessCheck{ + AccessCheck: &gitalypb.AccessCheckError{ + ErrorMessage: "GL_ID=user-123", }, }, - ), err) - } else { - require.NoError(t, err) - require.Contains(t, response.PreReceiveError, "GL_ID="+gittest.TestUser.GlId) - } + }, + ), err) }) } } func TestServer_UserCherryPick_failedWithCreateTreeError(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.CherryPickStructuredErrors).Run(t, testServerUserCherryPickFailedWithCreateTreeError) -} -func testServerUserCherryPickFailedWithCreateTreeError(t *testing.T, ctx context.Context) { - t.Parallel() - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -430,32 +412,21 @@ func testServerUserCherryPickFailedWithCreateTreeError(t *testing.T, ctx context } response, err := client.UserCherryPick(ctx, request) - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - require.Nil(t, response) - testhelper.RequireGrpcError(t, errWithDetails(t, - helper.ErrFailedPrecondition( - errors.New("cherry-pick: could not apply because the result was empty"), - ), - &gitalypb.UserCherryPickError{ - Error: &gitalypb.UserCherryPickError_ChangesAlreadyApplied{}, - }, - ), err) - } else { - require.NoError(t, err) - require.NotEmpty(t, response.CreateTreeError) - require.Equal(t, gitalypb.UserCherryPickResponse_EMPTY, response.CreateTreeErrorCode) - } + require.Nil(t, response) + testhelper.RequireGrpcError(t, errWithDetails(t, + helper.ErrFailedPrecondition( + errors.New("cherry-pick: could not apply because the result was empty"), + ), + &gitalypb.UserCherryPickError{ + Error: &gitalypb.UserCherryPickError_ChangesAlreadyApplied{}, + }, + ), err) } func TestServer_UserCherryPick_failedWithCommitError(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.CherryPickStructuredErrors).Run(t, testServerUserCherryPickFailedWithCommitError) -} -func testServerUserCherryPickFailedWithCommitError(t *testing.T, ctx context.Context) { - t.Parallel() - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -477,36 +448,24 @@ func testServerUserCherryPickFailedWithCommitError(t *testing.T, ctx context.Con } response, err := client.UserCherryPick(ctx, request) - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - require.Nil(t, response) - s, ok := status.FromError(err) - require.True(t, ok) - - details := s.Details() - require.Len(t, details, 1) - detailedErr, ok := details[0].(*gitalypb.UserCherryPickError) - require.True(t, ok) - - targetBranchDivergedErr, ok := detailedErr.Error.(*gitalypb.UserCherryPickError_TargetBranchDiverged) - require.True(t, ok) - assert.Equal(t, []byte("8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"), targetBranchDivergedErr.TargetBranchDiverged.ParentRevision) - } else { - require.NoError(t, err) - require.Equal(t, "Branch diverged", response.CommitError) - } + require.Nil(t, response) + s, ok := status.FromError(err) + require.True(t, ok) + + details := s.Details() + require.Len(t, details, 1) + detailedErr, ok := details[0].(*gitalypb.UserCherryPickError) + require.True(t, ok) + + targetBranchDivergedErr, ok := detailedErr.Error.(*gitalypb.UserCherryPickError_TargetBranchDiverged) + require.True(t, ok) + assert.Equal(t, []byte("8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"), targetBranchDivergedErr.TargetBranchDiverged.ParentRevision) } func TestServerUserCherryPickRailedWithConflict(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.CherryPickStructuredErrors).Run( - t, - testServerUserCherryPickRailedWithConflict, - ) -} - -func testServerUserCherryPickRailedWithConflict(t *testing.T, ctx context.Context) { - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -526,25 +485,19 @@ func testServerUserCherryPickRailedWithConflict(t *testing.T, ctx context.Contex } response, err := client.UserCherryPick(ctx, request) - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - require.Nil(t, response) - s, ok := status.FromError(err) - require.True(t, ok) - - details := s.Details() - require.Len(t, details, 1) - detailedErr, ok := details[0].(*gitalypb.UserCherryPickError) - require.True(t, ok) - - conflictErr, ok := detailedErr.Error.(*gitalypb.UserCherryPickError_CherryPickConflict) - require.True(t, ok) - require.Len(t, conflictErr.CherryPickConflict.ConflictingFiles, 1) - assert.Equal(t, []byte("NEW_FILE.md"), conflictErr.CherryPickConflict.ConflictingFiles[0]) - } else { - require.NoError(t, err) - require.NotEmpty(t, response.CreateTreeError) - require.Equal(t, gitalypb.UserCherryPickResponse_CONFLICT, response.CreateTreeErrorCode) - } + require.Nil(t, response) + s, ok := status.FromError(err) + require.True(t, ok) + + details := s.Details() + require.Len(t, details, 1) + detailedErr, ok := details[0].(*gitalypb.UserCherryPickError) + require.True(t, ok) + + conflictErr, ok := detailedErr.Error.(*gitalypb.UserCherryPickError_CherryPickConflict) + require.True(t, ok) + require.Len(t, conflictErr.CherryPickConflict.ConflictingFiles, 1) + assert.Equal(t, []byte("NEW_FILE.md"), conflictErr.CherryPickConflict.ConflictingFiles[0]) } func TestServer_UserCherryPick_successfulWithGivenCommits(t *testing.T) { @@ -605,13 +558,7 @@ func TestServer_UserCherryPick_successfulWithGivenCommits(t *testing.T) { func TestServer_UserCherryPick_quarantine(t *testing.T) { t.Parallel() - testhelper.NewFeatureSets(featureflag.CherryPickStructuredErrors).Run(t, testServerUserCherryPickQuarantine) -} - -func testServerUserCherryPickQuarantine(t *testing.T, ctx context.Context) { - t.Parallel() - - ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx) + ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, testhelper.Context(t)) repo := localrepo.NewTestRepo(t, cfg, repoProto) // Set up a hook that parses the new object and then aborts the update. Like this, we can @@ -636,14 +583,9 @@ func testServerUserCherryPickQuarantine(t *testing.T, ctx context.Context) { } response, err := client.UserCherryPick(ctx, request) - if featureflag.CherryPickStructuredErrors.IsEnabled(ctx) { - require.Nil(t, response) - require.NotNil(t, err) - assert.Contains(t, err.Error(), "access check failed") - } else { - require.NoError(t, err) - require.NotNil(t, response) - } + require.Nil(t, response) + require.NotNil(t, err) + assert.Contains(t, err.Error(), "access check failed") hookOutput := testhelper.MustReadFile(t, outputPath) oid, err := git.ObjectHashSHA1.FromHex(text.ChompBytes(hookOutput)) diff --git a/internal/metadata/featureflag/ff_cherry_pick_structured_errors.go b/internal/metadata/featureflag/ff_cherry_pick_structured_errors.go deleted file mode 100644 index 594fddf3c..000000000 --- a/internal/metadata/featureflag/ff_cherry_pick_structured_errors.go +++ /dev/null @@ -1,10 +0,0 @@ -package featureflag - -// CherryPickStructuredErrors enables the UserCherryPick RPC to return -// structured errors. -var CherryPickStructuredErrors = NewFeatureFlag( - "cherry_pick_structured_errors", - "v15.2.0", - "https://gitlab.com/gitlab-org/gitaly/-/issues/4325", - false, -) |