Fix Default Branch Creation (#37)

While the HEAD is pointed to the correct branch (might not exist), we created the initial files during repo creation still on the master branch (as it's an empty repo and clone by default sets up master when cloning an empty repo)
This commit is contained in:
Johannes Batzill 2022-10-17 19:09:46 -07:00 committed by GitHub
parent 41cbb6622f
commit e423ffda3c
10 changed files with 54 additions and 42 deletions

View File

@ -46,7 +46,7 @@ func initSystem(ctx context.Context, config *types.Config) (*system, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
repoController := repo.ProvideController(authorizer, spaceStore, repoStore, serviceAccountStore, gitrpcInterface) repoController := repo.ProvideController(config, authorizer, spaceStore, repoStore, serviceAccountStore, gitrpcInterface)
spaceController := space.NewController(authorizer, spaceStore, repoStore, serviceAccountStore) spaceController := space.NewController(authorizer, spaceStore, repoStore, serviceAccountStore)
serviceaccountController := serviceaccount.NewController(authorizer, serviceAccountStore, spaceStore, repoStore, tokenStore) serviceaccountController := serviceaccount.NewController(authorizer, serviceAccountStore, spaceStore, repoStore, tokenStore)
apiHandler := router.ProvideAPIHandler(systemStore, authenticator, repoController, spaceController, serviceaccountController, controller) apiHandler := router.ProvideAPIHandler(systemStore, authenticator, repoController, spaceController, serviceaccountController, controller)

View File

@ -20,6 +20,7 @@ type Controller struct {
} }
func NewController( func NewController(
defaultBranch string,
authorizer authz.Authorizer, authorizer authz.Authorizer,
spaceStore store.SpaceStore, spaceStore store.SpaceStore,
repoStore store.RepoStore, repoStore store.RepoStore,
@ -27,10 +28,11 @@ func NewController(
gitRPCClient gitrpc.Interface, gitRPCClient gitrpc.Interface,
) *Controller { ) *Controller {
return &Controller{ return &Controller{
authorizer: authorizer, defaultBranch: defaultBranch,
spaceStore: spaceStore, authorizer: authorizer,
repoStore: repoStore, spaceStore: spaceStore,
saStore: saStore, repoStore: repoStore,
gitRPCClient: gitRPCClient, saStore: saStore,
gitRPCClient: gitRPCClient,
} }
} }

View File

@ -25,16 +25,16 @@ import (
) )
type CreateInput struct { type CreateInput struct {
PathName string `json:"pathName"` PathName string `json:"pathName"`
SpaceID int64 `json:"spaceId"` SpaceID int64 `json:"spaceId"`
Name string `json:"name"` Name string `json:"name"`
Branch string `json:"branch"` DefaultBranch string `json:"defaultBranch"`
Description string `json:"description"` Description string `json:"description"`
IsPublic bool `json:"isPublic"` IsPublic bool `json:"isPublic"`
ForkID int64 `json:"forkId"` ForkID int64 `json:"forkId"`
Readme bool `json:"readme"` Readme bool `json:"readme"`
License string `json:"license"` License string `json:"license"`
GitIgnore string `json:"gitIgnore"` GitIgnore string `json:"gitIgnore"`
} }
// Create creates a new repository. // Create creates a new repository.
@ -68,8 +68,8 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea
} }
// set default branch in case it wasn't passed // set default branch in case it wasn't passed
if in.Branch == "" { if in.DefaultBranch == "" {
in.Branch = c.defaultBranch in.DefaultBranch = c.defaultBranch
} }
// create new repo object // create new repo object
@ -83,7 +83,7 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea
Created: time.Now().UnixMilli(), Created: time.Now().UnixMilli(),
Updated: time.Now().UnixMilli(), Updated: time.Now().UnixMilli(),
ForkID: in.ForkID, ForkID: in.ForkID,
DefaultBranch: in.Branch, DefaultBranch: in.DefaultBranch,
} }
// validate repo // validate repo

View File

@ -9,6 +9,7 @@ import (
"github.com/harness/gitness/internal/auth/authz" "github.com/harness/gitness/internal/auth/authz"
"github.com/harness/gitness/internal/gitrpc" "github.com/harness/gitness/internal/gitrpc"
"github.com/harness/gitness/internal/store" "github.com/harness/gitness/internal/store"
"github.com/harness/gitness/types"
) )
// WireSet provides a wire set for this package. // WireSet provides a wire set for this package.
@ -16,7 +17,7 @@ var WireSet = wire.NewSet(
ProvideController, ProvideController,
) )
func ProvideController(authorizer authz.Authorizer, spaceStore store.SpaceStore, func ProvideController(config *types.Config, authorizer authz.Authorizer, spaceStore store.SpaceStore,
repoStore store.RepoStore, saStore store.ServiceAccountStore, rpcClient gitrpc.Interface) *Controller { repoStore store.RepoStore, saStore store.ServiceAccountStore, rpcClient gitrpc.Interface) *Controller {
return NewController(authorizer, spaceStore, repoStore, saStore, rpcClient) return NewController(config.Git.DefaultBranch, authorizer, spaceStore, repoStore, saStore, rpcClient)
} }

View File

@ -11,11 +11,10 @@ import (
"github.com/harness/gitness/internal/api/controller/repo" "github.com/harness/gitness/internal/api/controller/repo"
"github.com/harness/gitness/internal/api/render" "github.com/harness/gitness/internal/api/render"
"github.com/harness/gitness/internal/api/request" "github.com/harness/gitness/internal/api/request"
"github.com/harness/gitness/types"
) )
// HandleCreate returns a http.HandlerFunc that creates a new repository. // HandleCreate returns a http.HandlerFunc that creates a new repository.
func HandleCreate(config *types.Config, repoCtrl *repo.Controller) http.HandlerFunc { func HandleCreate(repoCtrl *repo.Controller) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
session, _ := request.AuthSessionFrom(ctx) session, _ := request.AuthSessionFrom(ctx)
@ -27,11 +26,6 @@ func HandleCreate(config *types.Config, repoCtrl *repo.Controller) http.HandlerF
return return
} }
// set default branch if it wasn't provided by input
if in.Branch == "" {
in.Branch = config.Git.DefaultBranch
}
repo, err := repoCtrl.Create(ctx, session, in) repo, err := repoCtrl.Create(ctx, session, in)
if err != nil { if err != nil {
render.TranslatedUserError(w, err) render.TranslatedUserError(w, err)

View File

@ -5,12 +5,12 @@
package openapi package openapi
import ( import (
"net/http"
"github.com/harness/gitness/internal/api/usererror" "github.com/harness/gitness/internal/api/usererror"
"github.com/swaggest/openapi-go/openapi3" "github.com/swaggest/openapi-go/openapi3"
"net/http"
) )
//nolint:funlen
func resourceOperations(reflector *openapi3.Reflector) { func resourceOperations(reflector *openapi3.Reflector) {
opListGitignore := openapi3.Operation{} opListGitignore := openapi3.Operation{}
opListGitignore.WithTags("resource") opListGitignore.WithTags("resource")

View File

@ -38,14 +38,27 @@ func (g giteaAdapter) InitRepository(ctx context.Context, repoPath string, bare
} }
// SetDefaultBranch sets the default branch of a repo. // SetDefaultBranch sets the default branch of a repo.
func (g giteaAdapter) SetDefaultBranch(ctx context.Context, repoPath string, defaultBranch string) error { func (g giteaAdapter) SetDefaultBranch(ctx context.Context, repoPath string,
defaultBranch string, allowEmpty bool) error {
giteaRepo, err := gitea.OpenRepository(ctx, repoPath) giteaRepo, err := gitea.OpenRepository(ctx, repoPath)
if err != nil { if err != nil {
return err return err
} }
defer giteaRepo.Close() defer giteaRepo.Close()
return giteaRepo.SetDefaultBranch(defaultBranch) // if requested, error out if branch doesn't exist. Otherwise, blindly set it.
if !allowEmpty && !giteaRepo.IsBranchExist(defaultBranch) {
// TODO: ensure this returns not found error to caller
return fmt.Errorf("branch '%s' does not exist", defaultBranch)
}
// change default branch
err = giteaRepo.SetDefaultBranch(defaultBranch)
if err != nil {
return fmt.Errorf("failed to set new default branch: %w", err)
}
return nil
} }
func (g giteaAdapter) Clone(ctx context.Context, from, to string, opts cloneRepoOption) error { func (g giteaAdapter) Clone(ctx context.Context, from, to string, opts cloneRepoOption) error {

View File

@ -18,7 +18,7 @@ type Interface interface {
// gitAdapter for accessing git commands from gitea. // gitAdapter for accessing git commands from gitea.
type gitAdapter interface { type gitAdapter interface {
InitRepository(ctx context.Context, path string, bare bool) error InitRepository(ctx context.Context, path string, bare bool) error
SetDefaultBranch(ctx context.Context, repoPath string, defaultBranch string) error SetDefaultBranch(ctx context.Context, repoPath string, defaultBranch string, allowEmpty bool) error
Clone(ctx context.Context, from, to string, opts cloneRepoOption) error Clone(ctx context.Context, from, to string, opts cloneRepoOption) error
AddFiles(repoPath string, all bool, files ...string) error AddFiles(repoPath string, all bool, files ...string) error
Commit(repoPath string, opts commitChangesOptions) error Commit(repoPath string, opts commitChangesOptions) error

View File

@ -92,8 +92,8 @@ func (s repositoryService) CreateRepository(stream rpc.RepositoryService_CreateR
return fmt.Errorf("CreateRepository error: %w", err) return fmt.Errorf("CreateRepository error: %w", err)
} }
// update default branch // update default branch (currently set to non-existent branch)
err = s.adapter.SetDefaultBranch(ctx, repoPath, header.GetDefaultBranch()) err = s.adapter.SetDefaultBranch(ctx, repoPath, header.GetDefaultBranch(), true)
if err != nil { if err != nil {
return fmt.Errorf("error updating default branch for repo %s: %w", header.GetUid(), err) return fmt.Errorf("error updating default branch for repo %s: %w", header.GetUid(), err)
} }
@ -139,8 +139,9 @@ func (s repositoryService) CreateRepository(stream rpc.RepositoryService_CreateR
} }
if len(filePaths) > 0 { if len(filePaths) > 0 {
// NOTE: This creates the branch in origin repo (as it doesn't exist as of now)
// TODO: this should at least be a constant and not hardcoded? // TODO: this should at least be a constant and not hardcoded?
if err = s.AddFilesAndPush(ctx, tempDir, filePaths, "", SystemIdentity, SystemIdentity, if err = s.AddFilesAndPush(ctx, tempDir, filePaths, "HEAD:"+header.GetDefaultBranch(), SystemIdentity, SystemIdentity,
"origin", "initial commit"); err != nil { "origin", "initial commit"); err != nil {
return err return err
} }

View File

@ -7,9 +7,10 @@ package router
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/harness/gitness/internal/api/handler/resource"
"net/http" "net/http"
"github.com/harness/gitness/internal/api/handler/resource"
"github.com/harness/gitness/internal/api/controller/repo" "github.com/harness/gitness/internal/api/controller/repo"
"github.com/harness/gitness/internal/api/controller/serviceaccount" "github.com/harness/gitness/internal/api/controller/serviceaccount"
"github.com/harness/gitness/internal/api/controller/space" "github.com/harness/gitness/internal/api/controller/space"
@ -77,7 +78,7 @@ func NewAPIHandler(
r.Use(middlewareauthn.Attempt(authenticator)) r.Use(middlewareauthn.Attempt(authenticator))
r.Route("/v1", func(r chi.Router) { r.Route("/v1", func(r chi.Router) {
setupRoutesV1(r, config, repoCtrl, spaceCtrl, saCtrl, userCtrl) setupRoutesV1(r, repoCtrl, spaceCtrl, saCtrl, userCtrl)
}) })
// wrap router in terminatedPath encoder. // wrap router in terminatedPath encoder.
@ -97,10 +98,10 @@ func corsHandler(config *types.Config) func(http.Handler) http.Handler {
).Handler ).Handler
} }
func setupRoutesV1(r chi.Router, config *types.Config, repoCtrl *repo.Controller, spaceCtrl *space.Controller, func setupRoutesV1(r chi.Router, repoCtrl *repo.Controller, spaceCtrl *space.Controller,
saCtrl *serviceaccount.Controller, userCtrl *user.Controller) { saCtrl *serviceaccount.Controller, userCtrl *user.Controller) {
setupSpaces(r, spaceCtrl) setupSpaces(r, spaceCtrl)
setupRepos(r, config, repoCtrl) setupRepos(r, repoCtrl)
setupUsers(r, userCtrl) setupUsers(r, userCtrl)
setupServiceAccounts(r, saCtrl) setupServiceAccounts(r, saCtrl)
setupAdmin(r, userCtrl) setupAdmin(r, userCtrl)
@ -139,10 +140,10 @@ func setupSpaces(r chi.Router, spaceCtrl *space.Controller) {
}) })
} }
func setupRepos(r chi.Router, config *types.Config, repoCtrl *repo.Controller) { func setupRepos(r chi.Router, repoCtrl *repo.Controller) {
r.Route("/repos", func(r chi.Router) { r.Route("/repos", func(r chi.Router) {
// Create takes path and parentId via body, not uri // Create takes path and parentId via body, not uri
r.Post("/", handlerrepo.HandleCreate(config, repoCtrl)) r.Post("/", handlerrepo.HandleCreate(repoCtrl))
r.Route(fmt.Sprintf("/{%s}", request.PathParamRepoRef), func(r chi.Router) { r.Route(fmt.Sprintf("/{%s}", request.PathParamRepoRef), func(r chi.Router) {
// repo level operations // repo level operations
r.Get("/", handlerrepo.HandleFind(repoCtrl)) r.Get("/", handlerrepo.HandleFind(repoCtrl))