mirror of
https://github.com/harness/drone.git
synced 2025-05-07 17:01:30 +08:00
Update default branch on empty repo for first commit (#1122)
This commit is contained in:
parent
47f4070b3c
commit
b64f4c41fa
@ -19,7 +19,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/harness/gitness/app/api/controller/githook"
|
"github.com/harness/gitness/app/githook"
|
||||||
"github.com/harness/gitness/git"
|
"github.com/harness/gitness/git"
|
||||||
"github.com/harness/gitness/git/hook"
|
"github.com/harness/gitness/git/hook"
|
||||||
"github.com/harness/gitness/store"
|
"github.com/harness/gitness/store"
|
||||||
@ -33,12 +33,12 @@ var _ hook.Client = (*ControllerClient)(nil)
|
|||||||
|
|
||||||
// ControllerClientFactory creates clients that directly call the controller to execute githooks.
|
// ControllerClientFactory creates clients that directly call the controller to execute githooks.
|
||||||
type ControllerClientFactory struct {
|
type ControllerClientFactory struct {
|
||||||
githookCtrl *githook.Controller
|
githookCtrl *Controller
|
||||||
git git.Interface
|
git git.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *ControllerClientFactory) NewClient(_ context.Context, envVars map[string]string) (hook.Client, error) {
|
func (f *ControllerClientFactory) NewClient(_ context.Context, envVars map[string]string) (hook.Client, error) {
|
||||||
payload, err := hook.LoadPayloadFromMap[Payload](envVars)
|
payload, err := hook.LoadPayloadFromMap[githook.Payload](envVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to load payload from provided map of environment variables: %w", err)
|
return nil, fmt.Errorf("failed to load payload from provided map of environment variables: %w", err)
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ func (f *ControllerClientFactory) NewClient(_ context.Context, envVars map[strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &ControllerClient{
|
return &ControllerClient{
|
||||||
baseInput: GetInputBaseFromPayload(payload),
|
baseInput: githook.GetInputBaseFromPayload(payload),
|
||||||
githookCtrl: f.githookCtrl,
|
githookCtrl: f.githookCtrl,
|
||||||
git: f.git,
|
git: f.git,
|
||||||
}, nil
|
}, nil
|
||||||
@ -62,8 +62,8 @@ func (f *ControllerClientFactory) NewClient(_ context.Context, envVars map[strin
|
|||||||
// ControllerClient directly calls the controller to execute githooks.
|
// ControllerClient directly calls the controller to execute githooks.
|
||||||
type ControllerClient struct {
|
type ControllerClient struct {
|
||||||
baseInput types.GithookInputBase
|
baseInput types.GithookInputBase
|
||||||
githookCtrl *githook.Controller
|
githookCtrl *Controller
|
||||||
git githook.RestrictedGIT
|
git RestrictedGIT
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ControllerClient) PreReceive(
|
func (c *ControllerClient) PreReceive(
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/auth"
|
"github.com/harness/gitness/app/auth"
|
||||||
"github.com/harness/gitness/app/auth/authz"
|
"github.com/harness/gitness/app/auth/authz"
|
||||||
eventsgit "github.com/harness/gitness/app/events/git"
|
eventsgit "github.com/harness/gitness/app/events/git"
|
||||||
|
eventsrepo "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
"github.com/harness/gitness/app/services/settings"
|
"github.com/harness/gitness/app/services/settings"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
@ -41,6 +42,8 @@ type Controller struct {
|
|||||||
principalStore store.PrincipalStore
|
principalStore store.PrincipalStore
|
||||||
repoStore store.RepoStore
|
repoStore store.RepoStore
|
||||||
gitReporter *eventsgit.Reporter
|
gitReporter *eventsgit.Reporter
|
||||||
|
repoReporter *eventsrepo.Reporter
|
||||||
|
git git.Interface
|
||||||
pullreqStore store.PullReqStore
|
pullreqStore store.PullReqStore
|
||||||
urlProvider url.Provider
|
urlProvider url.Provider
|
||||||
protectionManager *protection.Manager
|
protectionManager *protection.Manager
|
||||||
@ -56,6 +59,8 @@ func NewController(
|
|||||||
principalStore store.PrincipalStore,
|
principalStore store.PrincipalStore,
|
||||||
repoStore store.RepoStore,
|
repoStore store.RepoStore,
|
||||||
gitReporter *eventsgit.Reporter,
|
gitReporter *eventsgit.Reporter,
|
||||||
|
repoReporter *eventsrepo.Reporter,
|
||||||
|
git git.Interface,
|
||||||
pullreqStore store.PullReqStore,
|
pullreqStore store.PullReqStore,
|
||||||
urlProvider url.Provider,
|
urlProvider url.Provider,
|
||||||
protectionManager *protection.Manager,
|
protectionManager *protection.Manager,
|
||||||
@ -64,13 +69,14 @@ func NewController(
|
|||||||
preReceiveExtender PreReceiveExtender,
|
preReceiveExtender PreReceiveExtender,
|
||||||
updateExtender UpdateExtender,
|
updateExtender UpdateExtender,
|
||||||
postReceiveExtender PostReceiveExtender,
|
postReceiveExtender PostReceiveExtender,
|
||||||
|
|
||||||
) *Controller {
|
) *Controller {
|
||||||
return &Controller{
|
return &Controller{
|
||||||
authorizer: authorizer,
|
authorizer: authorizer,
|
||||||
principalStore: principalStore,
|
principalStore: principalStore,
|
||||||
repoStore: repoStore,
|
repoStore: repoStore,
|
||||||
gitReporter: gitReporter,
|
gitReporter: gitReporter,
|
||||||
|
repoReporter: repoReporter,
|
||||||
|
git: git,
|
||||||
pullreqStore: pullreqStore,
|
pullreqStore: pullreqStore,
|
||||||
urlProvider: urlProvider,
|
urlProvider: urlProvider,
|
||||||
protectionManager: protectionManager,
|
protectionManager: protectionManager,
|
||||||
|
@ -19,13 +19,17 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/app/api/usererror"
|
||||||
"github.com/harness/gitness/app/auth"
|
"github.com/harness/gitness/app/auth"
|
||||||
|
"github.com/harness/gitness/app/bootstrap"
|
||||||
events "github.com/harness/gitness/app/events/git"
|
events "github.com/harness/gitness/app/events/git"
|
||||||
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/git"
|
"github.com/harness/gitness/git"
|
||||||
"github.com/harness/gitness/git/hook"
|
"github.com/harness/gitness/git/hook"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
"github.com/harness/gitness/types/enum"
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
|
"github.com/gotidy/ptr"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,13 +55,16 @@ func (c *Controller) PostReceive(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return hook.Output{}, err
|
return hook.Output{}, err
|
||||||
}
|
}
|
||||||
|
// create output object and have following messages fill its messages
|
||||||
|
out := hook.Output{}
|
||||||
|
|
||||||
|
// update default branch based on ref update info on empty repos.
|
||||||
|
// as the branch could be different than the configured default value.
|
||||||
|
c.handleEmptyRepoPush(ctx, repo, in.PostReceiveInput, &out)
|
||||||
|
|
||||||
// report ref events (best effort)
|
// report ref events (best effort)
|
||||||
c.reportReferenceEvents(ctx, rgit, repo, in.PrincipalID, in.PostReceiveInput)
|
c.reportReferenceEvents(ctx, rgit, repo, in.PrincipalID, in.PostReceiveInput)
|
||||||
|
|
||||||
// create output object and have following messages fill its messages
|
|
||||||
out := hook.Output{}
|
|
||||||
|
|
||||||
// handle branch updates related to PRs - best effort
|
// handle branch updates related to PRs - best effort
|
||||||
c.handlePRMessaging(ctx, repo, in.PostReceiveInput, &out)
|
c.handlePRMessaging(ctx, repo, in.PostReceiveInput, &out)
|
||||||
|
|
||||||
@ -250,3 +257,50 @@ func (c *Controller) suggestPullRequest(
|
|||||||
" "+c.urlProvider.GenerateUICompareURL(repo.Path, repo.DefaultBranch, branchName),
|
" "+c.urlProvider.GenerateUICompareURL(repo.Path, repo.DefaultBranch, branchName),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleEmptyRepoPush updates repo default branch on empty repos if push contains branches.
|
||||||
|
func (c *Controller) handleEmptyRepoPush(
|
||||||
|
ctx context.Context,
|
||||||
|
repo *types.Repository,
|
||||||
|
in hook.PostReceiveInput,
|
||||||
|
out *hook.Output,
|
||||||
|
) {
|
||||||
|
if !repo.IsEmpty {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var branchName string
|
||||||
|
// we only care about one active branch that was pushed.
|
||||||
|
for _, refUpdate := range in.RefUpdates {
|
||||||
|
if strings.HasPrefix(refUpdate.Ref, gitReferenceNamePrefixBranch) &&
|
||||||
|
refUpdate.New.String() != types.NilSHA {
|
||||||
|
branchName = refUpdate.Ref[len(gitReferenceNamePrefixBranch):]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if branchName == "" {
|
||||||
|
out.Error = ptr.String(usererror.ErrEmptyRepoNeedsBranch.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
oldName := repo.DefaultBranch
|
||||||
|
var err error
|
||||||
|
repo, err = c.repoStore.UpdateOptLock(ctx, repo, func(r *types.Repository) error {
|
||||||
|
r.IsEmpty = false
|
||||||
|
r.DefaultBranch = branchName
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Ctx(ctx).Warn().Err(err).Msgf("failed to update the repo default branch to %s and is_empty to false", branchName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if repo.DefaultBranch != oldName {
|
||||||
|
c.repoReporter.DefaultBranchUpdated(ctx, &repoevents.DefaultBranchUpdatedPayload{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
PrincipalID: bootstrap.NewSystemServiceSession().Principal.ID,
|
||||||
|
OldName: oldName,
|
||||||
|
NewName: repo.DefaultBranch,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,11 +14,76 @@
|
|||||||
|
|
||||||
package githook
|
package githook
|
||||||
|
|
||||||
import "github.com/google/wire"
|
import (
|
||||||
|
"github.com/harness/gitness/app/api/controller/limiter"
|
||||||
|
"github.com/harness/gitness/app/auth/authz"
|
||||||
|
eventsgit "github.com/harness/gitness/app/events/git"
|
||||||
|
eventsrepo "github.com/harness/gitness/app/events/repo"
|
||||||
|
"github.com/harness/gitness/app/services/protection"
|
||||||
|
"github.com/harness/gitness/app/services/settings"
|
||||||
|
"github.com/harness/gitness/app/store"
|
||||||
|
"github.com/harness/gitness/app/url"
|
||||||
|
"github.com/harness/gitness/git"
|
||||||
|
"github.com/harness/gitness/git/hook"
|
||||||
|
|
||||||
// Due to cyclic injection dependencies, wiring can be found at app/githook/wire.go
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
var WireSet = wire.NewSet(
|
var WireSet = wire.NewSet(
|
||||||
|
ProvideController,
|
||||||
|
ProvideFactory,
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProvideFactory() hook.ClientFactory {
|
||||||
|
return &ControllerClientFactory{
|
||||||
|
githookCtrl: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProvideController(
|
||||||
|
authorizer authz.Authorizer,
|
||||||
|
principalStore store.PrincipalStore,
|
||||||
|
repoStore store.RepoStore,
|
||||||
|
gitReporter *eventsgit.Reporter,
|
||||||
|
repoReporter *eventsrepo.Reporter,
|
||||||
|
git git.Interface,
|
||||||
|
pullreqStore store.PullReqStore,
|
||||||
|
urlProvider url.Provider,
|
||||||
|
protectionManager *protection.Manager,
|
||||||
|
githookFactory hook.ClientFactory,
|
||||||
|
limiter limiter.ResourceLimiter,
|
||||||
|
settings *settings.Service,
|
||||||
|
preReceiveExtender PreReceiveExtender,
|
||||||
|
updateExtender UpdateExtender,
|
||||||
|
postReceiveExtender PostReceiveExtender,
|
||||||
|
) *Controller {
|
||||||
|
ctrl := NewController(
|
||||||
|
authorizer,
|
||||||
|
principalStore,
|
||||||
|
repoStore,
|
||||||
|
gitReporter,
|
||||||
|
repoReporter,
|
||||||
|
git,
|
||||||
|
pullreqStore,
|
||||||
|
urlProvider,
|
||||||
|
protectionManager,
|
||||||
|
limiter,
|
||||||
|
settings,
|
||||||
|
preReceiveExtender,
|
||||||
|
updateExtender,
|
||||||
|
postReceiveExtender,
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: improve wiring if possible
|
||||||
|
if fct, ok := githookFactory.(*ControllerClientFactory); ok {
|
||||||
|
fct.githookCtrl = ctrl
|
||||||
|
fct.git = git
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctrl
|
||||||
|
}
|
||||||
|
|
||||||
|
var ExtenderWireSet = wire.NewSet(
|
||||||
ProvidePreReceiveExtender,
|
ProvidePreReceiveExtender,
|
||||||
ProvideUpdateExtender,
|
ProvideUpdateExtender,
|
||||||
ProvidePostReceiveExtender,
|
ProvidePostReceiveExtender,
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
||||||
"github.com/harness/gitness/app/services/codecomments"
|
"github.com/harness/gitness/app/services/codecomments"
|
||||||
"github.com/harness/gitness/app/services/codeowners"
|
"github.com/harness/gitness/app/services/codeowners"
|
||||||
|
locker "github.com/harness/gitness/app/services/locker"
|
||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
"github.com/harness/gitness/app/services/pullreq"
|
"github.com/harness/gitness/app/services/pullreq"
|
||||||
"github.com/harness/gitness/app/sse"
|
"github.com/harness/gitness/app/sse"
|
||||||
@ -33,7 +34,6 @@ import (
|
|||||||
"github.com/harness/gitness/errors"
|
"github.com/harness/gitness/errors"
|
||||||
"github.com/harness/gitness/git"
|
"github.com/harness/gitness/git"
|
||||||
gitenum "github.com/harness/gitness/git/enum"
|
gitenum "github.com/harness/gitness/git/enum"
|
||||||
"github.com/harness/gitness/lock"
|
|
||||||
"github.com/harness/gitness/store/database/dbtx"
|
"github.com/harness/gitness/store/database/dbtx"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
"github.com/harness/gitness/types/enum"
|
"github.com/harness/gitness/types/enum"
|
||||||
@ -55,12 +55,12 @@ type Controller struct {
|
|||||||
checkStore store.CheckStore
|
checkStore store.CheckStore
|
||||||
git git.Interface
|
git git.Interface
|
||||||
eventReporter *pullreqevents.Reporter
|
eventReporter *pullreqevents.Reporter
|
||||||
mtxManager lock.MutexManager
|
|
||||||
codeCommentMigrator *codecomments.Migrator
|
codeCommentMigrator *codecomments.Migrator
|
||||||
pullreqService *pullreq.Service
|
pullreqService *pullreq.Service
|
||||||
protectionManager *protection.Manager
|
protectionManager *protection.Manager
|
||||||
sseStreamer sse.Streamer
|
sseStreamer sse.Streamer
|
||||||
codeOwners *codeowners.Service
|
codeOwners *codeowners.Service
|
||||||
|
locker *locker.Locker
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewController(
|
func NewController(
|
||||||
@ -79,12 +79,12 @@ func NewController(
|
|||||||
checkStore store.CheckStore,
|
checkStore store.CheckStore,
|
||||||
git git.Interface,
|
git git.Interface,
|
||||||
eventReporter *pullreqevents.Reporter,
|
eventReporter *pullreqevents.Reporter,
|
||||||
mtxManager lock.MutexManager,
|
|
||||||
codeCommentMigrator *codecomments.Migrator,
|
codeCommentMigrator *codecomments.Migrator,
|
||||||
pullreqService *pullreq.Service,
|
pullreqService *pullreq.Service,
|
||||||
protectionManager *protection.Manager,
|
protectionManager *protection.Manager,
|
||||||
sseStreamer sse.Streamer,
|
sseStreamer sse.Streamer,
|
||||||
codeowners *codeowners.Service,
|
codeowners *codeowners.Service,
|
||||||
|
locker *locker.Locker,
|
||||||
) *Controller {
|
) *Controller {
|
||||||
return &Controller{
|
return &Controller{
|
||||||
tx: tx,
|
tx: tx,
|
||||||
@ -103,11 +103,11 @@ func NewController(
|
|||||||
git: git,
|
git: git,
|
||||||
codeCommentMigrator: codeCommentMigrator,
|
codeCommentMigrator: codeCommentMigrator,
|
||||||
eventReporter: eventReporter,
|
eventReporter: eventReporter,
|
||||||
mtxManager: mtxManager,
|
|
||||||
pullreqService: pullreqService,
|
pullreqService: pullreqService,
|
||||||
protectionManager: protectionManager,
|
protectionManager: protectionManager,
|
||||||
sseStreamer: sseStreamer,
|
sseStreamer: sseStreamer,
|
||||||
codeOwners: codeowners,
|
codeOwners: codeowners,
|
||||||
|
locker: locker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
// Copyright 2023 Harness, Inc.
|
|
||||||
//
|
|
||||||
// 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 pullreq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/harness/gitness/contextutil"
|
|
||||||
"github.com/harness/gitness/lock"
|
|
||||||
"github.com/harness/gitness/logging"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *Controller) lockPR(
|
|
||||||
ctx context.Context,
|
|
||||||
repoID int64,
|
|
||||||
prNum int64,
|
|
||||||
expiry time.Duration,
|
|
||||||
) (func(), error) {
|
|
||||||
key := fmt.Sprintf("%d/pulls", repoID)
|
|
||||||
if prNum != 0 {
|
|
||||||
key += "/" + strconv.FormatInt(prNum, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
// annotate logs for easier debugging of lock related merge issues
|
|
||||||
// TODO: refactor once common logging annotations are added
|
|
||||||
ctx = logging.NewContext(ctx, func(c zerolog.Context) zerolog.Context {
|
|
||||||
return c.
|
|
||||||
Str("pullreq_lock", key).
|
|
||||||
Int64("repo_id", repoID)
|
|
||||||
})
|
|
||||||
|
|
||||||
mutex, err := c.mtxManager.NewMutex(
|
|
||||||
key,
|
|
||||||
lock.WithNamespace("repo"),
|
|
||||||
lock.WithExpiry(expiry),
|
|
||||||
lock.WithTimeoutFactor(4/expiry.Seconds()), // 4s
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create new mutex for pr %d in repo %d: %w", prNum, repoID, err)
|
|
||||||
}
|
|
||||||
err = mutex.Lock(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to lock mutex for pr %d in repo %d: %w", prNum, repoID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Ctx(ctx).Debug().Msgf("successfully locked PR (expiry: %s)", expiry)
|
|
||||||
|
|
||||||
unlockFn := func() {
|
|
||||||
// always unlock independent of whether source context got canceled or not
|
|
||||||
ctx, cancel := context.WithTimeout(
|
|
||||||
contextutil.WithNewValues(context.Background(), ctx),
|
|
||||||
30*time.Second,
|
|
||||||
)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
err := mutex.Unlock(ctx)
|
|
||||||
if err != nil {
|
|
||||||
log.Ctx(ctx).Warn().Err(err).Msg("failed to unlock PR")
|
|
||||||
} else {
|
|
||||||
log.Ctx(ctx).Debug().Msg("successfully unlocked PR")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return unlockFn, nil
|
|
||||||
}
|
|
@ -117,7 +117,7 @@ func (c *Controller) Merge(
|
|||||||
// first one and second one will wait, when first one is done then second one
|
// first one and second one will wait, when first one is done then second one
|
||||||
// continue with latest data from db with state merged and return error that
|
// continue with latest data from db with state merged and return error that
|
||||||
// pr is already merged.
|
// pr is already merged.
|
||||||
unlock, err := c.lockPR(
|
unlock, err := c.locker.LockPR(
|
||||||
ctx,
|
ctx,
|
||||||
targetRepo.ID,
|
targetRepo.ID,
|
||||||
0, // 0 means locks all PRs for this repo
|
0, // 0 means locks all PRs for this repo
|
||||||
|
@ -19,13 +19,13 @@ import (
|
|||||||
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
||||||
"github.com/harness/gitness/app/services/codecomments"
|
"github.com/harness/gitness/app/services/codecomments"
|
||||||
"github.com/harness/gitness/app/services/codeowners"
|
"github.com/harness/gitness/app/services/codeowners"
|
||||||
|
"github.com/harness/gitness/app/services/locker"
|
||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
"github.com/harness/gitness/app/services/pullreq"
|
"github.com/harness/gitness/app/services/pullreq"
|
||||||
"github.com/harness/gitness/app/sse"
|
"github.com/harness/gitness/app/sse"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
"github.com/harness/gitness/app/url"
|
"github.com/harness/gitness/app/url"
|
||||||
"github.com/harness/gitness/git"
|
"github.com/harness/gitness/git"
|
||||||
"github.com/harness/gitness/lock"
|
|
||||||
"github.com/harness/gitness/store/database/dbtx"
|
"github.com/harness/gitness/store/database/dbtx"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
@ -43,10 +43,9 @@ func ProvideController(tx dbtx.Transactor, urlProvider url.Provider, authorizer
|
|||||||
repoStore store.RepoStore, principalStore store.PrincipalStore,
|
repoStore store.RepoStore, principalStore store.PrincipalStore,
|
||||||
fileViewStore store.PullReqFileViewStore, membershipStore store.MembershipStore,
|
fileViewStore store.PullReqFileViewStore, membershipStore store.MembershipStore,
|
||||||
checkStore store.CheckStore,
|
checkStore store.CheckStore,
|
||||||
rpcClient git.Interface, eventReporter *pullreqevents.Reporter,
|
rpcClient git.Interface, eventReporter *pullreqevents.Reporter, codeCommentMigrator *codecomments.Migrator,
|
||||||
mtxManager lock.MutexManager, codeCommentMigrator *codecomments.Migrator,
|
|
||||||
pullreqService *pullreq.Service, ruleManager *protection.Manager, sseStreamer sse.Streamer,
|
pullreqService *pullreq.Service, ruleManager *protection.Manager, sseStreamer sse.Streamer,
|
||||||
codeOwners *codeowners.Service,
|
codeOwners *codeowners.Service, locker *locker.Locker,
|
||||||
) *Controller {
|
) *Controller {
|
||||||
return NewController(tx, urlProvider, authorizer,
|
return NewController(tx, urlProvider, authorizer,
|
||||||
pullReqStore, pullReqActivityStore,
|
pullReqStore, pullReqActivityStore,
|
||||||
@ -56,6 +55,6 @@ func ProvideController(tx dbtx.Transactor, urlProvider url.Provider, authorizer
|
|||||||
fileViewStore, membershipStore,
|
fileViewStore, membershipStore,
|
||||||
checkStore,
|
checkStore,
|
||||||
rpcClient, eventReporter,
|
rpcClient, eventReporter,
|
||||||
mtxManager, codeCommentMigrator,
|
codeCommentMigrator,
|
||||||
pullreqService, ruleManager, sseStreamer, codeOwners)
|
pullreqService, ruleManager, sseStreamer, codeOwners, locker)
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/codeowners"
|
"github.com/harness/gitness/app/services/codeowners"
|
||||||
"github.com/harness/gitness/app/services/importer"
|
"github.com/harness/gitness/app/services/importer"
|
||||||
"github.com/harness/gitness/app/services/keywordsearch"
|
"github.com/harness/gitness/app/services/keywordsearch"
|
||||||
|
"github.com/harness/gitness/app/services/locker"
|
||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
"github.com/harness/gitness/app/services/settings"
|
"github.com/harness/gitness/app/services/settings"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
@ -66,6 +67,7 @@ type Controller struct {
|
|||||||
eventReporter *repoevents.Reporter
|
eventReporter *repoevents.Reporter
|
||||||
indexer keywordsearch.Indexer
|
indexer keywordsearch.Indexer
|
||||||
resourceLimiter limiter.ResourceLimiter
|
resourceLimiter limiter.ResourceLimiter
|
||||||
|
locker *locker.Locker
|
||||||
mtxManager lock.MutexManager
|
mtxManager lock.MutexManager
|
||||||
identifierCheck check.RepoIdentifier
|
identifierCheck check.RepoIdentifier
|
||||||
repoCheck Check
|
repoCheck Check
|
||||||
@ -90,6 +92,7 @@ func NewController(
|
|||||||
eventReporter *repoevents.Reporter,
|
eventReporter *repoevents.Reporter,
|
||||||
indexer keywordsearch.Indexer,
|
indexer keywordsearch.Indexer,
|
||||||
limiter limiter.ResourceLimiter,
|
limiter limiter.ResourceLimiter,
|
||||||
|
locker *locker.Locker,
|
||||||
mtxManager lock.MutexManager,
|
mtxManager lock.MutexManager,
|
||||||
identifierCheck check.RepoIdentifier,
|
identifierCheck check.RepoIdentifier,
|
||||||
repoCheck Check,
|
repoCheck Check,
|
||||||
@ -114,6 +117,7 @@ func NewController(
|
|||||||
eventReporter: eventReporter,
|
eventReporter: eventReporter,
|
||||||
indexer: indexer,
|
indexer: indexer,
|
||||||
resourceLimiter: limiter,
|
resourceLimiter: limiter,
|
||||||
|
locker: locker,
|
||||||
mtxManager: mtxManager,
|
mtxManager: mtxManager,
|
||||||
identifierCheck: identifierCheck,
|
identifierCheck: identifierCheck,
|
||||||
repoCheck: repoCheck,
|
repoCheck: repoCheck,
|
||||||
|
@ -81,7 +81,7 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea
|
|||||||
return fmt.Errorf("resource limit exceeded: %w", limiter.ErrMaxNumReposReached)
|
return fmt.Errorf("resource limit exceeded: %w", limiter.ErrMaxNumReposReached)
|
||||||
}
|
}
|
||||||
|
|
||||||
gitResp, err := c.createGitRepository(ctx, session, in)
|
gitResp, isEmpty, err := c.createGitRepository(ctx, session, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating repository on git: %w", err)
|
return fmt.Errorf("error creating repository on git: %w", err)
|
||||||
}
|
}
|
||||||
@ -99,6 +99,7 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea
|
|||||||
Updated: now,
|
Updated: now,
|
||||||
ForkID: in.ForkID,
|
ForkID: in.ForkID,
|
||||||
DefaultBranch: in.DefaultBranch,
|
DefaultBranch: in.DefaultBranch,
|
||||||
|
IsEmpty: isEmpty,
|
||||||
}
|
}
|
||||||
err = c.repoStore.Create(ctx, repo)
|
err = c.repoStore.Create(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -118,7 +119,7 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea
|
|||||||
repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path)
|
repo.GitURL = c.urlProvider.GenerateGITCloneURL(repo.Path)
|
||||||
|
|
||||||
// index repository if files are created
|
// index repository if files are created
|
||||||
if in.Readme || in.GitIgnore != "" || (in.License != "" && in.License != "none") {
|
if !repo.IsEmpty {
|
||||||
err = c.indexer.Index(ctx, repo)
|
err = c.indexer.Index(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Ctx(ctx).Warn().Err(err).Int64("repo_id", repo.ID).Msg("failed to index repo")
|
log.Ctx(ctx).Warn().Err(err).Int64("repo_id", repo.ID).Msg("failed to index repo")
|
||||||
@ -186,7 +187,7 @@ func (c *Controller) sanitizeCreateInput(in *CreateInput) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) createGitRepository(ctx context.Context, session *auth.Session,
|
func (c *Controller) createGitRepository(ctx context.Context, session *auth.Session,
|
||||||
in *CreateInput) (*git.CreateRepositoryOutput, error) {
|
in *CreateInput) (*git.CreateRepositoryOutput, bool, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
content []byte
|
content []byte
|
||||||
@ -202,7 +203,7 @@ func (c *Controller) createGitRepository(ctx context.Context, session *auth.Sess
|
|||||||
if in.License != "" && in.License != "none" {
|
if in.License != "" && in.License != "none" {
|
||||||
content, err = resources.ReadLicense(in.License)
|
content, err = resources.ReadLicense(in.License)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read license '%s': %w", in.License, err)
|
return nil, false, fmt.Errorf("failed to read license '%s': %w", in.License, err)
|
||||||
}
|
}
|
||||||
files = append(files, git.File{
|
files = append(files, git.File{
|
||||||
Path: "LICENSE",
|
Path: "LICENSE",
|
||||||
@ -212,7 +213,7 @@ func (c *Controller) createGitRepository(ctx context.Context, session *auth.Sess
|
|||||||
if in.GitIgnore != "" {
|
if in.GitIgnore != "" {
|
||||||
content, err = resources.ReadGitIgnore(in.GitIgnore)
|
content, err = resources.ReadGitIgnore(in.GitIgnore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read git ignore '%s': %w", in.GitIgnore, err)
|
return nil, false, fmt.Errorf("failed to read git ignore '%s': %w", in.GitIgnore, err)
|
||||||
}
|
}
|
||||||
files = append(files, git.File{
|
files = append(files, git.File{
|
||||||
Path: ".gitignore",
|
Path: ".gitignore",
|
||||||
@ -230,7 +231,7 @@ func (c *Controller) createGitRepository(ctx context.Context, session *auth.Sess
|
|||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to generate git hook environment variables: %w", err)
|
return nil, false, fmt.Errorf("failed to generate git hook environment variables: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
actor := identityFromPrincipal(session.Principal)
|
actor := identityFromPrincipal(session.Principal)
|
||||||
@ -247,10 +248,10 @@ func (c *Controller) createGitRepository(ctx context.Context, session *auth.Sess
|
|||||||
CommitterDate: &now,
|
CommitterDate: &now,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create repo on: %w", err)
|
return nil, false, fmt.Errorf("failed to create repo on: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, len(files) == 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createReadme(name, description string) []byte {
|
func createReadme(name, description string) []byte {
|
||||||
|
@ -21,12 +21,12 @@ import (
|
|||||||
|
|
||||||
"github.com/harness/gitness/app/api/controller"
|
"github.com/harness/gitness/app/api/controller"
|
||||||
"github.com/harness/gitness/app/auth"
|
"github.com/harness/gitness/app/auth"
|
||||||
|
"github.com/harness/gitness/app/bootstrap"
|
||||||
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/contextutil"
|
"github.com/harness/gitness/contextutil"
|
||||||
"github.com/harness/gitness/git"
|
"github.com/harness/gitness/git"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
"github.com/harness/gitness/types/enum"
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type UpdateDefaultBranchInput struct {
|
type UpdateDefaultBranchInput struct {
|
||||||
@ -50,11 +50,11 @@ func (c *Controller) UpdateDefaultBranch(
|
|||||||
|
|
||||||
// lock concurrent requests for updating the default branch of a repo
|
// lock concurrent requests for updating the default branch of a repo
|
||||||
// requests will wait for previous ones to compelete before proceed
|
// requests will wait for previous ones to compelete before proceed
|
||||||
unlock, err := c.lockDefaultBranch(
|
unlock, err := c.locker.LockDefaultBranch(
|
||||||
ctx,
|
ctx,
|
||||||
repo.GitUID,
|
repo.ID,
|
||||||
in.Name, // branch name only used for logging (lock is on repo)
|
in.Name, // branch name only used for logging (lock is on repo)
|
||||||
timeout+30*time.Second,
|
timeout+30*time.Second, // add 30s to the lock to give enough time for updating default branch
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -82,6 +82,7 @@ func (c *Controller) UpdateDefaultBranch(
|
|||||||
return nil, fmt.Errorf("failed to update the repo default branch: %w", err)
|
return nil, fmt.Errorf("failed to update the repo default branch: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oldName := repo.DefaultBranch
|
||||||
repo, err = c.repoStore.UpdateOptLock(ctx, repo, func(r *types.Repository) error {
|
repo, err = c.repoStore.UpdateOptLock(ctx, repo, func(r *types.Repository) error {
|
||||||
r.DefaultBranch = in.Name
|
r.DefaultBranch = in.Name
|
||||||
return nil
|
return nil
|
||||||
@ -90,11 +91,12 @@ func (c *Controller) UpdateDefaultBranch(
|
|||||||
return nil, fmt.Errorf("failed to update the repo default branch on db:%w", err)
|
return nil, fmt.Errorf("failed to update the repo default branch on db:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.indexer.Index(ctx, repo)
|
c.eventReporter.DefaultBranchUpdated(ctx, &repoevents.DefaultBranchUpdatedPayload{
|
||||||
if err != nil {
|
RepoID: repo.ID,
|
||||||
log.Ctx(ctx).Warn().Err(err).Int64("repo_id", repo.ID).
|
PrincipalID: bootstrap.NewSystemServiceSession().Principal.ID,
|
||||||
Msgf("failed to index repo with the updated default branch %s", in.Name)
|
OldName: oldName,
|
||||||
}
|
NewName: repo.DefaultBranch,
|
||||||
|
})
|
||||||
|
|
||||||
return repo, nil
|
return repo, nil
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/codeowners"
|
"github.com/harness/gitness/app/services/codeowners"
|
||||||
"github.com/harness/gitness/app/services/importer"
|
"github.com/harness/gitness/app/services/importer"
|
||||||
"github.com/harness/gitness/app/services/keywordsearch"
|
"github.com/harness/gitness/app/services/keywordsearch"
|
||||||
|
"github.com/harness/gitness/app/services/locker"
|
||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
"github.com/harness/gitness/app/services/settings"
|
"github.com/harness/gitness/app/services/settings"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
@ -58,6 +59,7 @@ func ProvideController(
|
|||||||
reporeporter *repoevents.Reporter,
|
reporeporter *repoevents.Reporter,
|
||||||
indexer keywordsearch.Indexer,
|
indexer keywordsearch.Indexer,
|
||||||
limiter limiter.ResourceLimiter,
|
limiter limiter.ResourceLimiter,
|
||||||
|
locker *locker.Locker,
|
||||||
mtxManager lock.MutexManager,
|
mtxManager lock.MutexManager,
|
||||||
identifierCheck check.RepoIdentifier,
|
identifierCheck check.RepoIdentifier,
|
||||||
repoChecks Check,
|
repoChecks Check,
|
||||||
@ -65,8 +67,8 @@ func ProvideController(
|
|||||||
return NewController(config, tx, urlProvider,
|
return NewController(config, tx, urlProvider,
|
||||||
authorizer, repoStore,
|
authorizer, repoStore,
|
||||||
spaceStore, pipelineStore,
|
spaceStore, pipelineStore,
|
||||||
principalStore, ruleStore, settings, principalInfoCache, protectionManager,
|
principalStore, ruleStore, settings, principalInfoCache, protectionManager, rpcClient, importer,
|
||||||
rpcClient, importer, codeOwners, reporeporter, indexer, limiter, mtxManager, identifierCheck, repoChecks)
|
codeOwners, reporeporter, indexer, limiter, locker, mtxManager, identifierCheck, repoChecks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideRepoCheck() Check {
|
func ProvideRepoCheck() Check {
|
||||||
|
@ -88,6 +88,10 @@ var (
|
|||||||
http.StatusLocked,
|
http.StatusLocked,
|
||||||
"The requested resource is temporarily locked, please retry the operation.",
|
"The requested resource is temporarily locked, please retry the operation.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrEmptyRepoNeedsBranch is returned if no branch found on the githook post receieve for empty repositories.
|
||||||
|
ErrEmptyRepoNeedsBranch = New(http.StatusBadRequest,
|
||||||
|
"Pushing to an empty repository requires at least one branch with commits.")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error represents a json-encoded API error.
|
// Error represents a json-encoded API error.
|
||||||
|
@ -45,3 +45,27 @@ func (r *Reader) RegisterRepoDeleted(fn events.HandlerFunc[*DeletedPayload],
|
|||||||
opts ...events.HandlerOption) error {
|
opts ...events.HandlerOption) error {
|
||||||
return events.ReaderRegisterEvent(r.innerReader, DeletedEvent, fn, opts...)
|
return events.ReaderRegisterEvent(r.innerReader, DeletedEvent, fn, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DefaultBranchUpdatedEvent events.EventType = "default-branch-updated"
|
||||||
|
|
||||||
|
type DefaultBranchUpdatedPayload struct {
|
||||||
|
RepoID int64 `json:"repo_id"`
|
||||||
|
PrincipalID int64 `json:"principal_id"`
|
||||||
|
OldName string `json:"old_name"`
|
||||||
|
NewName string `json:"new_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reporter) DefaultBranchUpdated(ctx context.Context, payload *DefaultBranchUpdatedPayload) {
|
||||||
|
eventID, err := events.ReporterSendEvent(r.innerReporter, ctx, DefaultBranchUpdatedEvent, payload)
|
||||||
|
if err != nil {
|
||||||
|
log.Ctx(ctx).Err(err).Msgf("failed to send default branch updated event")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Ctx(ctx).Debug().Msgf("reported default branch updated event with id '%s'", eventID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) RegisterDefaultBranchUpdated(fn events.HandlerFunc[*DefaultBranchUpdatedPayload],
|
||||||
|
opts ...events.HandlerOption) error {
|
||||||
|
return events.ReaderRegisterEvent(r.innerReader, DefaultBranchUpdatedEvent, fn, opts...)
|
||||||
|
}
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
// Copyright 2023 Harness, Inc.
|
|
||||||
//
|
|
||||||
// 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 githook
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/harness/gitness/app/api/controller/githook"
|
|
||||||
"github.com/harness/gitness/app/api/controller/limiter"
|
|
||||||
"github.com/harness/gitness/app/auth/authz"
|
|
||||||
eventsgit "github.com/harness/gitness/app/events/git"
|
|
||||||
"github.com/harness/gitness/app/services/protection"
|
|
||||||
"github.com/harness/gitness/app/services/settings"
|
|
||||||
"github.com/harness/gitness/app/store"
|
|
||||||
"github.com/harness/gitness/app/url"
|
|
||||||
"github.com/harness/gitness/git"
|
|
||||||
"github.com/harness/gitness/git/hook"
|
|
||||||
|
|
||||||
"github.com/google/wire"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WireSet provides a wire set for this package.
|
|
||||||
var WireSet = wire.NewSet(
|
|
||||||
ProvideController,
|
|
||||||
ProvideFactory,
|
|
||||||
)
|
|
||||||
|
|
||||||
func ProvideFactory() hook.ClientFactory {
|
|
||||||
return &ControllerClientFactory{
|
|
||||||
// will be set in ProvideController (to break cyclic dependency during wiring)
|
|
||||||
githookCtrl: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ProvideController(
|
|
||||||
authorizer authz.Authorizer,
|
|
||||||
principalStore store.PrincipalStore,
|
|
||||||
repoStore store.RepoStore,
|
|
||||||
gitReporter *eventsgit.Reporter,
|
|
||||||
git git.Interface,
|
|
||||||
pullreqStore store.PullReqStore,
|
|
||||||
urlProvider url.Provider,
|
|
||||||
protectionManager *protection.Manager,
|
|
||||||
githookFactory hook.ClientFactory,
|
|
||||||
limiter limiter.ResourceLimiter,
|
|
||||||
settings *settings.Service,
|
|
||||||
preReceiveExtender githook.PreReceiveExtender,
|
|
||||||
updateExtender githook.UpdateExtender,
|
|
||||||
postReceiveExtender githook.PostReceiveExtender,
|
|
||||||
) *githook.Controller {
|
|
||||||
ctrl := githook.NewController(
|
|
||||||
authorizer,
|
|
||||||
principalStore,
|
|
||||||
repoStore,
|
|
||||||
gitReporter,
|
|
||||||
pullreqStore,
|
|
||||||
urlProvider,
|
|
||||||
protectionManager,
|
|
||||||
limiter,
|
|
||||||
settings,
|
|
||||||
preReceiveExtender,
|
|
||||||
updateExtender,
|
|
||||||
postReceiveExtender,
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: improve wiring if possible
|
|
||||||
if fct, ok := githookFactory.(*ControllerClientFactory); ok {
|
|
||||||
fct.githookCtrl = ctrl
|
|
||||||
fct.git = git
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctrl
|
|
||||||
}
|
|
@ -20,6 +20,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
gitevents "github.com/harness/gitness/app/events/git"
|
gitevents "github.com/harness/gitness/app/events/git"
|
||||||
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/events"
|
"github.com/harness/gitness/events"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,6 +34,21 @@ func (s *Service) handleEventBranchUpdated(ctx context.Context,
|
|||||||
return s.indexRepo(ctx, event.Payload.RepoID, event.Payload.Ref)
|
return s.indexRepo(ctx, event.Payload.RepoID, event.Payload.Ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) handleUpdateDefaultBranch(ctx context.Context,
|
||||||
|
event *events.Event[*repoevents.DefaultBranchUpdatedPayload]) error {
|
||||||
|
repo, err := s.repoStore.Find(ctx, event.Payload.RepoID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to find repository in db: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.indexer.Index(ctx, repo)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("index update failed for repo %d: %w", repo.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) indexRepo(
|
func (s *Service) indexRepo(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
repoID int64,
|
repoID int64,
|
||||||
@ -64,6 +80,7 @@ func (s *Service) indexRepo(
|
|||||||
|
|
||||||
func getBranchFromRef(ref string) (string, error) {
|
func getBranchFromRef(ref string) (string, error) {
|
||||||
const refPrefix = "refs/heads/"
|
const refPrefix = "refs/heads/"
|
||||||
|
|
||||||
if !strings.HasPrefix(ref, refPrefix) {
|
if !strings.HasPrefix(ref, refPrefix) {
|
||||||
return "", fmt.Errorf("failed to get branch name from branch ref %s", ref)
|
return "", fmt.Errorf("failed to get branch name from branch ref %s", ref)
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
gitevents "github.com/harness/gitness/app/events/git"
|
gitevents "github.com/harness/gitness/app/events/git"
|
||||||
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
"github.com/harness/gitness/events"
|
"github.com/harness/gitness/events"
|
||||||
"github.com/harness/gitness/stream"
|
"github.com/harness/gitness/stream"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const groupGitEvents = "gitness:keywordsearch"
|
||||||
eventsReaderGroupName = "gitness:keywordsearch"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
EventReaderName string
|
EventReaderName string
|
||||||
@ -63,6 +62,7 @@ func NewService(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
config Config,
|
config Config,
|
||||||
gitReaderFactory *events.ReaderFactory[*gitevents.Reader],
|
gitReaderFactory *events.ReaderFactory[*gitevents.Reader],
|
||||||
|
repoReaderFactory *events.ReaderFactory[*repoevents.Reader],
|
||||||
repoStore store.RepoStore,
|
repoStore store.RepoStore,
|
||||||
indexer Indexer,
|
indexer Indexer,
|
||||||
) (*Service, error) {
|
) (*Service, error) {
|
||||||
@ -75,7 +75,7 @@ func NewService(
|
|||||||
indexer: indexer,
|
indexer: indexer,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := gitReaderFactory.Launch(ctx, eventsReaderGroupName, config.EventReaderName,
|
_, err := gitReaderFactory.Launch(ctx, groupGitEvents, config.EventReaderName,
|
||||||
func(r *gitevents.Reader) error {
|
func(r *gitevents.Reader) error {
|
||||||
const idleTimeout = 1 * time.Minute
|
const idleTimeout = 1 * time.Minute
|
||||||
r.Configure(
|
r.Configure(
|
||||||
@ -95,5 +95,22 @@ func NewService(
|
|||||||
return nil, fmt.Errorf("failed to launch git event reader for webhooks: %w", err)
|
return nil, fmt.Errorf("failed to launch git event reader for webhooks: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = repoReaderFactory.Launch(ctx, groupGitEvents, config.EventReaderName,
|
||||||
|
func(r *repoevents.Reader) error {
|
||||||
|
const idleTimeout = 1 * time.Minute
|
||||||
|
r.Configure(
|
||||||
|
stream.WithConcurrency(config.Concurrency),
|
||||||
|
stream.WithHandlerOptions(
|
||||||
|
stream.WithIdleTimeout(idleTimeout),
|
||||||
|
stream.WithMaxRetries(config.MaxRetries),
|
||||||
|
))
|
||||||
|
|
||||||
|
_ = r.RegisterDefaultBranchUpdated((service.handleUpdateDefaultBranch))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to launch reader factory for repo git group: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return service, nil
|
return service, nil
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
gitevents "github.com/harness/gitness/app/events/git"
|
gitevents "github.com/harness/gitness/app/events/git"
|
||||||
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
"github.com/harness/gitness/events"
|
"github.com/harness/gitness/events"
|
||||||
|
|
||||||
@ -35,12 +36,14 @@ var WireSet = wire.NewSet(
|
|||||||
func ProvideService(ctx context.Context,
|
func ProvideService(ctx context.Context,
|
||||||
config Config,
|
config Config,
|
||||||
gitReaderFactory *events.ReaderFactory[*gitevents.Reader],
|
gitReaderFactory *events.ReaderFactory[*gitevents.Reader],
|
||||||
|
repoReaderFactory *events.ReaderFactory[*repoevents.Reader],
|
||||||
repoStore store.RepoStore,
|
repoStore store.RepoStore,
|
||||||
indexer Indexer,
|
indexer Indexer,
|
||||||
) (*Service, error) {
|
) (*Service, error) {
|
||||||
return NewService(ctx,
|
return NewService(ctx,
|
||||||
config,
|
config,
|
||||||
gitReaderFactory,
|
gitReaderFactory,
|
||||||
|
repoReaderFactory,
|
||||||
repoStore,
|
repoStore,
|
||||||
indexer)
|
indexer)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package repo
|
package locker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -27,38 +27,50 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Controller) lockDefaultBranch(
|
const namespaceRepo = "repo"
|
||||||
|
|
||||||
|
type Locker struct {
|
||||||
|
mtxManager lock.MutexManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLocker(mtxManager lock.MutexManager) *Locker {
|
||||||
|
return &Locker{
|
||||||
|
mtxManager: mtxManager,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Locker) lock(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
repoUID string,
|
namespace string,
|
||||||
branchName string,
|
key string,
|
||||||
expiry time.Duration,
|
expiry time.Duration,
|
||||||
) (func(), error) {
|
) (func(), error) {
|
||||||
key := repoUID + "/defaultBranch"
|
|
||||||
|
|
||||||
// annotate logs for easier debugging of lock related issues
|
// annotate logs for easier debugging of lock related issues
|
||||||
// TODO: refactor once common logging annotations are added
|
|
||||||
ctx = logging.NewContext(ctx, func(zc zerolog.Context) zerolog.Context {
|
ctx = logging.NewContext(ctx, func(zc zerolog.Context) zerolog.Context {
|
||||||
return zc.
|
return zc.
|
||||||
Str("default_branch_lock", key).
|
Str("key", key).
|
||||||
Str("repo_uid", repoUID)
|
Str("namespace", namespaceRepo).
|
||||||
|
Str("expiry", expiry.String())
|
||||||
})
|
})
|
||||||
|
|
||||||
mutext, err := c.mtxManager.NewMutex(
|
mutext, err := l.mtxManager.NewMutex(
|
||||||
key,
|
key,
|
||||||
lock.WithNamespace("repo"),
|
lock.WithNamespace(namespace),
|
||||||
lock.WithExpiry(expiry),
|
lock.WithExpiry(expiry),
|
||||||
lock.WithTimeoutFactor(4/expiry.Seconds()), // 4s
|
lock.WithTimeoutFactor(4/expiry.Seconds()), // 4s
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create new mutex for repo %q with default branch %s: %w", repoUID, branchName, err)
|
return nil, fmt.Errorf("failed to create new mutex: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Ctx(ctx).Debug().Msg("attempting to acquire lock")
|
||||||
|
|
||||||
err = mutext.Lock(ctx)
|
err = mutext.Lock(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to lock the mutex for repo %q with default branch %s: %w", repoUID, branchName, err)
|
return nil, fmt.Errorf("failed to lock the mutex: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Ctx(ctx).Info().Msgf("successfully locked the repo default branch (expiry: %s)", expiry)
|
log.Ctx(ctx).Debug().Msgf("successfully locked (expiry: %s)", expiry)
|
||||||
|
|
||||||
unlockFn := func() {
|
unlockFn := func() {
|
||||||
// always unlock independent of whether source context got canceled or not
|
// always unlock independent of whether source context got canceled or not
|
||||||
@ -70,10 +82,11 @@ func (c *Controller) lockDefaultBranch(
|
|||||||
|
|
||||||
err := mutext.Unlock(ctx)
|
err := mutext.Unlock(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Ctx(ctx).Warn().Err(err).Msg("failed to unlock repo default branch")
|
log.Ctx(ctx).Warn().Err(err).Msg("failed to unlock")
|
||||||
} else {
|
} else {
|
||||||
log.Ctx(ctx).Info().Msg("successfully unlocked repo default branch")
|
log.Ctx(ctx).Debug().Msg("successfully unlocked")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return unlockFn, nil
|
return unlockFn, nil
|
||||||
}
|
}
|
41
app/services/locker/pullreq.go
Normal file
41
app/services/locker/pullreq.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// 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 locker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l Locker) LockPR(
|
||||||
|
ctx context.Context,
|
||||||
|
repoID int64,
|
||||||
|
prNum int64,
|
||||||
|
expiry time.Duration,
|
||||||
|
) (func(), error) {
|
||||||
|
key := fmt.Sprintf("%d/pulls", repoID)
|
||||||
|
if prNum != 0 {
|
||||||
|
key += "/" + strconv.FormatInt(prNum, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
unlockFn, err := l.lock(ctx, namespaceRepo, key, expiry)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to lock mutex for pr %d in repo %d: %w", prNum, repoID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return unlockFn, nil
|
||||||
|
}
|
42
app/services/locker/repo.go
Normal file
42
app/services/locker/repo.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// 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 locker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l Locker) LockDefaultBranch(
|
||||||
|
ctx context.Context,
|
||||||
|
repoID int64,
|
||||||
|
branchName string,
|
||||||
|
expiry time.Duration,
|
||||||
|
) (func(), error) {
|
||||||
|
key := strconv.FormatInt(repoID, 10) + "/defaultBranch"
|
||||||
|
|
||||||
|
log.Ctx(ctx).Info().Msg("attempting to lock to update the repo default branch")
|
||||||
|
|
||||||
|
unlockFn, err := l.lock(ctx, namespaceRepo, key, expiry)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to lock repo to update default branch to %s: %w", branchName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return unlockFn, nil
|
||||||
|
}
|
29
app/services/locker/wire.go
Normal file
29
app/services/locker/wire.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// 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 locker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/harness/gitness/lock"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
var WireSet = wire.NewSet(
|
||||||
|
ProvideLocker,
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProvideLocker(mtxManager lock.MutexManager) *Locker {
|
||||||
|
return NewLocker(mtxManager)
|
||||||
|
}
|
93
app/services/repo/handlers_default_branch.go
Normal file
93
app/services/repo/handlers_default_branch.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// 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 repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/app/bootstrap"
|
||||||
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
|
"github.com/harness/gitness/app/githook"
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
"github.com/harness/gitness/git"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// handleUpdateDefaultBranch handles git update default branch using branch name from db (not event payload).
|
||||||
|
func (s *Service) handleUpdateDefaultBranch(
|
||||||
|
ctx context.Context,
|
||||||
|
event *events.Event[*repoevents.DefaultBranchUpdatedPayload],
|
||||||
|
) error {
|
||||||
|
// the max time we give an update default branch to succeed
|
||||||
|
const timeout = 2 * time.Minute
|
||||||
|
unlock, err := s.locker.LockDefaultBranch(
|
||||||
|
ctx,
|
||||||
|
event.Payload.RepoID,
|
||||||
|
event.Payload.NewName, // only used for logging
|
||||||
|
timeout+30*time.Second, // add 30s to the lock to give enough time for updating default branch
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to lock repo for updating default branch to %s", event.Payload.NewName)
|
||||||
|
}
|
||||||
|
defer unlock()
|
||||||
|
|
||||||
|
repo, err := s.repoStore.Find(ctx, event.Payload.RepoID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("update default branch handler failed to find the repo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new, time-restricted context to guarantee update completion, even if request is canceled.
|
||||||
|
// TODO: a proper error handling solution required.
|
||||||
|
ctx, cancel := context.WithTimeout(
|
||||||
|
ctx,
|
||||||
|
timeout,
|
||||||
|
)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
systemPrincipal := bootstrap.NewSystemServiceSession().Principal
|
||||||
|
envVars, err := githook.GenerateEnvironmentVariables(
|
||||||
|
ctx,
|
||||||
|
s.urlProvider.GetInternalAPIURL(),
|
||||||
|
repo.ID,
|
||||||
|
systemPrincipal.ID,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to generate git hook env variables: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.git.UpdateDefaultBranch(ctx, &git.UpdateDefaultBranchParams{
|
||||||
|
WriteParams: git.WriteParams{
|
||||||
|
Actor: git.Identity{
|
||||||
|
Name: systemPrincipal.DisplayName,
|
||||||
|
Email: systemPrincipal.Email,
|
||||||
|
},
|
||||||
|
RepoUID: repo.GitUID,
|
||||||
|
EnvVars: envVars,
|
||||||
|
},
|
||||||
|
BranchName: repo.DefaultBranch,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to update the repo default branch to %s", repo.DefaultBranch)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Ctx(ctx).Info().Msgf("git repo default branch updated to %s by default branch event handler", repo.DefaultBranch)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package reposize
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -30,7 +30,7 @@ import (
|
|||||||
|
|
||||||
const jobType = "repo-size-calculator"
|
const jobType = "repo-size-calculator"
|
||||||
|
|
||||||
type Calculator struct {
|
type SizeCalculator struct {
|
||||||
enabled bool
|
enabled bool
|
||||||
cron string
|
cron string
|
||||||
maxDur time.Duration
|
maxDur time.Duration
|
||||||
@ -40,12 +40,12 @@ type Calculator struct {
|
|||||||
scheduler *job.Scheduler
|
scheduler *job.Scheduler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Calculator) Register(ctx context.Context) error {
|
func (s *SizeCalculator) Register(ctx context.Context) error {
|
||||||
if !c.enabled {
|
if !s.enabled {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := c.scheduler.AddRecurring(ctx, jobType, jobType, c.cron, c.maxDur)
|
err := s.scheduler.AddRecurring(ctx, jobType, jobType, s.cron, s.maxDur)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to register recurring job for calculator: %w", err)
|
return fmt.Errorf("failed to register recurring job for calculator: %w", err)
|
||||||
}
|
}
|
||||||
@ -53,17 +53,17 @@ func (c *Calculator) Register(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Calculator) Handle(ctx context.Context, _ string, _ job.ProgressReporter) (string, error) {
|
func (s *SizeCalculator) Handle(ctx context.Context, _ string, _ job.ProgressReporter) (string, error) {
|
||||||
if !c.enabled {
|
if !s.enabled {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeInfos, err := c.repoStore.ListSizeInfos(ctx)
|
sizeInfos, err := s.repoStore.ListSizeInfos(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get repository sizes: %w", err)
|
return "", fmt.Errorf("failed to get repository sizes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expiredBefore := time.Now().Add(c.maxDur)
|
expiredBefore := time.Now().Add(s.maxDur)
|
||||||
log.Ctx(ctx).Info().Msgf(
|
log.Ctx(ctx).Info().Msgf(
|
||||||
"start repo size calculation (operation timeout: %s)",
|
"start repo size calculation (operation timeout: %s)",
|
||||||
expiredBefore.Format(time.RFC3339Nano),
|
expiredBefore.Format(time.RFC3339Nano),
|
||||||
@ -71,9 +71,9 @@ func (c *Calculator) Handle(ctx context.Context, _ string, _ job.ProgressReporte
|
|||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
taskCh := make(chan *types.RepositorySizeInfo)
|
taskCh := make(chan *types.RepositorySizeInfo)
|
||||||
for i := 0; i < c.numWorkers; i++ {
|
for i := 0; i < s.numWorkers; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go worker(ctx, c, &wg, taskCh)
|
go worker(ctx, s, &wg, taskCh)
|
||||||
}
|
}
|
||||||
for _, sizeInfo := range sizeInfos {
|
for _, sizeInfo := range sizeInfos {
|
||||||
select {
|
select {
|
||||||
@ -88,7 +88,7 @@ func (c *Calculator) Handle(ctx context.Context, _ string, _ job.ProgressReporte
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func worker(ctx context.Context, c *Calculator, wg *sync.WaitGroup, taskCh <-chan *types.RepositorySizeInfo) {
|
func worker(ctx context.Context, s *SizeCalculator, wg *sync.WaitGroup, taskCh <-chan *types.RepositorySizeInfo) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
for sizeInfo := range taskCh {
|
for sizeInfo := range taskCh {
|
||||||
@ -96,7 +96,7 @@ func worker(ctx context.Context, c *Calculator, wg *sync.WaitGroup, taskCh <-cha
|
|||||||
|
|
||||||
log.Debug().Msgf("previous repo size: %d", sizeInfo.Size)
|
log.Debug().Msgf("previous repo size: %d", sizeInfo.Size)
|
||||||
|
|
||||||
sizeOut, err := c.git.GetRepositorySize(
|
sizeOut, err := s.git.GetRepositorySize(
|
||||||
ctx,
|
ctx,
|
||||||
&git.GetRepositorySizeParams{ReadParams: git.ReadParams{RepoUID: sizeInfo.GitUID}})
|
&git.GetRepositorySizeParams{ReadParams: git.ReadParams{RepoUID: sizeInfo.GitUID}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -108,7 +108,7 @@ func worker(ctx context.Context, c *Calculator, wg *sync.WaitGroup, taskCh <-cha
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.repoStore.UpdateSize(ctx, sizeInfo.ID, sizeOut.Size); err != nil {
|
if err := s.repoStore.UpdateSize(ctx, sizeInfo.ID, sizeOut.Size); err != nil {
|
||||||
log.Error().Msgf("failed to update repo size: %s", err.Error())
|
log.Error().Msgf("failed to update repo size: %s", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
79
app/services/repo/service.go
Normal file
79
app/services/repo/service.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// 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 repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
|
"github.com/harness/gitness/app/services/locker"
|
||||||
|
"github.com/harness/gitness/app/store"
|
||||||
|
"github.com/harness/gitness/app/url"
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
"github.com/harness/gitness/git"
|
||||||
|
"github.com/harness/gitness/stream"
|
||||||
|
"github.com/harness/gitness/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const groupRepo = "gitness:repo"
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
repoEvReporter *repoevents.Reporter
|
||||||
|
repoStore store.RepoStore
|
||||||
|
urlProvider url.Provider
|
||||||
|
git git.Interface
|
||||||
|
locker *locker.Locker
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(
|
||||||
|
ctx context.Context,
|
||||||
|
config *types.Config,
|
||||||
|
repoEvReporter *repoevents.Reporter,
|
||||||
|
repoReaderFactory *events.ReaderFactory[*repoevents.Reader],
|
||||||
|
repoStore store.RepoStore,
|
||||||
|
urlProvider url.Provider,
|
||||||
|
git git.Interface,
|
||||||
|
locker *locker.Locker,
|
||||||
|
) (*Service, error) {
|
||||||
|
service := &Service{
|
||||||
|
repoEvReporter: repoEvReporter,
|
||||||
|
repoStore: repoStore,
|
||||||
|
urlProvider: urlProvider,
|
||||||
|
git: git,
|
||||||
|
locker: locker,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := repoReaderFactory.Launch(ctx, groupRepo, config.InstanceID,
|
||||||
|
func(r *repoevents.Reader) error {
|
||||||
|
const idleTimeout = 15 * time.Second
|
||||||
|
r.Configure(
|
||||||
|
stream.WithConcurrency(1),
|
||||||
|
stream.WithHandlerOptions(
|
||||||
|
stream.WithIdleTimeout(idleTimeout),
|
||||||
|
stream.WithMaxRetries(3),
|
||||||
|
))
|
||||||
|
|
||||||
|
_ = r.RegisterDefaultBranchUpdated(service.handleUpdateDefaultBranch)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to launch reader factory for repo git group: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return service, nil
|
||||||
|
}
|
@ -12,10 +12,16 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package reposize
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
|
"github.com/harness/gitness/app/services/locker"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
|
"github.com/harness/gitness/app/url"
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
"github.com/harness/gitness/git"
|
"github.com/harness/gitness/git"
|
||||||
"github.com/harness/gitness/job"
|
"github.com/harness/gitness/job"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
@ -25,6 +31,7 @@ import (
|
|||||||
|
|
||||||
var WireSet = wire.NewSet(
|
var WireSet = wire.NewSet(
|
||||||
ProvideCalculator,
|
ProvideCalculator,
|
||||||
|
ProvideService,
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideCalculator(
|
func ProvideCalculator(
|
||||||
@ -33,8 +40,8 @@ func ProvideCalculator(
|
|||||||
repoStore store.RepoStore,
|
repoStore store.RepoStore,
|
||||||
scheduler *job.Scheduler,
|
scheduler *job.Scheduler,
|
||||||
executor *job.Executor,
|
executor *job.Executor,
|
||||||
) (*Calculator, error) {
|
) (*SizeCalculator, error) {
|
||||||
job := &Calculator{
|
job := &SizeCalculator{
|
||||||
enabled: config.RepoSize.Enabled,
|
enabled: config.RepoSize.Enabled,
|
||||||
cron: config.RepoSize.CRON,
|
cron: config.RepoSize.CRON,
|
||||||
maxDur: config.RepoSize.MaxDuration,
|
maxDur: config.RepoSize.MaxDuration,
|
||||||
@ -51,3 +58,16 @@ func ProvideCalculator(
|
|||||||
|
|
||||||
return job, nil
|
return job, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProvideService(ctx context.Context,
|
||||||
|
config *types.Config,
|
||||||
|
repoEvReporter *repoevents.Reporter,
|
||||||
|
repoReaderFactory *events.ReaderFactory[*repoevents.Reader],
|
||||||
|
repoStore store.RepoStore,
|
||||||
|
urlProvider url.Provider,
|
||||||
|
git git.Interface,
|
||||||
|
locker *locker.Locker,
|
||||||
|
) (*Service, error) {
|
||||||
|
return NewService(ctx, config, repoEvReporter, repoReaderFactory,
|
||||||
|
repoStore, urlProvider, git, locker)
|
||||||
|
}
|
@ -20,7 +20,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/metric"
|
"github.com/harness/gitness/app/services/metric"
|
||||||
"github.com/harness/gitness/app/services/notification"
|
"github.com/harness/gitness/app/services/notification"
|
||||||
"github.com/harness/gitness/app/services/pullreq"
|
"github.com/harness/gitness/app/services/pullreq"
|
||||||
"github.com/harness/gitness/app/services/reposize"
|
"github.com/harness/gitness/app/services/repo"
|
||||||
"github.com/harness/gitness/app/services/trigger"
|
"github.com/harness/gitness/app/services/trigger"
|
||||||
"github.com/harness/gitness/app/services/webhook"
|
"github.com/harness/gitness/app/services/webhook"
|
||||||
"github.com/harness/gitness/job"
|
"github.com/harness/gitness/job"
|
||||||
@ -38,7 +38,8 @@ type Services struct {
|
|||||||
Trigger *trigger.Service
|
Trigger *trigger.Service
|
||||||
JobScheduler *job.Scheduler
|
JobScheduler *job.Scheduler
|
||||||
MetricCollector *metric.Collector
|
MetricCollector *metric.Collector
|
||||||
RepoSizeCalculator *reposize.Calculator
|
RepoSizeCalculator *repo.SizeCalculator
|
||||||
|
Repo *repo.Service
|
||||||
Cleanup *cleanup.Service
|
Cleanup *cleanup.Service
|
||||||
Notification *notification.Service
|
Notification *notification.Service
|
||||||
Keywordsearch *keywordsearch.Service
|
Keywordsearch *keywordsearch.Service
|
||||||
@ -50,7 +51,8 @@ func ProvideServices(
|
|||||||
triggerSvc *trigger.Service,
|
triggerSvc *trigger.Service,
|
||||||
jobScheduler *job.Scheduler,
|
jobScheduler *job.Scheduler,
|
||||||
metricCollector *metric.Collector,
|
metricCollector *metric.Collector,
|
||||||
repoSizeCalculator *reposize.Calculator,
|
repoSizeCalculator *repo.SizeCalculator,
|
||||||
|
repo *repo.Service,
|
||||||
cleanupSvc *cleanup.Service,
|
cleanupSvc *cleanup.Service,
|
||||||
notificationSvc *notification.Service,
|
notificationSvc *notification.Service,
|
||||||
keywordsearchSvc *keywordsearch.Service,
|
keywordsearchSvc *keywordsearch.Service,
|
||||||
@ -62,6 +64,7 @@ func ProvideServices(
|
|||||||
JobScheduler: jobScheduler,
|
JobScheduler: jobScheduler,
|
||||||
MetricCollector: metricCollector,
|
MetricCollector: metricCollector,
|
||||||
RepoSizeCalculator: repoSizeCalculator,
|
RepoSizeCalculator: repoSizeCalculator,
|
||||||
|
Repo: repo,
|
||||||
Cleanup: cleanupSvc,
|
Cleanup: cleanupSvc,
|
||||||
Notification: notificationSvc,
|
Notification: notificationSvc,
|
||||||
Keywordsearch: keywordsearchSvc,
|
Keywordsearch: keywordsearchSvc,
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE repositories DROP COLUMN repo_is_empty;
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE repositories ADD COLUMN repo_is_empty BOOLEAN NOT NULL DEFAULT false;
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE repositories DROP COLUMN repo_is_empty;
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE repositories ADD COLUMN repo_is_empty BOOLEAN NOT NULL DEFAULT false;
|
@ -88,6 +88,7 @@ type repository struct {
|
|||||||
NumMergedPulls int `db:"repo_num_merged_pulls"`
|
NumMergedPulls int `db:"repo_num_merged_pulls"`
|
||||||
|
|
||||||
Importing bool `db:"repo_importing"`
|
Importing bool `db:"repo_importing"`
|
||||||
|
IsEmpty bool `db:"repo_is_empty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -113,7 +114,8 @@ const (
|
|||||||
,repo_num_closed_pulls
|
,repo_num_closed_pulls
|
||||||
,repo_num_open_pulls
|
,repo_num_open_pulls
|
||||||
,repo_num_merged_pulls
|
,repo_num_merged_pulls
|
||||||
,repo_importing`
|
,repo_importing
|
||||||
|
,repo_is_empty`
|
||||||
)
|
)
|
||||||
|
|
||||||
// Find finds the repo by id.
|
// Find finds the repo by id.
|
||||||
@ -238,6 +240,7 @@ func (s *RepoStore) Create(ctx context.Context, repo *types.Repository) error {
|
|||||||
,repo_num_open_pulls
|
,repo_num_open_pulls
|
||||||
,repo_num_merged_pulls
|
,repo_num_merged_pulls
|
||||||
,repo_importing
|
,repo_importing
|
||||||
|
,repo_is_empty
|
||||||
) values (
|
) values (
|
||||||
:repo_version
|
:repo_version
|
||||||
,:repo_parent_id
|
,:repo_parent_id
|
||||||
@ -260,6 +263,7 @@ func (s *RepoStore) Create(ctx context.Context, repo *types.Repository) error {
|
|||||||
,:repo_num_open_pulls
|
,:repo_num_open_pulls
|
||||||
,:repo_num_merged_pulls
|
,:repo_num_merged_pulls
|
||||||
,:repo_importing
|
,:repo_importing
|
||||||
|
,:repo_is_empty
|
||||||
) RETURNING repo_id`
|
) RETURNING repo_id`
|
||||||
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
@ -303,6 +307,7 @@ func (s *RepoStore) Update(ctx context.Context, repo *types.Repository) error {
|
|||||||
,repo_num_open_pulls = :repo_num_open_pulls
|
,repo_num_open_pulls = :repo_num_open_pulls
|
||||||
,repo_num_merged_pulls = :repo_num_merged_pulls
|
,repo_num_merged_pulls = :repo_num_merged_pulls
|
||||||
,repo_importing = :repo_importing
|
,repo_importing = :repo_importing
|
||||||
|
,repo_is_empty = :repo_is_empty
|
||||||
WHERE repo_id = :repo_id AND repo_version = :repo_version - 1`
|
WHERE repo_id = :repo_id AND repo_version = :repo_version - 1`
|
||||||
|
|
||||||
dbRepo := mapToInternalRepo(repo)
|
dbRepo := mapToInternalRepo(repo)
|
||||||
@ -746,6 +751,7 @@ func (s *RepoStore) mapToRepo(
|
|||||||
NumOpenPulls: in.NumOpenPulls,
|
NumOpenPulls: in.NumOpenPulls,
|
||||||
NumMergedPulls: in.NumMergedPulls,
|
NumMergedPulls: in.NumMergedPulls,
|
||||||
Importing: in.Importing,
|
Importing: in.Importing,
|
||||||
|
IsEmpty: in.IsEmpty,
|
||||||
// Path: is set below
|
// Path: is set below
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -829,6 +835,7 @@ func mapToInternalRepo(in *types.Repository) *repository {
|
|||||||
NumOpenPulls: in.NumOpenPulls,
|
NumOpenPulls: in.NumOpenPulls,
|
||||||
NumMergedPulls: in.NumMergedPulls,
|
NumMergedPulls: in.NumMergedPulls,
|
||||||
Importing: in.Importing,
|
Importing: in.Importing,
|
||||||
|
IsEmpty: in.IsEmpty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
checkcontroller "github.com/harness/gitness/app/api/controller/check"
|
checkcontroller "github.com/harness/gitness/app/api/controller/check"
|
||||||
"github.com/harness/gitness/app/api/controller/connector"
|
"github.com/harness/gitness/app/api/controller/connector"
|
||||||
"github.com/harness/gitness/app/api/controller/execution"
|
"github.com/harness/gitness/app/api/controller/execution"
|
||||||
ctrlgithook "github.com/harness/gitness/app/api/controller/githook"
|
githookCtrl "github.com/harness/gitness/app/api/controller/githook"
|
||||||
controllerkeywordsearch "github.com/harness/gitness/app/api/controller/keywordsearch"
|
controllerkeywordsearch "github.com/harness/gitness/app/api/controller/keywordsearch"
|
||||||
"github.com/harness/gitness/app/api/controller/limiter"
|
"github.com/harness/gitness/app/api/controller/limiter"
|
||||||
controllerlogs "github.com/harness/gitness/app/api/controller/logs"
|
controllerlogs "github.com/harness/gitness/app/api/controller/logs"
|
||||||
@ -40,7 +40,6 @@ import (
|
|||||||
gitevents "github.com/harness/gitness/app/events/git"
|
gitevents "github.com/harness/gitness/app/events/git"
|
||||||
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
||||||
repoevents "github.com/harness/gitness/app/events/repo"
|
repoevents "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/app/githook"
|
|
||||||
"github.com/harness/gitness/app/pipeline/canceler"
|
"github.com/harness/gitness/app/pipeline/canceler"
|
||||||
"github.com/harness/gitness/app/pipeline/commit"
|
"github.com/harness/gitness/app/pipeline/commit"
|
||||||
"github.com/harness/gitness/app/pipeline/converter"
|
"github.com/harness/gitness/app/pipeline/converter"
|
||||||
@ -59,12 +58,13 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/exporter"
|
"github.com/harness/gitness/app/services/exporter"
|
||||||
"github.com/harness/gitness/app/services/importer"
|
"github.com/harness/gitness/app/services/importer"
|
||||||
"github.com/harness/gitness/app/services/keywordsearch"
|
"github.com/harness/gitness/app/services/keywordsearch"
|
||||||
|
locker "github.com/harness/gitness/app/services/locker"
|
||||||
"github.com/harness/gitness/app/services/metric"
|
"github.com/harness/gitness/app/services/metric"
|
||||||
"github.com/harness/gitness/app/services/notification"
|
"github.com/harness/gitness/app/services/notification"
|
||||||
"github.com/harness/gitness/app/services/notification/mailer"
|
"github.com/harness/gitness/app/services/notification/mailer"
|
||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
pullreqservice "github.com/harness/gitness/app/services/pullreq"
|
pullreqservice "github.com/harness/gitness/app/services/pullreq"
|
||||||
"github.com/harness/gitness/app/services/reposize"
|
reposervice "github.com/harness/gitness/app/services/repo"
|
||||||
"github.com/harness/gitness/app/services/settings"
|
"github.com/harness/gitness/app/services/settings"
|
||||||
"github.com/harness/gitness/app/services/trigger"
|
"github.com/harness/gitness/app/services/trigger"
|
||||||
"github.com/harness/gitness/app/services/usergroup"
|
"github.com/harness/gitness/app/services/usergroup"
|
||||||
@ -142,10 +142,11 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||||||
webhook.WireSet,
|
webhook.WireSet,
|
||||||
cliserver.ProvideTriggerConfig,
|
cliserver.ProvideTriggerConfig,
|
||||||
trigger.WireSet,
|
trigger.WireSet,
|
||||||
githook.WireSet,
|
githookCtrl.ExtenderWireSet,
|
||||||
ctrlgithook.WireSet,
|
githookCtrl.WireSet,
|
||||||
cliserver.ProvideLockConfig,
|
cliserver.ProvideLockConfig,
|
||||||
lock.WireSet,
|
lock.WireSet,
|
||||||
|
locker.WireSet,
|
||||||
cliserver.ProvidePubsubConfig,
|
cliserver.ProvidePubsubConfig,
|
||||||
pubsub.WireSet,
|
pubsub.WireSet,
|
||||||
cliserver.ProvideJobsConfig,
|
cliserver.ProvideJobsConfig,
|
||||||
@ -178,7 +179,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||||||
canceler.WireSet,
|
canceler.WireSet,
|
||||||
exporter.WireSet,
|
exporter.WireSet,
|
||||||
metric.WireSet,
|
metric.WireSet,
|
||||||
reposize.WireSet,
|
reposervice.WireSet,
|
||||||
cliserver.ProvideCodeOwnerConfig,
|
cliserver.ProvideCodeOwnerConfig,
|
||||||
codeowners.WireSet,
|
codeowners.WireSet,
|
||||||
cliserver.ProvideKeywordSearchConfig,
|
cliserver.ProvideKeywordSearchConfig,
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
check2 "github.com/harness/gitness/app/api/controller/check"
|
check2 "github.com/harness/gitness/app/api/controller/check"
|
||||||
"github.com/harness/gitness/app/api/controller/connector"
|
"github.com/harness/gitness/app/api/controller/connector"
|
||||||
"github.com/harness/gitness/app/api/controller/execution"
|
"github.com/harness/gitness/app/api/controller/execution"
|
||||||
githook2 "github.com/harness/gitness/app/api/controller/githook"
|
"github.com/harness/gitness/app/api/controller/githook"
|
||||||
keywordsearch2 "github.com/harness/gitness/app/api/controller/keywordsearch"
|
keywordsearch2 "github.com/harness/gitness/app/api/controller/keywordsearch"
|
||||||
"github.com/harness/gitness/app/api/controller/limiter"
|
"github.com/harness/gitness/app/api/controller/limiter"
|
||||||
logs2 "github.com/harness/gitness/app/api/controller/logs"
|
logs2 "github.com/harness/gitness/app/api/controller/logs"
|
||||||
@ -39,7 +39,6 @@ import (
|
|||||||
events4 "github.com/harness/gitness/app/events/git"
|
events4 "github.com/harness/gitness/app/events/git"
|
||||||
events3 "github.com/harness/gitness/app/events/pullreq"
|
events3 "github.com/harness/gitness/app/events/pullreq"
|
||||||
events2 "github.com/harness/gitness/app/events/repo"
|
events2 "github.com/harness/gitness/app/events/repo"
|
||||||
"github.com/harness/gitness/app/githook"
|
|
||||||
"github.com/harness/gitness/app/pipeline/canceler"
|
"github.com/harness/gitness/app/pipeline/canceler"
|
||||||
"github.com/harness/gitness/app/pipeline/commit"
|
"github.com/harness/gitness/app/pipeline/commit"
|
||||||
"github.com/harness/gitness/app/pipeline/converter"
|
"github.com/harness/gitness/app/pipeline/converter"
|
||||||
@ -58,12 +57,13 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/exporter"
|
"github.com/harness/gitness/app/services/exporter"
|
||||||
"github.com/harness/gitness/app/services/importer"
|
"github.com/harness/gitness/app/services/importer"
|
||||||
"github.com/harness/gitness/app/services/keywordsearch"
|
"github.com/harness/gitness/app/services/keywordsearch"
|
||||||
|
"github.com/harness/gitness/app/services/locker"
|
||||||
"github.com/harness/gitness/app/services/metric"
|
"github.com/harness/gitness/app/services/metric"
|
||||||
"github.com/harness/gitness/app/services/notification"
|
"github.com/harness/gitness/app/services/notification"
|
||||||
"github.com/harness/gitness/app/services/notification/mailer"
|
"github.com/harness/gitness/app/services/notification/mailer"
|
||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
"github.com/harness/gitness/app/services/pullreq"
|
"github.com/harness/gitness/app/services/pullreq"
|
||||||
"github.com/harness/gitness/app/services/reposize"
|
repo2 "github.com/harness/gitness/app/services/repo"
|
||||||
"github.com/harness/gitness/app/services/settings"
|
"github.com/harness/gitness/app/services/settings"
|
||||||
trigger2 "github.com/harness/gitness/app/services/trigger"
|
trigger2 "github.com/harness/gitness/app/services/trigger"
|
||||||
"github.com/harness/gitness/app/services/usergroup"
|
"github.com/harness/gitness/app/services/usergroup"
|
||||||
@ -192,9 +192,10 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
lockerLocker := locker.ProvideLocker(mutexManager)
|
||||||
repoIdentifier := check.ProvideRepoIdentifierCheck()
|
repoIdentifier := check.ProvideRepoIdentifierCheck()
|
||||||
repoCheck := repo.ProvideRepoCheck()
|
repoCheck := repo.ProvideRepoCheck()
|
||||||
repoController := repo.ProvideController(config, transactor, provider, authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, settingsService, principalInfoCache, protectionManager, gitInterface, repository, codeownersService, reporter, indexer, resourceLimiter, mutexManager, repoIdentifier, repoCheck)
|
repoController := repo.ProvideController(config, transactor, provider, authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, settingsService, principalInfoCache, protectionManager, gitInterface, repository, codeownersService, reporter, indexer, resourceLimiter, lockerLocker, mutexManager, repoIdentifier, repoCheck)
|
||||||
reposettingsController := reposettings.ProvideController(authorizer, repoStore, settingsService)
|
reposettingsController := reposettings.ProvideController(authorizer, repoStore, settingsService)
|
||||||
executionStore := database.ProvideExecutionStore(db)
|
executionStore := database.ProvideExecutionStore(db)
|
||||||
checkStore := database.ProvideCheckStore(db, principalInfoCache)
|
checkStore := database.ProvideCheckStore(db, principalInfoCache)
|
||||||
@ -254,7 +255,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pullreqController := pullreq2.ProvideController(transactor, provider, authorizer, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, pullReqFileViewStore, membershipStore, checkStore, gitInterface, eventsReporter, mutexManager, migrator, pullreqService, protectionManager, streamer, codeownersService)
|
pullreqController := pullreq2.ProvideController(transactor, provider, authorizer, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, pullReqFileViewStore, membershipStore, checkStore, gitInterface, eventsReporter, migrator, pullreqService, protectionManager, streamer, codeownersService, lockerLocker)
|
||||||
webhookConfig := server.ProvideWebhookConfig(config)
|
webhookConfig := server.ProvideWebhookConfig(config)
|
||||||
webhookStore := database.ProvideWebhookStore(db)
|
webhookStore := database.ProvideWebhookStore(db)
|
||||||
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)
|
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)
|
||||||
@ -267,19 +268,19 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
preReceiveExtender, err := githook2.ProvidePreReceiveExtender()
|
preReceiveExtender, err := githook.ProvidePreReceiveExtender()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
updateExtender, err := githook2.ProvideUpdateExtender()
|
updateExtender, err := githook.ProvideUpdateExtender()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
postReceiveExtender, err := githook2.ProvidePostReceiveExtender()
|
postReceiveExtender, err := githook.ProvidePostReceiveExtender()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
githookController := githook.ProvideController(authorizer, principalStore, repoStore, reporter2, gitInterface, pullReqStore, provider, protectionManager, clientFactory, resourceLimiter, settingsService, preReceiveExtender, updateExtender, postReceiveExtender)
|
githookController := githook.ProvideController(authorizer, principalStore, repoStore, reporter2, reporter, gitInterface, pullReqStore, provider, protectionManager, clientFactory, resourceLimiter, settingsService, preReceiveExtender, updateExtender, postReceiveExtender)
|
||||||
serviceaccountController := serviceaccount.NewController(principalUID, authorizer, principalStore, spaceStore, repoStore, tokenStore)
|
serviceaccountController := serviceaccount.NewController(principalUID, authorizer, principalStore, spaceStore, repoStore, tokenStore)
|
||||||
principalController := principal.ProvideController(principalStore)
|
principalController := principal.ProvideController(principalStore)
|
||||||
v := check2.ProvideCheckSanitizers()
|
v := check2.ProvideCheckSanitizers()
|
||||||
@ -319,7 +320,15 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
calculator, err := reposize.ProvideCalculator(config, gitInterface, repoStore, jobScheduler, executor)
|
sizeCalculator, err := repo2.ProvideCalculator(config, gitInterface, repoStore, jobScheduler, executor)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
readerFactory2, err := events2.ProvideReaderFactory(eventsSystem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
repoService, err := repo2.ProvideService(ctx, config, reporter, readerFactory2, repoStore, provider, gitInterface, lockerLocker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -336,11 +345,11 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
keywordsearchConfig := server.ProvideKeywordSearchConfig(config)
|
keywordsearchConfig := server.ProvideKeywordSearchConfig(config)
|
||||||
keywordsearchService, err := keywordsearch.ProvideService(ctx, keywordsearchConfig, readerFactory, repoStore, indexer)
|
keywordsearchService, err := keywordsearch.ProvideService(ctx, keywordsearchConfig, readerFactory, readerFactory2, repoStore, indexer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
servicesServices := services.ProvideServices(webhookService, pullreqService, triggerService, jobScheduler, collector, calculator, cleanupService, notificationService, keywordsearchService)
|
servicesServices := services.ProvideServices(webhookService, pullreqService, triggerService, jobScheduler, collector, sizeCalculator, repoService, cleanupService, notificationService, keywordsearchService)
|
||||||
serverSystem := server.NewSystem(bootstrapBootstrap, serverServer, poller, resolverManager, servicesServices)
|
serverSystem := server.NewSystem(bootstrapBootstrap, serverServer, poller, resolverManager, servicesServices)
|
||||||
return serverSystem, nil
|
return serverSystem, nil
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ type Repository struct {
|
|||||||
NumMergedPulls int `json:"num_merged_pulls"`
|
NumMergedPulls int `json:"num_merged_pulls"`
|
||||||
|
|
||||||
Importing bool `json:"importing"`
|
Importing bool `json:"importing"`
|
||||||
|
IsEmpty bool `json:"is_empty,omitempty"`
|
||||||
|
|
||||||
// git urls
|
// git urls
|
||||||
GitURL string `json:"git_url"`
|
GitURL string `json:"git_url"`
|
||||||
|
Loading…
Reference in New Issue
Block a user