mirror of
https://github.com/harness/drone.git
synced 2025-05-04 20:23:25 +08:00
Merge branch 'main' into add-pipeline-editor
This commit is contained in:
commit
94e4cca4d6
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/harness/gitness/events"
|
"github.com/harness/gitness/events"
|
||||||
"github.com/harness/gitness/gitrpc"
|
"github.com/harness/gitness/gitrpc"
|
||||||
"github.com/harness/gitness/gitrpc/server"
|
"github.com/harness/gitness/gitrpc/server"
|
||||||
|
"github.com/harness/gitness/internal/services/trigger"
|
||||||
"github.com/harness/gitness/internal/services/webhook"
|
"github.com/harness/gitness/internal/services/webhook"
|
||||||
"github.com/harness/gitness/lock"
|
"github.com/harness/gitness/lock"
|
||||||
"github.com/harness/gitness/store/database"
|
"github.com/harness/gitness/store/database"
|
||||||
@ -147,23 +148,26 @@ func ProvideEventsConfig() (events.Config, error) {
|
|||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvideWebhookConfig loads the webhook config from the environment.
|
// ProvideWebhookConfig loads the webhook service config from the main config.
|
||||||
// It backfills certain config elements if required.
|
func ProvideWebhookConfig(config *types.Config) webhook.Config {
|
||||||
func ProvideWebhookConfig() (webhook.Config, error) {
|
return webhook.Config{
|
||||||
config := webhook.Config{}
|
UserAgentIdentity: config.Webhook.UserAgentIdentity,
|
||||||
err := envconfig.Process("", &config)
|
HeaderIdentity: config.Webhook.HeaderIdentity,
|
||||||
if err != nil {
|
EventReaderName: config.InstanceID,
|
||||||
return webhook.Config{}, fmt.Errorf("failed to load events config: %w", err)
|
Concurrency: config.Webhook.Concurrency,
|
||||||
|
MaxRetries: config.Webhook.MaxRetries,
|
||||||
|
AllowPrivateNetwork: config.Webhook.AllowPrivateNetwork,
|
||||||
|
AllowLoopback: config.Webhook.AllowLoopback,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if config.EventReaderName == "" {
|
// ProvideTriggerConfig loads the trigger service config from the main config.
|
||||||
config.EventReaderName, err = getSanitizedMachineName()
|
func ProvideTriggerConfig(config *types.Config) trigger.Config {
|
||||||
if err != nil {
|
return trigger.Config{
|
||||||
return webhook.Config{}, fmt.Errorf("failed to get sanitized machine name: %w", err)
|
EventReaderName: config.InstanceID,
|
||||||
}
|
Concurrency: config.Webhook.Concurrency,
|
||||||
|
MaxRetries: config.Webhook.MaxRetries,
|
||||||
}
|
}
|
||||||
|
|
||||||
return config, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvideLockConfig generates the `lock` package config from the gitness config.
|
// ProvideLockConfig generates the `lock` package config from the gitness config.
|
||||||
|
@ -32,7 +32,7 @@ import (
|
|||||||
"github.com/harness/gitness/internal/api/controller/space"
|
"github.com/harness/gitness/internal/api/controller/space"
|
||||||
"github.com/harness/gitness/internal/api/controller/system"
|
"github.com/harness/gitness/internal/api/controller/system"
|
||||||
"github.com/harness/gitness/internal/api/controller/template"
|
"github.com/harness/gitness/internal/api/controller/template"
|
||||||
"github.com/harness/gitness/internal/api/controller/trigger"
|
controllertrigger "github.com/harness/gitness/internal/api/controller/trigger"
|
||||||
"github.com/harness/gitness/internal/api/controller/user"
|
"github.com/harness/gitness/internal/api/controller/user"
|
||||||
controllerwebhook "github.com/harness/gitness/internal/api/controller/webhook"
|
controllerwebhook "github.com/harness/gitness/internal/api/controller/webhook"
|
||||||
"github.com/harness/gitness/internal/auth/authn"
|
"github.com/harness/gitness/internal/auth/authn"
|
||||||
@ -41,6 +41,7 @@ import (
|
|||||||
gitevents "github.com/harness/gitness/internal/events/git"
|
gitevents "github.com/harness/gitness/internal/events/git"
|
||||||
pullreqevents "github.com/harness/gitness/internal/events/pullreq"
|
pullreqevents "github.com/harness/gitness/internal/events/pullreq"
|
||||||
"github.com/harness/gitness/internal/pipeline/commit"
|
"github.com/harness/gitness/internal/pipeline/commit"
|
||||||
|
eventsstream "github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/pipeline/file"
|
"github.com/harness/gitness/internal/pipeline/file"
|
||||||
"github.com/harness/gitness/internal/pipeline/manager"
|
"github.com/harness/gitness/internal/pipeline/manager"
|
||||||
"github.com/harness/gitness/internal/pipeline/runner"
|
"github.com/harness/gitness/internal/pipeline/runner"
|
||||||
@ -50,8 +51,10 @@ import (
|
|||||||
"github.com/harness/gitness/internal/server"
|
"github.com/harness/gitness/internal/server"
|
||||||
"github.com/harness/gitness/internal/services"
|
"github.com/harness/gitness/internal/services"
|
||||||
"github.com/harness/gitness/internal/services/codecomments"
|
"github.com/harness/gitness/internal/services/codecomments"
|
||||||
|
"github.com/harness/gitness/internal/services/importer"
|
||||||
"github.com/harness/gitness/internal/services/job"
|
"github.com/harness/gitness/internal/services/job"
|
||||||
pullreqservice "github.com/harness/gitness/internal/services/pullreq"
|
pullreqservice "github.com/harness/gitness/internal/services/pullreq"
|
||||||
|
"github.com/harness/gitness/internal/services/trigger"
|
||||||
"github.com/harness/gitness/internal/services/webhook"
|
"github.com/harness/gitness/internal/services/webhook"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/internal/store/cache"
|
"github.com/harness/gitness/internal/store/cache"
|
||||||
@ -104,6 +107,8 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||||||
events.WireSet,
|
events.WireSet,
|
||||||
cliserver.ProvideWebhookConfig,
|
cliserver.ProvideWebhookConfig,
|
||||||
webhook.WireSet,
|
webhook.WireSet,
|
||||||
|
cliserver.ProvideTriggerConfig,
|
||||||
|
trigger.WireSet,
|
||||||
githook.WireSet,
|
githook.WireSet,
|
||||||
cliserver.ProvideLockConfig,
|
cliserver.ProvideLockConfig,
|
||||||
lock.WireSet,
|
lock.WireSet,
|
||||||
@ -124,10 +129,12 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||||||
triggerer.WireSet,
|
triggerer.WireSet,
|
||||||
file.WireSet,
|
file.WireSet,
|
||||||
runner.WireSet,
|
runner.WireSet,
|
||||||
|
eventsstream.WireSet,
|
||||||
scheduler.WireSet,
|
scheduler.WireSet,
|
||||||
commit.WireSet,
|
commit.WireSet,
|
||||||
trigger.WireSet,
|
controllertrigger.WireSet,
|
||||||
plugin.WireSet,
|
plugin.WireSet,
|
||||||
|
importer.WireSet,
|
||||||
)
|
)
|
||||||
return &cliserver.System{}, nil
|
return &cliserver.System{}, nil
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/harness/gitness/cli/server"
|
"github.com/harness/gitness/cli/server"
|
||||||
"github.com/harness/gitness/encrypt"
|
"github.com/harness/gitness/encrypt"
|
||||||
"github.com/harness/gitness/events"
|
events2 "github.com/harness/gitness/events"
|
||||||
"github.com/harness/gitness/gitrpc"
|
"github.com/harness/gitness/gitrpc"
|
||||||
server3 "github.com/harness/gitness/gitrpc/server"
|
server3 "github.com/harness/gitness/gitrpc/server"
|
||||||
"github.com/harness/gitness/gitrpc/server/cron"
|
"github.com/harness/gitness/gitrpc/server/cron"
|
||||||
@ -37,9 +36,10 @@ import (
|
|||||||
"github.com/harness/gitness/internal/auth/authn"
|
"github.com/harness/gitness/internal/auth/authn"
|
||||||
"github.com/harness/gitness/internal/auth/authz"
|
"github.com/harness/gitness/internal/auth/authz"
|
||||||
"github.com/harness/gitness/internal/bootstrap"
|
"github.com/harness/gitness/internal/bootstrap"
|
||||||
events3 "github.com/harness/gitness/internal/events/git"
|
events4 "github.com/harness/gitness/internal/events/git"
|
||||||
events2 "github.com/harness/gitness/internal/events/pullreq"
|
events3 "github.com/harness/gitness/internal/events/pullreq"
|
||||||
"github.com/harness/gitness/internal/pipeline/commit"
|
"github.com/harness/gitness/internal/pipeline/commit"
|
||||||
|
"github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/pipeline/file"
|
"github.com/harness/gitness/internal/pipeline/file"
|
||||||
"github.com/harness/gitness/internal/pipeline/manager"
|
"github.com/harness/gitness/internal/pipeline/manager"
|
||||||
"github.com/harness/gitness/internal/pipeline/runner"
|
"github.com/harness/gitness/internal/pipeline/runner"
|
||||||
@ -49,8 +49,10 @@ import (
|
|||||||
server2 "github.com/harness/gitness/internal/server"
|
server2 "github.com/harness/gitness/internal/server"
|
||||||
"github.com/harness/gitness/internal/services"
|
"github.com/harness/gitness/internal/services"
|
||||||
"github.com/harness/gitness/internal/services/codecomments"
|
"github.com/harness/gitness/internal/services/codecomments"
|
||||||
|
"github.com/harness/gitness/internal/services/importer"
|
||||||
"github.com/harness/gitness/internal/services/job"
|
"github.com/harness/gitness/internal/services/job"
|
||||||
pullreq2 "github.com/harness/gitness/internal/services/pullreq"
|
pullreq2 "github.com/harness/gitness/internal/services/pullreq"
|
||||||
|
trigger2 "github.com/harness/gitness/internal/services/trigger"
|
||||||
"github.com/harness/gitness/internal/services/webhook"
|
"github.com/harness/gitness/internal/services/webhook"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/internal/store/cache"
|
"github.com/harness/gitness/internal/store/cache"
|
||||||
@ -104,17 +106,29 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
repoController := repo.ProvideController(config, db, provider, pathUID, authorizer, pathStore, repoStore, spaceStore, pipelineStore, principalStore, gitrpcInterface)
|
jobStore := database.ProvideJobStore(db)
|
||||||
executionStore := database.ProvideExecutionStore(db)
|
pubsubConfig := pubsub.ProvideConfig(config)
|
||||||
commitService := commit.ProvideCommitService(gitrpcInterface)
|
|
||||||
stageStore := database.ProvideStageStore(db)
|
|
||||||
fileService := file.ProvideFileService(gitrpcInterface)
|
|
||||||
lockConfig := server.ProvideLockConfig(config)
|
|
||||||
universalClient, err := server.ProvideRedis(config)
|
universalClient, err := server.ProvideRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
pubSub := pubsub.ProvidePubSub(pubsubConfig, universalClient)
|
||||||
|
executor := job.ProvideExecutor(jobStore, pubSub)
|
||||||
|
lockConfig := server.ProvideLockConfig(config)
|
||||||
mutexManager := lock.ProvideMutexManager(lockConfig, universalClient)
|
mutexManager := lock.ProvideMutexManager(lockConfig, universalClient)
|
||||||
|
jobScheduler, err := job.ProvideScheduler(jobStore, executor, mutexManager, pubSub, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
repository, err := importer.ProvideRepoImporter(provider, gitrpcInterface, repoStore, jobScheduler, executor)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
repoController := repo.ProvideController(config, db, provider, pathUID, authorizer, pathStore, repoStore, spaceStore, pipelineStore, principalStore, gitrpcInterface, repository)
|
||||||
|
executionStore := database.ProvideExecutionStore(db)
|
||||||
|
commitService := commit.ProvideCommitService(gitrpcInterface)
|
||||||
|
stageStore := database.ProvideStageStore(db)
|
||||||
|
fileService := file.ProvideFileService(gitrpcInterface)
|
||||||
schedulerScheduler, err := scheduler.ProvideScheduler(stageStore, mutexManager)
|
schedulerScheduler, err := scheduler.ProvideScheduler(stageStore, mutexManager)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -125,10 +139,11 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
logStore := logs.ProvideLogStore(db, config)
|
logStore := logs.ProvideLogStore(db, config)
|
||||||
logStream := livelog.ProvideLogStream(config)
|
logStream := livelog.ProvideLogStream(config)
|
||||||
logsController := logs2.ProvideController(db, authorizer, executionStore, repoStore, pipelineStore, stageStore, stepStore, logStore, logStream)
|
logsController := logs2.ProvideController(db, authorizer, executionStore, repoStore, pipelineStore, stageStore, stepStore, logStore, logStream)
|
||||||
|
eventsStreamer := events.ProvideEventsStreaming(pubSub)
|
||||||
secretStore := database.ProvideSecretStore(db)
|
secretStore := database.ProvideSecretStore(db)
|
||||||
connectorStore := database.ProvideConnectorStore(db)
|
connectorStore := database.ProvideConnectorStore(db)
|
||||||
templateStore := database.ProvideTemplateStore(db)
|
templateStore := database.ProvideTemplateStore(db)
|
||||||
spaceController := space.ProvideController(db, provider, pathUID, authorizer, pathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, repoController, membershipStore)
|
spaceController := space.ProvideController(db, provider, eventsStreamer, pathUID, authorizer, pathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, repoController, membershipStore)
|
||||||
pipelineController := pipeline.ProvideController(db, pathUID, pathStore, repoStore, authorizer, pipelineStore)
|
pipelineController := pipeline.ProvideController(db, pathUID, pathStore, repoStore, authorizer, pipelineStore)
|
||||||
encrypter, err := encrypt.ProvideEncrypter(config)
|
encrypter, err := encrypt.ProvideEncrypter(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -150,27 +165,24 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
eventsSystem, err := events.ProvideSystem(eventsConfig, universalClient)
|
eventsSystem, err := events2.ProvideSystem(eventsConfig, universalClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
reporter, err := events2.ProvideReporter(eventsSystem)
|
reporter, err := events3.ProvideReporter(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
migrator := codecomments.ProvideMigrator(gitrpcInterface)
|
migrator := codecomments.ProvideMigrator(gitrpcInterface)
|
||||||
pullreqController := pullreq.ProvideController(db, provider, authorizer, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, gitrpcInterface, reporter, mutexManager, migrator)
|
pullreqController := pullreq.ProvideController(db, provider, authorizer, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, gitrpcInterface, reporter, mutexManager, migrator)
|
||||||
webhookConfig, err := server.ProvideWebhookConfig()
|
webhookConfig := server.ProvideWebhookConfig(config)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
webhookStore := database.ProvideWebhookStore(db)
|
webhookStore := database.ProvideWebhookStore(db)
|
||||||
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)
|
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)
|
||||||
readerFactory, err := events3.ProvideReaderFactory(eventsSystem)
|
readerFactory, err := events4.ProvideReaderFactory(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
eventsReaderFactory, err := events2.ProvideReaderFactory(eventsSystem)
|
eventsReaderFactory, err := events3.ProvideReaderFactory(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -179,7 +191,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
webhookController := webhook2.ProvideController(webhookConfig, db, authorizer, webhookStore, webhookExecutionStore, repoStore, webhookService)
|
webhookController := webhook2.ProvideController(webhookConfig, db, authorizer, webhookStore, webhookExecutionStore, repoStore, webhookService)
|
||||||
eventsReporter, err := events3.ProvideReporter(eventsSystem)
|
eventsReporter, err := events4.ProvideReporter(eventsSystem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -194,7 +206,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
webHandler := router.ProvideWebHandler(config)
|
webHandler := router.ProvideWebHandler(config)
|
||||||
routerRouter := router.ProvideRouter(config, apiHandler, gitHandler, webHandler)
|
routerRouter := router.ProvideRouter(config, apiHandler, gitHandler, webHandler)
|
||||||
serverServer := server2.ProvideServer(config, routerRouter)
|
serverServer := server2.ProvideServer(config, routerRouter)
|
||||||
executionManager := manager.ProvideExecutionManager(config, executionStore, pipelineStore, provider, fileService, logStore, logStream, repoStore, schedulerScheduler, secretStore, stageStore, stepStore, principalStore)
|
executionManager := manager.ProvideExecutionManager(config, executionStore, pipelineStore, provider, eventsStreamer, fileService, logStore, logStream, repoStore, schedulerScheduler, secretStore, stageStore, stepStore, principalStore)
|
||||||
client := manager.ProvideExecutionClient(executionManager, config)
|
client := manager.ProvideExecutionClient(executionManager, config)
|
||||||
runtimeRunner, err := runner.ProvideExecutionRunner(config, client, executionManager)
|
runtimeRunner, err := runner.ProvideExecutionRunner(config, client, executionManager)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -218,19 +230,16 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
cronManager := cron.ProvideManager(serverConfig)
|
cronManager := cron.ProvideManager(serverConfig)
|
||||||
repoGitInfoView := database.ProvideRepoGitInfoView(db)
|
repoGitInfoView := database.ProvideRepoGitInfoView(db)
|
||||||
repoGitInfoCache := cache.ProvideRepoGitInfoCache(repoGitInfoView)
|
repoGitInfoCache := cache.ProvideRepoGitInfoCache(repoGitInfoView)
|
||||||
pubsubConfig := pubsub.ProvideConfig(config)
|
|
||||||
pubSub := pubsub.ProvidePubSub(pubsubConfig, universalClient)
|
|
||||||
pullreqService, err := pullreq2.ProvideService(ctx, config, readerFactory, eventsReaderFactory, reporter, gitrpcInterface, db, repoGitInfoCache, repoStore, pullReqStore, pullReqActivityStore, codeCommentView, migrator, pubSub, provider)
|
pullreqService, err := pullreq2.ProvideService(ctx, config, readerFactory, eventsReaderFactory, reporter, gitrpcInterface, db, repoGitInfoCache, repoStore, pullReqStore, pullReqActivityStore, codeCommentView, migrator, pubSub, provider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
jobStore := database.ProvideJobStore(db)
|
triggerConfig := server.ProvideTriggerConfig(config)
|
||||||
executor := job.ProvideExecutor(jobStore, pubSub)
|
triggerService, err := trigger2.ProvideService(ctx, triggerConfig, readerFactory, eventsReaderFactory)
|
||||||
jobScheduler, err := job.ProvideScheduler(jobStore, executor, mutexManager, pubSub, config)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
servicesServices := services.ProvideServices(webhookService, pullreqService, executor, jobScheduler)
|
servicesServices := services.ProvideServices(webhookService, pullreqService, triggerService, jobScheduler)
|
||||||
serverSystem := server.NewSystem(bootstrapBootstrap, serverServer, poller, grpcServer, cronManager, servicesServices)
|
serverSystem := server.NewSystem(bootstrapBootstrap, serverServer, poller, grpcServer, cronManager, servicesServices)
|
||||||
return serverSystem, nil
|
return serverSystem, nil
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ func (f *ReaderFactory[R]) Launch(ctx context.Context,
|
|||||||
|
|
||||||
// setup ctx with copied logger that has extra fields set
|
// setup ctx with copied logger that has extra fields set
|
||||||
log := log.Ctx(ctx).With().
|
log := log.Ctx(ctx).With().
|
||||||
Str("events_category", f.category).
|
Str("events.category", f.category).
|
||||||
Str("events_group_name", groupName).
|
Str("events.group_name", groupName).
|
||||||
Str("events_reader_name", readerName).
|
Str("events.reader_name", readerName).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
// create new stream consumer using factory method
|
// create new stream consumer using factory method
|
||||||
@ -191,8 +191,8 @@ func ReaderRegisterEvent[T interface{}](reader *GenericReader,
|
|||||||
|
|
||||||
// update ctx with event type for proper logging
|
// update ctx with event type for proper logging
|
||||||
log := log.Ctx(ctx).With().
|
log := log.Ctx(ctx).With().
|
||||||
Str("events_type", string(eventType)).
|
Str("events.type", string(eventType)).
|
||||||
Str("events_id", event.ID).
|
Str("events.id", event.ID).
|
||||||
Logger()
|
Logger()
|
||||||
ctx = log.WithContext(ctx)
|
ctx = log.WithContext(ctx)
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ type Interface interface {
|
|||||||
// not update of an exiting one, set the zero ref as the OldValue.
|
// not update of an exiting one, set the zero ref as the OldValue.
|
||||||
UpdateRef(ctx context.Context, params UpdateRefParams) error
|
UpdateRef(ctx context.Context, params UpdateRefParams) error
|
||||||
|
|
||||||
|
SyncRepository(ctx context.Context, params *SyncRepositoryParams) (*SyncRepositoryOutput, error)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Commits service
|
* Commits service
|
||||||
*/
|
*/
|
||||||
|
@ -354,7 +354,9 @@ func (s RepositoryService) SyncRepository(
|
|||||||
return nil, processGitErrorf(err, "failed to set default branch of repo")
|
return nil, processGitErrorf(err, "failed to set default branch of repo")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &rpc.SyncRepositoryResponse{}, nil
|
return &rpc.SyncRepositoryResponse{
|
||||||
|
DefaultBranch: defaultBranch,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s RepositoryService) HashRepository(
|
func (s RepositoryService) HashRepository(
|
||||||
|
@ -203,7 +203,9 @@ message SyncRepositoryRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SyncRepositoryResponse {
|
message SyncRepositoryResponse {
|
||||||
|
string default_branch = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HashType {
|
enum HashType {
|
||||||
HashTypeSHA256 = 0;
|
HashTypeSHA256 = 0;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ type SyncRepositoryParams struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SyncRepositoryOutput struct {
|
type SyncRepositoryOutput struct {
|
||||||
|
DefaultBranch string
|
||||||
}
|
}
|
||||||
|
|
||||||
type HashRepositoryParams struct {
|
type HashRepositoryParams struct {
|
||||||
@ -164,7 +165,7 @@ func (c *Client) DeleteRepository(ctx context.Context, params *DeleteRepositoryP
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) SyncRepository(ctx context.Context, params *SyncRepositoryParams) (*SyncRepositoryOutput, error) {
|
func (c *Client) SyncRepository(ctx context.Context, params *SyncRepositoryParams) (*SyncRepositoryOutput, error) {
|
||||||
_, err := c.repoService.SyncRepository(ctx, &rpc.SyncRepositoryRequest{
|
result, err := c.repoService.SyncRepository(ctx, &rpc.SyncRepositoryRequest{
|
||||||
Base: mapToRPCWriteRequest(params.WriteParams),
|
Base: mapToRPCWriteRequest(params.WriteParams),
|
||||||
Source: params.Source,
|
Source: params.Source,
|
||||||
CreateIfNotExists: params.CreateIfNotExists,
|
CreateIfNotExists: params.CreateIfNotExists,
|
||||||
@ -173,7 +174,9 @@ func (c *Client) SyncRepository(ctx context.Context, params *SyncRepositoryParam
|
|||||||
return nil, processRPCErrorf(err, "failed to sync repository on server to match provided source")
|
return nil, processRPCErrorf(err, "failed to sync repository on server to match provided source")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &SyncRepositoryOutput{}, nil
|
return &SyncRepositoryOutput{
|
||||||
|
DefaultBranch: result.DefaultBranch,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) HashRepository(ctx context.Context, params *HashRepositoryParams) (*HashRepositoryOutput, error) {
|
func (c *Client) HashRepository(ctx context.Context, params *HashRepositoryParams) (*HashRepositoryOutput, error) {
|
||||||
|
@ -1987,6 +1987,8 @@ type SyncRepositoryResponse struct {
|
|||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
DefaultBranch string `protobuf:"bytes,1,opt,name=default_branch,json=defaultBranch,proto3" json:"default_branch,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SyncRepositoryResponse) Reset() {
|
func (x *SyncRepositoryResponse) Reset() {
|
||||||
@ -2021,6 +2023,13 @@ func (*SyncRepositoryResponse) Descriptor() ([]byte, []int) {
|
|||||||
return file_repo_proto_rawDescGZIP(), []int{29}
|
return file_repo_proto_rawDescGZIP(), []int{29}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *SyncRepositoryResponse) GetDefaultBranch() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.DefaultBranch
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type HashRepositoryRequest struct {
|
type HashRepositoryRequest struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@ -2438,114 +2447,117 @@ var file_repo_proto_rawDesc = []byte{
|
|||||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2f, 0x0a,
|
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2f, 0x0a,
|
||||||
0x14, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65,
|
0x14, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65,
|
||||||
0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x72, 0x65,
|
0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x72, 0x65,
|
||||||
0x61, 0x74, 0x65, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x18,
|
0x61, 0x74, 0x65, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x3f,
|
||||||
0x0a, 0x16, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79,
|
0x0a, 0x16, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79,
|
||||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xae, 0x01, 0x0a, 0x15, 0x48, 0x61, 0x73,
|
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61,
|
||||||
0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
|
0x75, 0x6c, 0x74, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||||
|
0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x22,
|
||||||
|
0xae, 0x01, 0x0a, 0x15, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f,
|
||||||
|
0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x62, 0x61, 0x73,
|
||||||
|
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65,
|
||||||
|
0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x12,
|
||||||
|
0x2a, 0x0a, 0x09, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||||
|
0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70,
|
||||||
|
0x65, 0x52, 0x08, 0x68, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x61,
|
||||||
|
0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||||
|
0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x61, 0x73, 0x68,
|
||||||
|
0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52,
|
||||||
|
0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65,
|
||||||
|
0x22, 0x2c, 0x0a, 0x16, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f,
|
||||||
|
0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61,
|
||||||
|
0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x60,
|
||||||
|
0x0a, 0x10, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||||
0x32, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65,
|
0x32, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
0x73, 0x74, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x09, 0x68, 0x61, 0x73, 0x68,
|
0x73, 0x74, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x31,
|
||||||
0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x72, 0x70,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x66, 0x31, 0x12, 0x12, 0x0a, 0x04,
|
||||||
0x63, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x68, 0x61, 0x73, 0x68,
|
0x72, 0x65, 0x66, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x66, 0x32,
|
||||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74,
|
0x22, 0x39, 0x0a, 0x11, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73,
|
||||||
0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18,
|
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x62,
|
||||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
|
0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d,
|
||||||
0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67,
|
0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, 0x2a, 0x52, 0x0a, 0x0c, 0x54,
|
||||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x48, 0x61, 0x73,
|
0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54,
|
||||||
0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x54, 0x72, 0x65, 0x65, 0x10,
|
||||||
0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70,
|
||||||
0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x60, 0x0a, 0x10, 0x4d, 0x65, 0x72, 0x67, 0x65,
|
0x65, 0x42, 0x6c, 0x6f, 0x62, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x72, 0x65, 0x65, 0x4e,
|
||||||
0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x62,
|
0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x10, 0x02, 0x2a,
|
||||||
0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
0x81, 0x01, 0x0a, 0x0c, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65,
|
||||||
0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x62, 0x61, 0x73,
|
0x12, 0x14, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65,
|
||||||
0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
0x46, 0x69, 0x6c, 0x65, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f,
|
||||||
0x04, 0x72, 0x65, 0x66, 0x31, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x32, 0x18, 0x03, 0x20,
|
0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x10, 0x01, 0x12,
|
||||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x66, 0x32, 0x22, 0x39, 0x0a, 0x11, 0x4d, 0x65, 0x72,
|
0x14, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x45,
|
||||||
0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24,
|
0x78, 0x65, 0x63, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64,
|
||||||
0x0a, 0x0e, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x61,
|
0x65, 0x4d, 0x6f, 0x64, 0x65, 0x54, 0x72, 0x65, 0x65, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x54,
|
||||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73,
|
0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69,
|
||||||
0x65, 0x53, 0x68, 0x61, 0x2a, 0x52, 0x0a, 0x0c, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
0x74, 0x10, 0x04, 0x2a, 0x1e, 0x0a, 0x08, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12,
|
||||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
0x12, 0x0a, 0x0e, 0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x53, 0x48, 0x41, 0x32, 0x35,
|
||||||
0x54, 0x79, 0x70, 0x65, 0x54, 0x72, 0x65, 0x65, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x72,
|
0x36, 0x10, 0x00, 0x2a, 0x31, 0x0a, 0x13, 0x48, 0x61, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65,
|
||||||
0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x10, 0x01,
|
0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x48, 0x61,
|
||||||
0x12, 0x16, 0x0a, 0x12, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65,
|
0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70,
|
||||||
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x10, 0x02, 0x2a, 0x81, 0x01, 0x0a, 0x0c, 0x54, 0x72, 0x65,
|
0x65, 0x58, 0x4f, 0x52, 0x10, 0x00, 0x32, 0xb8, 0x07, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x73,
|
||||||
0x65, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x72, 0x65,
|
0x69, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x51, 0x0a, 0x10,
|
||||||
0x65, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x10, 0x00, 0x12,
|
|
||||||
0x17, 0x0a, 0x13, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x53,
|
|
||||||
0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x72, 0x65, 0x65,
|
|
||||||
0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x45, 0x78, 0x65, 0x63, 0x10, 0x02, 0x12, 0x14,
|
|
||||||
0x0a, 0x10, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x54, 0x72,
|
|
||||||
0x65, 0x65, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
|
||||||
0x4d, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x10, 0x04, 0x2a, 0x1e, 0x0a, 0x08,
|
|
||||||
0x48, 0x61, 0x73, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x61, 0x73, 0x68,
|
|
||||||
0x54, 0x79, 0x70, 0x65, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x00, 0x2a, 0x31, 0x0a, 0x13,
|
|
||||||
0x48, 0x61, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54,
|
|
||||||
0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x48, 0x61, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65,
|
|
||||||
0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x58, 0x4f, 0x52, 0x10, 0x00, 0x32,
|
|
||||||
0xb8, 0x07, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65,
|
|
||||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x51, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52,
|
|
||||||
0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
|
||||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79,
|
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79,
|
||||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x72,
|
0x12, 0x1c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70,
|
||||||
0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65,
|
0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d,
|
||||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x40, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54,
|
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73,
|
||||||
0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65,
|
0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12,
|
||||||
0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x40, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x17,
|
||||||
0x1a, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f,
|
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
||||||
0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0d, 0x4c, 0x69,
|
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65,
|
||||||
0x73, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x72, 0x70,
|
0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52,
|
0x65, 0x12, 0x48, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64,
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73,
|
0x65, 0x73, 0x12, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x65,
|
||||||
0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
|
||||||
0x73, 0x65, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x0c, 0x50, 0x61, 0x74, 0x68, 0x73, 0x44, 0x65, 0x74,
|
0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
||||||
0x61, 0x69, 0x6c, 0x73, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x73,
|
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x0c, 0x50,
|
||||||
0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19,
|
0x61, 0x74, 0x68, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x18, 0x2e, 0x72, 0x70,
|
||||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
|
0x63, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65,
|
||||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x47, 0x65, 0x74,
|
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x68,
|
||||||
0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||||
0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75,
|
0x12, 0x43, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
|
||||||
0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62,
|
0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64,
|
||||||
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36,
|
0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63,
|
||||||
0x0a, 0x07, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73,
|
||||||
0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14,
|
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62,
|
||||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70,
|
0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f,
|
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x42,
|
||||||
0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74,
|
0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x42, 0x0a,
|
||||||
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
|
0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x17, 0x2e, 0x72,
|
||||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73,
|
0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65,
|
||||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x3a, 0x0a, 0x09, 0x47, 0x65,
|
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74,
|
||||||
0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65,
|
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30,
|
||||||
0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
|
0x01, 0x12, 0x3a, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x15,
|
||||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65,
|
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65,
|
||||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d,
|
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43,
|
||||||
0x6d, 0x69, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x20,
|
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a,
|
||||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69,
|
0x14, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67,
|
||||||
0x76, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43,
|
||||||
0x1a, 0x21, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
|
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x65, 0x73,
|
||||||
0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65,
|
||||||
0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70,
|
0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x69, 0x76, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63,
|
||||||
0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65,
|
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x10, 0x44, 0x65,
|
||||||
0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65,
|
0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c,
|
||||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65,
|
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73,
|
||||||
0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70,
|
0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, 0x6f,
|
0x70, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
|
||||||
0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x79, 0x6e,
|
0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x53,
|
||||||
0x63, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
|
0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x2e,
|
||||||
0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70,
|
0x72, 0x70, 0x63, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f,
|
||||||
0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||||
0x00, 0x12, 0x4b, 0x0a, 0x0e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
|
0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65,
|
||||||
0x6f, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65,
|
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0e, 0x48, 0x61, 0x73, 0x68,
|
||||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63,
|
||||||
0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69,
|
0x2e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52,
|
||||||
0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a,
|
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x61, 0x73,
|
||||||
0x0a, 0x09, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x12, 0x15, 0x2e, 0x72, 0x70,
|
0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||||
0x63, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x09, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61,
|
||||||
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61,
|
0x73, 0x65, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61,
|
||||||
0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69,
|
0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x72, 0x6e, 0x65, 0x73, 0x73,
|
0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x2f, 0x67, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2f,
|
0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||||
0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x68, 0x61, 0x72, 0x6e, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x2f,
|
||||||
|
0x67, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
2
go.mod
2
go.mod
@ -25,7 +25,6 @@ require (
|
|||||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/google/go-cmp v0.5.9
|
github.com/google/go-cmp v0.5.9
|
||||||
github.com/google/uuid v1.3.1
|
|
||||||
github.com/google/wire v0.5.0
|
github.com/google/wire v0.5.0
|
||||||
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75
|
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75
|
||||||
github.com/gotidy/ptr v1.3.0
|
github.com/gotidy/ptr v1.3.0
|
||||||
@ -81,6 +80,7 @@ require (
|
|||||||
github.com/ghodss/yaml v1.0.0 // indirect
|
github.com/ghodss/yaml v1.0.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
github.com/google/uuid v1.3.1 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
|
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
|
1
go.sum
1
go.sum
@ -317,6 +317,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
|
|||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/guregu/null v4.0.0+incompatible h1:4zw0ckM7ECd6FNNddc3Fu4aty9nTlpkkzH7dPn4/4Gw=
|
github.com/guregu/null v4.0.0+incompatible h1:4zw0ckM7ECd6FNNddc3Fu4aty9nTlpkkzH7dPn4/4Gw=
|
||||||
github.com/guregu/null v4.0.0+incompatible/go.mod h1:ePGpQaN9cw0tj45IR5E5ehMvsFlLlQZAkkOXZurJ3NM=
|
github.com/guregu/null v4.0.0+incompatible/go.mod h1:ePGpQaN9cw0tj45IR5E5ehMvsFlLlQZAkkOXZurJ3NM=
|
||||||
|
github.com/h2non/gock v1.0.9 h1:17gCehSo8ZOgEsFKpQgqHiR7VLyjxdAG3lkhVvO9QZU=
|
||||||
github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE=
|
github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE=
|
||||||
github.com/harness/go-rbac v0.0.0-20230829014129-c9b217856ea2 h1:M1Jd2uEKl4YW9g/6vzN1qo06d5dshYYdwxlhOTUSnh4=
|
github.com/harness/go-rbac v0.0.0-20230829014129-c9b217856ea2 h1:M1Jd2uEKl4YW9g/6vzN1qo06d5dshYYdwxlhOTUSnh4=
|
||||||
github.com/harness/go-rbac v0.0.0-20230829014129-c9b217856ea2/go.mod h1:uGgBgSZPgyygG5rWzoYsKIQ8TM4zt5yQq9nreznWvOI=
|
github.com/harness/go-rbac v0.0.0-20230829014129-c9b217856ea2/go.mod h1:uGgBgSZPgyygG5rWzoYsKIQ8TM4zt5yQq9nreznWvOI=
|
||||||
|
@ -114,6 +114,10 @@ func (c *Controller) getRepoCheckAccess(ctx context.Context,
|
|||||||
return nil, fmt.Errorf("failed to find repository: %w", err)
|
return nil, fmt.Errorf("failed to find repository: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if repo.Importing {
|
||||||
|
return nil, usererror.BadRequest("Repository import is in progress.")
|
||||||
|
}
|
||||||
|
|
||||||
if err = apiauth.CheckRepo(ctx, c.authorizer, session, repo, reqPermission, false); err != nil {
|
if err = apiauth.CheckRepo(ctx, c.authorizer, session, repo, reqPermission, false); err != nil {
|
||||||
return nil, fmt.Errorf("access check failed: %w", err)
|
return nil, fmt.Errorf("access check failed: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,14 @@ package repo
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/harness/gitness/gitrpc"
|
"github.com/harness/gitness/gitrpc"
|
||||||
"github.com/harness/gitness/internal/auth"
|
"github.com/harness/gitness/internal/auth"
|
||||||
"github.com/harness/gitness/internal/auth/authz"
|
"github.com/harness/gitness/internal/auth/authz"
|
||||||
"github.com/harness/gitness/internal/githook"
|
"github.com/harness/gitness/internal/githook"
|
||||||
|
"github.com/harness/gitness/internal/services/importer"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/internal/url"
|
"github.com/harness/gitness/internal/url"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
@ -32,6 +35,7 @@ type Controller struct {
|
|||||||
pipelineStore store.PipelineStore
|
pipelineStore store.PipelineStore
|
||||||
principalStore store.PrincipalStore
|
principalStore store.PrincipalStore
|
||||||
gitRPCClient gitrpc.Interface
|
gitRPCClient gitrpc.Interface
|
||||||
|
importer *importer.Repository
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewController(
|
func NewController(
|
||||||
@ -46,6 +50,7 @@ func NewController(
|
|||||||
pipelineStore store.PipelineStore,
|
pipelineStore store.PipelineStore,
|
||||||
principalStore store.PrincipalStore,
|
principalStore store.PrincipalStore,
|
||||||
gitRPCClient gitrpc.Interface,
|
gitRPCClient gitrpc.Interface,
|
||||||
|
importer *importer.Repository,
|
||||||
) *Controller {
|
) *Controller {
|
||||||
return &Controller{
|
return &Controller{
|
||||||
defaultBranch: defaultBranch,
|
defaultBranch: defaultBranch,
|
||||||
@ -59,6 +64,7 @@ func NewController(
|
|||||||
pipelineStore: pipelineStore,
|
pipelineStore: pipelineStore,
|
||||||
principalStore: principalStore,
|
principalStore: principalStore,
|
||||||
gitRPCClient: gitRPCClient,
|
gitRPCClient: gitRPCClient,
|
||||||
|
importer: importer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,3 +101,12 @@ func CreateRPCReadParams(repo *types.Repository) gitrpc.ReadParams {
|
|||||||
RepoUID: repo.GitUID,
|
RepoUID: repo.GitUID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Controller) validateParentRef(parentRef string) error {
|
||||||
|
parentRefAsID, err := strconv.ParseInt(parentRef, 10, 64)
|
||||||
|
if (err == nil && parentRefAsID <= 0) || (len(strings.TrimSpace(parentRef)) == 0) {
|
||||||
|
return errRepositoryRequiresParent
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -151,10 +150,8 @@ func (c *Controller) getSpaceCheckAuthRepoCreation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) sanitizeCreateInput(in *CreateInput) error {
|
func (c *Controller) sanitizeCreateInput(in *CreateInput) error {
|
||||||
parentRefAsID, err := strconv.ParseInt(in.ParentRef, 10, 64)
|
if err := c.validateParentRef(in.ParentRef); err != nil {
|
||||||
|
return err
|
||||||
if (err == nil && parentRefAsID <= 0) || (len(strings.TrimSpace(in.ParentRef)) == 0) {
|
|
||||||
return errRepositoryRequiresParent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.uidCheck(in.UID, false); err != nil {
|
if err := c.uidCheck(in.UID, false); err != nil {
|
||||||
|
202
internal/api/controller/repo/import.go
Normal file
202
internal/api/controller/repo/import.go
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/gitrpc"
|
||||||
|
"github.com/harness/gitness/internal/api/usererror"
|
||||||
|
"github.com/harness/gitness/internal/auth"
|
||||||
|
"github.com/harness/gitness/internal/bootstrap"
|
||||||
|
"github.com/harness/gitness/internal/githook"
|
||||||
|
"github.com/harness/gitness/internal/paths"
|
||||||
|
"github.com/harness/gitness/internal/services/importer"
|
||||||
|
"github.com/harness/gitness/internal/services/job"
|
||||||
|
"github.com/harness/gitness/store/database/dbtx"
|
||||||
|
"github.com/harness/gitness/types"
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImportInput struct {
|
||||||
|
ParentRef string `json:"parent_ref"`
|
||||||
|
UID string `json:"uid"`
|
||||||
|
|
||||||
|
Provider importer.ProviderType `json:"provider"`
|
||||||
|
ProviderURL string `json:"provider_url"`
|
||||||
|
RepoSlug string `json:"repo_slug"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import creates a new empty repository and starts git import to it from a remote repository.
|
||||||
|
func (c *Controller) Import(ctx context.Context, session *auth.Session, in *ImportInput) (*types.Repository, error) {
|
||||||
|
parentSpace, err := c.getSpaceCheckAuthRepoCreation(ctx, session, in.ParentRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.sanitizeImportInput(in)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to sanitize input: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
providerInfo := importer.ProviderInfo{
|
||||||
|
Type: in.Provider,
|
||||||
|
Host: in.ProviderURL,
|
||||||
|
User: in.Username,
|
||||||
|
Pass: in.Password,
|
||||||
|
}
|
||||||
|
|
||||||
|
repoInfo, err := importer.Repo(ctx, providerInfo, in.RepoSlug)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
jobUID, err := job.UID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error creating job UID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gitRPCResp, err := c.createEmptyGitRepository(ctx, session)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error creating repository on GitRPC: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().UnixMilli()
|
||||||
|
repo := &types.Repository{
|
||||||
|
Version: 0,
|
||||||
|
ParentID: parentSpace.ID,
|
||||||
|
UID: in.UID,
|
||||||
|
GitUID: gitRPCResp.UID,
|
||||||
|
Path: "", // the path is set in the DB transaction below
|
||||||
|
Description: in.Description,
|
||||||
|
IsPublic: repoInfo.IsPublic,
|
||||||
|
CreatedBy: session.Principal.ID,
|
||||||
|
Created: now,
|
||||||
|
Updated: now,
|
||||||
|
ForkID: 0,
|
||||||
|
DefaultBranch: repoInfo.DefaultBranch,
|
||||||
|
Importing: true,
|
||||||
|
ImportingJobUID: &jobUID,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) error {
|
||||||
|
// lock parent space path to ensure it doesn't get updated while we setup new repo
|
||||||
|
spacePath, err := c.pathStore.FindPrimaryWithLock(ctx, enum.PathTargetTypeSpace, parentSpace.ID)
|
||||||
|
if err != nil {
|
||||||
|
return usererror.BadRequest("Parent not found'")
|
||||||
|
}
|
||||||
|
|
||||||
|
repo.Path = paths.Concatinate(spacePath.Value, in.UID)
|
||||||
|
|
||||||
|
err = c.repoStore.Create(ctx, repo)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create repository in storage: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
path := &types.Path{
|
||||||
|
Version: 0,
|
||||||
|
Value: repo.Path,
|
||||||
|
IsPrimary: true,
|
||||||
|
TargetType: enum.PathTargetTypeRepo,
|
||||||
|
TargetID: repo.ID,
|
||||||
|
CreatedBy: repo.CreatedBy,
|
||||||
|
Created: repo.Created,
|
||||||
|
Updated: repo.Updated,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.pathStore.Create(ctx, path)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create path: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if err := c.DeleteRepositoryRPC(ctx, session, repo); err != nil {
|
||||||
|
log.Ctx(ctx).Warn().Err(err).Msg("gitrpc failed to delete repo for cleanup")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.importer.Run(ctx, jobUID, importer.Input{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
GitUser: in.Username,
|
||||||
|
GitPass: in.Password,
|
||||||
|
CloneURL: repoInfo.CloneURL,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Ctx(ctx).Err(err).Msg("failed to start import repository job")
|
||||||
|
}
|
||||||
|
|
||||||
|
repo.GitURL = c.urlProvider.GenerateRepoCloneURL(repo.Path)
|
||||||
|
|
||||||
|
return repo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Controller) sanitizeImportInput(in *ImportInput) error {
|
||||||
|
if err := c.validateParentRef(in.ParentRef); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.uidCheck(in.UID, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.Provider == "" {
|
||||||
|
return usererror.BadRequest("provider must be provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.RepoSlug == "" {
|
||||||
|
return usererror.BadRequest("repo slug must be provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Controller) createEmptyGitRepository(
|
||||||
|
ctx context.Context,
|
||||||
|
session *auth.Session,
|
||||||
|
) (*gitrpc.CreateRepositoryOutput, error) {
|
||||||
|
// generate envars (add everything githook CLI needs for execution)
|
||||||
|
envVars, err := githook.GenerateEnvironmentVariables(
|
||||||
|
ctx,
|
||||||
|
c.urlProvider.GetAPIBaseURLInternal(),
|
||||||
|
0,
|
||||||
|
session.Principal.ID,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate git hook environment variables: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actor := rpcIdentityFromPrincipal(session.Principal)
|
||||||
|
committer := rpcIdentityFromPrincipal(bootstrap.NewSystemServiceSession().Principal)
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
resp, err := c.gitRPCClient.CreateRepository(ctx, &gitrpc.CreateRepositoryParams{
|
||||||
|
Actor: *actor,
|
||||||
|
EnvVars: envVars,
|
||||||
|
DefaultBranch: c.defaultBranch,
|
||||||
|
Files: nil,
|
||||||
|
Author: actor,
|
||||||
|
AuthorDate: &now,
|
||||||
|
Committer: committer,
|
||||||
|
CommitterDate: &now,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create repo on gitrpc: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
31
internal/api/controller/repo/import_progress.go
Normal file
31
internal/api/controller/repo/import_progress.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
apiauth "github.com/harness/gitness/internal/api/auth"
|
||||||
|
"github.com/harness/gitness/internal/auth"
|
||||||
|
"github.com/harness/gitness/types"
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ImportProgress returns progress of the import job.
|
||||||
|
func (c *Controller) ImportProgress(ctx context.Context,
|
||||||
|
session *auth.Session,
|
||||||
|
repoRef string,
|
||||||
|
) (types.JobProgress, error) {
|
||||||
|
repo, err := c.repoStore.FindByRef(ctx, repoRef)
|
||||||
|
if err != nil {
|
||||||
|
return types.JobProgress{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = apiauth.CheckRepo(ctx, c.authorizer, session, repo, enum.PermissionRepoView, false); err != nil {
|
||||||
|
return types.JobProgress{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.importer.GetProgress(ctx, repo)
|
||||||
|
}
|
@ -7,6 +7,7 @@ package repo
|
|||||||
import (
|
import (
|
||||||
"github.com/harness/gitness/gitrpc"
|
"github.com/harness/gitness/gitrpc"
|
||||||
"github.com/harness/gitness/internal/auth/authz"
|
"github.com/harness/gitness/internal/auth/authz"
|
||||||
|
"github.com/harness/gitness/internal/services/importer"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/internal/url"
|
"github.com/harness/gitness/internal/url"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
@ -24,7 +25,11 @@ var WireSet = wire.NewSet(
|
|||||||
func ProvideController(config *types.Config, db *sqlx.DB, urlProvider *url.Provider,
|
func ProvideController(config *types.Config, db *sqlx.DB, urlProvider *url.Provider,
|
||||||
uidCheck check.PathUID, authorizer authz.Authorizer, pathStore store.PathStore, repoStore store.RepoStore,
|
uidCheck check.PathUID, authorizer authz.Authorizer, pathStore store.PathStore, repoStore store.RepoStore,
|
||||||
spaceStore store.SpaceStore, pipelineStore store.PipelineStore,
|
spaceStore store.SpaceStore, pipelineStore store.PipelineStore,
|
||||||
principalStore store.PrincipalStore, rpcClient gitrpc.Interface) *Controller {
|
principalStore store.PrincipalStore, rpcClient gitrpc.Interface,
|
||||||
return NewController(config.Git.DefaultBranch, db, urlProvider, uidCheck,
|
importer *importer.Repository,
|
||||||
authorizer, pathStore, repoStore, spaceStore, pipelineStore, principalStore, rpcClient)
|
) *Controller {
|
||||||
|
return NewController(config.Git.DefaultBranch, db, urlProvider,
|
||||||
|
uidCheck, authorizer, pathStore, repoStore,
|
||||||
|
spaceStore, pipelineStore, principalStore, rpcClient,
|
||||||
|
importer)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ package space
|
|||||||
import (
|
import (
|
||||||
"github.com/harness/gitness/internal/api/controller/repo"
|
"github.com/harness/gitness/internal/api/controller/repo"
|
||||||
"github.com/harness/gitness/internal/auth/authz"
|
"github.com/harness/gitness/internal/auth/authz"
|
||||||
|
"github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/internal/url"
|
"github.com/harness/gitness/internal/url"
|
||||||
"github.com/harness/gitness/types/check"
|
"github.com/harness/gitness/types/check"
|
||||||
@ -17,6 +18,7 @@ import (
|
|||||||
type Controller struct {
|
type Controller struct {
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
urlProvider *url.Provider
|
urlProvider *url.Provider
|
||||||
|
eventsStream events.EventsStreamer
|
||||||
uidCheck check.PathUID
|
uidCheck check.PathUID
|
||||||
authorizer authz.Authorizer
|
authorizer authz.Authorizer
|
||||||
pathStore store.PathStore
|
pathStore store.PathStore
|
||||||
@ -31,7 +33,7 @@ type Controller struct {
|
|||||||
membershipStore store.MembershipStore
|
membershipStore store.MembershipStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewController(db *sqlx.DB, urlProvider *url.Provider,
|
func NewController(db *sqlx.DB, urlProvider *url.Provider, eventsStream events.EventsStreamer,
|
||||||
uidCheck check.PathUID, authorizer authz.Authorizer,
|
uidCheck check.PathUID, authorizer authz.Authorizer,
|
||||||
pathStore store.PathStore, pipelineStore store.PipelineStore, secretStore store.SecretStore,
|
pathStore store.PathStore, pipelineStore store.PipelineStore, secretStore store.SecretStore,
|
||||||
connectorStore store.ConnectorStore, templateStore store.TemplateStore, spaceStore store.SpaceStore,
|
connectorStore store.ConnectorStore, templateStore store.TemplateStore, spaceStore store.SpaceStore,
|
||||||
@ -41,6 +43,7 @@ func NewController(db *sqlx.DB, urlProvider *url.Provider,
|
|||||||
return &Controller{
|
return &Controller{
|
||||||
db: db,
|
db: db,
|
||||||
urlProvider: urlProvider,
|
urlProvider: urlProvider,
|
||||||
|
eventsStream: eventsStream,
|
||||||
uidCheck: uidCheck,
|
uidCheck: uidCheck,
|
||||||
authorizer: authorizer,
|
authorizer: authorizer,
|
||||||
pathStore: pathStore,
|
pathStore: pathStore,
|
||||||
|
93
internal/api/controller/space/events.go
Normal file
93
internal/api/controller/space/events.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package space
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
apiauth "github.com/harness/gitness/internal/api/auth"
|
||||||
|
"github.com/harness/gitness/internal/auth"
|
||||||
|
"github.com/harness/gitness/internal/writer"
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
pingInterval = 30 * time.Second
|
||||||
|
tailMaxTime = 2 * time.Hour
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Controller) Events(
|
||||||
|
ctx context.Context,
|
||||||
|
session *auth.Session,
|
||||||
|
spaceRef string,
|
||||||
|
w writer.WriterFlusher,
|
||||||
|
) error {
|
||||||
|
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to find space ref: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = apiauth.CheckSpace(ctx, c.authorizer, session, space, enum.PermissionSpaceView, true); err != nil {
|
||||||
|
return fmt.Errorf("failed to authorize stream: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, tailMaxTime)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
io.WriteString(w, ": ping\n\n")
|
||||||
|
w.Flush()
|
||||||
|
|
||||||
|
events, errc, consumer := c.eventsStream.Subscribe(ctx, space.ID)
|
||||||
|
defer c.eventsStream.Unsubscribe(ctx, consumer)
|
||||||
|
// could not get error channel
|
||||||
|
if errc == nil {
|
||||||
|
io.WriteString(w, "event: error\ndata: eof\n\n")
|
||||||
|
w.Flush()
|
||||||
|
return fmt.Errorf("could not get error channel")
|
||||||
|
}
|
||||||
|
pingTimer := time.NewTimer(pingInterval)
|
||||||
|
defer pingTimer.Stop()
|
||||||
|
|
||||||
|
enc := json.NewEncoder(w)
|
||||||
|
L:
|
||||||
|
for {
|
||||||
|
// ensure timer is stopped before resetting (see documentation)
|
||||||
|
if !pingTimer.Stop() {
|
||||||
|
// in this specific case the timer's channel could be both, empty or full
|
||||||
|
select {
|
||||||
|
case <-pingTimer.C:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pingTimer.Reset(pingInterval)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
log.Debug().Msg("events: stream cancelled")
|
||||||
|
break L
|
||||||
|
case err := <-errc:
|
||||||
|
log.Err(err).Msg("events: received error in the tail channel")
|
||||||
|
break L
|
||||||
|
case <-pingTimer.C:
|
||||||
|
// if time b/w messages takes longer, send a ping
|
||||||
|
io.WriteString(w, ": ping\n\n")
|
||||||
|
w.Flush()
|
||||||
|
case event := <-events:
|
||||||
|
io.WriteString(w, "data: ")
|
||||||
|
enc.Encode(event)
|
||||||
|
io.WriteString(w, "\n\n")
|
||||||
|
w.Flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
io.WriteString(w, "event: error\ndata: eof\n\n")
|
||||||
|
w.Flush()
|
||||||
|
log.Debug().Msg("events: stream closed")
|
||||||
|
return nil
|
||||||
|
}
|
@ -7,6 +7,7 @@ package space
|
|||||||
import (
|
import (
|
||||||
"github.com/harness/gitness/internal/api/controller/repo"
|
"github.com/harness/gitness/internal/api/controller/repo"
|
||||||
"github.com/harness/gitness/internal/auth/authz"
|
"github.com/harness/gitness/internal/auth/authz"
|
||||||
|
"github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/internal/url"
|
"github.com/harness/gitness/internal/url"
|
||||||
"github.com/harness/gitness/types/check"
|
"github.com/harness/gitness/types/check"
|
||||||
@ -20,13 +21,14 @@ var WireSet = wire.NewSet(
|
|||||||
ProvideController,
|
ProvideController,
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideController(db *sqlx.DB, urlProvider *url.Provider, uidCheck check.PathUID, authorizer authz.Authorizer,
|
func ProvideController(db *sqlx.DB, urlProvider *url.Provider, eventsStream events.EventsStreamer,
|
||||||
pathStore store.PathStore, pipelineStore store.PipelineStore, secretStore store.SecretStore,
|
uidCheck check.PathUID, authorizer authz.Authorizer, pathStore store.PathStore,
|
||||||
|
pipelineStore store.PipelineStore, secretStore store.SecretStore,
|
||||||
connectorStore store.ConnectorStore, templateStore store.TemplateStore,
|
connectorStore store.ConnectorStore, templateStore store.TemplateStore,
|
||||||
spaceStore store.SpaceStore, repoStore store.RepoStore, principalStore store.PrincipalStore,
|
spaceStore store.SpaceStore, repoStore store.RepoStore, principalStore store.PrincipalStore,
|
||||||
repoCtrl *repo.Controller, membershipStore store.MembershipStore,
|
repoCtrl *repo.Controller, membershipStore store.MembershipStore,
|
||||||
) *Controller {
|
) *Controller {
|
||||||
return NewController(db, urlProvider, uidCheck, authorizer,
|
return NewController(db, urlProvider, eventsStream, uidCheck, authorizer,
|
||||||
pathStore, pipelineStore, secretStore, connectorStore, templateStore,
|
pathStore, pipelineStore, secretStore, connectorStore, templateStore,
|
||||||
spaceStore, repoStore, principalStore, repoCtrl, membershipStore)
|
spaceStore, repoStore, principalStore, repoCtrl, membershipStore)
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,13 @@ func HandleTail(logCtrl *logs.Controller) http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h := w.Header()
|
||||||
|
h.Set("Content-Type", "text/event-stream")
|
||||||
|
h.Set("Cache-Control", "no-cache")
|
||||||
|
h.Set("Connection", "keep-alive")
|
||||||
|
h.Set("X-Accel-Buffering", "no")
|
||||||
|
h.Set("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
io.WriteString(w, ": ping\n\n")
|
io.WriteString(w, ": ping\n\n")
|
||||||
f.Flush()
|
f.Flush()
|
||||||
|
|
||||||
@ -77,13 +84,6 @@ func HandleTail(logCtrl *logs.Controller) http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
h := w.Header()
|
|
||||||
h.Set("Content-Type", "text/event-stream")
|
|
||||||
h.Set("Cache-Control", "no-cache")
|
|
||||||
h.Set("Connection", "keep-alive")
|
|
||||||
h.Set("X-Accel-Buffering", "no")
|
|
||||||
h.Set("Access-Control-Allow-Origin", "*")
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), tailMaxTime)
|
ctx, cancel := context.WithTimeout(r.Context(), tailMaxTime)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
36
internal/api/handler/repo/import.go
Normal file
36
internal/api/handler/repo/import.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/api/controller/repo"
|
||||||
|
"github.com/harness/gitness/internal/api/render"
|
||||||
|
"github.com/harness/gitness/internal/api/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HandleImport(repoCtrl *repo.Controller) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
session, _ := request.AuthSessionFrom(ctx)
|
||||||
|
|
||||||
|
in := new(repo.ImportInput)
|
||||||
|
err := json.NewDecoder(r.Body).Decode(in)
|
||||||
|
if err != nil {
|
||||||
|
render.BadRequestf(w, "Invalid Request Body: %s.", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := repoCtrl.Import(ctx, session, in)
|
||||||
|
if err != nil {
|
||||||
|
render.TranslatedUserError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
render.JSON(w, http.StatusCreated, repo)
|
||||||
|
}
|
||||||
|
}
|
33
internal/api/handler/repo/import_progress.go
Normal file
33
internal/api/handler/repo/import_progress.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/api/controller/repo"
|
||||||
|
"github.com/harness/gitness/internal/api/render"
|
||||||
|
"github.com/harness/gitness/internal/api/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HandleImportProgress(repoCtrl *repo.Controller) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
session, _ := request.AuthSessionFrom(ctx)
|
||||||
|
repoRef, err := request.GetRepoRefFromPath(r)
|
||||||
|
if err != nil {
|
||||||
|
render.TranslatedUserError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
progress, err := repoCtrl.ImportProgress(ctx, session, repoRef)
|
||||||
|
if err != nil {
|
||||||
|
render.TranslatedUserError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
render.JSON(w, http.StatusOK, progress)
|
||||||
|
}
|
||||||
|
}
|
52
internal/api/handler/space/events_stream.go
Normal file
52
internal/api/handler/space/events_stream.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package space
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/api/controller/space"
|
||||||
|
"github.com/harness/gitness/internal/api/render"
|
||||||
|
"github.com/harness/gitness/internal/api/request"
|
||||||
|
"github.com/harness/gitness/internal/writer"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandleEventsStream returns an http.HandlerFunc that watches for
|
||||||
|
// events on a space
|
||||||
|
func HandleEventsStream(spaceCtrl *space.Controller) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
session, _ := request.AuthSessionFrom(ctx)
|
||||||
|
|
||||||
|
spaceRef, err := request.GetSpaceRefFromPath(r)
|
||||||
|
if err != nil {
|
||||||
|
render.TranslatedUserError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h := w.Header()
|
||||||
|
h.Set("Content-Type", "text/event-stream")
|
||||||
|
h.Set("Cache-Control", "no-cache")
|
||||||
|
h.Set("Connection", "keep-alive")
|
||||||
|
h.Set("X-Accel-Buffering", "no")
|
||||||
|
h.Set("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
|
f, ok := w.(http.Flusher)
|
||||||
|
if !ok {
|
||||||
|
log.Error().Msg("http writer type assertion failed")
|
||||||
|
render.InternalError(w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writer := writer.NewWriterFlusher(w, f)
|
||||||
|
|
||||||
|
err = spaceCtrl.Events(ctx, session, spaceRef, writer)
|
||||||
|
if err != nil {
|
||||||
|
render.TranslatedUserError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,12 @@ package openapi
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gotidy/ptr"
|
|
||||||
"github.com/harness/gitness/internal/api/controller/user"
|
"github.com/harness/gitness/internal/api/controller/user"
|
||||||
"github.com/harness/gitness/internal/api/request"
|
"github.com/harness/gitness/internal/api/request"
|
||||||
"github.com/harness/gitness/internal/api/usererror"
|
"github.com/harness/gitness/internal/api/usererror"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
|
|
||||||
|
"github.com/gotidy/ptr"
|
||||||
"github.com/swaggest/openapi-go/openapi3"
|
"github.com/swaggest/openapi-go/openapi3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
83
internal/pipeline/events/events.go
Normal file
83
internal/pipeline/events/events.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package events
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/pubsub"
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Event is an event which is sent to the UI via server-sent events.
|
||||||
|
type Event struct {
|
||||||
|
Type enum.EventType `json:"type"`
|
||||||
|
Data json.RawMessage `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventsStreamer interface {
|
||||||
|
// Publish publishes an event to a given space ID.
|
||||||
|
Publish(ctx context.Context, spaceID int64, event *Event) error
|
||||||
|
|
||||||
|
// Subscribe listens to events on a space ID.
|
||||||
|
Subscribe(ctx context.Context, spaceID int64) (<-chan *Event, <-chan error, pubsub.Consumer)
|
||||||
|
|
||||||
|
// Unsubscribe unsubscribes the consumer.
|
||||||
|
Unsubscribe(ctx context.Context, consumer pubsub.Consumer) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type event struct {
|
||||||
|
pubsub pubsub.PubSub
|
||||||
|
topic string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(pubsub pubsub.PubSub, topic string) EventsStreamer {
|
||||||
|
return &event{
|
||||||
|
pubsub: pubsub,
|
||||||
|
topic: topic,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *event) Publish(ctx context.Context, spaceID int64, event *Event) error {
|
||||||
|
bytes, err := json.Marshal(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
option := pubsub.WithPublishNamespace(format(spaceID))
|
||||||
|
return e.pubsub.Publish(ctx, e.topic, bytes, option)
|
||||||
|
}
|
||||||
|
|
||||||
|
// format creates the namespace name which will be spaces-<id>
|
||||||
|
func format(id int64) string {
|
||||||
|
return "spaces-" + strconv.Itoa(int(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *event) Subscribe(ctx context.Context, spaceID int64) (<-chan *Event, <-chan error, pubsub.Consumer) {
|
||||||
|
chEvent := make(chan *Event, 100) // TODO: check best size here
|
||||||
|
chErr := make(chan error)
|
||||||
|
g := func(payload []byte) error {
|
||||||
|
event := &Event{}
|
||||||
|
err := json.Unmarshal(payload, event)
|
||||||
|
if err != nil {
|
||||||
|
// This should never happen
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case chEvent <- event:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
option := pubsub.WithChannelNamespace(format(spaceID))
|
||||||
|
consumer := e.pubsub.Subscribe(ctx, e.topic, g, option)
|
||||||
|
return chEvent, chErr, consumer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *event) Unsubscribe(ctx context.Context, consumer pubsub.Consumer) error {
|
||||||
|
return consumer.Unsubscribe(ctx, e.topic)
|
||||||
|
}
|
23
internal/pipeline/events/wire.go
Normal file
23
internal/pipeline/events/wire.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package events
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/harness/gitness/pubsub"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WireSet provides a wire set for this package.
|
||||||
|
var WireSet = wire.NewSet(
|
||||||
|
ProvideEventsStreaming,
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProvideEventsStreaming(pubsub pubsub.PubSub) EventsStreamer {
|
||||||
|
return &event{
|
||||||
|
pubsub: pubsub,
|
||||||
|
topic: "events",
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/pipeline/file"
|
"github.com/harness/gitness/internal/pipeline/file"
|
||||||
"github.com/harness/gitness/internal/pipeline/scheduler"
|
"github.com/harness/gitness/internal/pipeline/scheduler"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
@ -98,7 +99,7 @@ type Manager struct {
|
|||||||
Pipelines store.PipelineStore
|
Pipelines store.PipelineStore
|
||||||
urlProvider *urlprovider.Provider
|
urlProvider *urlprovider.Provider
|
||||||
// Converter store.ConvertService
|
// Converter store.ConvertService
|
||||||
// Events store.Pubsub
|
Events events.EventsStreamer
|
||||||
// Globals store.GlobalSecretStore
|
// Globals store.GlobalSecretStore
|
||||||
Logs store.LogStore
|
Logs store.LogStore
|
||||||
Logz livelog.LogStream
|
Logz livelog.LogStream
|
||||||
@ -119,6 +120,7 @@ func New(
|
|||||||
executionStore store.ExecutionStore,
|
executionStore store.ExecutionStore,
|
||||||
pipelineStore store.PipelineStore,
|
pipelineStore store.PipelineStore,
|
||||||
urlProvider *urlprovider.Provider,
|
urlProvider *urlprovider.Provider,
|
||||||
|
events events.EventsStreamer,
|
||||||
fileService file.FileService,
|
fileService file.FileService,
|
||||||
logStore store.LogStore,
|
logStore store.LogStore,
|
||||||
logStream livelog.LogStream,
|
logStream livelog.LogStream,
|
||||||
@ -134,6 +136,7 @@ func New(
|
|||||||
Executions: executionStore,
|
Executions: executionStore,
|
||||||
Pipelines: pipelineStore,
|
Pipelines: pipelineStore,
|
||||||
urlProvider: urlProvider,
|
urlProvider: urlProvider,
|
||||||
|
Events: events,
|
||||||
FileService: fileService,
|
FileService: fileService,
|
||||||
Logs: logStore,
|
Logs: logStore,
|
||||||
Logz: logStream,
|
Logz: logStream,
|
||||||
@ -313,6 +316,7 @@ func (m *Manager) BeforeStep(ctx context.Context, step *types.Step) error {
|
|||||||
}
|
}
|
||||||
updater := &updater{
|
updater := &updater{
|
||||||
Executions: m.Executions,
|
Executions: m.Executions,
|
||||||
|
Events: m.Events,
|
||||||
Repos: m.Repos,
|
Repos: m.Repos,
|
||||||
Steps: m.Steps,
|
Steps: m.Steps,
|
||||||
Stages: m.Stages,
|
Stages: m.Stages,
|
||||||
@ -332,6 +336,7 @@ func (m *Manager) AfterStep(ctx context.Context, step *types.Step) error {
|
|||||||
var retErr error
|
var retErr error
|
||||||
updater := &updater{
|
updater := &updater{
|
||||||
Executions: m.Executions,
|
Executions: m.Executions,
|
||||||
|
Events: m.Events,
|
||||||
Repos: m.Repos,
|
Repos: m.Repos,
|
||||||
Steps: m.Steps,
|
Steps: m.Steps,
|
||||||
Stages: m.Stages,
|
Stages: m.Stages,
|
||||||
@ -352,6 +357,7 @@ func (m *Manager) AfterStep(ctx context.Context, step *types.Step) error {
|
|||||||
func (m *Manager) BeforeStage(ctx context.Context, stage *types.Stage) error {
|
func (m *Manager) BeforeStage(ctx context.Context, stage *types.Stage) error {
|
||||||
s := &setup{
|
s := &setup{
|
||||||
Executions: m.Executions,
|
Executions: m.Executions,
|
||||||
|
Events: m.Events,
|
||||||
Repos: m.Repos,
|
Repos: m.Repos,
|
||||||
Steps: m.Steps,
|
Steps: m.Steps,
|
||||||
Stages: m.Stages,
|
Stages: m.Stages,
|
||||||
@ -365,6 +371,7 @@ func (m *Manager) BeforeStage(ctx context.Context, stage *types.Stage) error {
|
|||||||
func (m *Manager) AfterStage(ctx context.Context, stage *types.Stage) error {
|
func (m *Manager) AfterStage(ctx context.Context, stage *types.Stage) error {
|
||||||
t := &teardown{
|
t := &teardown{
|
||||||
Executions: m.Executions,
|
Executions: m.Executions,
|
||||||
|
Events: m.Events,
|
||||||
Logs: m.Logz,
|
Logs: m.Logz,
|
||||||
Repos: m.Repos,
|
Repos: m.Repos,
|
||||||
Scheduler: m.Scheduler,
|
Scheduler: m.Scheduler,
|
||||||
|
@ -6,9 +6,11 @@ package manager
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
gitness_store "github.com/harness/gitness/store"
|
gitness_store "github.com/harness/gitness/store"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
@ -19,6 +21,7 @@ import (
|
|||||||
|
|
||||||
type setup struct {
|
type setup struct {
|
||||||
Executions store.ExecutionStore
|
Executions store.ExecutionStore
|
||||||
|
Events events.EventsStreamer
|
||||||
Repos store.RepoStore
|
Repos store.RepoStore
|
||||||
Steps store.StepStore
|
Steps store.StepStore
|
||||||
Stages store.StageStore
|
Stages store.StageStore
|
||||||
@ -39,7 +42,7 @@ func (s *setup) do(ctx context.Context, stage *types.Stage) error {
|
|||||||
Int64("repo.id", execution.RepoID).
|
Int64("repo.id", execution.RepoID).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
_, err = s.Repos.Find(noContext, execution.RepoID)
|
repo, err := s.Repos.Find(noContext, execution.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("manager: cannot find the repository")
|
log.Error().Err(err).Msg("manager: cannot find the repository")
|
||||||
return err
|
return err
|
||||||
@ -72,15 +75,37 @@ func (s *setup) do(ctx context.Context, stage *types.Stage) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.updateExecution(ctx, execution)
|
_, err = s.updateExecution(noContext, execution)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("manager: cannot update the execution")
|
log.Error().Err(err).Msg("manager: cannot update the execution")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
stages, err := s.Stages.ListWithSteps(noContext, execution.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("manager: could not list stages with steps")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
execution.Stages = stages
|
||||||
|
err = s.Events.Publish(noContext, repo.ParentID, executionEvent(enum.ExecutionRunning, execution))
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Msg("manager: could not publish execution event")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func executionEvent(
|
||||||
|
eventType enum.EventType,
|
||||||
|
execution *types.Execution,
|
||||||
|
) *events.Event {
|
||||||
|
// json.Marshal will not return an error here, it can be absorbed
|
||||||
|
bytes, _ := json.Marshal(execution)
|
||||||
|
return &events.Event{
|
||||||
|
Type: eventType,
|
||||||
|
Data: bytes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// helper function that updates the execution status from pending to running.
|
// helper function that updates the execution status from pending to running.
|
||||||
// This accounts for the fact that another agent may have already updated
|
// This accounts for the fact that another agent may have already updated
|
||||||
// the execution status, which may happen if two stages execute concurrently.
|
// the execution status, which may happen if two stages execute concurrently.
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/pipeline/scheduler"
|
"github.com/harness/gitness/internal/pipeline/scheduler"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/livelog"
|
"github.com/harness/gitness/livelog"
|
||||||
@ -20,6 +21,7 @@ import (
|
|||||||
|
|
||||||
type teardown struct {
|
type teardown struct {
|
||||||
Executions store.ExecutionStore
|
Executions store.ExecutionStore
|
||||||
|
Events events.EventsStreamer
|
||||||
Logs livelog.LogStream
|
Logs livelog.LogStream
|
||||||
Scheduler scheduler.Scheduler
|
Scheduler scheduler.Scheduler
|
||||||
Repos store.RepoStore
|
Repos store.RepoStore
|
||||||
@ -46,7 +48,7 @@ func (t *teardown) do(ctx context.Context, stage *types.Stage) error {
|
|||||||
Str("stage.status", stage.Status).
|
Str("stage.status", stage.Status).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
_, err = t.Repos.Find(noContext, execution.RepoID)
|
repo, err := t.Repos.Find(noContext, execution.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("manager: cannot find the repository")
|
log.Error().Err(err).Msg("manager: cannot find the repository")
|
||||||
return err
|
return err
|
||||||
@ -131,6 +133,13 @@ func (t *teardown) do(ctx context.Context, stage *types.Stage) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
execution.Stages = stages
|
||||||
|
err = t.Events.Publish(noContext, repo.ParentID, executionEvent(enum.ExecutionCompleted, execution))
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).
|
||||||
|
Msg("manager: could not publish execution completed event")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,10 @@ package manager
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
|
"github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
@ -16,6 +18,7 @@ import (
|
|||||||
type updater struct {
|
type updater struct {
|
||||||
Executions store.ExecutionStore
|
Executions store.ExecutionStore
|
||||||
Repos store.RepoStore
|
Repos store.RepoStore
|
||||||
|
Events events.EventsStreamer
|
||||||
Steps store.StepStore
|
Steps store.StepStore
|
||||||
Stages store.StageStore
|
Stages store.StageStore
|
||||||
}
|
}
|
||||||
@ -36,5 +39,35 @@ func (u *updater) do(ctx context.Context, step *types.Step) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stage, err := u.Stages.Find(noContext, step.StageID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("manager: cannot find stage")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
execution, err := u.Executions.Find(noContext, stage.ExecutionID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("manager: cannot find execution")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := u.Repos.Find(noContext, execution.RepoID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("manager: cannot find repo")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
stages, err := u.Stages.ListWithSteps(noContext, stage.ExecutionID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("manager: cannot find stages")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
execution.Stages = stages
|
||||||
|
err = u.Events.Publish(noContext, repo.ParentID, executionEvent(enum.ExecutionUpdated, execution))
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Msg("manager: cannot publish execution updated event")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package manager
|
package manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/harness/gitness/internal/pipeline/events"
|
||||||
"github.com/harness/gitness/internal/pipeline/file"
|
"github.com/harness/gitness/internal/pipeline/file"
|
||||||
"github.com/harness/gitness/internal/pipeline/scheduler"
|
"github.com/harness/gitness/internal/pipeline/scheduler"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
@ -28,6 +29,7 @@ func ProvideExecutionManager(
|
|||||||
executionStore store.ExecutionStore,
|
executionStore store.ExecutionStore,
|
||||||
pipelineStore store.PipelineStore,
|
pipelineStore store.PipelineStore,
|
||||||
urlProvider *url.Provider,
|
urlProvider *url.Provider,
|
||||||
|
events events.EventsStreamer,
|
||||||
fileService file.FileService,
|
fileService file.FileService,
|
||||||
logStore store.LogStore,
|
logStore store.LogStore,
|
||||||
logStream livelog.LogStream,
|
logStream livelog.LogStream,
|
||||||
@ -37,7 +39,7 @@ func ProvideExecutionManager(
|
|||||||
stageStore store.StageStore,
|
stageStore store.StageStore,
|
||||||
stepStore store.StepStore,
|
stepStore store.StepStore,
|
||||||
userStore store.PrincipalStore) ExecutionManager {
|
userStore store.PrincipalStore) ExecutionManager {
|
||||||
return New(config, executionStore, pipelineStore, urlProvider, fileService, logStore,
|
return New(config, executionStore, pipelineStore, urlProvider, events, fileService, logStore,
|
||||||
logStream, repoStore, scheduler, secretStore, stageStore, stepStore, userStore)
|
logStream, repoStore, scheduler, secretStore, stageStore, stepStore, userStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,6 +188,8 @@ func setupSpaces(r chi.Router, spaceCtrl *space.Controller) {
|
|||||||
r.Patch("/", handlerspace.HandleUpdate(spaceCtrl))
|
r.Patch("/", handlerspace.HandleUpdate(spaceCtrl))
|
||||||
r.Delete("/", handlerspace.HandleDelete(spaceCtrl))
|
r.Delete("/", handlerspace.HandleDelete(spaceCtrl))
|
||||||
|
|
||||||
|
r.Get("/stream", handlerspace.HandleEventsStream(spaceCtrl))
|
||||||
|
|
||||||
r.Post("/move", handlerspace.HandleMove(spaceCtrl))
|
r.Post("/move", handlerspace.HandleMove(spaceCtrl))
|
||||||
r.Get("/spaces", handlerspace.HandleListSpaces(spaceCtrl))
|
r.Get("/spaces", handlerspace.HandleListSpaces(spaceCtrl))
|
||||||
r.Get("/repos", handlerspace.HandleListRepos(spaceCtrl))
|
r.Get("/repos", handlerspace.HandleListRepos(spaceCtrl))
|
||||||
@ -232,6 +234,7 @@ func setupRepos(r chi.Router,
|
|||||||
r.Route("/repos", func(r chi.Router) {
|
r.Route("/repos", func(r chi.Router) {
|
||||||
// Create takes path and parentId via body, not uri
|
// Create takes path and parentId via body, not uri
|
||||||
r.Post("/", handlerrepo.HandleCreate(repoCtrl))
|
r.Post("/", handlerrepo.HandleCreate(repoCtrl))
|
||||||
|
r.Post("/import", handlerrepo.HandleImport(repoCtrl))
|
||||||
r.Route(fmt.Sprintf("/{%s}", request.PathParamRepoRef), func(r chi.Router) {
|
r.Route(fmt.Sprintf("/{%s}", request.PathParamRepoRef), func(r chi.Router) {
|
||||||
// repo level operations
|
// repo level operations
|
||||||
r.Get("/", handlerrepo.HandleFind(repoCtrl))
|
r.Get("/", handlerrepo.HandleFind(repoCtrl))
|
||||||
@ -241,6 +244,8 @@ func setupRepos(r chi.Router,
|
|||||||
r.Post("/move", handlerrepo.HandleMove(repoCtrl))
|
r.Post("/move", handlerrepo.HandleMove(repoCtrl))
|
||||||
r.Get("/service-accounts", handlerrepo.HandleListServiceAccounts(repoCtrl))
|
r.Get("/service-accounts", handlerrepo.HandleListServiceAccounts(repoCtrl))
|
||||||
|
|
||||||
|
r.Get("/import-progress", handlerrepo.HandleImportProgress(repoCtrl))
|
||||||
|
|
||||||
// content operations
|
// content operations
|
||||||
// NOTE: this allows /content and /content/ to both be valid (without any other tricks.)
|
// NOTE: this allows /content and /content/ to both be valid (without any other tricks.)
|
||||||
// We don't expect there to be any other operations in that route (as that could overlap with file names)
|
// We don't expect there to be any other operations in that route (as that could overlap with file names)
|
||||||
|
142
internal/services/importer/provider.go
Normal file
142
internal/services/importer/provider.go
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package importer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/api/usererror"
|
||||||
|
|
||||||
|
"github.com/drone/go-scm/scm"
|
||||||
|
"github.com/drone/go-scm/scm/driver/github"
|
||||||
|
"github.com/drone/go-scm/scm/transport/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProviderType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ProviderTypeGitHub ProviderType = "github"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProviderInfo struct {
|
||||||
|
Type ProviderType
|
||||||
|
Host string
|
||||||
|
User string
|
||||||
|
Pass string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RepositoryInfo struct {
|
||||||
|
Space string
|
||||||
|
UID string
|
||||||
|
CloneURL string
|
||||||
|
IsPublic bool
|
||||||
|
DefaultBranch string
|
||||||
|
}
|
||||||
|
|
||||||
|
func getClient(provider ProviderInfo) (*scm.Client, error) {
|
||||||
|
var scmClient *scm.Client
|
||||||
|
|
||||||
|
switch provider.Type {
|
||||||
|
case "":
|
||||||
|
return nil, usererror.BadRequest("provider can not be empty")
|
||||||
|
case ProviderTypeGitHub:
|
||||||
|
scmClient = github.NewDefault()
|
||||||
|
if provider.Pass != "" {
|
||||||
|
scmClient.Client = &http.Client{
|
||||||
|
Transport: &oauth2.Transport{
|
||||||
|
Source: oauth2.StaticTokenSource(&scm.Token{Token: provider.Pass}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, usererror.BadRequestf("unsupported provider: %s", provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
return scmClient, nil
|
||||||
|
}
|
||||||
|
func Repo(ctx context.Context, provider ProviderInfo, repoSlug string) (RepositoryInfo, error) {
|
||||||
|
scmClient, err := getClient(provider)
|
||||||
|
if err != nil {
|
||||||
|
return RepositoryInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
scmRepo, _, err := scmClient.Repositories.Find(ctx, repoSlug)
|
||||||
|
if errors.Is(err, scm.ErrNotFound) {
|
||||||
|
return RepositoryInfo{}, usererror.BadRequestf("repository %s not found at %s", repoSlug, provider)
|
||||||
|
}
|
||||||
|
if errors.Is(err, scm.ErrNotAuthorized) {
|
||||||
|
return RepositoryInfo{}, usererror.BadRequestf("bad credentials provided for %s at %s", repoSlug, provider)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return RepositoryInfo{}, fmt.Errorf("failed to fetch repository %s from %s: %w", repoSlug, provider, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return RepositoryInfo{
|
||||||
|
Space: scmRepo.Namespace,
|
||||||
|
UID: scmRepo.Name,
|
||||||
|
CloneURL: scmRepo.Clone,
|
||||||
|
IsPublic: !scmRepo.Private,
|
||||||
|
DefaultBranch: scmRepo.Branch,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Space(ctx context.Context, provider ProviderInfo, space string) (map[string]RepositoryInfo, error) {
|
||||||
|
scmClient, err := getClient(provider)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
repoMap := make(map[string]RepositoryInfo)
|
||||||
|
|
||||||
|
const pageSize = 50
|
||||||
|
page := 1
|
||||||
|
for {
|
||||||
|
scmRepos, scmResponse, err := scmClient.Repositories.ListV2(ctx, scm.RepoListOptions{
|
||||||
|
ListOptions: scm.ListOptions{
|
||||||
|
URL: "",
|
||||||
|
Page: page,
|
||||||
|
Size: pageSize,
|
||||||
|
},
|
||||||
|
RepoSearchTerm: scm.RepoSearchTerm{
|
||||||
|
RepoName: "",
|
||||||
|
User: space,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if errors.Is(err, scm.ErrNotFound) {
|
||||||
|
return nil, usererror.BadRequestf("space %s not found at %s", space, provider)
|
||||||
|
}
|
||||||
|
if errors.Is(err, scm.ErrNotAuthorized) {
|
||||||
|
return nil, usererror.BadRequestf("bad credentials provided for %s at %s", space, provider)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to fetch space %s from %s: %w", space, provider, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, scmRepo := range scmRepos {
|
||||||
|
if !scmRepo.Perm.Pull {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
repoMap[scmRepo.Name] = RepositoryInfo{
|
||||||
|
Space: scmRepo.Namespace,
|
||||||
|
UID: scmRepo.Name,
|
||||||
|
CloneURL: scmRepo.Clone,
|
||||||
|
IsPublic: !scmRepo.Private,
|
||||||
|
DefaultBranch: scmRepo.Branch,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(scmRepos) == 0 || page == scmResponse.Page.Last {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
page++
|
||||||
|
}
|
||||||
|
|
||||||
|
return repoMap, nil
|
||||||
|
}
|
165
internal/services/importer/repository.go
Normal file
165
internal/services/importer/repository.go
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package importer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/gitrpc"
|
||||||
|
"github.com/harness/gitness/internal/bootstrap"
|
||||||
|
"github.com/harness/gitness/internal/githook"
|
||||||
|
"github.com/harness/gitness/internal/services/job"
|
||||||
|
"github.com/harness/gitness/internal/store"
|
||||||
|
gitnessurl "github.com/harness/gitness/internal/url"
|
||||||
|
gitness_store "github.com/harness/gitness/store"
|
||||||
|
"github.com/harness/gitness/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
urlProvider *gitnessurl.Provider
|
||||||
|
git gitrpc.Interface
|
||||||
|
repoStore store.RepoStore
|
||||||
|
scheduler *job.Scheduler
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ job.Handler = (*Repository)(nil)
|
||||||
|
|
||||||
|
type Input struct {
|
||||||
|
RepoID int64 `json:"repo_id"`
|
||||||
|
GitUser string `json:"git_user"`
|
||||||
|
GitPass string `json:"git_pass"`
|
||||||
|
CloneURL string `json:"clone_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const jobType = "repository_import"
|
||||||
|
|
||||||
|
func (i *Repository) Register(executor *job.Executor) error {
|
||||||
|
return executor.Register(jobType, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Repository) Run(ctx context.Context, jobUID string, input Input) error {
|
||||||
|
data, err := json.Marshal(input)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
strData := strings.TrimSpace(string(data))
|
||||||
|
|
||||||
|
return i.scheduler.RunJob(ctx, job.Definition{
|
||||||
|
UID: jobUID,
|
||||||
|
Type: jobType,
|
||||||
|
MaxRetries: 1,
|
||||||
|
Timeout: 30 * time.Minute,
|
||||||
|
Data: strData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle is repository import background job handler.
|
||||||
|
func (i *Repository) Handle(ctx context.Context, data string, _ job.ProgressReporter) (string, error) {
|
||||||
|
var input Input
|
||||||
|
if err := json.NewDecoder(strings.NewReader(data)).Decode(&input); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to unmarshal job input: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.CloneURL == "" {
|
||||||
|
return "", errors.New("missing git repository clone URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.GitUser != "" || input.GitPass != "" {
|
||||||
|
repoURL, err := url.Parse(input.CloneURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to parse git clone URL: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
repoURL.User = url.UserPassword(input.GitUser, input.GitPass)
|
||||||
|
input.CloneURL = repoURL.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := i.repoStore.Find(ctx, input.RepoID)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to find repo by id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !repo.Importing {
|
||||||
|
return "", fmt.Errorf("repository %s is not being imported", repo.UID)
|
||||||
|
}
|
||||||
|
|
||||||
|
writeParams, err := createRPCWriteParams(ctx, i.urlProvider, repo)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to create write params: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
syncOut, err := i.git.SyncRepository(ctx, &gitrpc.SyncRepositoryParams{
|
||||||
|
WriteParams: writeParams,
|
||||||
|
Source: input.CloneURL,
|
||||||
|
CreateIfNotExists: false,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to sync repositories: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
repo.Importing = false
|
||||||
|
repo.DefaultBranch = syncOut.DefaultBranch
|
||||||
|
|
||||||
|
err = i.repoStore.Update(ctx, repo)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to update repository after import: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Repository) GetProgress(ctx context.Context, repo *types.Repository) (types.JobProgress, error) {
|
||||||
|
if !repo.Importing || repo.ImportingJobUID == nil || *repo.ImportingJobUID == "" {
|
||||||
|
// if the repo is not being imported, or it's job ID has been cleared (or never existed) return state=finished
|
||||||
|
return job.DoneProgress(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
progress, err := i.scheduler.GetJobProgress(ctx, *repo.ImportingJobUID)
|
||||||
|
if errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||||
|
// if the job is not found return state=failed
|
||||||
|
return job.FailProgress(), nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return types.JobProgress{}, fmt.Errorf("failed to get job progress: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return progress, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRPCWriteParams creates base write parameters for gitrpc write operations.
|
||||||
|
func createRPCWriteParams(ctx context.Context,
|
||||||
|
urlProvider *gitnessurl.Provider,
|
||||||
|
repo *types.Repository,
|
||||||
|
) (gitrpc.WriteParams, error) {
|
||||||
|
gitnessSession := bootstrap.NewSystemServiceSession()
|
||||||
|
|
||||||
|
// generate envars (add everything githook CLI needs for execution)
|
||||||
|
envVars, err := githook.GenerateEnvironmentVariables(
|
||||||
|
ctx,
|
||||||
|
urlProvider.GetAPIBaseURLInternal(),
|
||||||
|
repo.ID,
|
||||||
|
gitnessSession.Principal.ID,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return gitrpc.WriteParams{}, fmt.Errorf("failed to generate git hook environment variables: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return gitrpc.WriteParams{
|
||||||
|
Actor: gitrpc.Identity{
|
||||||
|
Name: gitnessSession.Principal.DisplayName,
|
||||||
|
Email: gitnessSession.Principal.Email,
|
||||||
|
},
|
||||||
|
RepoUID: repo.GitUID,
|
||||||
|
EnvVars: envVars,
|
||||||
|
}, nil
|
||||||
|
}
|
40
internal/services/importer/wire.go
Normal file
40
internal/services/importer/wire.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package importer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/harness/gitness/gitrpc"
|
||||||
|
"github.com/harness/gitness/internal/services/job"
|
||||||
|
"github.com/harness/gitness/internal/store"
|
||||||
|
"github.com/harness/gitness/internal/url"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
var WireSet = wire.NewSet(
|
||||||
|
ProvideRepoImporter,
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProvideRepoImporter(
|
||||||
|
urlProvider *url.Provider,
|
||||||
|
git gitrpc.Interface,
|
||||||
|
repoStore store.RepoStore,
|
||||||
|
scheduler *job.Scheduler,
|
||||||
|
executor *job.Executor,
|
||||||
|
) (*Repository, error) {
|
||||||
|
importer := &Repository{
|
||||||
|
urlProvider: urlProvider,
|
||||||
|
git: git,
|
||||||
|
repoStore: repoStore,
|
||||||
|
scheduler: scheduler,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := executor.Register(jobType, importer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return importer, nil
|
||||||
|
}
|
22
internal/services/trigger/handler_branch.go
Normal file
22
internal/services/trigger/handler_branch.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package trigger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
gitevents "github.com/harness/gitness/internal/events/git"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) handleEventBranchCreated(ctx context.Context,
|
||||||
|
event *events.Event[*gitevents.BranchCreatedPayload]) error {
|
||||||
|
return events.NewDiscardEventErrorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) handleEventBranchUpdated(ctx context.Context,
|
||||||
|
event *events.Event[*gitevents.BranchUpdatedPayload]) error {
|
||||||
|
return events.NewDiscardEventErrorf("not implemented")
|
||||||
|
}
|
27
internal/services/trigger/handler_pullreq.go
Normal file
27
internal/services/trigger/handler_pullreq.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package trigger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
pullreqevents "github.com/harness/gitness/internal/events/pullreq"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) handleEventPullReqCreated(ctx context.Context,
|
||||||
|
event *events.Event[*pullreqevents.CreatedPayload]) error {
|
||||||
|
return events.NewDiscardEventErrorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) handleEventPullReqReopened(ctx context.Context,
|
||||||
|
event *events.Event[*pullreqevents.ReopenedPayload]) error {
|
||||||
|
return events.NewDiscardEventErrorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) handleEventPullReqBranchUpdated(ctx context.Context,
|
||||||
|
event *events.Event[*pullreqevents.BranchUpdatedPayload]) error {
|
||||||
|
return events.NewDiscardEventErrorf("not implemented")
|
||||||
|
}
|
22
internal/services/trigger/handler_tag.go
Normal file
22
internal/services/trigger/handler_tag.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package trigger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
gitevents "github.com/harness/gitness/internal/events/git"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) handleEventTagCreated(ctx context.Context,
|
||||||
|
event *events.Event[*gitevents.TagCreatedPayload]) error {
|
||||||
|
return events.NewDiscardEventErrorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) handleEventTagUpdated(ctx context.Context,
|
||||||
|
event *events.Event[*gitevents.TagUpdatedPayload]) error {
|
||||||
|
return events.NewDiscardEventErrorf("not implemented")
|
||||||
|
}
|
103
internal/services/trigger/service.go
Normal file
103
internal/services/trigger/service.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package trigger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
gitevents "github.com/harness/gitness/internal/events/git"
|
||||||
|
pullreqevents "github.com/harness/gitness/internal/events/pullreq"
|
||||||
|
"github.com/harness/gitness/stream"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eventsReaderGroupName = "gitness:trigger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
EventReaderName string
|
||||||
|
Concurrency int
|
||||||
|
MaxRetries int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) Prepare() error {
|
||||||
|
if c == nil {
|
||||||
|
return errors.New("config is required")
|
||||||
|
}
|
||||||
|
if c.EventReaderName == "" {
|
||||||
|
return errors.New("config.EventReaderName is required")
|
||||||
|
}
|
||||||
|
if c.Concurrency < 1 {
|
||||||
|
return errors.New("config.Concurrency has to be a positive number")
|
||||||
|
}
|
||||||
|
if c.MaxRetries < 0 {
|
||||||
|
return errors.New("config.MaxRetries can't be negative")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service struct{}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
ctx context.Context,
|
||||||
|
config Config,
|
||||||
|
gitReaderFactory *events.ReaderFactory[*gitevents.Reader],
|
||||||
|
pullreqEvReaderFactory *events.ReaderFactory[*pullreqevents.Reader],
|
||||||
|
) (*Service, error) {
|
||||||
|
if err := config.Prepare(); err != nil {
|
||||||
|
return nil, fmt.Errorf("provided trigger service config is invalid: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
service := &Service{}
|
||||||
|
|
||||||
|
_, err := gitReaderFactory.Launch(ctx, eventsReaderGroupName, config.EventReaderName,
|
||||||
|
func(r *gitevents.Reader) error {
|
||||||
|
const idleTimeout = 1 * time.Minute
|
||||||
|
r.Configure(
|
||||||
|
stream.WithConcurrency(config.Concurrency),
|
||||||
|
stream.WithHandlerOptions(
|
||||||
|
stream.WithIdleTimeout(idleTimeout),
|
||||||
|
stream.WithMaxRetries(config.MaxRetries),
|
||||||
|
))
|
||||||
|
|
||||||
|
_ = r.RegisterBranchCreated(service.handleEventBranchCreated)
|
||||||
|
_ = r.RegisterBranchUpdated(service.handleEventBranchUpdated)
|
||||||
|
|
||||||
|
_ = r.RegisterTagCreated(service.handleEventTagCreated)
|
||||||
|
_ = r.RegisterTagUpdated(service.handleEventTagUpdated)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to launch git events reader: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = pullreqEvReaderFactory.Launch(ctx, eventsReaderGroupName, config.EventReaderName,
|
||||||
|
func(r *pullreqevents.Reader) error {
|
||||||
|
const idleTimeout = 1 * time.Minute
|
||||||
|
r.Configure(
|
||||||
|
stream.WithConcurrency(config.Concurrency),
|
||||||
|
stream.WithHandlerOptions(
|
||||||
|
stream.WithIdleTimeout(idleTimeout),
|
||||||
|
stream.WithMaxRetries(config.MaxRetries),
|
||||||
|
))
|
||||||
|
|
||||||
|
_ = r.RegisterCreated(service.handleEventPullReqCreated)
|
||||||
|
_ = r.RegisterBranchUpdated(service.handleEventPullReqBranchUpdated)
|
||||||
|
_ = r.RegisterReopened(service.handleEventPullReqReopened)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to launch pr events reader: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return service, nil
|
||||||
|
}
|
28
internal/services/trigger/wire.go
Normal file
28
internal/services/trigger/wire.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package trigger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/events"
|
||||||
|
gitevents "github.com/harness/gitness/internal/events/git"
|
||||||
|
pullreqevents "github.com/harness/gitness/internal/events/pullreq"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
var WireSet = wire.NewSet(
|
||||||
|
ProvideService,
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProvideService(
|
||||||
|
ctx context.Context,
|
||||||
|
config Config,
|
||||||
|
gitReaderFactory *events.ReaderFactory[*gitevents.Reader],
|
||||||
|
pullReqEvFactory *events.ReaderFactory[*pullreqevents.Reader],
|
||||||
|
) (*Service, error) {
|
||||||
|
return New(ctx, config, gitReaderFactory, pullReqEvFactory)
|
||||||
|
}
|
@ -27,17 +27,15 @@ const (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
// UserAgentIdentity specifies the identity used for the user agent header
|
// UserAgentIdentity specifies the identity used for the user agent header
|
||||||
// IMPORTANT: do not include version.
|
// IMPORTANT: do not include version.
|
||||||
UserAgentIdentity string `envconfig:"GITNESS_WEBHOOK_USER_AGENT_IDENTITY" default:"Gitness"`
|
UserAgentIdentity string
|
||||||
// HeaderIdentity specifies the identity used for headers in webhook calls (e.g. X-Gitness-Trigger, ...).
|
// HeaderIdentity specifies the identity used for headers in webhook calls (e.g. X-Gitness-Trigger, ...).
|
||||||
// NOTE: If no value is provided, the UserAgentIdentity will be used.
|
// NOTE: If no value is provided, the UserAgentIdentity will be used.
|
||||||
HeaderIdentity string `envconfig:"GITNESS_WEBHOOK_HEADER_IDENTITY"`
|
HeaderIdentity string
|
||||||
// EventReaderName is the name used to read events from stream.
|
EventReaderName string
|
||||||
// Note: this should be different for every running instance.
|
Concurrency int
|
||||||
EventReaderName string `envconfig:"GITNESS_WEBHOOK_EVENT_READER_NAME"`
|
MaxRetries int
|
||||||
Concurrency int `envconfig:"GITNESS_WEBHOOK_CONCURRENCY" default:"4"`
|
AllowPrivateNetwork bool
|
||||||
MaxRetries int `envconfig:"GITNESS_WEBHOOK_MAX_RETRIES" default:"3"`
|
AllowLoopback bool
|
||||||
AllowPrivateNetwork bool `envconfig:"GITNESS_WEBHOOK_ALLOW_PRIVATE_NETWORK" default:"false"`
|
|
||||||
AllowLoopback bool `envconfig:"GITNESS_WEBHOOK_ALLOW_LOOPBACK" default:"false"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Prepare() error {
|
func (c *Config) Prepare() error {
|
||||||
@ -91,7 +89,7 @@ func NewService(ctx context.Context, config Config,
|
|||||||
repoStore store.RepoStore, pullreqStore store.PullReqStore, urlProvider *url.Provider,
|
repoStore store.RepoStore, pullreqStore store.PullReqStore, urlProvider *url.Provider,
|
||||||
principalStore store.PrincipalStore, gitRPCClient gitrpc.Interface) (*Service, error) {
|
principalStore store.PrincipalStore, gitRPCClient gitrpc.Interface) (*Service, error) {
|
||||||
if err := config.Prepare(); err != nil {
|
if err := config.Prepare(); err != nil {
|
||||||
return nil, fmt.Errorf("provided config is invalid: %w", err)
|
return nil, fmt.Errorf("provided webhook service config is invalid: %w", err)
|
||||||
}
|
}
|
||||||
service := &Service{
|
service := &Service{
|
||||||
webhookStore: webhookStore,
|
webhookStore: webhookStore,
|
||||||
|
@ -7,6 +7,7 @@ package services
|
|||||||
import (
|
import (
|
||||||
"github.com/harness/gitness/internal/services/job"
|
"github.com/harness/gitness/internal/services/job"
|
||||||
"github.com/harness/gitness/internal/services/pullreq"
|
"github.com/harness/gitness/internal/services/pullreq"
|
||||||
|
"github.com/harness/gitness/internal/services/trigger"
|
||||||
"github.com/harness/gitness/internal/services/webhook"
|
"github.com/harness/gitness/internal/services/webhook"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
@ -19,20 +20,20 @@ var WireSet = wire.NewSet(
|
|||||||
type Services struct {
|
type Services struct {
|
||||||
Webhook *webhook.Service
|
Webhook *webhook.Service
|
||||||
PullReq *pullreq.Service
|
PullReq *pullreq.Service
|
||||||
JobExecutor *job.Executor
|
Trigger *trigger.Service
|
||||||
JobScheduler *job.Scheduler
|
JobScheduler *job.Scheduler
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideServices(
|
func ProvideServices(
|
||||||
webhooksSrv *webhook.Service,
|
webhooksSvc *webhook.Service,
|
||||||
pullReqSrv *pullreq.Service,
|
pullReqSvc *pullreq.Service,
|
||||||
jobExecutor *job.Executor,
|
triggerSvc *trigger.Service,
|
||||||
jobScheduler *job.Scheduler,
|
jobScheduler *job.Scheduler,
|
||||||
) Services {
|
) Services {
|
||||||
return Services{
|
return Services{
|
||||||
Webhook: webhooksSrv,
|
Webhook: webhooksSvc,
|
||||||
PullReq: pullReqSrv,
|
PullReq: pullReqSvc,
|
||||||
JobExecutor: jobExecutor,
|
Trigger: triggerSvc,
|
||||||
JobScheduler: jobScheduler,
|
JobScheduler: jobScheduler,
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE repositories
|
||||||
|
DROP CONSTRAINT fk_repo_importing_job_uid,
|
||||||
|
DROP COLUMN repo_importing_job_uid,
|
||||||
|
DROP COLUMN repo_importing;
|
@ -0,0 +1,8 @@
|
|||||||
|
ALTER TABLE repositories
|
||||||
|
ADD COLUMN repo_importing BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
ADD COLUMN repo_importing_job_uid TEXT,
|
||||||
|
ADD CONSTRAINT fk_repo_importing_job_uid
|
||||||
|
FOREIGN KEY (repo_importing_job_uid)
|
||||||
|
REFERENCES jobs(job_uid)
|
||||||
|
ON DELETE SET NULL
|
||||||
|
ON UPDATE NO ACTION;
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE repositories DROP COLUMN repo_importing_job_uid;
|
||||||
|
ALTER TABLE repositories DROP COLUMN repo_importing;
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE repositories ADD COLUMN repo_importing BOOLEAN NOT NULL DEFAULT false;
|
||||||
|
ALTER TABLE repositories ADD COLUMN repo_importing_job_uid TEXT;
|
@ -58,7 +58,9 @@ const (
|
|||||||
,repo_num_pulls
|
,repo_num_pulls
|
||||||
,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_job_uid`
|
||||||
|
|
||||||
repoSelectBaseWithJoin = `
|
repoSelectBaseWithJoin = `
|
||||||
SELECT` + repoColumnsForJoin + `
|
SELECT` + repoColumnsForJoin + `
|
||||||
@ -124,6 +126,8 @@ func (s *RepoStore) Create(ctx context.Context, repo *types.Repository) error {
|
|||||||
,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_job_uid
|
||||||
) values (
|
) values (
|
||||||
:repo_version
|
:repo_version
|
||||||
,:repo_parent_id
|
,:repo_parent_id
|
||||||
@ -142,6 +146,8 @@ func (s *RepoStore) Create(ctx context.Context, repo *types.Repository) error {
|
|||||||
,: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_job_uid
|
||||||
) RETURNING repo_id`
|
) RETURNING repo_id`
|
||||||
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
@ -170,12 +176,15 @@ func (s *RepoStore) Update(ctx context.Context, repo *types.Repository) error {
|
|||||||
,repo_uid = :repo_uid
|
,repo_uid = :repo_uid
|
||||||
,repo_description = :repo_description
|
,repo_description = :repo_description
|
||||||
,repo_is_public = :repo_is_public
|
,repo_is_public = :repo_is_public
|
||||||
|
,repo_default_branch = :repo_default_branch
|
||||||
,repo_pullreq_seq = :repo_pullreq_seq
|
,repo_pullreq_seq = :repo_pullreq_seq
|
||||||
,repo_num_forks = :repo_num_forks
|
,repo_num_forks = :repo_num_forks
|
||||||
,repo_num_pulls = :repo_num_pulls
|
,repo_num_pulls = :repo_num_pulls
|
||||||
,repo_num_closed_pulls = :repo_num_closed_pulls
|
,repo_num_closed_pulls = :repo_num_closed_pulls
|
||||||
,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_job_uid = :repo_importing_job_uid
|
||||||
WHERE repo_id = :repo_id AND repo_version = :repo_version - 1`
|
WHERE repo_id = :repo_id AND repo_version = :repo_version - 1`
|
||||||
|
|
||||||
updatedAt := time.Now()
|
updatedAt := time.Now()
|
||||||
@ -295,17 +304,13 @@ func (s *RepoStore) List(ctx context.Context, parentID int64, opts *types.RepoFi
|
|||||||
// NOTE: string concatenation is safe because the
|
// NOTE: string concatenation is safe because the
|
||||||
// order attribute is an enum and is not user-defined,
|
// order attribute is an enum and is not user-defined,
|
||||||
// and is therefore not subject to injection attacks.
|
// and is therefore not subject to injection attacks.
|
||||||
stmt = stmt.OrderBy("repo_uid " + opts.Order.String())
|
stmt = stmt.OrderBy("repo_importing desc, repo_uid " + opts.Order.String())
|
||||||
//TODO: Postgres does not support COLLATE NOCASE for UTF8
|
|
||||||
// stmt = stmt.OrderBy("repo_uid COLLATE NOCASE " + opts.Order.String())
|
|
||||||
case enum.RepoAttrCreated:
|
case enum.RepoAttrCreated:
|
||||||
stmt = stmt.OrderBy("repo_created " + opts.Order.String())
|
stmt = stmt.OrderBy("repo_created " + opts.Order.String())
|
||||||
case enum.RepoAttrUpdated:
|
case enum.RepoAttrUpdated:
|
||||||
stmt = stmt.OrderBy("repo_updated " + opts.Order.String())
|
stmt = stmt.OrderBy("repo_updated " + opts.Order.String())
|
||||||
case enum.RepoAttrPath:
|
case enum.RepoAttrPath:
|
||||||
stmt = stmt.OrderBy("repo_path " + opts.Order.String())
|
stmt = stmt.OrderBy("repo_importing desc, repo_path " + opts.Order.String())
|
||||||
//TODO: Postgres does not support COLLATE NOCASE for UTF8
|
|
||||||
// stmt = stmt.OrderBy("repo_path COLLATE NOCASE " + opts.Order.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sql, args, err := stmt.ToSql()
|
sql, args, err := stmt.ToSql()
|
||||||
|
37
internal/writer/writeflush.go
Normal file
37
internal/writer/writeflush.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
package writer
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
type Flusher interface {
|
||||||
|
Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
type writeWithFlusher struct {
|
||||||
|
writer io.Writer
|
||||||
|
flusher Flusher
|
||||||
|
}
|
||||||
|
|
||||||
|
type WriterFlusher interface {
|
||||||
|
io.Writer
|
||||||
|
Flusher
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWriterFlusher(writer io.Writer, flusher Flusher) WriterFlusher {
|
||||||
|
return &writeWithFlusher{
|
||||||
|
writer: writer,
|
||||||
|
flusher: flusher,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *writeWithFlusher) Write(p []byte) (int, error) {
|
||||||
|
n, err := w.writer.Write(p)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *writeWithFlusher) Flush() {
|
||||||
|
w.flusher.Flush()
|
||||||
|
}
|
@ -200,4 +200,22 @@ type Config struct {
|
|||||||
// finished and failed jobs will be purged from the DB.
|
// finished and failed jobs will be purged from the DB.
|
||||||
PurgeFinishedOlderThan time.Duration `envconfig:"GITNESS_JOBS_PURGE_FINISHED_OLDER_THAN" default:"120h"`
|
PurgeFinishedOlderThan time.Duration `envconfig:"GITNESS_JOBS_PURGE_FINISHED_OLDER_THAN" default:"120h"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Webhook struct {
|
||||||
|
// UserAgentIdentity specifies the identity used for the user agent header
|
||||||
|
// IMPORTANT: do not include version.
|
||||||
|
UserAgentIdentity string `envconfig:"GITNESS_WEBHOOK_USER_AGENT_IDENTITY" default:"Gitness"`
|
||||||
|
// HeaderIdentity specifies the identity used for headers in webhook calls (e.g. X-Gitness-Trigger, ...).
|
||||||
|
// NOTE: If no value is provided, the UserAgentIdentity will be used.
|
||||||
|
HeaderIdentity string `envconfig:"GITNESS_WEBHOOK_HEADER_IDENTITY"`
|
||||||
|
Concurrency int `envconfig:"GITNESS_WEBHOOK_CONCURRENCY" default:"4"`
|
||||||
|
MaxRetries int `envconfig:"GITNESS_WEBHOOK_MAX_RETRIES" default:"3"`
|
||||||
|
AllowPrivateNetwork bool `envconfig:"GITNESS_WEBHOOK_ALLOW_PRIVATE_NETWORK" default:"false"`
|
||||||
|
AllowLoopback bool `envconfig:"GITNESS_WEBHOOK_ALLOW_LOOPBACK" default:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Trigger struct {
|
||||||
|
Concurrency int `envconfig:"GITNESS_TRIGGER_CONCURRENCY" default:"4"`
|
||||||
|
MaxRetries int `envconfig:"GITNESS_TRIGGER_MAX_RETRIES" default:"3"`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
15
types/enum/event_types.go
Normal file
15
types/enum/event_types.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2022 Harness Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Polyform Free Trial License
|
||||||
|
// that can be found in the LICENSE.md file for this repository.
|
||||||
|
|
||||||
|
// Enums for event types delivered to the event stream for the UI
|
||||||
|
package enum
|
||||||
|
|
||||||
|
// EventType defines the kind of event
|
||||||
|
type EventType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ExecutionUpdated = "execution_updated"
|
||||||
|
ExecutionRunning = "execution_running"
|
||||||
|
ExecutionCompleted = "execution_completed"
|
||||||
|
)
|
@ -35,6 +35,9 @@ type Repository struct {
|
|||||||
NumOpenPulls int `db:"repo_num_open_pulls" json:"num_open_pulls"`
|
NumOpenPulls int `db:"repo_num_open_pulls" json:"num_open_pulls"`
|
||||||
NumMergedPulls int `db:"repo_num_merged_pulls" json:"num_merged_pulls"`
|
NumMergedPulls int `db:"repo_num_merged_pulls" json:"num_merged_pulls"`
|
||||||
|
|
||||||
|
Importing bool `db:"repo_importing" json:"importing"`
|
||||||
|
ImportingJobUID *string `db:"repo_importing_job_uid" json:"-"`
|
||||||
|
|
||||||
// git urls
|
// git urls
|
||||||
GitURL string `db:"-" json:"git_url"`
|
GitURL string `db:"-" json:"git_url"`
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,8 @@ const devConfig = {
|
|||||||
secure: false,
|
secure: false,
|
||||||
changeOrigin: true
|
changeOrigin: true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
compress: false
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
"marked": "^4.0.12",
|
"marked": "^4.0.12",
|
||||||
"masonry-layout": "^4.2.2",
|
"masonry-layout": "^4.2.2",
|
||||||
"moment": "^2.25.3",
|
"moment": "^2.25.3",
|
||||||
"monaco-editor": "^0.37.1",
|
"monaco-editor": "^0.40.0",
|
||||||
"monaco-editor-webpack-plugin": "^7.0.1",
|
"monaco-editor-webpack-plugin": "^7.0.1",
|
||||||
"monaco-yaml": "^4.0.4",
|
"monaco-yaml": "^4.0.4",
|
||||||
"qs": "^6.9.4",
|
"qs": "^6.9.4",
|
||||||
@ -72,7 +72,7 @@
|
|||||||
"react-intersection-observer": "^9.4.1",
|
"react-intersection-observer": "^9.4.1",
|
||||||
"react-jsx-match": "^1.1.5",
|
"react-jsx-match": "^1.1.5",
|
||||||
"react-keywords": "^0.0.5",
|
"react-keywords": "^0.0.5",
|
||||||
"react-monaco-editor": "^0.52.0",
|
"react-monaco-editor": "^0.54.0",
|
||||||
"react-pdf": "^7.1.2",
|
"react-pdf": "^7.1.2",
|
||||||
"react-resize-detector": "^7.1.2",
|
"react-resize-detector": "^7.1.2",
|
||||||
"react-router-dom": "^5.2.1",
|
"react-router-dom": "^5.2.1",
|
||||||
@ -130,7 +130,6 @@
|
|||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^26.2.0",
|
"jest": "^26.2.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"lint-staged": "^11.0.0",
|
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mini-css-extract-plugin": "^2.4.2",
|
"mini-css-extract-plugin": "^2.4.2",
|
||||||
"mustache": "^4.0.1",
|
"mustache": "^4.0.1",
|
||||||
@ -157,34 +156,5 @@
|
|||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.16.0"
|
"node": ">=14.16.0"
|
||||||
},
|
|
||||||
"lint-staged": {
|
|
||||||
"*.{ts,tsx}": [
|
|
||||||
"eslint --rulesdir ./scripts/eslint-rules --resolve-plugins-relative-to",
|
|
||||||
"sh scripts/typecheck-staged.sh",
|
|
||||||
"prettier --check"
|
|
||||||
],
|
|
||||||
"*.scss": [
|
|
||||||
"prettier --check"
|
|
||||||
],
|
|
||||||
"strings.*.yaml": [
|
|
||||||
"npm strings:check"
|
|
||||||
],
|
|
||||||
"webpack.devServerProxy.config.js": [
|
|
||||||
"exit 1"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"i18nSettings": {
|
|
||||||
"extensionToLanguageMap": {
|
|
||||||
"es": [
|
|
||||||
"es"
|
|
||||||
],
|
|
||||||
"en": [
|
|
||||||
"en",
|
|
||||||
"en-US",
|
|
||||||
"en-IN",
|
|
||||||
"en-UK"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState, useContext, useEffect } from 'react'
|
import React, { useState, useContext, useEffect, useMemo } from 'react'
|
||||||
|
import { matchPath } from 'react-router-dom'
|
||||||
import { noop } from 'lodash-es'
|
import { noop } from 'lodash-es'
|
||||||
import { useGet } from 'restful-react'
|
import { useGet } from 'restful-react'
|
||||||
import type { AppProps } from 'AppProps'
|
import type { AppProps } from 'AppProps'
|
||||||
@ -33,8 +34,13 @@ export const AppContextProvider: React.FC<{ value: AppProps }> = React.memo(func
|
|||||||
value: initialValue,
|
value: initialValue,
|
||||||
children
|
children
|
||||||
}) {
|
}) {
|
||||||
|
const lazy = useMemo(
|
||||||
|
() => initialValue.standalone && !!matchPath(location.pathname, { path: '/(signin|register)' }),
|
||||||
|
[initialValue.standalone]
|
||||||
|
)
|
||||||
const { data: currentUser = defaultCurrentUser } = useGet({
|
const { data: currentUser = defaultCurrentUser } = useGet({
|
||||||
path: '/api/v1/user'
|
path: '/api/v1/user',
|
||||||
|
lazy
|
||||||
})
|
})
|
||||||
const [appStates, setAppStates] = useState<AppProps>(initialValue)
|
const [appStates, setAppStates] = useState<AppProps>(initialValue)
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ import AddUpdatePipeline from 'pages/AddUpdatePipeline/AddUpdatePipeline'
|
|||||||
export const RouteDestinations: React.FC = React.memo(function RouteDestinations() {
|
export const RouteDestinations: React.FC = React.memo(function RouteDestinations() {
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
const repoPath = `${pathProps.space}/${pathProps.repoName}`
|
const repoPath = `${pathProps.space}/${pathProps.repoName}`
|
||||||
|
|
||||||
const { OPEN_SOURCE_PIPELINES, OPEN_SOURCE_SECRETS } = useFeatureFlag()
|
const { OPEN_SOURCE_PIPELINES, OPEN_SOURCE_SECRETS } = useFeatureFlag()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: black;
|
background-color: var(--black);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.header {
|
.header {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
background-color: var(--black);
|
background-color: var(--black) !important;
|
||||||
height: var(--log-content-header-height);
|
height: var(--log-content-header-height);
|
||||||
|
|
||||||
.headerLayout {
|
.headerLayout {
|
||||||
|
@ -6,7 +6,7 @@ import type { CODEProps } from 'RouteDefinitions'
|
|||||||
import type { TypesStage } from 'services/code'
|
import type { TypesStage } from 'services/code'
|
||||||
import ConsoleStep from 'components/ConsoleStep/ConsoleStep'
|
import ConsoleStep from 'components/ConsoleStep/ConsoleStep'
|
||||||
import { timeDistance } from 'utils/Utils'
|
import { timeDistance } from 'utils/Utils'
|
||||||
// import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
import { useStrings } from 'framework/strings'
|
||||||
import css from './Console.module.scss'
|
import css from './Console.module.scss'
|
||||||
|
|
||||||
interface ConsoleProps {
|
interface ConsoleProps {
|
||||||
@ -16,6 +16,7 @@ interface ConsoleProps {
|
|||||||
|
|
||||||
const Console: FC<ConsoleProps> = ({ stage, repoPath }) => {
|
const Console: FC<ConsoleProps> = ({ stage, repoPath }) => {
|
||||||
const { pipeline, execution: executionNum } = useParams<CODEProps>()
|
const { pipeline, execution: executionNum } = useParams<CODEProps>()
|
||||||
|
const { getString } = useStrings()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={css.container}>
|
<div className={css.container}>
|
||||||
@ -26,8 +27,7 @@ const Console: FC<ConsoleProps> = ({ stage, repoPath }) => {
|
|||||||
</Text>
|
</Text>
|
||||||
{stage?.started && stage?.stopped && (
|
{stage?.started && stage?.stopped && (
|
||||||
<Text font={{ variation: FontVariation.BODY }} color={Color.GREY_500}>
|
<Text font={{ variation: FontVariation.BODY }} color={Color.GREY_500}>
|
||||||
{/* this needs fixed */}
|
{getString('executions.completedTime', { timeString: timeDistance(stage?.stopped, Date.now()) })}
|
||||||
{timeDistance(stage?.started, stage?.stopped)}
|
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
.logLayout {
|
.logLayout {
|
||||||
margin-left: var(--spacing-xxxlarge) !important;
|
margin-left: 30px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lineNumber {
|
.lineNumber {
|
||||||
width: var(--spacing-xlarge);
|
min-width: var(--spacing-xlarge);
|
||||||
color: #999;
|
color: #999;
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
font-family: 'Roboto Mono' !important;
|
font-family: 'Roboto Mono' !important;
|
||||||
|
@ -1,35 +1,22 @@
|
|||||||
import { Layout, Text } from '@harnessio/uicore'
|
import { FlexExpander, Layout, Text } from '@harnessio/uicore'
|
||||||
import React, { FC } from 'react'
|
import React, { FC } from 'react'
|
||||||
|
import type { LivelogLine } from 'services/code'
|
||||||
import css from './ConsoleLogs.module.scss'
|
import css from './ConsoleLogs.module.scss'
|
||||||
|
|
||||||
// currently a string - should be an array of strings in future
|
|
||||||
interface ConsoleLogsProps {
|
interface ConsoleLogsProps {
|
||||||
logs: string
|
logs: LivelogLine[]
|
||||||
}
|
|
||||||
|
|
||||||
interface log {
|
|
||||||
pos: number
|
|
||||||
out: string
|
|
||||||
time: number
|
|
||||||
}
|
|
||||||
|
|
||||||
const convertStringToLogArray = (logs: string): log[] => {
|
|
||||||
const logStrings = logs.split('\n').map(log => {
|
|
||||||
return JSON.parse(log)
|
|
||||||
})
|
|
||||||
|
|
||||||
return logStrings
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConsoleLogs: FC<ConsoleLogsProps> = ({ logs }) => {
|
const ConsoleLogs: FC<ConsoleLogsProps> = ({ logs }) => {
|
||||||
const logArray = convertStringToLogArray(logs)
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{logArray.map((log, index) => {
|
{logs.map((log, index) => {
|
||||||
return (
|
return (
|
||||||
<Layout.Horizontal key={index} spacing={'medium'} className={css.logLayout}>
|
<Layout.Horizontal key={index} spacing={'medium'} className={css.logLayout}>
|
||||||
<Text className={css.lineNumber}>{log.pos}</Text>
|
<Text className={css.lineNumber}>{log.pos}</Text>
|
||||||
<Text className={css.log}>{log.out}</Text>
|
<Text className={css.log}>{log.out}</Text>
|
||||||
|
<FlexExpander />
|
||||||
|
<Text>{log.time}s</Text>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
@ -7,3 +7,16 @@
|
|||||||
.loading {
|
.loading {
|
||||||
margin-left: var(--spacing-xxxlarge) !important;
|
margin-left: var(--spacing-xxxlarge) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spin {
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// this is an auto-generated file
|
// this is an auto-generated file
|
||||||
declare const styles: {
|
declare const styles: {
|
||||||
readonly stepLayout: string
|
readonly spin: string
|
||||||
readonly loading: string
|
readonly loading: string
|
||||||
|
readonly stepLayout: string
|
||||||
}
|
}
|
||||||
export default styles
|
export default styles
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Icon } from '@harnessio/icons'
|
import { Icon } from '@harnessio/icons'
|
||||||
import { FlexExpander, Layout } from '@harnessio/uicore'
|
import { FlexExpander, Layout } from '@harnessio/uicore'
|
||||||
import React, { FC, useEffect } from 'react'
|
import React, { FC, useEffect, useRef, useState } from 'react'
|
||||||
import { useGet } from 'restful-react'
|
import { useGet } from 'restful-react'
|
||||||
import { Text } from '@harnessio/uicore'
|
import { Text } from '@harnessio/uicore'
|
||||||
import type { TypesStep } from 'services/code'
|
import type { LivelogLine, TypesStep } from 'services/code'
|
||||||
import { timeDistance } from 'utils/Utils'
|
import { timeDistance } from 'utils/Utils'
|
||||||
import ConsoleLogs from 'components/ConsoleLogs/ConsoleLogs'
|
import ConsoleLogs from 'components/ConsoleLogs/ConsoleLogs'
|
||||||
import { useStrings } from 'framework/strings'
|
import { useStrings } from 'framework/strings'
|
||||||
|
import { ExecutionState } from 'components/ExecutionStatus/ExecutionStatus'
|
||||||
import css from './ConsoleStep.module.scss'
|
import css from './ConsoleStep.module.scss'
|
||||||
|
|
||||||
interface ConsoleStepProps {
|
interface ConsoleStepProps {
|
||||||
@ -20,20 +21,68 @@ interface ConsoleStepProps {
|
|||||||
const ConsoleStep: FC<ConsoleStepProps> = ({ step, stageNumber, repoPath, pipelineName, executionNumber }) => {
|
const ConsoleStep: FC<ConsoleStepProps> = ({ step, stageNumber, repoPath, pipelineName, executionNumber }) => {
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
|
|
||||||
const [isOpened, setIsOpened] = React.useState(false)
|
const [isOpened, setIsOpened] = useState(false)
|
||||||
|
const [streamingLogs, setStreamingLogs] = useState<LivelogLine[]>([])
|
||||||
|
const eventSourceRef = useRef<EventSource | null>(null)
|
||||||
|
|
||||||
const { data, error, loading, refetch } = useGet<string>({
|
const shouldUseGet = step?.status !== ExecutionState.RUNNING && step?.status !== ExecutionState.PENDING
|
||||||
|
const isPending = step?.status === ExecutionState.PENDING
|
||||||
|
|
||||||
|
const { data, error, loading, refetch } = useGet<LivelogLine[]>({
|
||||||
path: `/api/v1/repos/${repoPath}/+/pipelines/${pipelineName}/executions/${executionNumber}/logs/${String(
|
path: `/api/v1/repos/${repoPath}/+/pipelines/${pipelineName}/executions/${executionNumber}/logs/${String(
|
||||||
stageNumber
|
stageNumber
|
||||||
)}/${String(step?.number)}`,
|
)}/${String(step?.number)}`,
|
||||||
lazy: true
|
lazy: true
|
||||||
})
|
})
|
||||||
|
|
||||||
// this refetches any open steps when the stage number changes - really it shouldnt refetch until reopened...
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsOpened(false)
|
setIsOpened(false)
|
||||||
refetch()
|
}, [stageNumber])
|
||||||
}, [stageNumber, refetch])
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (step?.status === ExecutionState.RUNNING) {
|
||||||
|
if (eventSourceRef.current) {
|
||||||
|
eventSourceRef.current.close()
|
||||||
|
setStreamingLogs([])
|
||||||
|
}
|
||||||
|
eventSourceRef.current = new EventSource(
|
||||||
|
`/api/v1/repos/${repoPath}/+/pipelines/${pipelineName}/executions/${executionNumber}/logs/${String(
|
||||||
|
stageNumber
|
||||||
|
)}/${String(step?.number)}/stream`
|
||||||
|
)
|
||||||
|
eventSourceRef.current.onmessage = event => {
|
||||||
|
const newLog = JSON.parse(event.data)
|
||||||
|
setStreamingLogs(existingLogs => {
|
||||||
|
return [...existingLogs, newLog]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
if (eventSourceRef.current) eventSourceRef.current.close()
|
||||||
|
}
|
||||||
|
}, [executionNumber, pipelineName, repoPath, stageNumber, step?.number, step?.status])
|
||||||
|
|
||||||
|
let icon
|
||||||
|
if (step?.status === ExecutionState.SUCCESS) {
|
||||||
|
icon = <Icon name="success-tick" />
|
||||||
|
} else if (isPending) {
|
||||||
|
icon = <Icon name="circle" />
|
||||||
|
} else if (step?.status === ExecutionState.RUNNING) {
|
||||||
|
icon = <Icon className={css.spin} name="pending" />
|
||||||
|
} else {
|
||||||
|
icon = <Icon name="circle" /> // Default icon in case of other statuses or unknown status
|
||||||
|
}
|
||||||
|
|
||||||
|
let content
|
||||||
|
if (loading) {
|
||||||
|
content = <div className={css.loading}>{getString('loading')}</div>
|
||||||
|
} else if (error && step?.status !== ExecutionState.RUNNING) {
|
||||||
|
content = <div>Error: {error.message}</div>
|
||||||
|
} else if (streamingLogs.length) {
|
||||||
|
content = <ConsoleLogs logs={streamingLogs} />
|
||||||
|
} else if (data) {
|
||||||
|
content = <ConsoleLogs logs={data} />
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -41,25 +90,20 @@ const ConsoleStep: FC<ConsoleStepProps> = ({ step, stageNumber, repoPath, pipeli
|
|||||||
className={css.stepLayout}
|
className={css.stepLayout}
|
||||||
spacing="medium"
|
spacing="medium"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsOpened(!isOpened)
|
if (!isPending) {
|
||||||
if (!data && !loading) refetch()
|
setIsOpened(!isOpened)
|
||||||
|
if (shouldUseGet && !isOpened) refetch()
|
||||||
|
}
|
||||||
}}>
|
}}>
|
||||||
<Icon name={isOpened ? 'chevron-down' : 'chevron-right'} />
|
<Icon name={isOpened ? 'chevron-down' : 'chevron-right'} />
|
||||||
<Icon name={step?.status === 'Success' ? 'success-tick' : 'circle'} />
|
{/* TODO - flesh icon logic out */}
|
||||||
|
{icon}
|
||||||
<Text>{step?.name}</Text>
|
<Text>{step?.name}</Text>
|
||||||
<FlexExpander />
|
<FlexExpander />
|
||||||
{step?.started && step?.stopped && <div>{timeDistance(step?.stopped, step?.started)}</div>}
|
{step?.started && step?.stopped && <div>{timeDistance(step?.stopped, step?.started)}</div>}
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
|
|
||||||
{isOpened ? (
|
{isOpened && content}
|
||||||
loading ? (
|
|
||||||
<div className={css.loading}>{getString('loading')}</div>
|
|
||||||
) : error ? (
|
|
||||||
<div>Error: {error}</div>
|
|
||||||
) : data ? (
|
|
||||||
<ConsoleLogs logs={data} />
|
|
||||||
) : null
|
|
||||||
) : null}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ export function getCommentLineInfo(
|
|||||||
) {
|
) {
|
||||||
const isSideBySideView = viewStyle === ViewStyle.SIDE_BY_SIDE
|
const isSideBySideView = viewStyle === ViewStyle.SIDE_BY_SIDE
|
||||||
const { left, lineNumber, filePath } = commentEntry
|
const { left, lineNumber, filePath } = commentEntry
|
||||||
const filePathBody = contentDOM?.querySelector(`[data="${filePath}"`)
|
const filePathBody = filePath ? contentDOM?.querySelector(`[data="${filePath}"`) : contentDOM
|
||||||
|
|
||||||
const diffBody = filePathBody?.querySelector(
|
const diffBody = filePathBody?.querySelector(
|
||||||
`${isSideBySideView ? `.d2h-file-side-diff${left ? '.left' : '.right'} ` : ''}.d2h-diff-tbody`
|
`${isSideBySideView ? `.d2h-file-side-diff${left ? '.left' : '.right'} ` : ''}.d2h-diff-tbody`
|
||||||
|
@ -5,16 +5,6 @@
|
|||||||
gap: var(--spacing-small) !important;
|
gap: var(--spacing-small) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
|
||||||
width: 100% !important;
|
|
||||||
gap: var(--spacing-small) !important;
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-size: var(--font-size-small);
|
|
||||||
color: var(--primary-7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
@ -36,6 +26,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.executionInfo {
|
.executionInfo {
|
||||||
|
display: flex !important;
|
||||||
|
gap: var(--spacing-small) !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Fragment } from 'react'
|
import React, { Fragment } from 'react'
|
||||||
import { Layout, Text, PageHeader, Utils, Avatar, FlexExpander } from '@harnessio/uicore'
|
import { Layout, Text, PageHeader, Utils, Avatar, FlexExpander, Container } from '@harnessio/uicore'
|
||||||
import { Icon } from '@harnessio/icons'
|
import { Icon } from '@harnessio/icons'
|
||||||
import { Color } from '@harnessio/design-system'
|
import { Color } from '@harnessio/design-system'
|
||||||
import { Link, useParams } from 'react-router-dom'
|
import { Link, useParams } from 'react-router-dom'
|
||||||
@ -78,8 +78,7 @@ export function ExecutionPageHeader({
|
|||||||
}
|
}
|
||||||
content={
|
content={
|
||||||
executionInfo && (
|
executionInfo && (
|
||||||
// TODO - margin left not playing ball... why?
|
<Container className={css.executionInfo}>
|
||||||
<Layout.Horizontal className={css.executionInfo} spacing="small" style={{ marginLeft: 0 }}>
|
|
||||||
<ExecutionStatus status={getStatus(executionInfo.status)} iconOnly noBackground iconSize={18} />
|
<ExecutionStatus status={getStatus(executionInfo.status)} iconOnly noBackground iconSize={18} />
|
||||||
<Text inline color={Color.GREY_800} font={{ size: 'small' }}>
|
<Text inline color={Color.GREY_800} font={{ size: 'small' }}>
|
||||||
{executionInfo.message}
|
{executionInfo.message}
|
||||||
@ -106,14 +105,13 @@ export function ExecutionPageHeader({
|
|||||||
<Text inline color={Color.GREY_500} font={{ size: 'small' }}>
|
<Text inline color={Color.GREY_500} font={{ size: 'small' }}>
|
||||||
{timeDistance(executionInfo.started, executionInfo.finished)}
|
{timeDistance(executionInfo.started, executionInfo.finished)}
|
||||||
</Text>
|
</Text>
|
||||||
</Layout.Horizontal>
|
<PipeSeparator height={7} />
|
||||||
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center' }}>
|
|
||||||
<Calendar height={16} width={16} color={Utils.getRealCSSColor(Color.GREY_500)} />
|
<Calendar height={16} width={16} color={Utils.getRealCSSColor(Color.GREY_500)} />
|
||||||
<Text inline color={Color.GREY_500} font={{ size: 'small' }}>
|
<Text inline color={Color.GREY_500} font={{ size: 'small' }}>
|
||||||
{timeDistance(executionInfo.finished, Date.now())} ago
|
{timeDistance(executionInfo.finished, Date.now())} ago
|
||||||
</Text>
|
</Text>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
</Layout.Horizontal>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -32,7 +32,7 @@ const ExecutionStage: FC<ExecutionStageProps> = ({ stage, isSelected = false, se
|
|||||||
status={getStatus(stage.status || ExecutionState.PENDING)}
|
status={getStatus(stage.status || ExecutionState.PENDING)}
|
||||||
iconOnly
|
iconOnly
|
||||||
noBackground
|
noBackground
|
||||||
iconSize={16}
|
iconSize={18}
|
||||||
className={css.statusIcon}
|
className={css.statusIcon}
|
||||||
/>
|
/>
|
||||||
<Text className={css.uid} lineClamp={1}>
|
<Text className={css.uid} lineClamp={1}>
|
||||||
|
@ -38,7 +38,7 @@ export interface NewSecretModalButtonProps extends Omit<ButtonProps, 'onClick' |
|
|||||||
modalTitle: string
|
modalTitle: string
|
||||||
submitButtonTitle?: string
|
submitButtonTitle?: string
|
||||||
cancelButtonTitle?: string
|
cancelButtonTitle?: string
|
||||||
onSubmit: (data: TypesSecret) => void
|
onSuccess: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
|
export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
|
||||||
@ -46,12 +46,12 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
|
|||||||
modalTitle,
|
modalTitle,
|
||||||
submitButtonTitle,
|
submitButtonTitle,
|
||||||
cancelButtonTitle,
|
cancelButtonTitle,
|
||||||
onSubmit,
|
onSuccess,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const ModalComponent: React.FC = () => {
|
const ModalComponent: React.FC = () => {
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
const { showError } = useToaster()
|
const { showError, showSuccess } = useToaster()
|
||||||
|
|
||||||
const { mutate: createSecret, loading } = useMutate<TypesSecret>({
|
const { mutate: createSecret, loading } = useMutate<TypesSecret>({
|
||||||
verb: 'POST',
|
verb: 'POST',
|
||||||
@ -66,9 +66,10 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
|
|||||||
description: formData.description,
|
description: formData.description,
|
||||||
uid: formData.name
|
uid: formData.name
|
||||||
}
|
}
|
||||||
const response = await createSecret(payload)
|
await createSecret(payload)
|
||||||
hideModal()
|
hideModal()
|
||||||
onSubmit(response)
|
showSuccess(getString('secrets.createSuccess'))
|
||||||
|
onSuccess()
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
showError(getErrorMessage(exception), 0, getString('secrets.failedToCreate'))
|
showError(getErrorMessage(exception), 0, getString('secrets.failedToCreate'))
|
||||||
}
|
}
|
||||||
@ -152,7 +153,7 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const [openModal, hideModal] = useModalHook(ModalComponent, [onSubmit])
|
const [openModal, hideModal] = useModalHook(ModalComponent, [onSuccess])
|
||||||
|
|
||||||
return <Button onClick={openModal} {...props} />
|
return <Button onClick={openModal} {...props} />
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,7 @@ export interface StringsMap {
|
|||||||
enterUser: string
|
enterUser: string
|
||||||
error: string
|
error: string
|
||||||
error404Text: string
|
error404Text: string
|
||||||
|
'executions.completedTime': string
|
||||||
'executions.description': string
|
'executions.description': string
|
||||||
'executions.name': string
|
'executions.name': string
|
||||||
'executions.newExecutionButton': string
|
'executions.newExecutionButton': string
|
||||||
@ -480,11 +481,16 @@ export interface StringsMap {
|
|||||||
searchBranches: string
|
searchBranches: string
|
||||||
secret: string
|
secret: string
|
||||||
'secrets.createSecret': string
|
'secrets.createSecret': string
|
||||||
|
'secrets.createSuccess': string
|
||||||
|
'secrets.deleteSecret': string
|
||||||
|
'secrets.deleteSecretConfirm': string
|
||||||
'secrets.enterSecretName': string
|
'secrets.enterSecretName': string
|
||||||
'secrets.failedToCreate': string
|
'secrets.failedToCreate': string
|
||||||
|
'secrets.failedToDeleteSecret': string
|
||||||
'secrets.name': string
|
'secrets.name': string
|
||||||
'secrets.newSecretButton': string
|
'secrets.newSecretButton': string
|
||||||
'secrets.noData': string
|
'secrets.noData': string
|
||||||
|
'secrets.secretDeleted': string
|
||||||
'secrets.value': string
|
'secrets.value': string
|
||||||
selectBranchPlaceHolder: string
|
selectBranchPlaceHolder: string
|
||||||
selectRange: string
|
selectRange: string
|
||||||
|
@ -648,6 +648,7 @@ executions:
|
|||||||
name: Execution Name
|
name: Execution Name
|
||||||
description: Description
|
description: Description
|
||||||
time: Time
|
time: Time
|
||||||
|
completedTime: completed {{timeString}} ago
|
||||||
selectRange: Shift-click to select a range
|
selectRange: Shift-click to select a range
|
||||||
allCommits: All Commits
|
allCommits: All Commits
|
||||||
secrets:
|
secrets:
|
||||||
@ -658,6 +659,11 @@ secrets:
|
|||||||
enterSecretName: Enter Secret name
|
enterSecretName: Enter Secret name
|
||||||
value: Secret Value
|
value: Secret Value
|
||||||
createSecret: Create Secret
|
createSecret: Create Secret
|
||||||
|
createSuccess: Secret created successfully
|
||||||
|
secretDeleted: Secret {uid} deleted.
|
||||||
|
deleteSecretConfirm: Are you sure you want to delete secret <strong>{{uid}}</strong>? You can't undo this action.
|
||||||
|
failedToDeleteSecret: Failed to delete Secret. Please try again.
|
||||||
|
deleteSecret: Delete Secrets
|
||||||
userUpdateSuccess: 'User updated successfully'
|
userUpdateSuccess: 'User updated successfully'
|
||||||
run: Run
|
run: Run
|
||||||
plugins:
|
plugins:
|
||||||
|
@ -9,13 +9,14 @@ import {
|
|||||||
PageBody,
|
PageBody,
|
||||||
TableV2 as Table,
|
TableV2 as Table,
|
||||||
Text,
|
Text,
|
||||||
Utils
|
Utils,
|
||||||
|
useToaster
|
||||||
} from '@harnessio/uicore'
|
} from '@harnessio/uicore'
|
||||||
import { Color } from '@harnessio/design-system'
|
import { Color } from '@harnessio/design-system'
|
||||||
import cx from 'classnames'
|
import cx from 'classnames'
|
||||||
import type { CellProps, Column } from 'react-table'
|
import type { CellProps, Column } from 'react-table'
|
||||||
import { Link, useHistory, useParams } from 'react-router-dom'
|
import { Link, useHistory, useParams } from 'react-router-dom'
|
||||||
import { useGet } from 'restful-react'
|
import { useGet, useMutate } from 'restful-react'
|
||||||
import { Timer, Calendar } from 'iconoir-react'
|
import { Timer, Calendar } from 'iconoir-react'
|
||||||
import { useStrings } from 'framework/strings'
|
import { useStrings } from 'framework/strings'
|
||||||
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
||||||
@ -29,7 +30,7 @@ import { usePageIndex } from 'hooks/usePageIndex'
|
|||||||
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
|
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
|
||||||
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
||||||
import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader'
|
import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader'
|
||||||
import { ExecutionState, ExecutionStatus } from 'components/ExecutionStatus/ExecutionStatus'
|
import { ExecutionStatus } from 'components/ExecutionStatus/ExecutionStatus'
|
||||||
import { getStatus } from 'utils/PipelineUtils'
|
import { getStatus } from 'utils/PipelineUtils'
|
||||||
import { PipeSeparator } from 'components/PipeSeparator/PipeSeparator'
|
import { PipeSeparator } from 'components/PipeSeparator/PipeSeparator'
|
||||||
import noExecutionImage from '../RepositoriesListing/no-repo.svg'
|
import noExecutionImage from '../RepositoriesListing/no-repo.svg'
|
||||||
@ -43,6 +44,7 @@ const ExecutionList = () => {
|
|||||||
const pageBrowser = useQueryParams<PageBrowserProps>()
|
const pageBrowser = useQueryParams<PageBrowserProps>()
|
||||||
const pageInit = pageBrowser.page ? parseInt(pageBrowser.page) : 1
|
const pageInit = pageBrowser.page ? parseInt(pageBrowser.page) : 1
|
||||||
const [page, setPage] = usePageIndex(pageInit)
|
const [page, setPage] = usePageIndex(pageInit)
|
||||||
|
const { showError, showSuccess } = useToaster()
|
||||||
|
|
||||||
const { repoMetadata, error, loading, refetch } = useGetRepositoryMetadata()
|
const { repoMetadata, error, loading, refetch } = useGetRepositoryMetadata()
|
||||||
|
|
||||||
@ -50,19 +52,39 @@ const ExecutionList = () => {
|
|||||||
data: executions,
|
data: executions,
|
||||||
error: executionsError,
|
error: executionsError,
|
||||||
loading: executionsLoading,
|
loading: executionsLoading,
|
||||||
response
|
response,
|
||||||
|
refetch: executionsRefetch
|
||||||
} = useGet<TypesExecution[]>({
|
} = useGet<TypesExecution[]>({
|
||||||
path: `/api/v1/repos/${repoMetadata?.path}/+/pipelines/${pipeline}/executions`,
|
path: `/api/v1/repos/${repoMetadata?.path}/+/pipelines/${pipeline}/executions`,
|
||||||
queryParams: { page, limit: LIST_FETCHING_LIMIT },
|
queryParams: { page, limit: LIST_FETCHING_LIMIT },
|
||||||
lazy: !repoMetadata
|
lazy: !repoMetadata
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//TODO - this should NOT be hardcoded to master branch - need a modal to insert branch
|
||||||
|
const { mutate, loading: mutateLoading } = useMutate<TypesExecution>({
|
||||||
|
verb: 'POST',
|
||||||
|
path: `/api/v1/repos/${repoMetadata?.path}/+/pipelines/${pipeline}/executions`,
|
||||||
|
queryParams: { branch: 'master' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleClick = async () => {
|
||||||
|
try {
|
||||||
|
//TODO - really this should be handled by the event bus
|
||||||
|
await mutate(null)
|
||||||
|
showSuccess('Build started')
|
||||||
|
executionsRefetch()
|
||||||
|
} catch {
|
||||||
|
showError('Failed to start build')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const NewExecutionButton = (
|
const NewExecutionButton = (
|
||||||
<Button
|
<Button
|
||||||
text={getString('executions.newExecutionButton')}
|
text={getString('executions.newExecutionButton')}
|
||||||
variation={ButtonVariation.PRIMARY}
|
variation={ButtonVariation.PRIMARY}
|
||||||
disabled={true}
|
icon="play-outline"
|
||||||
icon="play-outline"></Button>
|
disabled={mutateLoading}
|
||||||
|
onClick={handleClick}></Button>
|
||||||
)
|
)
|
||||||
|
|
||||||
const columns: Column<TypesExecution>[] = useMemo(
|
const columns: Column<TypesExecution>[] = useMemo(
|
||||||
@ -75,14 +97,9 @@ const ExecutionList = () => {
|
|||||||
return (
|
return (
|
||||||
<Layout.Vertical className={css.nameContainer}>
|
<Layout.Vertical className={css.nameContainer}>
|
||||||
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center' }}>
|
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center' }}>
|
||||||
<ExecutionStatus
|
<ExecutionStatus status={getStatus(record.status)} iconOnly noBackground iconSize={20} />
|
||||||
status={getStatus(record?.status || ExecutionState.PENDING)}
|
|
||||||
iconOnly
|
|
||||||
noBackground
|
|
||||||
iconSize={20}
|
|
||||||
/>
|
|
||||||
<Text className={css.number}>{`#${record.number}.`}</Text>
|
<Text className={css.number}>{`#${record.number}.`}</Text>
|
||||||
<Text className={css.desc}>{record.title}</Text>
|
<Text className={css.desc}>{record.message}</Text>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center', marginLeft: '1.2rem' }}>
|
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center', marginLeft: '1.2rem' }}>
|
||||||
<Avatar email={record.author_email} name={record.author_name} size="small" hoverCard={false} />
|
<Avatar email={record.author_email} name={record.author_name} size="small" hoverCard={false} />
|
||||||
@ -112,16 +129,18 @@ const ExecutionList = () => {
|
|||||||
const record = row.original
|
const record = row.original
|
||||||
return (
|
return (
|
||||||
<Layout.Vertical spacing={'small'}>
|
<Layout.Vertical spacing={'small'}>
|
||||||
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center' }}>
|
{record?.started && record?.finished && (
|
||||||
<Timer color={Utils.getRealCSSColor(Color.GREY_500)} />
|
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center' }}>
|
||||||
<Text inline color={Color.GREY_500} lineClamp={1} width={180} font={{ size: 'small' }}>
|
<Timer color={Utils.getRealCSSColor(Color.GREY_500)} />
|
||||||
{timeDistance(record.started, record.finished)}
|
<Text inline color={Color.GREY_500} lineClamp={1} width={180} font={{ size: 'small' }}>
|
||||||
</Text>
|
{timeDistance(record.started, record.finished)}
|
||||||
</Layout.Horizontal>
|
</Text>
|
||||||
|
</Layout.Horizontal>
|
||||||
|
)}
|
||||||
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center' }}>
|
<Layout.Horizontal spacing={'small'} style={{ alignItems: 'center' }}>
|
||||||
<Calendar color={Utils.getRealCSSColor(Color.GREY_500)} />
|
<Calendar color={Utils.getRealCSSColor(Color.GREY_500)} />
|
||||||
<Text inline color={Color.GREY_500} lineClamp={1} width={180} font={{ size: 'small' }}>
|
<Text inline color={Color.GREY_500} lineClamp={1} width={180} font={{ size: 'small' }}>
|
||||||
{timeDistance(record.finished, Date.now())} ago
|
{timeDistance(record.created, Date.now())} ago
|
||||||
</Text>
|
</Text>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
</Layout.Vertical>
|
</Layout.Vertical>
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { ButtonVariation, Container, Layout, PageBody, Text } from '@harnessio/uicore'
|
import { ButtonVariation, Container, Layout, PageBody, Text } from '@harnessio/uicore'
|
||||||
import { FontVariation } from '@harnessio/design-system'
|
import { FontVariation } from '@harnessio/design-system'
|
||||||
import { useGet } from 'restful-react'
|
import { noop } from 'lodash-es'
|
||||||
import { useHistory } from 'react-router-dom'
|
import { useHistory } from 'react-router-dom'
|
||||||
// import type { TypesSpace } from 'services/code'
|
|
||||||
import { useStrings } from 'framework/strings'
|
import { useStrings } from 'framework/strings'
|
||||||
// import { usePageIndex } from 'hooks/usePageIndex'
|
|
||||||
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
||||||
import { useAppContext } from 'AppContext'
|
import { useAppContext } from 'AppContext'
|
||||||
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata'
|
||||||
@ -16,15 +14,11 @@ export default function Home() {
|
|||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const { routes } = useAppContext()
|
const { routes } = useAppContext()
|
||||||
// const [searchTerm, setSearchTerm] = useState('')
|
|
||||||
// const [page, setPage] = usePageIndex(1)
|
|
||||||
const { currentUser } = useAppContext()
|
const { currentUser } = useAppContext()
|
||||||
const { space } = useGetRepositoryMetadata()
|
const { space } = useGetRepositoryMetadata()
|
||||||
|
|
||||||
const spaces = []
|
const spaces = []
|
||||||
const { refetch } = useGet({
|
|
||||||
path: '/api/v1/user/memberships'
|
|
||||||
})
|
|
||||||
const NewSpaceButton = (
|
const NewSpaceButton = (
|
||||||
<NewSpaceModalButton
|
<NewSpaceModalButton
|
||||||
space={space}
|
space={space}
|
||||||
@ -34,7 +28,7 @@ export default function Home() {
|
|||||||
icon="plus"
|
icon="plus"
|
||||||
width={173}
|
width={173}
|
||||||
height={48}
|
height={48}
|
||||||
onRefetch={refetch}
|
onRefetch={noop}
|
||||||
handleNavigation={spaceName => {
|
handleNavigation={spaceName => {
|
||||||
history.push(routes.toCODERepositories({ space: spaceName }))
|
history.push(routes.toCODERepositories({ space: spaceName }))
|
||||||
}}
|
}}
|
||||||
|
@ -31,6 +31,7 @@ import { useAppContext } from 'AppContext'
|
|||||||
import { LatestCommitForFile } from 'components/LatestCommit/LatestCommit'
|
import { LatestCommitForFile } from 'components/LatestCommit/LatestCommit'
|
||||||
import { useCommitModal } from 'components/CommitModalButton/CommitModalButton'
|
import { useCommitModal } from 'components/CommitModalButton/CommitModalButton'
|
||||||
import { useStrings } from 'framework/strings'
|
import { useStrings } from 'framework/strings'
|
||||||
|
import { getConfig } from 'services/config'
|
||||||
import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton'
|
import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton'
|
||||||
import { PlainButton } from 'components/PlainButton/PlainButton'
|
import { PlainButton } from 'components/PlainButton/PlainButton'
|
||||||
import { CommitsView } from 'components/CommitsView/CommitsView'
|
import { CommitsView } from 'components/CommitsView/CommitsView'
|
||||||
@ -57,7 +58,6 @@ export function FileContent({
|
|||||||
useFileContentViewerDecision({ repoMetadata, gitRef, resourcePath, resourceContent })
|
useFileContentViewerDecision({ repoMetadata, gitRef, resourcePath, resourceContent })
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
const [activeTab, setActiveTab] = React.useState<string>(FileSection.CONTENT)
|
const [activeTab, setActiveTab] = React.useState<string>(FileSection.CONTENT)
|
||||||
|
|
||||||
const content = useMemo(
|
const content = useMemo(
|
||||||
() => decodeGitContent((resourceContent?.content as RepoFileContent)?.data),
|
() => decodeGitContent((resourceContent?.content as RepoFileContent)?.data),
|
||||||
[resourceContent?.content]
|
[resourceContent?.content]
|
||||||
@ -199,13 +199,18 @@ export function FileContent({
|
|||||||
style={{ padding: '5px' }}
|
style={{ padding: '5px' }}
|
||||||
width="145px"
|
width="145px"
|
||||||
items={[
|
items={[
|
||||||
// {
|
{
|
||||||
// hasIcon: true,
|
hasIcon: true,
|
||||||
// iconName: 'arrow-right',
|
iconName: 'arrow-right',
|
||||||
// text: getString('viewRaw'),
|
text: getString('viewRaw'),
|
||||||
// onClick: () => window.open(rawURL, '_blank') // TODO: This is still not working due to token is not stored in cookies
|
onClick: () => {
|
||||||
// },
|
const url = standalone
|
||||||
// '-',
|
? rawURL.replace(/^\/code/, '')
|
||||||
|
: getConfig(rawURL).replace('//', '/')
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'-',
|
||||||
{
|
{
|
||||||
hasIcon: true,
|
hasIcon: true,
|
||||||
iconName: 'cloud-download',
|
iconName: 'cloud-download',
|
||||||
@ -243,6 +248,7 @@ export function FileContent({
|
|||||||
<Match expr={isViewable}>
|
<Match expr={isViewable}>
|
||||||
<Falsy>
|
<Falsy>
|
||||||
<Center>
|
<Center>
|
||||||
|
rawURL: {rawURL}
|
||||||
<Link
|
<Link
|
||||||
to={rawURL} // TODO: Link component generates wrong copy link
|
to={rawURL} // TODO: Link component generates wrong copy link
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
|
@ -1,45 +1,42 @@
|
|||||||
@import 'src/utils/utils';
|
@import 'src/utils/utils';
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
flex-grow: 1;
|
--code-editor-border-color: var(--grey-200);
|
||||||
|
|
||||||
:global {
|
.codeViewer {
|
||||||
.cm-editor {
|
flex-grow: 1;
|
||||||
border: none !important;
|
|
||||||
|
|
||||||
.cm-scroller {
|
:global {
|
||||||
padding: 0 !important;
|
.cm-gutter {
|
||||||
|
background-color: var(--grey-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-content {
|
.cm-editor {
|
||||||
padding: 0;
|
border: none !important;
|
||||||
}
|
|
||||||
|
|
||||||
.cm-line {
|
.cm-scroller {
|
||||||
&,
|
padding: 0 !important;
|
||||||
* {
|
|
||||||
@include mono-font;
|
.cm-line {
|
||||||
|
&,
|
||||||
|
* {
|
||||||
|
@include mono-font;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-content {
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.lineNo {
|
.lineNo {
|
||||||
min-width: 70px !important;
|
min-width: 70px !important;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
color: var(--grey-400);
|
color: var(--grey-400);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gitBlame {
|
|
||||||
--code-editor-border-color: var(--grey-200);
|
|
||||||
// padding: 0 var(--spacing-xlarge) 0 var(--spacing-small) !important;
|
|
||||||
|
|
||||||
:global {
|
|
||||||
.cm-gutter {
|
|
||||||
background-color: var(--grey-50);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ export const GitBlame: React.FC<Pick<GitInfoProps, 'repoMetadata' | 'resourcePat
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className={css.gitBlame}>
|
<Container className={css.main}>
|
||||||
<Layout.Horizontal className={css.layout}>
|
<Layout.Horizontal className={css.layout}>
|
||||||
<Container className={css.blameColumn}>
|
<Container className={css.blameColumn}>
|
||||||
{Object.values(blameBlocks).map(blameInfo => (
|
{Object.values(blameBlocks).map(blameInfo => (
|
||||||
@ -246,7 +246,7 @@ const GitBlameRenderer = React.memo(function GitBlameSourceViewer({
|
|||||||
filename={filename}
|
filename={filename}
|
||||||
content={source}
|
content={source}
|
||||||
readonly={true}
|
readonly={true}
|
||||||
className={css.main}
|
className={css.codeViewer}
|
||||||
onViewUpdate={onViewUpdate}
|
onViewUpdate={onViewUpdate}
|
||||||
extensions={extensions.of([])}
|
extensions={extensions.of([])}
|
||||||
maxHeight="auto"
|
maxHeight="auto"
|
||||||
|
@ -6,16 +6,17 @@ import {
|
|||||||
Layout,
|
Layout,
|
||||||
PageBody,
|
PageBody,
|
||||||
PageHeader,
|
PageHeader,
|
||||||
|
StringSubstitute,
|
||||||
TableV2 as Table,
|
TableV2 as Table,
|
||||||
Text
|
Text,
|
||||||
|
useToaster
|
||||||
} from '@harnessio/uicore'
|
} from '@harnessio/uicore'
|
||||||
import { Color } from '@harnessio/design-system'
|
import { Color, Intent } from '@harnessio/design-system'
|
||||||
import cx from 'classnames'
|
import cx from 'classnames'
|
||||||
import type { CellProps, Column } from 'react-table'
|
import type { CellProps, Column } from 'react-table'
|
||||||
import Keywords from 'react-keywords'
|
import Keywords from 'react-keywords'
|
||||||
import { useHistory } from 'react-router-dom'
|
import { useGet, useMutate } from 'restful-react'
|
||||||
import { useGet } from 'restful-react'
|
import { String, useStrings } from 'framework/strings'
|
||||||
import { useStrings } from 'framework/strings'
|
|
||||||
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
||||||
import { SearchInputWithSpinner } from 'components/SearchInputWithSpinner/SearchInputWithSpinner'
|
import { SearchInputWithSpinner } from 'components/SearchInputWithSpinner/SearchInputWithSpinner'
|
||||||
import { NoResultCard } from 'components/NoResultCard/NoResultCard'
|
import { NoResultCard } from 'components/NoResultCard/NoResultCard'
|
||||||
@ -26,14 +27,13 @@ import { useQueryParams } from 'hooks/useQueryParams'
|
|||||||
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
|
||||||
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
|
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
|
||||||
import { NewSecretModalButton } from 'components/NewSecretModalButton/NewSecretModalButton'
|
import { NewSecretModalButton } from 'components/NewSecretModalButton/NewSecretModalButton'
|
||||||
import { useAppContext } from 'AppContext'
|
import { useConfirmAct } from 'hooks/useConfirmAction'
|
||||||
|
import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton'
|
||||||
import noSecretsImage from '../RepositoriesListing/no-repo.svg'
|
import noSecretsImage from '../RepositoriesListing/no-repo.svg'
|
||||||
import css from './SecretList.module.scss'
|
import css from './SecretList.module.scss'
|
||||||
|
|
||||||
const SecretList = () => {
|
const SecretList = () => {
|
||||||
const { routes } = useAppContext()
|
|
||||||
const space = useGetSpaceParam()
|
const space = useGetSpaceParam()
|
||||||
const history = useHistory()
|
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
const [searchTerm, setSearchTerm] = useState<string | undefined>()
|
const [searchTerm, setSearchTerm] = useState<string | undefined>()
|
||||||
const pageBrowser = useQueryParams<PageBrowserProps>()
|
const pageBrowser = useQueryParams<PageBrowserProps>()
|
||||||
@ -58,9 +58,7 @@ const SecretList = () => {
|
|||||||
text={getString('secrets.newSecretButton')}
|
text={getString('secrets.newSecretButton')}
|
||||||
variation={ButtonVariation.PRIMARY}
|
variation={ButtonVariation.PRIMARY}
|
||||||
icon="plus"
|
icon="plus"
|
||||||
onSubmit={secretInfo =>
|
onSuccess={() => refetch()}></NewSecretModalButton>
|
||||||
history.push(routes.toCODESecret({ space, secret: secretInfo.uid as string }))
|
|
||||||
}></NewSecretModalButton>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const columns: Column<TypesSecret>[] = useMemo(
|
const columns: Column<TypesSecret>[] = useMemo(
|
||||||
@ -97,9 +95,62 @@ const SecretList = () => {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
disableSortBy: true
|
disableSortBy: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'action',
|
||||||
|
width: '30px',
|
||||||
|
Cell: ({ row }: CellProps<TypesSecret>) => {
|
||||||
|
const { mutate: deleteSecret } = useMutate({
|
||||||
|
verb: 'DELETE',
|
||||||
|
path: `/api/v1/secrets/${space}/${row.original.uid}`
|
||||||
|
})
|
||||||
|
const { showSuccess, showError } = useToaster()
|
||||||
|
const confirmDeleteSecret = useConfirmAct()
|
||||||
|
|
||||||
|
// TODO - add edit option
|
||||||
|
return (
|
||||||
|
<OptionsMenuButton
|
||||||
|
isDark
|
||||||
|
width="100px"
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
text: getString('delete'),
|
||||||
|
isDanger: true,
|
||||||
|
onClick: () =>
|
||||||
|
confirmDeleteSecret({
|
||||||
|
title: getString('secrets.deleteSecret'),
|
||||||
|
confirmText: getString('delete'),
|
||||||
|
intent: Intent.DANGER,
|
||||||
|
message: (
|
||||||
|
<String useRichText stringID="secrets.deleteSecretConfirm" vars={{ uid: row.original.uid }} />
|
||||||
|
),
|
||||||
|
action: async () => {
|
||||||
|
deleteSecret({})
|
||||||
|
.then(() => {
|
||||||
|
showSuccess(
|
||||||
|
<StringSubstitute
|
||||||
|
str={getString('secrets.secretDeleted')}
|
||||||
|
vars={{
|
||||||
|
uid: row.original.uid
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
5000
|
||||||
|
)
|
||||||
|
refetch()
|
||||||
|
})
|
||||||
|
.catch(secretDeleteError => {
|
||||||
|
showError(getErrorMessage(secretDeleteError), 0, 'secrets.failedToDeleteSecret')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[getString, searchTerm]
|
[getString, refetch, searchTerm, space]
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -130,9 +181,6 @@ const SecretList = () => {
|
|||||||
className={css.table}
|
className={css.table}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={secrets || []}
|
data={secrets || []}
|
||||||
onRowClick={secretInfo =>
|
|
||||||
history.push(routes.toCODESecret({ space: 'root', secret: secretInfo.uid as string }))
|
|
||||||
}
|
|
||||||
getRowClassName={row => cx(css.row, !row.original.description && css.noDesc)}
|
getRowClassName={row => cx(css.row, !row.original.description && css.noDesc)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -286,7 +286,7 @@ export default function Webhooks() {
|
|||||||
showWhen={() => webhooks?.length === 0}
|
showWhen={() => webhooks?.length === 0}
|
||||||
forSearch={!!searchTerm}
|
forSearch={!!searchTerm}
|
||||||
message={getString('webhookEmpty')}
|
message={getString('webhookEmpty')}
|
||||||
buttonText={getString('createWebhook')}
|
buttonText={getString('newWebhook')}
|
||||||
onButtonClick={() =>
|
onButtonClick={() =>
|
||||||
history.push(
|
history.push(
|
||||||
routes.toCODEWebhookNew({
|
routes.toCODEWebhookNew({
|
||||||
|
@ -740,6 +740,7 @@ export interface TypesRepository {
|
|||||||
fork_id?: number
|
fork_id?: number
|
||||||
git_url?: string
|
git_url?: string
|
||||||
id?: number
|
id?: number
|
||||||
|
importing?: boolean
|
||||||
is_public?: boolean
|
is_public?: boolean
|
||||||
num_closed_pulls?: number
|
num_closed_pulls?: number
|
||||||
num_forks?: number
|
num_forks?: number
|
||||||
|
@ -7453,6 +7453,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
id:
|
id:
|
||||||
type: integer
|
type: integer
|
||||||
|
importing:
|
||||||
|
type: boolean
|
||||||
is_public:
|
is_public:
|
||||||
type: boolean
|
type: boolean
|
||||||
num_closed_pulls:
|
num_closed_pulls:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ExecutionState } from 'components/ExecutionStatus/ExecutionStatus'
|
import { ExecutionState } from 'components/ExecutionStatus/ExecutionStatus'
|
||||||
|
|
||||||
export const getStatus = (status: string): ExecutionState => {
|
export const getStatus = (status: string | undefined): ExecutionState => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'success':
|
case 'success':
|
||||||
return ExecutionState.SUCCESS
|
return ExecutionState.SUCCESS
|
||||||
@ -10,6 +10,8 @@ export const getStatus = (status: string): ExecutionState => {
|
|||||||
return ExecutionState.RUNNING
|
return ExecutionState.RUNNING
|
||||||
case 'pending':
|
case 'pending':
|
||||||
return ExecutionState.PENDING
|
return ExecutionState.PENDING
|
||||||
|
case 'error':
|
||||||
|
return ExecutionState.ERROR
|
||||||
default:
|
default:
|
||||||
return ExecutionState.PENDING
|
return ExecutionState.PENDING
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ $code-editor-font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menl
|
|||||||
monospace;
|
monospace;
|
||||||
|
|
||||||
@mixin mono-font {
|
@mixin mono-font {
|
||||||
font-family: var(--font-family-mono) !important;
|
font-family: Menlo, Monaco, 'Courier New', monospace var(--font-family-mono) !important;
|
||||||
|
font-weight: normal !important;
|
||||||
font-size: 13px !important;
|
font-size: 13px !important;
|
||||||
font-feature-settings: 'liga' 0, 'calt' 0;
|
font-feature-settings: 'liga' 0, 'calt' 0;
|
||||||
|
font-variation-settings: normal;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
letter-spacing: 0px;
|
letter-spacing: 0px;
|
||||||
}
|
}
|
||||||
|
192
web/yarn.lock
192
web/yarn.lock
@ -2219,14 +2219,6 @@ agent-base@6:
|
|||||||
dependencies:
|
dependencies:
|
||||||
debug "4"
|
debug "4"
|
||||||
|
|
||||||
aggregate-error@^3.0.0:
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
|
|
||||||
integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
|
|
||||||
dependencies:
|
|
||||||
clean-stack "^2.0.0"
|
|
||||||
indent-string "^4.0.0"
|
|
||||||
|
|
||||||
ajv-formats@^2.1.1:
|
ajv-formats@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
|
resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
|
||||||
@ -2293,7 +2285,7 @@ ansi-colors@^4.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
|
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
|
||||||
integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
|
integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
|
||||||
|
|
||||||
ansi-escapes@^4.2.1, ansi-escapes@^4.3.0:
|
ansi-escapes@^4.2.1:
|
||||||
version "4.3.2"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
|
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
|
||||||
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
|
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
|
||||||
@ -2994,11 +2986,6 @@ clean-css@^5.2.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
source-map "~0.6.0"
|
source-map "~0.6.0"
|
||||||
|
|
||||||
clean-stack@^2.0.0:
|
|
||||||
version "2.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
|
|
||||||
integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
|
|
||||||
|
|
||||||
cli-boxes@^1.0.0:
|
cli-boxes@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
|
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
|
||||||
@ -3011,14 +2998,6 @@ cli-cursor@^3.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
restore-cursor "^3.1.0"
|
restore-cursor "^3.1.0"
|
||||||
|
|
||||||
cli-truncate@2.1.0, cli-truncate@^2.1.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7"
|
|
||||||
integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==
|
|
||||||
dependencies:
|
|
||||||
slice-ansi "^3.0.0"
|
|
||||||
string-width "^4.2.0"
|
|
||||||
|
|
||||||
cli-width@^3.0.0:
|
cli-width@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
|
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
|
||||||
@ -3127,12 +3106,7 @@ color-name@~1.1.4:
|
|||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
colorette@^1.4.0:
|
colorette@^2.0.10, colorette@^2.0.14:
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40"
|
|
||||||
integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==
|
|
||||||
|
|
||||||
colorette@^2.0.10, colorette@^2.0.14, colorette@^2.0.16:
|
|
||||||
version "2.0.20"
|
version "2.0.20"
|
||||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
|
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
|
||||||
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
|
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
|
||||||
@ -3174,7 +3148,7 @@ commander@^4.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
|
||||||
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
|
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
|
||||||
|
|
||||||
commander@^8.2.0, commander@^8.3.0:
|
commander@^8.3.0:
|
||||||
version "8.3.0"
|
version "8.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
|
||||||
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
|
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
|
||||||
@ -3289,17 +3263,6 @@ cosmiconfig@^6.0.0:
|
|||||||
path-type "^4.0.0"
|
path-type "^4.0.0"
|
||||||
yaml "^1.7.2"
|
yaml "^1.7.2"
|
||||||
|
|
||||||
cosmiconfig@^7.0.1:
|
|
||||||
version "7.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6"
|
|
||||||
integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==
|
|
||||||
dependencies:
|
|
||||||
"@types/parse-json" "^4.0.0"
|
|
||||||
import-fresh "^3.2.1"
|
|
||||||
parse-json "^5.0.0"
|
|
||||||
path-type "^4.0.0"
|
|
||||||
yaml "^1.10.0"
|
|
||||||
|
|
||||||
create-error-class@^3.0.0:
|
create-error-class@^3.0.0:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
|
resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
|
||||||
@ -3436,7 +3399,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "2.0.0"
|
ms "2.0.0"
|
||||||
|
|
||||||
debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
|
debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4:
|
||||||
version "4.3.4"
|
version "4.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||||
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||||
@ -3826,7 +3789,7 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.13.0, enhanced-resolve@^5.7.0:
|
|||||||
graceful-fs "^4.2.4"
|
graceful-fs "^4.2.4"
|
||||||
tapable "^2.2.0"
|
tapable "^2.2.0"
|
||||||
|
|
||||||
enquirer@^2.3.5, enquirer@^2.3.6:
|
enquirer@^2.3.5:
|
||||||
version "2.3.6"
|
version "2.3.6"
|
||||||
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
|
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
|
||||||
integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
|
integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
|
||||||
@ -4260,7 +4223,7 @@ execa@^4.0.0:
|
|||||||
signal-exit "^3.0.2"
|
signal-exit "^3.0.2"
|
||||||
strip-final-newline "^2.0.0"
|
strip-final-newline "^2.0.0"
|
||||||
|
|
||||||
execa@^5.0.0, execa@^5.1.1:
|
execa@^5.0.0:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
||||||
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
|
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
|
||||||
@ -4745,11 +4708,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@
|
|||||||
has "^1.0.3"
|
has "^1.0.3"
|
||||||
has-symbols "^1.0.3"
|
has-symbols "^1.0.3"
|
||||||
|
|
||||||
get-own-enumerable-property-symbols@^3.0.0:
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
|
|
||||||
integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==
|
|
||||||
|
|
||||||
get-package-type@^0.1.0:
|
get-package-type@^0.1.0:
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
|
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
|
||||||
@ -5811,7 +5769,7 @@ is-number@^7.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||||
|
|
||||||
is-obj@^1.0.0, is-obj@^1.0.1:
|
is-obj@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
||||||
integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==
|
integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==
|
||||||
@ -5858,11 +5816,6 @@ is-regex@^1.0.4, is-regex@^1.1.4:
|
|||||||
call-bind "^1.0.2"
|
call-bind "^1.0.2"
|
||||||
has-tostringtag "^1.0.0"
|
has-tostringtag "^1.0.0"
|
||||||
|
|
||||||
is-regexp@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
|
|
||||||
integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==
|
|
||||||
|
|
||||||
is-retry-allowed@^1.0.0:
|
is-retry-allowed@^1.0.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
|
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
|
||||||
@ -6756,40 +6709,6 @@ lines-and-columns@^1.1.6:
|
|||||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
||||||
|
|
||||||
lint-staged@^11.0.0:
|
|
||||||
version "11.2.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-11.2.6.tgz#f477b1af0294db054e5937f171679df63baa4c43"
|
|
||||||
integrity sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==
|
|
||||||
dependencies:
|
|
||||||
cli-truncate "2.1.0"
|
|
||||||
colorette "^1.4.0"
|
|
||||||
commander "^8.2.0"
|
|
||||||
cosmiconfig "^7.0.1"
|
|
||||||
debug "^4.3.2"
|
|
||||||
enquirer "^2.3.6"
|
|
||||||
execa "^5.1.1"
|
|
||||||
listr2 "^3.12.2"
|
|
||||||
micromatch "^4.0.4"
|
|
||||||
normalize-path "^3.0.0"
|
|
||||||
please-upgrade-node "^3.2.0"
|
|
||||||
string-argv "0.3.1"
|
|
||||||
stringify-object "3.3.0"
|
|
||||||
supports-color "8.1.1"
|
|
||||||
|
|
||||||
listr2@^3.12.2:
|
|
||||||
version "3.14.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e"
|
|
||||||
integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==
|
|
||||||
dependencies:
|
|
||||||
cli-truncate "^2.1.0"
|
|
||||||
colorette "^2.0.16"
|
|
||||||
log-update "^4.0.0"
|
|
||||||
p-map "^4.0.0"
|
|
||||||
rfdc "^1.3.0"
|
|
||||||
rxjs "^7.5.1"
|
|
||||||
through "^2.3.8"
|
|
||||||
wrap-ansi "^7.0.0"
|
|
||||||
|
|
||||||
load-json-file@^4.0.0:
|
load-json-file@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
|
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
|
||||||
@ -6858,16 +6777,6 @@ lodash@4.x, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21,
|
|||||||
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
|
||||||
log-update@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1"
|
|
||||||
integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==
|
|
||||||
dependencies:
|
|
||||||
ansi-escapes "^4.3.0"
|
|
||||||
cli-cursor "^3.1.0"
|
|
||||||
slice-ansi "^4.0.0"
|
|
||||||
wrap-ansi "^6.2.0"
|
|
||||||
|
|
||||||
longest-streak@^3.0.0:
|
longest-streak@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4"
|
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4"
|
||||||
@ -7573,10 +7482,10 @@ monaco-editor-webpack-plugin@^7.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
loader-utils "^2.0.2"
|
loader-utils "^2.0.2"
|
||||||
|
|
||||||
monaco-editor@^0.37.1:
|
monaco-editor@^0.40.0:
|
||||||
version "0.37.1"
|
version "0.40.0"
|
||||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.37.1.tgz#d6f5ffb593e019e74e19bf8a2bdef5a691876f4e"
|
resolved "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.40.0.tgz#d10834e15ad50a15ec61fd01892e508464ebe2fe"
|
||||||
integrity sha512-jLXEEYSbqMkT/FuJLBZAVWGuhIb4JNwHE9kPTorAVmsdZ4UzHAfgWxLsVtD7pLRFaOwYPhNG9nUCpmFL1t/dIg==
|
integrity sha512-1wymccLEuFSMBvCk/jT1YDW/GuxMLYwnFwF9CDyYCxoTw2Pt379J3FUhwy9c43j51JdcxVPjwk0jm0EVDsBS2g==
|
||||||
|
|
||||||
monaco-marker-data-provider@^1.0.0:
|
monaco-marker-data-provider@^1.0.0:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
@ -8107,13 +8016,6 @@ p-locate@^4.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
p-limit "^2.2.0"
|
p-limit "^2.2.0"
|
||||||
|
|
||||||
p-map@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b"
|
|
||||||
integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==
|
|
||||||
dependencies:
|
|
||||||
aggregate-error "^3.0.0"
|
|
||||||
|
|
||||||
p-retry@^4.5.0:
|
p-retry@^4.5.0:
|
||||||
version "4.6.2"
|
version "4.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16"
|
resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16"
|
||||||
@ -8345,13 +8247,6 @@ pkg-dir@^4.2.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
find-up "^4.0.0"
|
find-up "^4.0.0"
|
||||||
|
|
||||||
please-upgrade-node@^3.2.0:
|
|
||||||
version "3.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
|
|
||||||
integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==
|
|
||||||
dependencies:
|
|
||||||
semver-compare "^1.0.0"
|
|
||||||
|
|
||||||
popper.js@^1.14.4, popper.js@^1.15.0:
|
popper.js@^1.14.4, popper.js@^1.15.0:
|
||||||
version "1.16.1"
|
version "1.16.1"
|
||||||
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
||||||
@ -8708,13 +8603,20 @@ react-markdown@~8.0.0:
|
|||||||
unist-util-visit "^4.0.0"
|
unist-util-visit "^4.0.0"
|
||||||
vfile "^5.0.0"
|
vfile "^5.0.0"
|
||||||
|
|
||||||
react-monaco-editor@*, react-monaco-editor@^0.52.0:
|
react-monaco-editor@*:
|
||||||
version "0.52.0"
|
version "0.52.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-monaco-editor/-/react-monaco-editor-0.52.0.tgz#69a7c450a22830064d2fc1b446674b1b7da0f540"
|
resolved "https://registry.yarnpkg.com/react-monaco-editor/-/react-monaco-editor-0.52.0.tgz#69a7c450a22830064d2fc1b446674b1b7da0f540"
|
||||||
integrity sha512-jhQSekf2JABbcpN45gKZlWfTS0QcBOZAbAWKGyfqy/KEcMXTwJpCOYGcn2Ur11SUUxWJUzhKjE2fx9BGBc5S8g==
|
integrity sha512-jhQSekf2JABbcpN45gKZlWfTS0QcBOZAbAWKGyfqy/KEcMXTwJpCOYGcn2Ur11SUUxWJUzhKjE2fx9BGBc5S8g==
|
||||||
dependencies:
|
dependencies:
|
||||||
prop-types "^15.8.1"
|
prop-types "^15.8.1"
|
||||||
|
|
||||||
|
react-monaco-editor@^0.54.0:
|
||||||
|
version "0.54.0"
|
||||||
|
resolved "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.54.0.tgz#ec9293249a991b08264be723c1ec0ca3a6d480d8"
|
||||||
|
integrity sha512-9JwO69851mfpuhYLHlKbae7omQWJ/2ICE2lbL0VHyNyZR8rCOH7440u+zAtDgiOMpLwmYdY1sEZCdRefywX6GQ==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.8.1"
|
||||||
|
|
||||||
react-pdf@^7.1.2:
|
react-pdf@^7.1.2:
|
||||||
version "7.1.2"
|
version "7.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-pdf/-/react-pdf-7.1.2.tgz#c6979cff9ac09c3e5ab7ea9e0182f79a499768e5"
|
resolved "https://registry.yarnpkg.com/react-pdf/-/react-pdf-7.1.2.tgz#c6979cff9ac09c3e5ab7ea9e0182f79a499768e5"
|
||||||
@ -9291,11 +9193,6 @@ reusify@^1.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||||
|
|
||||||
rfdc@^1.3.0:
|
|
||||||
version "1.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
|
|
||||||
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
|
|
||||||
|
|
||||||
rimraf@^3.0.0, rimraf@^3.0.2:
|
rimraf@^3.0.0, rimraf@^3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||||
@ -9327,13 +9224,6 @@ rxjs@^6.6.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
rxjs@^7.5.1:
|
|
||||||
version "7.8.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4"
|
|
||||||
integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==
|
|
||||||
dependencies:
|
|
||||||
tslib "^2.1.0"
|
|
||||||
|
|
||||||
sade@^1.7.3:
|
sade@^1.7.3:
|
||||||
version "1.8.1"
|
version "1.8.1"
|
||||||
resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
|
resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
|
||||||
@ -9459,11 +9349,6 @@ selfsigned@^2.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
node-forge "^1"
|
node-forge "^1"
|
||||||
|
|
||||||
semver-compare@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
|
|
||||||
integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
|
|
||||||
|
|
||||||
semver-diff@^2.0.0:
|
semver-diff@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
|
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
|
||||||
@ -9676,15 +9561,6 @@ slash@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||||
|
|
||||||
slice-ansi@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787"
|
|
||||||
integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==
|
|
||||||
dependencies:
|
|
||||||
ansi-styles "^4.0.0"
|
|
||||||
astral-regex "^2.0.0"
|
|
||||||
is-fullwidth-code-point "^3.0.0"
|
|
||||||
|
|
||||||
slice-ansi@^4.0.0:
|
slice-ansi@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
|
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
|
||||||
@ -9890,11 +9766,6 @@ stop-iteration-iterator@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
internal-slot "^1.0.4"
|
internal-slot "^1.0.4"
|
||||||
|
|
||||||
string-argv@0.3.1:
|
|
||||||
version "0.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da"
|
|
||||||
integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==
|
|
||||||
|
|
||||||
string-length@^4.0.1:
|
string-length@^4.0.1:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
|
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
|
||||||
@ -9993,15 +9864,6 @@ string_decoder@~1.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.0"
|
safe-buffer "~5.1.0"
|
||||||
|
|
||||||
stringify-object@3.3.0:
|
|
||||||
version "3.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629"
|
|
||||||
integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==
|
|
||||||
dependencies:
|
|
||||||
get-own-enumerable-property-symbols "^3.0.0"
|
|
||||||
is-obj "^1.0.1"
|
|
||||||
is-regexp "^1.0.0"
|
|
||||||
|
|
||||||
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
|
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||||
@ -10077,13 +9939,6 @@ style-to-object@^0.4.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
inline-style-parser "0.1.1"
|
inline-style-parser "0.1.1"
|
||||||
|
|
||||||
supports-color@8.1.1, supports-color@^8.0.0:
|
|
||||||
version "8.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
|
||||||
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
|
|
||||||
dependencies:
|
|
||||||
has-flag "^4.0.0"
|
|
||||||
|
|
||||||
supports-color@^5.3.0:
|
supports-color@^5.3.0:
|
||||||
version "5.5.0"
|
version "5.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||||
@ -10098,6 +9953,13 @@ supports-color@^7.0.0, supports-color@^7.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^4.0.0"
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
|
supports-color@^8.0.0:
|
||||||
|
version "8.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
||||||
|
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
|
||||||
|
dependencies:
|
||||||
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
supports-hyperlinks@^2.0.0:
|
supports-hyperlinks@^2.0.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624"
|
resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624"
|
||||||
@ -10214,7 +10076,7 @@ throat@^5.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
|
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
|
||||||
integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==
|
integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==
|
||||||
|
|
||||||
through@^2.3.6, through@^2.3.8:
|
through@^2.3.6:
|
||||||
version "2.3.8"
|
version "2.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||||
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
|
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
|
||||||
|
Loading…
Reference in New Issue
Block a user