diff --git a/pkg/dal/dao/code_repository.go b/pkg/dal/dao/code_repository.go index 0bc05dfb..df8c5059 100644 --- a/pkg/dal/dao/code_repository.go +++ b/pkg/dal/dao/code_repository.go @@ -60,6 +60,8 @@ type CodeRepositoryService interface { ListOwnerWithoutPagination(ctx context.Context, userID int64, provider enums.Provider, owner *string) ([]*models.CodeRepositoryOwner, int64, error) // ListBranchesWithoutPagination ... ListBranchesWithoutPagination(ctx context.Context, codeRepositoryID int64) ([]*models.CodeRepositoryBranch, int64, error) + // GetBranchByName ... + GetBranchByName(ctx context.Context, codeRepositoryID int64, branch string) (*models.CodeRepositoryBranch, error) // GetCloneCredential ... GetCloneCredential(ctx context.Context, user3rdPartyID int64) (*models.CodeRepositoryCloneCredential, error) } @@ -241,6 +243,11 @@ func (s *codeRepositoryService) ListBranchesWithoutPagination(ctx context.Contex return s.tx.CodeRepositoryBranch.WithContext(ctx).Where(s.tx.CodeRepositoryBranch.CodeRepositoryID.Eq(codeRepositoryID)).FindByPage(-1, -1) } +// GetBranchByName ... +func (s *codeRepositoryService) GetBranchByName(ctx context.Context, codeRepositoryID int64, branch string) (*models.CodeRepositoryBranch, error) { + return s.tx.CodeRepositoryBranch.WithContext(ctx).Where(s.tx.CodeRepositoryBranch.CodeRepositoryID.Eq(codeRepositoryID), s.tx.CodeRepositoryBranch.Name.Eq(branch)).First() +} + // GetCloneCredential ... func (s *codeRepositoryService) GetCloneCredential(ctx context.Context, user3rdPartyID int64) (*models.CodeRepositoryCloneCredential, error) { return s.tx.CodeRepositoryCloneCredential.WithContext(ctx).Where(s.tx.CodeRepositoryCloneCredential.User3rdPartyID.Eq(user3rdPartyID)).First() diff --git a/pkg/dal/dao/mocks/code_repository.go b/pkg/dal/dao/mocks/code_repository.go index 8458f55d..92f14501 100644 --- a/pkg/dal/dao/mocks/code_repository.go +++ b/pkg/dal/dao/mocks/code_repository.go @@ -140,6 +140,36 @@ func (mr *MockCodeRepositoryServiceMockRecorder) Get(arg0, arg1 any) *gomock.Cal return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockCodeRepositoryService)(nil).Get), arg0, arg1) } +// GetBranchByName mocks base method. +func (m *MockCodeRepositoryService) GetBranchByName(arg0 context.Context, arg1 int64, arg2 string) (*models.CodeRepositoryBranch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBranchByName", arg0, arg1, arg2) + ret0, _ := ret[0].(*models.CodeRepositoryBranch) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBranchByName indicates an expected call of GetBranchByName. +func (mr *MockCodeRepositoryServiceMockRecorder) GetBranchByName(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBranchByName", reflect.TypeOf((*MockCodeRepositoryService)(nil).GetBranchByName), arg0, arg1, arg2) +} + +// GetCloneCredential mocks base method. +func (m *MockCodeRepositoryService) GetCloneCredential(arg0 context.Context, arg1 int64) (*models.CodeRepositoryCloneCredential, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCloneCredential", arg0, arg1) + ret0, _ := ret[0].(*models.CodeRepositoryCloneCredential) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCloneCredential indicates an expected call of GetCloneCredential. +func (mr *MockCodeRepositoryServiceMockRecorder) GetCloneCredential(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCloneCredential", reflect.TypeOf((*MockCodeRepositoryService)(nil).GetCloneCredential), arg0, arg1) +} + // ListAll mocks base method. func (m *MockCodeRepositoryService) ListAll(arg0 context.Context, arg1 int64) ([]*models.CodeRepository, error) { m.ctrl.T.Helper() diff --git a/pkg/dal/dao/repository.go b/pkg/dal/dao/repository.go index a328d588..f610375b 100644 --- a/pkg/dal/dao/repository.go +++ b/pkg/dal/dao/repository.go @@ -171,6 +171,8 @@ func (s *repositoryService) FindAll(ctx context.Context, namespaceID, limit, las func (s *repositoryService) Get(ctx context.Context, repositoryID int64) (*models.Repository, error) { return s.tx.Repository.WithContext(ctx). Where(s.tx.Repository.ID.Eq(repositoryID)). + Preload(s.tx.Repository.Builder.CodeRepository). + Preload(s.tx.Repository.Builder.CodeRepository.User3rdParty). Preload(s.tx.Repository.Builder).First() } @@ -242,6 +244,8 @@ func (s *repositoryService) ListRepositoryWithAuth(ctx context.Context, namespac } else { q = q.Order(s.tx.Repository.UpdatedAt.Desc()) } + q = q.Preload(s.tx.Repository.Builder.CodeRepository). + Preload(s.tx.Repository.Builder.CodeRepository.User3rdParty) return q.FindByPage(ptr.To(pagination.Limit)*(ptr.To(pagination.Page)-1), ptr.To(pagination.Limit)) } diff --git a/pkg/handlers/apidocs/docs.go b/pkg/handlers/apidocs/docs.go index 021e576b..06d328b4 100644 --- a/pkg/handlers/apidocs/docs.go +++ b/pkg/handlers/apidocs/docs.go @@ -219,63 +219,6 @@ const docTemplate = `{ } } }, - "/coderepos/{id}/branches": { - "get": { - "security": [ - { - "BasicAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "CodeRepository" - ], - "summary": "List code repository branches", - "parameters": [ - { - "type": "string", - "description": "code repository id", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/types.CommonList" - }, - { - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/definitions/types.CodeRepositoryBranchItem" - } - } - } - } - ] - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/xerrors.ErrCode" - } - } - } - } - }, "/coderepos/{provider}": { "get": { "security": [ @@ -5423,6 +5366,126 @@ const docTemplate = `{ } } } + }, + "/{provider}/repos/coderepos/{id}/branches": { + "get": { + "security": [ + { + "BasicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CodeRepository" + ], + "summary": "List code repository branches", + "parameters": [ + { + "type": "string", + "description": "code repository provider", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "code repository id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.CommonList" + }, + { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/types.CodeRepositoryBranchItem" + } + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/xerrors.ErrCode" + } + } + } + } + }, + "/{provider}/repos/coderepos/{id}/branches/{name}": { + "get": { + "security": [ + { + "BasicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CodeRepository" + ], + "summary": "Get specific name code repository branch", + "parameters": [ + { + "type": "string", + "description": "code repository provider", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "number", + "description": "Code repository id", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Branch name", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/types.CodeRepositoryBranchItem" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/xerrors.ErrCode" + } + } + } + } } }, "definitions": { @@ -5750,6 +5813,14 @@ const docTemplate = `{ "type": "string", "example": "sigma" }, + "scm_provider": { + "allOf": [ + { + "$ref": "#/definitions/enums.ScmProvider" + } + ], + "example": "github" + }, "scm_repository": { "description": "source SelfCodeRepository", "type": "string", @@ -5846,8 +5917,16 @@ const docTemplate = `{ "example": "go-sigma" }, "owner_id": { - "type": "string", - "example": "1" + "type": "integer", + "example": 1 + }, + "provider": { + "allOf": [ + { + "$ref": "#/definitions/enums.ScmProvider" + } + ], + "example": "github" }, "repository_id": { "type": "string", diff --git a/pkg/handlers/apidocs/swagger.json b/pkg/handlers/apidocs/swagger.json index 18bb7370..0b840877 100644 --- a/pkg/handlers/apidocs/swagger.json +++ b/pkg/handlers/apidocs/swagger.json @@ -211,63 +211,6 @@ } } }, - "/coderepos/{id}/branches": { - "get": { - "security": [ - { - "BasicAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "CodeRepository" - ], - "summary": "List code repository branches", - "parameters": [ - { - "type": "string", - "description": "code repository id", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/types.CommonList" - }, - { - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/definitions/types.CodeRepositoryBranchItem" - } - } - } - } - ] - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/xerrors.ErrCode" - } - } - } - } - }, "/coderepos/{provider}": { "get": { "security": [ @@ -5415,6 +5358,126 @@ } } } + }, + "/{provider}/repos/coderepos/{id}/branches": { + "get": { + "security": [ + { + "BasicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CodeRepository" + ], + "summary": "List code repository branches", + "parameters": [ + { + "type": "string", + "description": "code repository provider", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "code repository id", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/types.CommonList" + }, + { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/types.CodeRepositoryBranchItem" + } + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/xerrors.ErrCode" + } + } + } + } + }, + "/{provider}/repos/coderepos/{id}/branches/{name}": { + "get": { + "security": [ + { + "BasicAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CodeRepository" + ], + "summary": "Get specific name code repository branch", + "parameters": [ + { + "type": "string", + "description": "code repository provider", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "number", + "description": "Code repository id", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Branch name", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/types.CodeRepositoryBranchItem" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/xerrors.ErrCode" + } + } + } + } } }, "definitions": { @@ -5742,6 +5805,14 @@ "type": "string", "example": "sigma" }, + "scm_provider": { + "allOf": [ + { + "$ref": "#/definitions/enums.ScmProvider" + } + ], + "example": "github" + }, "scm_repository": { "description": "source SelfCodeRepository", "type": "string", @@ -5838,8 +5909,16 @@ "example": "go-sigma" }, "owner_id": { - "type": "string", - "example": "1" + "type": "integer", + "example": 1 + }, + "provider": { + "allOf": [ + { + "$ref": "#/definitions/enums.ScmProvider" + } + ], + "example": "github" }, "repository_id": { "type": "string", diff --git a/pkg/handlers/apidocs/swagger.yaml b/pkg/handlers/apidocs/swagger.yaml index 01e491f5..03a43510 100644 --- a/pkg/handlers/apidocs/swagger.yaml +++ b/pkg/handlers/apidocs/swagger.yaml @@ -248,6 +248,10 @@ definitions: scm_password: example: sigma type: string + scm_provider: + allOf: + - $ref: '#/definitions/enums.ScmProvider' + example: github scm_repository: description: source SelfCodeRepository example: https://github.com/go-sigma/sigma.git @@ -317,8 +321,12 @@ definitions: example: go-sigma type: string owner_id: - example: "1" - type: string + example: 1 + type: integer + provider: + allOf: + - $ref: '#/definitions/enums.ScmProvider' + example: github repository_id: example: "1" type: string @@ -1710,6 +1718,80 @@ info: title: sigma version: "1.0" paths: + /{provider}/repos/coderepos/{id}/branches: + get: + consumes: + - application/json + parameters: + - description: code repository provider + in: path + name: provider + required: true + type: string + - description: code repository id + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/types.CommonList' + - properties: + items: + items: + $ref: '#/definitions/types.CodeRepositoryBranchItem' + type: array + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/xerrors.ErrCode' + security: + - BasicAuth: [] + summary: List code repository branches + tags: + - CodeRepository + /{provider}/repos/coderepos/{id}/branches/{name}: + get: + consumes: + - application/json + parameters: + - description: code repository provider + in: path + name: provider + required: true + type: string + - description: Code repository id + in: path + name: id + required: true + type: number + - description: Branch name + in: path + name: name + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/types.CodeRepositoryBranchItem' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/xerrors.ErrCode' + security: + - BasicAuth: [] + summary: Get specific name code repository branch + tags: + - CodeRepository /caches/: delete: consumes: @@ -1800,39 +1882,6 @@ paths: summary: Create cache tags: - Cache - /coderepos/{id}/branches: - get: - consumes: - - application/json - parameters: - - description: code repository id - in: path - name: id - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - allOf: - - $ref: '#/definitions/types.CommonList' - - properties: - items: - items: - $ref: '#/definitions/types.CodeRepositoryBranchItem' - type: array - type: object - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/xerrors.ErrCode' - security: - - BasicAuth: [] - summary: List code repository branches - tags: - - CodeRepository /coderepos/{provider}: get: consumes: diff --git a/pkg/handlers/coderepos/coderepos_branch.go b/pkg/handlers/coderepos/coderepos_branch.go new file mode 100644 index 00000000..d2d18223 --- /dev/null +++ b/pkg/handlers/coderepos/coderepos_branch.go @@ -0,0 +1,66 @@ +// Copyright 2023 sigma +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package coderepos + +import ( + "fmt" + "net/http" + "time" + + "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" + + "github.com/go-sigma/sigma/pkg/consts" + "github.com/go-sigma/sigma/pkg/types" + "github.com/go-sigma/sigma/pkg/utils" + "github.com/go-sigma/sigma/pkg/xerrors" +) + +// GetBranch get branch by name +// +// @Summary Get specific name code repository branch +// @security BasicAuth +// @Tags CodeRepository +// @Accept json +// @Produce json +// @Router /{provider}/repos/coderepos/{id}/branches/{name} [get] +// @Param provider path string true "code repository provider" +// @Param id path number true "Code repository id" +// @Param name path string true "Branch name" +// @Success 200 {object} types.CodeRepositoryBranchItem +// @Failure 500 {object} xerrors.ErrCode +func (h *handler) GetBranch(c echo.Context) error { + ctx := log.Logger.WithContext(c.Request().Context()) + + var req types.GetCodeRepositoryBranchRequest + err := utils.BindValidate(c, &req) + if err != nil { + log.Error().Err(err).Msg("Bind and validate request body failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeBadRequest, fmt.Sprintf("Bind and validate request body failed: %v", err)) + } + + codeRepositoryService := h.codeRepositoryServiceFactory.New() + branchObj, err := codeRepositoryService.GetBranchByName(ctx, req.ID, req.Name) + if err != nil { + log.Error().Err(err).Msg("Get branch by id failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("List branches failed: %v", err)) + } + return c.JSON(http.StatusOK, types.CodeRepositoryBranchItem{ + ID: branchObj.ID, + Name: branchObj.Name, + CreatedAt: time.Unix(0, int64(time.Millisecond)*branchObj.CreatedAt).UTC().Format(consts.DefaultTimePattern), + UpdatedAt: time.Unix(0, int64(time.Millisecond)*branchObj.CreatedAt).UTC().Format(consts.DefaultTimePattern), + }) +} diff --git a/pkg/handlers/coderepos/coderepos_branches.go b/pkg/handlers/coderepos/coderepos_branches.go index 8acd45a0..20c6e628 100644 --- a/pkg/handlers/coderepos/coderepos_branches.go +++ b/pkg/handlers/coderepos/coderepos_branches.go @@ -35,10 +35,11 @@ import ( // @Tags CodeRepository // @Accept json // @Produce json -// @Router /coderepos/{id}/branches [get] -// @Param id path string true "code repository id" -// @Success 200 {object} types.CommonList{items=[]types.CodeRepositoryBranchItem} -// @Failure 500 {object} xerrors.ErrCode +// @Router /{provider}/repos/coderepos/{id}/branches [get] +// @Param provider path string true "code repository provider" +// @Param id path string true "code repository id" +// @Success 200 {object} types.CommonList{items=[]types.CodeRepositoryBranchItem} +// @Failure 500 {object} xerrors.ErrCode func (h *handler) ListBranches(c echo.Context) error { ctx := log.Logger.WithContext(c.Request().Context()) diff --git a/pkg/handlers/coderepos/coderepos_get.go b/pkg/handlers/coderepos/coderepos_get.go index f25f4b5b..13952f44 100644 --- a/pkg/handlers/coderepos/coderepos_get.go +++ b/pkg/handlers/coderepos/coderepos_get.go @@ -25,7 +25,9 @@ import ( "gorm.io/gorm" "github.com/go-sigma/sigma/pkg/consts" + "github.com/go-sigma/sigma/pkg/dal/models" "github.com/go-sigma/sigma/pkg/types" + "github.com/go-sigma/sigma/pkg/types/enums" "github.com/go-sigma/sigma/pkg/utils" "github.com/go-sigma/sigma/pkg/xerrors" ) @@ -45,13 +47,38 @@ import ( func (h *handler) Get(c echo.Context) error { ctx := log.Logger.WithContext(c.Request().Context()) + iuser := c.Get(consts.ContextUser) + if iuser == nil { + log.Error().Msg("Get user from header failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeUnauthorized) + } + user, ok := iuser.(*models.User) + if !ok { + log.Error().Msg("Convert user from header failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeUnauthorized) + } + var req types.GetCodeRepositoryRequest err := utils.BindValidate(c, &req) if err != nil { log.Error().Err(err).Msg("Bind and validate request body failed") return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeBadRequest, fmt.Sprintf("Bind and validate request body failed: %v", err)) } + codeRepositoryService := h.codeRepositoryServiceFactory.New() + userService := h.userServiceFactory.New() + user3rdPartyObj, err := userService.GetUser3rdPartyByProvider(ctx, user.ID, req.Provider) + if err != nil { + log.Error().Err(err).Str("Provider", req.Provider.String()).Msg("Get user 3rdParty by provider failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("Get user 3rdParty by provider failed: %v", err)) + } + + ownerObjs, err := codeRepositoryService.ListOwnersAll(ctx, user3rdPartyObj.ID) + if err != nil { + log.Error().Err(err).Msg("List all owners failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("List all owners failed: %v", err)) + } + codeRepositoryObj, err := codeRepositoryService.Get(ctx, req.ID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { @@ -69,8 +96,9 @@ func (h *handler) Get(c echo.Context) error { return c.JSON(http.StatusOK, types.CodeRepositoryItem{ ID: codeRepositoryObj.ID, RepositoryID: codeRepositoryObj.RepositoryID, + Provider: enums.ScmProvider(user3rdPartyObj.Provider), Name: codeRepositoryObj.Name, - OwnerID: codeRepositoryObj.OwnerID, + OwnerID: h.getOwnerID(ownerObjs, codeRepositoryObj.Owner), Owner: codeRepositoryObj.Owner, IsOrg: codeRepositoryObj.IsOrg, CloneUrl: codeRepositoryObj.CloneUrl, diff --git a/pkg/handlers/coderepos/coderepos_list.go b/pkg/handlers/coderepos/coderepos_list.go index 641ed165..612c2268 100644 --- a/pkg/handlers/coderepos/coderepos_list.go +++ b/pkg/handlers/coderepos/coderepos_list.go @@ -15,6 +15,7 @@ package coderepos import ( + "fmt" "net/http" "time" @@ -24,6 +25,7 @@ import ( "github.com/go-sigma/sigma/pkg/consts" "github.com/go-sigma/sigma/pkg/dal/models" "github.com/go-sigma/sigma/pkg/types" + "github.com/go-sigma/sigma/pkg/types/enums" "github.com/go-sigma/sigma/pkg/utils" "github.com/go-sigma/sigma/pkg/xerrors" ) @@ -67,7 +69,20 @@ func (h *handler) List(c echo.Context) error { } req.Pagination = utils.NormalizePagination(req.Pagination) + userService := h.userServiceFactory.New() + user3rdPartyObj, err := userService.GetUser3rdPartyByProvider(ctx, user.ID, req.Provider) + if err != nil { + log.Error().Err(err).Str("Provider", req.Provider.String()).Msg("Get user 3rdParty by provider failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("Get user 3rdParty by provider failed: %v", err)) + } + codeRepositoryService := h.codeRepositoryServiceFactory.New() + ownerObjs, err := codeRepositoryService.ListOwnersAll(ctx, user3rdPartyObj.ID) + if err != nil { + log.Error().Err(err).Msg("List all owners failed") + return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeInternalError, fmt.Sprintf("List all owners failed: %v", err)) + } + codeRepositoryObjs, total, err := codeRepositoryService.ListWithPagination(ctx, user.ID, req.Provider, req.Owner, req.Name, req.Pagination, req.Sortable) if err != nil { log.Error().Err(err).Msg("List code repositories failed") @@ -78,8 +93,9 @@ func (h *handler) List(c echo.Context) error { resp = append(resp, types.CodeRepositoryItem{ ID: codeRepositoryObj.ID, RepositoryID: codeRepositoryObj.RepositoryID, + Provider: enums.ScmProvider(user3rdPartyObj.Provider), Name: codeRepositoryObj.Name, - OwnerID: codeRepositoryObj.OwnerID, + OwnerID: h.getOwnerID(ownerObjs, codeRepositoryObj.Owner), Owner: codeRepositoryObj.Owner, IsOrg: codeRepositoryObj.IsOrg, CloneUrl: codeRepositoryObj.CloneUrl, @@ -92,3 +108,12 @@ func (h *handler) List(c echo.Context) error { return c.JSON(http.StatusOK, types.CommonList{Total: total, Items: resp}) } + +func (h *handler) getOwnerID(ownerObjs []*models.CodeRepositoryOwner, owner string) int64 { + for _, ownerObj := range ownerObjs { + if ownerObj.Owner == owner { + return ownerObj.ID + } + } + return 0 +} diff --git a/pkg/handlers/coderepos/handler.go b/pkg/handlers/coderepos/handler.go index 39304839..7a73197e 100644 --- a/pkg/handlers/coderepos/handler.go +++ b/pkg/handlers/coderepos/handler.go @@ -37,6 +37,8 @@ type Handler interface { ListOwners(c echo.Context) error // ListBranches ... ListBranches(c echo.Context) error + // GetBranch ... + GetBranch(c echo.Context) error // Resync resync all of the code repositories Resync(c echo.Context) error // Providers get providers @@ -117,7 +119,8 @@ func (f factory) Initialize(e *echo.Echo) error { codereposGroup.GET("/:provider/user3rdparty", codeRepositoryHandler.User3rdParty) codereposGroup.GET("/:provider/resync", codeRepositoryHandler.Resync) codereposGroup.GET("/:provider/owners", codeRepositoryHandler.ListOwners) - codereposGroup.GET("/:id/branches", codeRepositoryHandler.ListBranches) + codereposGroup.GET("/:provider/repos/:id/branches", codeRepositoryHandler.ListBranches) + codereposGroup.GET("/:provider/repos/:id/branches/:name", codeRepositoryHandler.GetBranch) return nil } diff --git a/pkg/handlers/repositories/repositories_get.go b/pkg/handlers/repositories/repositories_get.go index c2c8cf1e..0f49a52d 100644 --- a/pkg/handlers/repositories/repositories_get.go +++ b/pkg/handlers/repositories/repositories_get.go @@ -94,6 +94,10 @@ func (h *handler) GetRepository(c echo.Context) error { platforms = append(platforms, enums.OciPlatform(p)) } + var scmProvider *enums.ScmProvider + if repositoryObj.Builder.CodeRepository != nil { + scmProvider = ptr.Of(enums.ScmProvider(repositoryObj.Builder.CodeRepository.User3rdParty.Provider.String())) + } builderItemObj = &types.BuilderItem{ ID: repositoryObj.Builder.ID, RepositoryID: repositoryObj.Builder.RepositoryID, @@ -110,6 +114,7 @@ func (h *handler) GetRepository(c echo.Context) error { ScmToken: repositoryObj.Builder.ScmToken, ScmUsername: repositoryObj.Builder.ScmUsername, ScmPassword: repositoryObj.Builder.ScmPassword, + ScmProvider: scmProvider, ScmBranch: repositoryObj.Builder.ScmBranch, diff --git a/pkg/handlers/repositories/repositories_list.go b/pkg/handlers/repositories/repositories_list.go index d76d352a..04c678a0 100644 --- a/pkg/handlers/repositories/repositories_list.go +++ b/pkg/handlers/repositories/repositories_list.go @@ -125,6 +125,10 @@ func (h *handler) ListRepositories(c echo.Context) error { for _, p := range strings.Split(builderObj.BuildkitPlatforms, ",") { platforms = append(platforms, enums.OciPlatform(p)) } + var scmProvider *enums.ScmProvider + if repository.Builder.CodeRepository != nil { + scmProvider = ptr.Of(enums.ScmProvider(repository.Builder.CodeRepository.User3rdParty.Provider.String())) + } repositoryObj.Builder = &types.BuilderItem{ ID: builderObj.ID, RepositoryID: builderObj.RepositoryID, @@ -141,6 +145,7 @@ func (h *handler) ListRepositories(c echo.Context) error { ScmToken: builderObj.ScmToken, ScmUsername: builderObj.ScmUsername, ScmPassword: builderObj.ScmPassword, + ScmProvider: scmProvider, ScmBranch: builderObj.ScmBranch, diff --git a/pkg/types/builder.go b/pkg/types/builder.go index 1324dc0f..d8083148 100644 --- a/pkg/types/builder.go +++ b/pkg/types/builder.go @@ -82,6 +82,7 @@ type BuilderItem struct { ScmToken *string `json:"scm_token" example:"xxxx"` ScmUsername *string `json:"scm_username" example:"sigma"` ScmPassword *string `json:"scm_password" example:"sigma"` + ScmProvider *enums.ScmProvider `json:"scm_provider" example:"github"` ScmBranch *string `json:"scm_branch" example:"main"` diff --git a/pkg/types/coderepos.go b/pkg/types/coderepos.go index ee2e5fd2..f6dda11b 100644 --- a/pkg/types/coderepos.go +++ b/pkg/types/coderepos.go @@ -18,17 +18,18 @@ import "github.com/go-sigma/sigma/pkg/types/enums" // CodeRepositoryItem ... type CodeRepositoryItem struct { - ID int64 `json:"id" example:"1"` - RepositoryID string `json:"repository_id" example:"1"` - Name string `json:"name" example:"sigma"` - OwnerID string `json:"owner_id" example:"1"` - Owner string `json:"owner" example:"go-sigma"` - IsOrg bool `json:"is_org" example:"true"` - CloneUrl string `json:"clone_url" example:"https://github.com/go-sigma/sigma.git"` - SshUrl string `json:"ssh_url" example:"git@github.com:go-sigma/sigma.git"` - OciRepoCount int64 `json:"oci_repo_count" example:"1"` - CreatedAt string `json:"created_at" example:"2006-01-02 15:04:05"` - UpdatedAt string `json:"updated_at" example:"2006-01-02 15:04:05"` + ID int64 `json:"id" example:"1"` + RepositoryID string `json:"repository_id" example:"1"` + Provider enums.ScmProvider `json:"provider" example:"github"` + Name string `json:"name" example:"sigma"` + OwnerID int64 `json:"owner_id" example:"1"` + Owner string `json:"owner" example:"go-sigma"` + IsOrg bool `json:"is_org" example:"true"` + CloneUrl string `json:"clone_url" example:"https://github.com/go-sigma/sigma.git"` + SshUrl string `json:"ssh_url" example:"git@github.com:go-sigma/sigma.git"` + OciRepoCount int64 `json:"oci_repo_count" example:"1"` + CreatedAt string `json:"created_at" example:"2006-01-02 15:04:05"` + UpdatedAt string `json:"updated_at" example:"2006-01-02 15:04:05"` } // CodeRepositoryOwnerItem ... @@ -76,6 +77,12 @@ type CodeRepositoryBranchItem struct { UpdatedAt string `json:"updated_at" example:"2006-01-02 15:04:05"` } +// GetCodeRepositoryBranchRequest ... +type GetCodeRepositoryBranchRequest struct { + ID int64 `json:"id" param:"id" validate:"required,number"` + Name string `json:"name" param:"name" validate:"required"` +} + // PostCodeRepositorySetupBuilder ... type PostCodeRepositorySetupBuilder struct { ID int64 `json:"id" param:"id" validate:"required,number"` diff --git a/web/package.json b/web/package.json index 3761fd4e..7a4ec3fe 100644 --- a/web/package.json +++ b/web/package.json @@ -21,12 +21,12 @@ "axios": "^1.6.2", "bytemd": "^1.21.0", "cron-parser": "^4.9.0", - "csstype": "^3.1.2", + "csstype": "^3.1.3", "dayjs": "^1.11.10", "flowbite": "^2.2.0", "human-format": "^1.2.0", "lodash": "^4.17.21", - "monaco-editor": "^0.44.0", + "monaco-editor": "^0.45.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet-async": "^2.0.3", @@ -40,17 +40,17 @@ "xterm-addon-fit": "^0.8.0" }, "devDependencies": { - "@types/node": "^20.10.2", - "@types/react": "^18.2.40", + "@types/node": "^20.10.4", + "@types/react": "^18.2.42", "@types/react-dom": "^18.2.17", "@vitejs/plugin-react-swc": "^3.5.0", "autoprefixer": "^10.4.16", "cssnano": "^6.0.1", "json-server": "^0.17.4", "postcss": "^8.4.32", - "tailwindcss": "^3.3.5", - "typescript": "^5.3.2", - "vite": "^5.0.4" + "tailwindcss": "^3.3.6", + "typescript": "^5.3.3", + "vite": "^5.0.6" }, "packageManager": "yarn@4.0.2" } diff --git a/web/src/interfaces/index.ts b/web/src/interfaces/index.ts index 393bbe5b..8dd6fdf2 100644 --- a/web/src/interfaces/index.ts +++ b/web/src/interfaces/index.ts @@ -202,7 +202,7 @@ export interface ICodeRepositoryItem { id: number; repository_id: string; name: string; - owner_id: string; + owner_id: number; owner: string; is_org: boolean; clone_url: string; @@ -263,6 +263,7 @@ export interface IBuilderItem { scm_token?: string; scm_username?: string; scm_password?: string; + scm_provider?: string; scm_branch?: string; diff --git a/web/src/pages/Builder/RunnerList.tsx b/web/src/pages/Builder/RunnerList.tsx index a15ec098..c918d12f 100644 --- a/web/src/pages/Builder/RunnerList.tsx +++ b/web/src/pages/Builder/RunnerList.tsx @@ -196,7 +196,7 @@ export default function ({ localServer }: { localServer: string }) { - Runners + Builder - Runners + Builder { if (response.status == 200) { const data = response.data as ICodeRepositoryBranchList; @@ -463,6 +463,42 @@ export default function ({ localServer }: { localServer: string }) { } } + const [codeRepositoryInit, setCodeRepositoryInit] = useState(0); + useEffect(() => { + if (codeRepositoryInit != 0) { + axios.get(`${localServer}/api/v1/coderepos/${codeRepositoryProviderSelected.provider}/repos/${codeRepositoryInit}`).then(response => { + let codeRepositoryItem = response.data as ICodeRepositoryItem; + setCodeRepositoryOwnerSelected({ + owner: codeRepositoryItem.owner, + id: codeRepositoryItem.owner_id, + } as ICodeRepositoryOwnerItem); + setCodeRepositorySelected({ + name: codeRepositoryItem.name, + id: codeRepositoryItem.id, + } as ICodeRepositoryItem) + }).catch(error => { + const errorcode = error.response.data as IHTTPError; + Toast({ level: "warning", title: errorcode.title, message: errorcode.description }); + }); + } + }, [codeRepositoryInit]); + + const [codeRepositoryBranchInit, setCodeRepositoryBranchInit] = useState(""); + useEffect(() => { + if (codeRepositoryInit != 0 && codeRepositoryBranchInit !== "") { + axios.get(`${localServer}/api/v1/coderepos/${codeRepositoryProviderSelected.provider}/repos/${codeRepositoryInit}/branches/${codeRepositoryBranchInit}`).then(response => { + let codeRepositoryBranch = response.data as ICodeRepositoryBranchItem; + setCodeRepositoryBranchSelected({ + name: codeRepositoryBranch.name, + id: codeRepositoryBranch.id, + } as ICodeRepositoryBranchItem); + }).catch(error => { + const errorcode = error.response.data as IHTTPError; + Toast({ level: "warning", title: errorcode.title, message: errorcode.description }); + }); + } + }, [codeRepositoryInit, codeRepositoryBranchInit]); + useEffect(() => { if (id === undefined) { return; @@ -484,7 +520,11 @@ export default function ({ localServer }: { localServer: string }) { }); } if (builderItem.code_repository_id !== undefined) { - + setCodeRepositoryInit(builderItem.code_repository_id || 0); + setCodeRepositoryBranchInit(builderItem.scm_branch || ""); + setCodeRepositoryProviderSelected({ + provider: builderItem.scm_provider || "", + } as ICodeRepositoryProviderItem) } let ps = ""; let platforms: { @@ -883,7 +923,7 @@ export default function ({ localServer }: { localServer: string }) { } value={provider} > - + {provider.provider} diff --git a/web/src/pages/Repository/Summary.tsx b/web/src/pages/Repository/Summary.tsx index 327f169d..57ad5510 100644 --- a/web/src/pages/Repository/Summary.tsx +++ b/web/src/pages/Repository/Summary.tsx @@ -105,7 +105,7 @@ export default function ({ localServer }: { localServer: string }) { to={`/namespaces/${namespace}/repository/runners?repository=${repositoryObj.name}&repository_id=${repository_id}&namespace_id=${namespaceId}`} className="inline-flex items-center border-b border-transparent px-1 pt-1 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700 capitalize" > - Runners + Builder - Runners + Builder ": - version: 5.3.2 - resolution: "typescript@patch:typescript@npm%3A5.3.2#optional!builtin::version=5.3.2&hash=e012d7" +"typescript@patch:typescript@npm%3A^5.3.3#optional!builtin": + version: 5.3.3 + resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin::version=5.3.3&hash=e012d7" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 73c8bad74e732d93211c9d77f28b03307e2f5fc6a0afc73f4b783261ab567686a16d6ae958bdaef383a00be1b0b8c8b6741dd6ca3d13af4963fa7e47456d49c7 + checksum: 1d0a5f4ce496c42caa9a30e659c467c5686eae15d54b027ee7866744952547f1be1262f2d40de911618c242b510029d51d43ff605dba8fb740ec85ca2d3f9500 languageName: node linkType: hard @@ -5573,13 +5580,13 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.4": - version: 5.0.4 - resolution: "vite@npm:5.0.4" +"vite@npm:^5.0.6": + version: 5.0.6 + resolution: "vite@npm:5.0.6" dependencies: esbuild: "npm:^0.19.3" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.31" + postcss: "npm:^8.4.32" rollup: "npm:^4.2.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 @@ -5609,7 +5616,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 67a0df248af042e75b1ecbf20098096df80a1068a832c5c964a20d7c06853e12b7310989c3c273cb88a9a3a37f4bada0a2115018b36df0fc09a6b6dba9a7d5b5 + checksum: 5c0f29e81865c8a4992d7a13a9c736b79a6caa4cdd98ade73ab5923e928818dddc23a954c99a3e1de5d59a0e004e7e86344c18a955e6d06194d7e394d7027e20 languageName: node linkType: hard