func transformPullRequestEvent(pullRequest PullRequestEventModel) hookCommon.TransformResultModel { if pullRequest.Action == "" { return hookCommon.TransformResultModel{ Error: errors.New("No Pull Request action specified"), ShouldSkip: true, } } if !isAcceptPullRequestAction(pullRequest.Action) { return hookCommon.TransformResultModel{ Error: fmt.Errorf("Pull Request action doesn't require a build: %s", pullRequest.Action), ShouldSkip: true, } } if pullRequest.Action == "edited" { // skip it if only title / description changed, and the previous pattern did not include a [skip ci] pattern if pullRequest.Changes.Base == nil { if !hookCommon.IsSkipBuildByCommitMessage(pullRequest.Changes.Title.From) && !hookCommon.IsSkipBuildByCommitMessage(pullRequest.Changes.Body.From) { return hookCommon.TransformResultModel{ Error: errors.New("Pull Request edit doesn't require a build: only title and/or description was changed, and previous one was not skipped"), ShouldSkip: true, } } } } if pullRequest.PullRequestInfo.Merged { return hookCommon.TransformResultModel{ Error: errors.New("Pull Request already merged"), ShouldSkip: true, } } if pullRequest.PullRequestInfo.Mergeable != nil && *pullRequest.PullRequestInfo.Mergeable == false { return hookCommon.TransformResultModel{ Error: errors.New("Pull Request is not mergeable"), ShouldSkip: true, } } commitMsg := pullRequest.PullRequestInfo.Title if pullRequest.PullRequestInfo.Body != "" { commitMsg = fmt.Sprintf("%s\n\n%s", commitMsg, pullRequest.PullRequestInfo.Body) } return hookCommon.TransformResultModel{ TriggerAPIParams: []bitriseapi.TriggerAPIParamsModel{ { BuildParams: bitriseapi.BuildParamsModel{ CommitMessage: commitMsg, CommitHash: pullRequest.PullRequestInfo.HeadBranchInfo.CommitHash, Branch: pullRequest.PullRequestInfo.HeadBranchInfo.Ref, BranchDest: pullRequest.PullRequestInfo.BaseBranchInfo.Ref, PullRequestID: &pullRequest.PullRequestID, PullRequestRepositoryURL: pullRequest.PullRequestInfo.HeadBranchInfo.getRepositoryURL(), PullRequestMergeBranch: fmt.Sprintf("pull/%d/merge", pullRequest.PullRequestID), PullRequestHeadBranch: fmt.Sprintf("pull/%d/head", pullRequest.PullRequestID), }, }, }, } }
// HTTPHandler ... func HTTPHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) serviceID := vars["service-id"] appSlug := vars["app-slug"] apiToken := vars["api-token"] if serviceID == "" { respondWithErrorString(w, nil, "No service-id defined") return } hookProvider, isSupported := supportedProviders()[serviceID] if !isSupported { respondWithErrorString(w, nil, fmt.Sprintf("Unsupported Webhook Type / Provider: %s", serviceID)) return } if appSlug == "" { respondWithErrorString(w, &hookProvider, "No App Slug parameter defined") return } if apiToken == "" { respondWithErrorString(w, &hookProvider, "No API Token parameter defined") return } hookTransformResult := hookCommon.TransformResultModel{} metrics.Trace("Hook: Transform", func() { hookTransformResult = hookProvider.TransformRequest(r) }) if hookTransformResult.ShouldSkip { respondWithSuccessMessage(w, &hookProvider, fmt.Sprintf("Acknowledged, but skipping. Reason: %s", hookTransformResult.Error)) return } if hookTransformResult.Error != nil { errMsg := fmt.Sprintf("Failed to transform the webhook: %s", hookTransformResult.Error) log.Printf(" (debug) %s", errMsg) respondWithErrorString(w, &hookProvider, errMsg) return } // Let's Trigger a build / some builds! triggerURL := config.SendRequestToURL if triggerURL == nil { u, err := bitriseapi.BuildTriggerURL("https://www.bitrise.io", appSlug) if err != nil { log.Printf(" [!] Exception: hookHandler: failed to create Build Trigger URL: %s", err) respondWithErrorString(w, &hookProvider, fmt.Sprintf("Failed to create Build Trigger URL: %s", err)) return } triggerURL = u } buildTriggerCount := len(hookTransformResult.TriggerAPIParams) if buildTriggerCount == 0 { respondWithErrorString(w, &hookProvider, "After processing the webhook we failed to detect any event in it which could be turned into a build.") return } respondWith := hookCommon.TransformResponseInputModel{ Errors: []string{}, SuccessTriggerResponses: []bitriseapi.TriggerAPIResponseModel{}, SkippedTriggerResponses: []hookCommon.SkipAPIResponseModel{}, FailedTriggerResponses: []bitriseapi.TriggerAPIResponseModel{}, } metrics.Trace("Hook: Trigger Builds", func() { for _, aBuildTriggerParam := range hookTransformResult.TriggerAPIParams { commitMessage := aBuildTriggerParam.BuildParams.CommitMessage if hookCommon.IsSkipBuildByCommitMessage(commitMessage) { respondWith.SkippedTriggerResponses = append(respondWith.SkippedTriggerResponses, hookCommon.SkipAPIResponseModel{ Message: "Build skipped because the commit message included a skip ci keyword ([skip ci] or [ci skip]).", CommitHash: aBuildTriggerParam.BuildParams.CommitHash, CommitMessage: aBuildTriggerParam.BuildParams.CommitMessage, Branch: aBuildTriggerParam.BuildParams.Branch, }) continue } if triggerResp, isSuccess, err := triggerBuild(triggerURL, apiToken, aBuildTriggerParam); err != nil { respondWith.Errors = append(respondWith.Errors, fmt.Sprintf("Failed to Trigger Build: %s", err)) } else if isSuccess { respondWith.SuccessTriggerResponses = append(respondWith.SuccessTriggerResponses, triggerResp) } else { respondWith.FailedTriggerResponses = append(respondWith.FailedTriggerResponses, triggerResp) } } }) respondWithResults(w, &hookProvider, respondWith) }