Beispiel #1
0
func handlePullRequestReviewComment(w http.ResponseWriter, r *http.Request) {
	hook, err := github.ParsePullRequestReviewCommentHook(r.Body)
	if err != nil {
		logrus.Error(err)
		w.WriteHeader(500)
		return
	}

	if !hook.IsOpen() {
		w.WriteHeader(200)
		return
	}

	g := github.GitHub{
		AuthToken: config.GHToken,
		User:      config.GHUser,
	}

	if err := g.MoveTriageForward(hook.Repo, hook.PullRequest.Number, hook.Comment); err != nil {
		logrus.Error(err)
		w.WriteHeader(500)
		return
	}

	w.WriteHeader(204)
	return
}
Beispiel #2
0
func (c Config) removeFailedBuildComment(repoName, job string, pr int) error {
	// parse git repo for username
	// and repo name
	r := strings.SplitN(repoName, "/", 2)
	if len(r) < 2 {
		return fmt.Errorf("repo name could not be parsed: %s", repoName)
	}

	// initialize github client
	g := github.GitHub{
		AuthToken: c.GHToken,
		User:      c.GHUser,
	}
	repo := octokat.Repo{
		Name:     r[1],
		UserName: r[0],
	}

	content, err := g.GetContent(repo, pr, true)
	if err != nil {
		return fmt.Errorf("getting pull request content failed: %v", err)
	}

	// find the comments about failed builds and remove them
	if comment := content.FindComment(fmt.Sprintf("Job: %s [FAILED", job), c.GHUser); comment != nil {
		if err := g.Client().RemoveComment(repo, comment.Id); err != nil {
			return fmt.Errorf("removing comment from %s#%d for %s failed: %v", repoName, pr, job, err)
		}
	}

	return nil
}
Beispiel #3
0
func handlePullRequest(w http.ResponseWriter, r *http.Request) {
	logrus.Debugf("Got a pull request hook")

	// parse the pull request
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		logrus.Errorf("Error reading github pull request handler body: %v", err)
		w.WriteHeader(500)
		return
	}

	prHook, err := octokat.ParsePullRequestHook(body)
	if err != nil {
		logrus.Errorf("Error parsing pull request hook: %v", err)
		w.WriteHeader(500)
		return
	}

	pr := prHook.PullRequest
	baseRepo := fmt.Sprintf("%s/%s", pr.Base.Repo.Owner.Login, pr.Base.Repo.Name)

	logrus.Infof("Received GitHub pull request notification for %s %d (%s): %s", baseRepo, pr.Number, pr.URL, prHook.Action)

	// ignore everything we don't care about
	if prHook.Action != "opened" && prHook.Action != "reopened" && prHook.Action != "synchronize" {
		logrus.Debugf("Ignoring PR hook action %q", prHook.Action)
		return
	}

	g := github.GitHub{
		AuthToken: config.GHToken,
		User:      config.GHUser,
	}

	pullRequest, err := g.LoadPullRequest(prHook)
	if err != nil {
		logrus.Errorf("Error loading the pull request: %v", err)
		w.WriteHeader(500)
		return
	}

	valid, err := g.DcoVerified(pullRequest)

	if err != nil {
		logrus.Errorf("Error validating DCO: %v", err)
		w.WriteHeader(500)
		return
	}

	// DCO not valid, we don't start the build
	if !valid {
		logrus.Errorf("Invalid DCO for %s #%d. Aborting build", baseRepo, pr.Number)
		w.WriteHeader(200)
		return
	}

	mergeable, err := g.IsMergeable(pullRequest)
	if err != nil {
		logrus.Errorf("Error checking if PR is mergeable: %v", err)
		w.WriteHeader(500)
		return
	}

	// PR is not mergeable, so don't start the build
	if !mergeable {
		logrus.Errorf("Unmergeable PR for %s #%d. Aborting build", baseRepo, pr.Number)
		w.WriteHeader(200)
		return
	}

	var builds []Build
	// Only run full jobs if there are code related changes
	if !pullRequest.Content.IsNonCodeOnly() {
		// get the builds
		var err error
		builds, err = config.getBuilds(baseRepo, false)
		if err != nil {
			logrus.Warn(err)
		}
	}

	// If there are doc-changes validate them
	if pullRequest.Content.HasDocsChanges() {
		build, err := config.getBuildByContextAndRepo("doc", baseRepo)
		if err != nil {
			logrus.Warnf("Adding doc build to %s for %d failed: %v", baseRepo, pr.Number, err)
		} else {
			builds = append(builds, build)
		}
	}

	// If there are vendoring changes validate them
	if pullRequest.Content.HasVendoringChanges() {
		build, err := config.getBuildByContextAndRepo("vendor", baseRepo)
		if err != nil {
			logrus.Warnf("Adding vendor build to %s for %d failed: %v", baseRepo, pr.Number, err)
		} else {
			builds = append(builds, build)
		}
	}

	// schedule the jenkins builds
	for _, build := range builds {
		if err := config.scheduleJenkinsBuild(baseRepo, pr.Number, build); err != nil {
			logrus.Error(err)
			w.WriteHeader(500)
		}
	}

	return
}
Beispiel #4
0
func handleIssue(w http.ResponseWriter, r *http.Request) {
	logrus.Debugf("Got an issue hook")

	// parse the issue
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		logrus.Errorf("Error reading github issue handler body: %v", err)
		w.WriteHeader(500)
		return
	}

	issueHook, err := octokat.ParseIssueHook(body)
	if err != nil {
		logrus.Errorf("Error parsing issue hook: %v", err)
		w.WriteHeader(500)
		return
	}

	// get the build
	baseRepo := fmt.Sprintf("%s/%s", issueHook.Repo.Owner.Login, issueHook.Repo.Name)
	logrus.Debugf("Issue is for repo: %s", baseRepo)
	build, err := config.getBuildByContextAndRepo("janky", baseRepo)
	if err != nil {
		logrus.Warnf("could not find build for repo %s for issue handler, skipping: %v", baseRepo, err)
		return
	}

	// if we do not handle issues for this build just return
	if !build.HandleIssues {
		logrus.Warnf("Not configured to handle issues for %s", baseRepo)
		return
	}

	g := github.GitHub{
		AuthToken: config.GHToken,
		User:      config.GHUser,
	}

	logrus.Infof("Received GitHub issue notification for %s %d (%s): %s", baseRepo, issueHook.Issue.Number, issueHook.Issue.URL, issueHook.Action)

	// if it is not a comment or an opened issue
	// return becuase we dont care
	if !issueHook.IsComment() && !issueHook.IsOpened() {
		logrus.Debugf("Ignoring issue hook action %q", issueHook.Action)
		return
	}

	// if the issue has just been opened
	// parse if ENEEDMOREINFO
	if issueHook.IsOpened() {
		logrus.Debug("Issue is opened, checking if we have correct info")
		if err := g.IssueInfoCheck(issueHook); err != nil {
			logrus.Errorf("Error checking if issue opened needs more info: %v", err)
			w.WriteHeader(500)
			return
		}

		w.WriteHeader(200)
		return
	}

	if issueHook.Issue.State != "open" {
		return
	}

	if issueHook.Issue.PullRequest.HTMLURL != "" {
		if err := g.MoveTriageForward(issueHook.Repo, issueHook.Issue.Number, issueHook.Comment); err != nil {
			logrus.Error(err)
			w.WriteHeader(500)
			return
		}

		w.WriteHeader(204)
		return
	}

	// handle if it is an issue comment
	// apply approproate labels
	if err := g.LabelIssueComment(issueHook); err != nil {
		logrus.Errorf("Error applying labels to issue comment: %v", err)
		w.WriteHeader(500)
		return
	}

	return
}
Beispiel #5
0
func handlePullRequest(w http.ResponseWriter, r *http.Request) {
	log.Debugf("Got a pull request hook")

	// parse the pull request
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Errorf("Error reading github pull request handler body: %v", err)
		w.WriteHeader(500)
		return
	}

	prHook, err := octokat.ParsePullRequestHook(body)
	if err != nil {
		log.Errorf("Error parsing pull request hook: %v", err)
		w.WriteHeader(500)
		return
	}

	pr := prHook.PullRequest
	baseRepo := fmt.Sprintf("%s/%s", pr.Base.Repo.Owner.Login, pr.Base.Repo.Name)

	log.Infof("Received GitHub pull request notification for %s %d (%s): %s", baseRepo, pr.Number, pr.URL, prHook.Action)

	// ignore everything we don't care about
	if prHook.Action != "opened" && prHook.Action != "reopened" && prHook.Action != "synchronize" {
		log.Debugf("Ignoring PR hook action %q", prHook.Action)
		return
	}

	g := github.GitHub{
		AuthToken: config.GHToken,
		User:      config.GHUser,
	}

	pullRequest, err := g.LoadPullRequest(prHook)
	if err != nil {
		log.Errorf("Error loading the pull request: %v", err)
		w.WriteHeader(500)
		return
	}

	valid, err := g.DcoVerified(pullRequest)

	if err != nil {
		log.Errorf("Error validating DCO: %v", err)
		w.WriteHeader(500)
		return
	}

	// DCO not valid, we don't start the build
	if !valid {
		log.Errorf("Invalid DCO for %s #%d. Aborting build", baseRepo, pr.Number)
		w.WriteHeader(200)
		return
	}

	mergeable, err := g.IsMergeable(pullRequest)
	if err != nil {
		log.Errorf("Error checking if PR is mergeable: %v", err)
		w.WriteHeader(500)
		return
	}

	// PR is not mergeable, so don't start the build
	if !mergeable {
		log.Errorf("Unmergeable PR for %s #%d. Aborting build", baseRepo, pr.Number)
		w.WriteHeader(200)
		return
	}

	// Only docs, don't start jenkins jobs
	if pullRequest.Content.IsDocsOnly() {
		w.WriteHeader(200)
		return
	}

	// get the builds
	builds, err := config.getBuilds(baseRepo, false)
	if err != nil {
		log.Error(err)
		w.WriteHeader(500)
		return
	}

	// schedule the jenkins builds
	for _, build := range builds {
		if err := config.scheduleJenkinsBuild(baseRepo, pr.Number, build); err != nil {
			log.Error(err)
			w.WriteHeader(500)
		}
	}

	return
}