webhook: add runRefType and convert webhook event

Introduce a runRefType that represent the ref type of the Run (branch/tag/PR)
Convert the webhook event type to the runRefType and use it to generate the run
group.
This commit is contained in:
Simone Gotti 2019-06-10 16:49:39 +02:00
parent 38b54b092c
commit 28ddfb1781
4 changed files with 81 additions and 31 deletions

View File

@ -39,19 +39,23 @@ const (
ApproversAnnotation = "approvers" ApproversAnnotation = "approvers"
) )
func GenRunGroup(baseGroupType GroupType, baseGroupID string, webhookData *types.WebhookData) string { func WebHookEventToRunRefType(we types.WebhookEvent) types.RunRefType {
// we pathescape the branch name to handle branches with slashes and make the switch we {
// branch a single path entry
switch webhookData.Event {
case types.WebhookEventPush: case types.WebhookEventPush:
return path.Join("/", string(baseGroupType), baseGroupID, string(GroupTypeBranch), url.PathEscape(webhookData.Branch)) return types.RunRefTypeBranch
case types.WebhookEventTag: case types.WebhookEventTag:
return path.Join("/", string(baseGroupType), baseGroupID, string(GroupTypeTag), url.PathEscape(webhookData.Tag)) return types.RunRefTypeTag
case types.WebhookEventPullRequest: case types.WebhookEventPullRequest:
return path.Join("/", string(baseGroupType), baseGroupID, string(GroupTypePullRequest), url.PathEscape(webhookData.PullRequestID)) return types.RunRefTypePullRequest
} }
panic(fmt.Errorf("invalid webhook event type: %q", webhookData.Event)) panic(fmt.Errorf("invalid webhook event type: %q", we))
}
func GenRunGroup(baseGroupType GroupType, baseGroupID string, groupType GroupType, group string) string {
// we pathescape the branch name to handle branches with slashes and make the
// branch a single path entry
return path.Join("/", string(baseGroupType), baseGroupID, string(groupType), url.PathEscape(group))
} }
func GroupTypeIDFromRunGroup(group string) (GroupType, string, error) { func GroupTypeIDFromRunGroup(group string) (GroupType, string, error) {

View File

@ -90,28 +90,30 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) {
return http.StatusBadRequest, "", errors.Errorf("bad webhook url %q. Missing projectid or userid", r.URL) return http.StatusBadRequest, "", errors.Errorf("bad webhook url %q. Missing projectid or userid", r.URL)
} }
isUserBuild := false runType := types.RunTypeProject
if projectID == "" { if projectID == "" {
isUserBuild = true runType = types.RunTypeUser
} }
defer r.Body.Close() defer r.Body.Close()
var project *types.Project
var user *types.User
var webhookData *types.WebhookData var webhookData *types.WebhookData
var sshPrivKey string var sshPrivKey string
var cloneURL string var cloneURL string
var sshHostKey string var sshHostKey string
var skipSSHHostKeyCheck bool var skipSSHHostKeyCheck bool
var runType types.RunType
variables := map[string]string{} variables := map[string]string{}
var gitSource gitsource.GitSource var gitSource gitsource.GitSource
if !isUserBuild { if runType == types.RunTypeProject {
project, _, err := h.configstoreClient.GetProject(ctx, projectID) csProject, _, err := h.configstoreClient.GetProject(ctx, projectID)
if err != nil { if err != nil {
return http.StatusBadRequest, "", errors.Errorf("failed to get project %s: %w", projectID, err) return http.StatusBadRequest, "", errors.Errorf("failed to get project %s: %w", projectID, err)
} }
h.log.Infof("project: %s", util.Dump(project)) h.log.Infof("project: %s", util.Dump(project))
project = csProject.Project
user, _, err := h.configstoreClient.GetUserByLinkedAccount(ctx, project.LinkedAccountID) user, _, err := h.configstoreClient.GetUserByLinkedAccount(ctx, project.LinkedAccountID)
if err != nil { if err != nil {
@ -209,12 +211,11 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) {
return 0, "", nil return 0, "", nil
} }
user, _, err := h.configstoreClient.GetUser(ctx, userID) user, _, err = h.configstoreClient.GetUser(ctx, userID)
if err != nil { if err != nil {
return http.StatusBadRequest, "", errors.Errorf("failed to get user with id %q: %w", userID, err) return http.StatusBadRequest, "", errors.Errorf("failed to get user with id %q: %w", userID, err)
} }
h.log.Debugf("user: %s", util.Dump(user)) h.log.Debugf("user: %s", util.Dump(user))
userID = user.ID
cloneURL = fmt.Sprintf("%s/%s", h.apiExposedURL+"/repos", webhookData.Repo.Path) cloneURL = fmt.Sprintf("%s/%s", h.apiExposedURL+"/repos", webhookData.Repo.Path)
runType = types.RunTypeUser runType = types.RunTypeUser
@ -269,7 +270,7 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) {
AnnotationCompareLink: webhookData.CompareLink, AnnotationCompareLink: webhookData.CompareLink,
} }
if !isUserBuild { if runType == types.RunTypeProject {
annotations[AnnotationProjectID] = webhookData.ProjectID annotations[AnnotationProjectID] = webhookData.ProjectID
} else { } else {
annotations[AnnotationUserID] = userID annotations[AnnotationUserID] = userID
@ -288,14 +289,36 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) {
annotations[AnnotationPullRequestLink] = webhookData.PullRequestLink annotations[AnnotationPullRequestLink] = webhookData.PullRequestLink
} }
var baseGroupType common.GroupType
var baseGroupID string
var groupType common.GroupType
var group string var group string
if !isUserBuild {
group = common.GenRunGroup(common.GroupTypeProject, webhookData.ProjectID, webhookData) refType := common.WebHookEventToRunRefType(webhookData.Event)
if runType == types.RunTypeProject {
baseGroupType = common.GroupTypeProject
baseGroupID = project.ID
} else { } else {
group = common.GenRunGroup(common.GroupTypeUser, userID, webhookData) baseGroupType = common.GroupTypeUser
baseGroupID = user.ID
} }
if err := h.createRuns(ctx, filename, data, group, annotations, env, variables, webhookData); err != nil { switch refType {
case types.RunRefTypeBranch:
groupType = common.GroupTypeBranch
group = webhookData.Branch
case types.RunRefTypeTag:
groupType = common.GroupTypeTag
group = webhookData.Tag
case types.RunRefTypePullRequest:
groupType = common.GroupTypePullRequest
group = webhookData.PullRequestID
}
runGroup := common.GenRunGroup(baseGroupType, baseGroupID, groupType, group)
if err := h.createRuns(ctx, filename, data, runGroup, annotations, env, variables, webhookData); err != nil {
return http.StatusInternalServerError, "", errors.Errorf("failed to create run: %w", err) return http.StatusInternalServerError, "", errors.Errorf("failed to create run: %w", err)
} }
//if err := gitSource.CreateStatus(webhookData.Repo.Owner, webhookData.Repo.Name, webhookData.CommitSHA, gitsource.CommitStatusPending, "localhost:8080", "build %s", "agola"); err != nil { //if err := gitSource.CreateStatus(webhookData.Repo.Owner, webhookData.Repo.Name, webhookData.CommitSHA, gitsource.CommitStatusPending, "localhost:8080", "build %s", "agola"); err != nil {
@ -327,7 +350,7 @@ func (h *webhooksHandler) fetchConfigFiles(gitSource gitsource.GitSource, webhoo
return data, filename, nil return data, filename, nil
} }
func (h *webhooksHandler) createRuns(ctx context.Context, filename string, configData []byte, group string, annotations, staticEnv, variables map[string]string, webhookData *types.WebhookData) error { func (h *webhooksHandler) createRuns(ctx context.Context, filename string, configData []byte, runGroup string, annotations, staticEnv, variables map[string]string, webhookData *types.WebhookData) error {
setupErrors := []string{} setupErrors := []string{}
var configFormat config.ConfigFormat var configFormat config.ConfigFormat
@ -349,7 +372,7 @@ func (h *webhooksHandler) createRuns(ctx context.Context, filename string, confi
setupErrors = append(setupErrors, err.Error()) setupErrors = append(setupErrors, err.Error())
createRunReq := &rsapi.RunCreateRequest{ createRunReq := &rsapi.RunCreateRequest{
RunConfigTasks: nil, RunConfigTasks: nil,
Group: group, Group: runGroup,
SetupErrors: setupErrors, SetupErrors: setupErrors,
Name: rstypes.RunGenericSetupErrorName, Name: rstypes.RunGenericSetupErrorName,
StaticEnvironment: staticEnv, StaticEnvironment: staticEnv,
@ -367,10 +390,10 @@ func (h *webhooksHandler) createRuns(ctx context.Context, filename string, confi
rcts := runconfig.GenRunConfigTasks(util.DefaultUUIDGenerator{}, config, run.Name, variables, webhookData.Branch, webhookData.Tag, webhookData.Ref) rcts := runconfig.GenRunConfigTasks(util.DefaultUUIDGenerator{}, config, run.Name, variables, webhookData.Branch, webhookData.Tag, webhookData.Ref)
h.log.Debugf("rcts: %s", util.Dump(rcts)) h.log.Debugf("rcts: %s", util.Dump(rcts))
h.log.Infof("group: %s", group) h.log.Infof("group: %s", runGroup)
createRunReq := &rsapi.RunCreateRequest{ createRunReq := &rsapi.RunCreateRequest{
RunConfigTasks: rcts, RunConfigTasks: rcts,
Group: group, Group: runGroup,
SetupErrors: setupErrors, SetupErrors: setupErrors,
Name: run.Name, Name: run.Name,
StaticEnvironment: staticEnv, StaticEnvironment: staticEnv,

View File

@ -0,0 +1,30 @@
// Copyright 2019 Sorint.lab
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
// See the License for the specific language governing permissions and
// limitations under the License.
package types
type RunType string
const (
RunTypeProject RunType = "project"
RunTypeUser RunType = "user"
)
type RunRefType string
const (
RunRefTypeBranch RunRefType = "branch"
RunRefTypeTag RunRefType = "tag"
RunRefTypePullRequest RunRefType = "pull_request"
)

View File

@ -22,13 +22,6 @@ const (
WebhookEventPullRequest WebhookEvent = "pull_request" WebhookEventPullRequest WebhookEvent = "pull_request"
) )
type RunType string
const (
RunTypeProject RunType = "project"
RunTypeUser RunType = "user"
)
type WebhookData struct { type WebhookData struct {
Event WebhookEvent `json:"event,omitempty"` Event WebhookEvent `json:"event,omitempty"`
ProjectID string `json:"project_id,omitempty"` ProjectID string `json:"project_id,omitempty"`