Merge branch 'mg/status-checks/api-layer' of _OKE5H2PQKOUfzFFDuD4FA/default/CODE/gitness (#104)

This commit is contained in:
Marko Gacesa 2023-06-08 13:17:25 +00:00 committed by Harness
commit e4ac32f430
23 changed files with 570 additions and 60 deletions

View File

@ -23,6 +23,7 @@ import (
harnessevents "github.com/harness/gitness/harness/services/events"
"github.com/harness/gitness/harness/store"
"github.com/harness/gitness/harness/types/check"
checkcontroller "github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/controller/githook"
"github.com/harness/gitness/internal/api/controller/principal"
"github.com/harness/gitness/internal/api/controller/pullreq"
@ -90,6 +91,7 @@ func initSystem(ctx context.Context, config *gitnesstypes.Config) (*system, erro
pubsub.WireSet,
codecomments.WireSet,
gitrpccron.WireSet,
checkcontroller.WireSet,
)
return &system{}, nil
}

View File

@ -20,6 +20,7 @@ import (
events4 "github.com/harness/gitness/harness/services/events"
"github.com/harness/gitness/harness/store"
"github.com/harness/gitness/harness/types/check"
check2 "github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/controller/githook"
"github.com/harness/gitness/internal/api/controller/principal"
"github.com/harness/gitness/internal/api/controller/pullreq"
@ -164,7 +165,9 @@ func initSystem(ctx context.Context, config *types.Config) (*system, error) {
return nil, err
}
githookController := githook.ProvideController(db, authorizer, principalStore, repoStore, eventsReporter)
apiHandler := router.ProvideAPIHandler(config, authenticator, accountClient, controller, principalController, spaceController, repoController, pullreqController, webhookController, githookController)
checkStore := database.ProvideCheckStore(db, principalInfoCache)
checkController := check2.ProvideController(db, authorizer, checkStore, repoStore, gitrpcInterface)
apiHandler := router.ProvideAPIHandler(config, authenticator, accountClient, controller, principalController, spaceController, repoController, pullreqController, webhookController, githookController, checkController)
gitHandler := router.ProvideGitHandler(config, provider, repoStore, authenticator, authorizer, gitrpcInterface)
webHandler := router2.ProvideWebHandler(config)
routerRouter := router2.ProvideRouter(config, apiHandler, gitHandler, webHandler)

View File

@ -14,6 +14,7 @@ import (
"github.com/harness/gitness/gitrpc"
gitrpcserver "github.com/harness/gitness/gitrpc/server"
gitrpccron "github.com/harness/gitness/gitrpc/server/cron"
checkcontroller "github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/controller/githook"
"github.com/harness/gitness/internal/api/controller/principal"
"github.com/harness/gitness/internal/api/controller/pullreq"
@ -85,6 +86,7 @@ func initSystem(ctx context.Context, config *types.Config) (*system, error) {
pubsub.WireSet,
codecomments.WireSet,
gitrpccron.WireSet,
checkcontroller.WireSet,
)
return &system{}, nil
}

View File

@ -11,6 +11,7 @@ import (
"github.com/harness/gitness/gitrpc"
server2 "github.com/harness/gitness/gitrpc/server"
"github.com/harness/gitness/gitrpc/server/cron"
check2 "github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/controller/githook"
"github.com/harness/gitness/internal/api/controller/principal"
"github.com/harness/gitness/internal/api/controller/pullreq"
@ -130,7 +131,9 @@ func initSystem(ctx context.Context, config *types.Config) (*system, error) {
githookController := githook.ProvideController(db, authorizer, principalStore, repoStore, eventsReporter)
serviceaccountController := serviceaccount.NewController(principalUID, authorizer, principalStore, spaceStore, repoStore, tokenStore)
principalController := principal.NewController(principalStore)
apiHandler := router.ProvideAPIHandler(config, authenticator, repoController, spaceController, pullreqController, webhookController, githookController, serviceaccountController, controller, principalController)
checkStore := database.ProvideCheckStore(db, principalInfoCache)
checkController := check2.ProvideController(db, authorizer, checkStore, repoStore, gitrpcInterface)
apiHandler := router.ProvideAPIHandler(config, authenticator, repoController, spaceController, pullreqController, webhookController, githookController, serviceaccountController, controller, principalController, checkController)
gitHandler := router.ProvideGitHandler(config, provider, repoStore, authenticator, authorizer, gitrpcInterface)
webHandler := router.ProvideWebHandler(config)
routerRouter := router.ProvideRouter(config, apiHandler, gitHandler, webHandler)

17
gitrpc/validate.go Normal file
View File

@ -0,0 +1,17 @@
// 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 gitrpc
import "regexp"
var matchCommitSHA = regexp.MustCompile("^[0-9a-f]+$")
func ValidateCommitSHA(commitSHA string) bool {
if len(commitSHA) != 40 && len(commitSHA) != 64 {
return false
}
return matchCommitSHA.MatchString(commitSHA)
}

View File

@ -0,0 +1,34 @@
// 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 check
import (
"context"
"fmt"
"github.com/harness/gitness/internal/auth"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
// ListChecks return an array of status check results for a commit in a repository.
func (c *Controller) ListChecks(
ctx context.Context,
session *auth.Session,
repoRef string,
commitSHA string,
) ([]*types.Check, error) {
repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoView)
if err != nil {
return nil, fmt.Errorf("failed to acquire access access to repo: %w", err)
}
list, err := c.checkStore.List(ctx, repo.ID, commitSHA)
if err != nil {
return nil, fmt.Errorf("failed to list status check results for repo=%s: %w", repo.UID, err)
}
return list, nil
}

View File

@ -0,0 +1,122 @@
// 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 check
import (
"context"
"encoding/json"
"fmt"
"regexp"
"time"
"github.com/harness/gitness/gitrpc"
"github.com/harness/gitness/internal/api/usererror"
"github.com/harness/gitness/internal/auth"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
type ReportInput struct {
CheckUID string `json:"check_uid"`
Status enum.CheckStatus `json:"status"`
Summary string `json:"summary"`
Link string `json:"link"`
Payload types.CheckPayload `json:"payload"`
}
var regexpCheckUID = "^[a-zA-Z_][0-9a-zA-Z-_.$]{0,127}$"
var matcherCheckUID = regexp.MustCompile(regexpCheckUID)
// Validate validates and sanitizes the ReportInput data.
func (in *ReportInput) Validate() error {
if in.CheckUID == "" {
return usererror.BadRequest("Status check UID is missing")
}
if !matcherCheckUID.MatchString(in.CheckUID) {
return usererror.BadRequestf("Status check UID must match the regular expression: %s", regexpCheckUID)
}
_, ok := in.Status.Sanitize()
if !ok {
return usererror.BadRequest("Invalid value provided for status check status")
}
payloadKind, ok := in.Payload.Kind.Sanitize()
if !ok {
return usererror.BadRequest("Invalid value provided for the payload type")
}
in.Payload.Kind = payloadKind
switch in.Payload.Kind {
case enum.CheckPayloadKindExternal:
// the default external type does not support payload: clear it here
in.Payload.Version = ""
in.Payload.Data = []byte{'{', '}'}
if in.Link == "" { // the link is mandatory for the external
return usererror.BadRequest("Link is missing")
}
}
return nil
}
// Report modifies an existing or creates a new (if none yet exists) status check report for a specific commit.
func (c *Controller) Report(
ctx context.Context,
session *auth.Session,
repoRef string,
commitSHA string,
in *ReportInput,
metadata map[string]string,
) (*types.Check, error) {
repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionCommitCheckReport)
if err != nil {
return nil, fmt.Errorf("failed to acquire access access to repo: %w", err)
}
if errValidate := in.Validate(); errValidate != nil {
return nil, errValidate
}
if !gitrpc.ValidateCommitSHA(commitSHA) {
return nil, usererror.BadRequest("invalid commit SHA provided")
}
_, err = c.gitRPCClient.GetCommit(ctx, &gitrpc.GetCommitParams{
ReadParams: gitrpc.ReadParams{RepoUID: repo.GitUID},
SHA: commitSHA,
})
if err != nil {
return nil, fmt.Errorf("failed to commit sha=%s: %w", commitSHA, err)
}
now := time.Now().UnixMilli()
metadataJson, _ := json.Marshal(metadata)
statusCheckReport := &types.Check{
CreatedBy: session.Principal.ID,
Created: now,
Updated: now,
RepoID: repo.ID,
CommitSHA: commitSHA,
UID: in.CheckUID,
Status: in.Status,
Summary: in.Summary,
Link: in.Link,
Payload: in.Payload,
Metadata: metadataJson,
ReportedBy: *session.Principal.ToPrincipalInfo(),
}
err = c.checkStore.Upsert(ctx, statusCheckReport)
if err != nil {
return nil, fmt.Errorf("failed to upsert status check result for repo=%s: %w", repo.UID, err)
}
return statusCheckReport, nil
}

View File

@ -0,0 +1,65 @@
// 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 check
import (
"context"
"fmt"
"github.com/harness/gitness/gitrpc"
apiauth "github.com/harness/gitness/internal/api/auth"
"github.com/harness/gitness/internal/api/usererror"
"github.com/harness/gitness/internal/auth"
"github.com/harness/gitness/internal/auth/authz"
"github.com/harness/gitness/internal/store"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/jmoiron/sqlx"
)
type Controller struct {
db *sqlx.DB
authorizer authz.Authorizer
checkStore store.CheckStore
reqCheckStore store.ReqCheckStore
repoStore store.RepoStore
gitRPCClient gitrpc.Interface
}
func NewController(
db *sqlx.DB,
authorizer authz.Authorizer,
checkStore store.CheckStore,
repoStore store.RepoStore,
gitRPCClient gitrpc.Interface,
) *Controller {
return &Controller{
db: db,
authorizer: authorizer,
checkStore: checkStore,
repoStore: repoStore,
gitRPCClient: gitRPCClient,
}
}
func (c *Controller) getRepoCheckAccess(ctx context.Context,
session *auth.Session, repoRef string, reqPermission enum.Permission,
) (*types.Repository, error) {
if repoRef == "" {
return nil, usererror.BadRequest("A valid repository reference must be provided.")
}
repo, err := c.repoStore.FindByRef(ctx, repoRef)
if err != nil {
return nil, fmt.Errorf("failed to find repository: %w", err)
}
if err = apiauth.CheckRepo(ctx, c.authorizer, session, repo, reqPermission, false); err != nil {
return nil, fmt.Errorf("access check failed: %w", err)
}
return repo, nil
}

View File

@ -0,0 +1,30 @@
// 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 check
import (
"github.com/harness/gitness/gitrpc"
"github.com/harness/gitness/internal/auth/authz"
"github.com/harness/gitness/internal/store"
"github.com/google/wire"
"github.com/jmoiron/sqlx"
)
// WireSet provides a wire set for this package.
var WireSet = wire.NewSet(
ProvideController,
)
func ProvideController(db *sqlx.DB, authorizer authz.Authorizer,
checkStore store.CheckStore,
repoStore store.RepoStore,
rpcClient gitrpc.Interface,
) *Controller {
return NewController(db, authorizer,
checkStore,
repoStore,
rpcClient)
}

View File

@ -0,0 +1,41 @@
// 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 pullreq
import (
"net/http"
"github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/render"
"github.com/harness/gitness/internal/api/request"
)
// HandleCheckList is an HTTP handler for listing status check results for a repository.
func HandleCheckList(checkCtrl *check.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
}
commitSHA, err := request.GetCommitSHAFromPath(r)
if err != nil {
render.TranslatedUserError(w, err)
return
}
list, err := checkCtrl.ListChecks(ctx, session, repoRef, commitSHA)
if err != nil {
render.TranslatedUserError(w, err)
return
}
render.JSON(w, http.StatusOK, list)
}
}

View File

@ -0,0 +1,50 @@
// 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 pullreq
import (
"encoding/json"
"net/http"
"github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/render"
"github.com/harness/gitness/internal/api/request"
)
// HandleCheckReport is an HTTP handler for reporting status check results.
func HandleCheckReport(checkCtrl *check.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
}
commitSHA, err := request.GetCommitSHAFromPath(r)
if err != nil {
render.TranslatedUserError(w, err)
return
}
in := new(check.ReportInput)
err = json.NewDecoder(r.Body).Decode(in)
if err != nil {
render.BadRequestf(w, "Invalid Request Body: %s.", err)
return
}
statusCheck, err := checkCtrl.Report(ctx, session,
repoRef, commitSHA, in, map[string]string{})
if err != nil {
render.TranslatedUserError(w, err)
return
}
render.JSON(w, http.StatusOK, statusCheck)
}
}

View File

@ -0,0 +1,54 @@
// 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 openapi
import (
"net/http"
"github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/usererror"
"github.com/harness/gitness/types"
"github.com/swaggest/openapi-go/openapi3"
)
type reportStatusCheckResultRequest struct {
repoRequest
CommitSHA string `path:"commit_sha"`
check.ReportInput
}
type listStatusCheckResultsRequest struct {
repoRequest
CommitSHA string `path:"commit_sha"`
}
func checkOperations(reflector *openapi3.Reflector) {
const tag = "status_checks"
reportStatusCheckResults := openapi3.Operation{}
reportStatusCheckResults.WithTags(tag)
reportStatusCheckResults.WithMapOfAnything(map[string]interface{}{"operationId": "reportStatusCheckResults"})
_ = reflector.SetRequest(&reportStatusCheckResults, new(reportStatusCheckResultRequest), http.MethodPut)
_ = reflector.SetJSONResponse(&reportStatusCheckResults, new(types.Check), http.StatusOK)
_ = reflector.SetJSONResponse(&reportStatusCheckResults, new(usererror.Error), http.StatusBadRequest)
_ = reflector.SetJSONResponse(&reportStatusCheckResults, new(usererror.Error), http.StatusInternalServerError)
_ = reflector.SetJSONResponse(&reportStatusCheckResults, new(usererror.Error), http.StatusUnauthorized)
_ = reflector.SetJSONResponse(&reportStatusCheckResults, new(usererror.Error), http.StatusForbidden)
_ = reflector.Spec.AddOperation(http.MethodPut, "/repos/{repo_ref}/checks/commits/{commit_sha}",
reportStatusCheckResults)
listStatusCheckResults := openapi3.Operation{}
listStatusCheckResults.WithTags(tag)
listStatusCheckResults.WithMapOfAnything(map[string]interface{}{"operationId": "listStatusCheckResults"})
_ = reflector.SetRequest(&listStatusCheckResults, new(listStatusCheckResultsRequest), http.MethodGet)
_ = reflector.SetJSONResponse(&listStatusCheckResults, new([]types.Check), http.StatusOK)
_ = reflector.SetJSONResponse(&listStatusCheckResults, new(usererror.Error), http.StatusBadRequest)
_ = reflector.SetJSONResponse(&listStatusCheckResults, new(usererror.Error), http.StatusInternalServerError)
_ = reflector.SetJSONResponse(&listStatusCheckResults, new(usererror.Error), http.StatusUnauthorized)
_ = reflector.SetJSONResponse(&listStatusCheckResults, new(usererror.Error), http.StatusForbidden)
_ = reflector.Spec.AddOperation(http.MethodGet, "/repos/{repo_ref}/checks/commits/{commit_sha}",
listStatusCheckResults)
}

View File

@ -43,6 +43,7 @@ func Generate() *openapi3.Spec {
resourceOperations(&reflector)
pullReqOperations(&reflector)
webhookOperations(&reflector)
checkOperations(&reflector)
//
// define security scheme

View File

@ -8,6 +8,7 @@ import (
"fmt"
"net/http"
"github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/controller/githook"
"github.com/harness/gitness/internal/api/controller/principal"
"github.com/harness/gitness/internal/api/controller/pullreq"
@ -17,6 +18,7 @@ import (
"github.com/harness/gitness/internal/api/controller/user"
"github.com/harness/gitness/internal/api/controller/webhook"
"github.com/harness/gitness/internal/api/handler/account"
handlercheck "github.com/harness/gitness/internal/api/handler/check"
handlergithook "github.com/harness/gitness/internal/api/handler/githook"
handlerprincipal "github.com/harness/gitness/internal/api/handler/principal"
handlerpullreq "github.com/harness/gitness/internal/api/handler/pullreq"
@ -64,7 +66,9 @@ func NewAPIHandler(
githookCtrl *githook.Controller,
saCtrl *serviceaccount.Controller,
userCtrl *user.Controller,
principalCtrl *principal.Controller) APIHandler {
principalCtrl *principal.Controller,
checkCtrl *check.Controller,
) APIHandler {
// Use go-chi router for inner routing.
r := chi.NewRouter()
@ -85,7 +89,8 @@ func NewAPIHandler(
r.Use(middlewareauthn.Attempt(authenticator, authn.SourceRouterAPI))
r.Route("/v1", func(r chi.Router) {
setupRoutesV1(r, repoCtrl, spaceCtrl, pullreqCtrl, webhookCtrl, githookCtrl, saCtrl, userCtrl, principalCtrl)
setupRoutesV1(r, repoCtrl, spaceCtrl, pullreqCtrl, webhookCtrl, githookCtrl,
saCtrl, userCtrl, principalCtrl, checkCtrl)
})
// wrap router in terminatedPath encoder.
@ -106,11 +111,18 @@ func corsHandler(config *types.Config) func(http.Handler) http.Handler {
}
func setupRoutesV1(r chi.Router,
repoCtrl *repo.Controller, spaceCtrl *space.Controller,
pullreqCtrl *pullreq.Controller, webhookCtrl *webhook.Controller, githookCtrl *githook.Controller,
saCtrl *serviceaccount.Controller, userCtrl *user.Controller, principalCtrl *principal.Controller) {
repoCtrl *repo.Controller,
spaceCtrl *space.Controller,
pullreqCtrl *pullreq.Controller,
webhookCtrl *webhook.Controller,
githookCtrl *githook.Controller,
saCtrl *serviceaccount.Controller,
userCtrl *user.Controller,
principalCtrl *principal.Controller,
checkCtrl *check.Controller,
) {
setupSpaces(r, spaceCtrl, repoCtrl)
setupRepos(r, repoCtrl, pullreqCtrl, webhookCtrl)
setupRepos(r, repoCtrl, pullreqCtrl, webhookCtrl, checkCtrl)
setupUser(r, userCtrl)
setupServiceAccounts(r, saCtrl)
setupPrincipals(r, principalCtrl)
@ -151,8 +163,12 @@ func setupSpaces(r chi.Router, spaceCtrl *space.Controller, repoCtrl *repo.Contr
})
}
func setupRepos(r chi.Router, repoCtrl *repo.Controller, pullreqCtrl *pullreq.Controller,
webhookCtrl *webhook.Controller) {
func setupRepos(r chi.Router,
repoCtrl *repo.Controller,
pullreqCtrl *pullreq.Controller,
webhookCtrl *webhook.Controller,
checkCtrl *check.Controller,
) {
r.Route("/repos", func(r chi.Router) {
// Create takes path and parentId via body, not uri
r.Post("/", handlerrepo.HandleCreate(repoCtrl))
@ -239,6 +255,8 @@ func setupRepos(r chi.Router, repoCtrl *repo.Controller, pullreqCtrl *pullreq.Co
SetupPullReq(r, pullreqCtrl)
SetupWebhook(r, webhookCtrl)
SetupChecks(r, checkCtrl)
})
})
}
@ -312,6 +330,15 @@ func SetupWebhook(r chi.Router, webhookCtrl *webhook.Controller) {
})
}
func SetupChecks(r chi.Router, checkCtrl *check.Controller) {
r.Route("/checks", func(r chi.Router) {
r.Route(fmt.Sprintf("/commits/{%s}", request.PathParamCommitSHA), func(r chi.Router) {
r.Put("/", handlercheck.HandleCheckReport(checkCtrl))
r.Get("/", handlercheck.HandleCheckList(checkCtrl))
})
})
}
func setupUser(r chi.Router, userCtrl *user.Controller) {
r.Route("/user", func(r chi.Router) {
// enforce principal authenticated and it's a user

View File

@ -6,6 +6,7 @@ package router
import (
"github.com/harness/gitness/gitrpc"
"github.com/harness/gitness/internal/api/controller/check"
"github.com/harness/gitness/internal/api/controller/githook"
"github.com/harness/gitness/internal/api/controller/principal"
"github.com/harness/gitness/internal/api/controller/pullreq"
@ -62,9 +63,11 @@ func ProvideAPIHandler(
githookCtrl *githook.Controller,
saCtrl *serviceaccount.Controller,
userCtrl *user.Controller,
principalCtrl *principal.Controller) APIHandler {
principalCtrl *principal.Controller,
checkCtrl *check.Controller,
) APIHandler {
return NewAPIHandler(config, authenticator, repoCtrl, spaceCtrl, pullreqCtrl,
webhookCtrl, githookCtrl, saCtrl, userCtrl, principalCtrl)
webhookCtrl, githookCtrl, saCtrl, userCtrl, principalCtrl, checkCtrl)
}
func ProvideWebHandler(config *types.Config) WebHandler {

View File

@ -46,13 +46,14 @@ const (
,check_updated
,check_repo_id
,check_commit_sha
,check_type
,check_uid
,check_status
,check_summary
,check_link
,check_payload
,check_metadata`
,check_metadata
,check_payload_kind
,check_payload_version`
)
type check struct {
@ -62,13 +63,14 @@ type check struct {
Updated int64 `db:"check_updated"`
RepoID int64 `db:"check_repo_id"`
CommitSHA string `db:"check_commit_sha"`
Type string `db:"check_type"`
UID string `db:"check_uid"`
Status enum.CheckStatus `db:"check_status"`
Summary string `db:"check_summary"`
Link string `db:"check_link"`
Payload json.RawMessage `db:"check_payload"`
Metadata json.RawMessage `db:"check_metadata"`
PayloadKind enum.CheckPayloadKind `db:"check_payload_kind"`
PayloadVersion string `db:"check_payload_version"`
}
// Upsert creates new or updates an existing status check result.
@ -80,26 +82,28 @@ func (s *CheckStore) Upsert(ctx context.Context, check *types.Check) error {
,check_updated
,check_repo_id
,check_commit_sha
,check_type
,check_uid
,check_status
,check_summary
,check_link
,check_payload
,check_metadata
,check_payload_kind
,check_payload_version
) VALUES (
:check_created_by
,:check_created
,:check_updated
,:check_repo_id
,:check_commit_sha
,:check_type
,:check_uid
,:check_status
,:check_summary
,:check_link
,:check_payload
,:check_metadata
,:check_payload_kind
,:check_payload_version
)
ON CONFLICT (check_repo_id, check_commit_sha, check_uid) DO
UPDATE SET
@ -109,7 +113,9 @@ func (s *CheckStore) Upsert(ctx context.Context, check *types.Check) error {
,check_link = :check_link
,check_payload = :check_payload
,check_metadata = :check_metadata
RETURNING check_id`
,check_payload_kind = :check_payload_kind
,check_payload_version = :check_payload_version
RETURNING check_id, check_created_by, check_created`
db := dbtx.GetAccessor(ctx, s.db)
@ -118,7 +124,7 @@ func (s *CheckStore) Upsert(ctx context.Context, check *types.Check) error {
return processSQLErrorf(err, "Failed to bind status check object")
}
if err = db.QueryRowContext(ctx, query, arg...).Scan(&check.ID); err != nil {
if err = db.QueryRowContext(ctx, query, arg...).Scan(&check.ID, &check.CreatedBy, &check.Created); err != nil {
return processSQLErrorf(err, "Upsert query failed")
}
@ -188,13 +194,14 @@ func mapInternalCheck(c *types.Check) *check {
Updated: c.Updated,
RepoID: c.RepoID,
CommitSHA: c.CommitSHA,
Type: c.Type,
UID: c.UID,
Status: c.Status,
Summary: c.Summary,
Link: c.Link,
Payload: c.Payload,
Payload: c.Payload.Data,
Metadata: c.Metadata,
PayloadKind: c.Payload.Kind,
PayloadVersion: c.Payload.Version,
}
return m
@ -208,13 +215,16 @@ func mapCheck(c *check) *types.Check {
Updated: c.Updated,
RepoID: c.RepoID,
CommitSHA: c.CommitSHA,
Type: c.Type,
UID: c.UID,
Status: c.Status,
Summary: c.Summary,
Link: c.Link,
Payload: c.Payload,
Metadata: c.Metadata,
Payload: types.CheckPayload{
Version: c.PayloadVersion,
Kind: c.PayloadKind,
Data: c.Payload,
},
ReportedBy: types.PrincipalInfo{},
}
}

View File

@ -0,0 +1,4 @@
ALTER TABLE checks
ADD COLUMN check_type TEXT NOT NULL DEFAULT '',
DROP COLUMN check_payload_version,
DROP COLUMN check_payload_kind;

View File

@ -0,0 +1,4 @@
ALTER TABLE checks
ADD COLUMN check_payload_version TEXT NOT NULL DEFAULT '',
ADD COLUMN check_payload_kind TEXT NOT NULL DEFAULT '',
DROP COLUMN check_type;

View File

@ -0,0 +1,3 @@
ALTER TABLE checks ADD COLUMN check_type TEXT NOT NULL DEFAULT '';
ALTER TABLE checks DROP COLUMN check_payload_version;
ALTER TABLE checks DROP COLUMN check_payload_kind;

View File

@ -0,0 +1,3 @@
ALTER TABLE checks ADD COLUMN check_payload_version TEXT NOT NULL DEFAULT '';
ALTER TABLE checks ADD COLUMN check_payload_kind TEXT NOT NULL DEFAULT '';
ALTER TABLE checks DROP COLUMN check_type;

View File

@ -17,17 +17,22 @@ type Check struct {
Updated int64 `json:"updated"`
RepoID int64 `json:"-"` // status checks are always returned for a commit in a repository
CommitSHA string `json:"-"` // status checks are always returned for a commit in a repository
Type string `json:"type"`
UID string `json:"uid"`
Status enum.CheckStatus `json:"status"`
Summary string `json:"summary"`
Link string `json:"link"`
Payload json.RawMessage `json:"payload"`
Metadata json.RawMessage `json:"metadata"`
Payload CheckPayload `json:"payload"`
ReportedBy PrincipalInfo `json:"reported_by"`
}
type CheckPayload struct {
Version string `json:"version"`
Kind enum.CheckPayloadKind `json:"kind"`
Data json.RawMessage `json:"data"`
}
type ReqCheck struct {
ID int64 `json:"id"`
CreatedBy int64 `json:"-"` // clients will use "added_by"

View File

@ -11,7 +11,7 @@ func (CheckStatus) Enum() []interface{} { return toInterfaceSlic
func (s CheckStatus) Sanitize() (CheckStatus, bool) { return Sanitize(s, GetAllCheckStatuses) }
func GetAllCheckStatuses() ([]CheckStatus, CheckStatus) { return checkStatuses, "" }
// PullReqState enumeration.
// CheckStatus enumeration.
const (
CheckStatusPending CheckStatus = "pending"
CheckStatusRunning CheckStatus = "running"
@ -27,3 +27,23 @@ var checkStatuses = sortEnum([]CheckStatus{
CheckStatusFailure,
CheckStatusError,
})
// CheckPayloadKind defines status payload type.
type CheckPayloadKind string
func (CheckPayloadKind) Enum() []interface{} { return toInterfaceSlice(checkPayloadTypes) }
func (s CheckPayloadKind) Sanitize() (CheckPayloadKind, bool) {
return Sanitize(s, GetAllCheckPayloadTypes)
}
func GetAllCheckPayloadTypes() ([]CheckPayloadKind, CheckPayloadKind) {
return checkPayloadTypes, CheckPayloadKindExternal
}
// CheckPayloadKind enumeration.
const (
CheckPayloadKindExternal CheckPayloadKind = "external"
)
var checkPayloadTypes = sortEnum([]CheckPayloadKind{
CheckPayloadKindExternal,
})

View File

@ -70,3 +70,10 @@ const (
PermissionServiceDelete Permission = "service_delete"
PermissionServiceEditAdmin Permission = "service_editadmin"
)
const (
/*
----- COMMIT CHECK -----
*/
PermissionCommitCheckReport Permission = "commitCheck_report"
)