Skip to content

Commit

Permalink
Merge pull request #15 from diegolnasc/docs/update
Browse files Browse the repository at this point in the history
docs: project documentation
  • Loading branch information
diegolnasc authored Dec 31, 2021
2 parents 1d86969 + 21bb34d commit d25835d
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 45 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<h2 align="center"> Gotcha Bot :robot: </h2>
<h2 align="center">A app to automate engineers tasks</h2>

![License](https://img.shields.io/github/license/diegolnasc/gotcha?style=plastic)
![go-version](https://img.shields.io/static/v1?label=golang&message=1.17&color=informational&style=plastic)
[![gotcha release (latest)](https://img.shields.io/github/v/release/diegolnasc/gotcha?sort=semver&style=plastic)](https://github.com/diegolnasc/gotcha/releases)
[![go-doc](https://godoc.org/github.com/diegolnasc/gotcha?status.svg)](https://godoc.org/github.com/diegolnasc/gotcha)
[![go-report](https://goreportcard.com/badge/github.com/diegolnasc/gotcha)](https://goreportcard.com/report/github.com/diegolnasc/gotcha)
![license](https://img.shields.io/github/license/diegolnasc/gotcha?style=plastic)
[![gotcha-release(latest)](https://img.shields.io/github/v/release/diegolnasc/gotcha?sort=semver&style=plastic)](https://github.com/diegolnasc/gotcha/releases)

---
## What can :robot: do?
Expand Down
20 changes: 12 additions & 8 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
// Copyright 2021 Diego Lima. All rights reserved.

// Use of this source code is governed by a Apache license.
// license that can be found in the LICENSE file.
package main

import (
"flag"
"log"
"net/http"

config "github.com/diegolnasc/gotcha/pkg/config"
"github.com/diegolnasc/gotcha/pkg/config"
github "github.com/diegolnasc/gotcha/pkg/github"
)

type Provider string
type provider string

const (
GitHub Provider = "github"
gitHub provider = "github"
)

func main() {
provider := flag.String("provider", "github", "Provider to run")
p := flag.String("provider", "github", "Provider to run")
flag.Parse()
startProvider(Provider(*provider))
startProvider(provider(*p))
err := http.ListenAndServe(":3000", nil)
if err != nil {
log.Panic(err)
}
}

func startProvider(provider Provider) {
switch provider {
case GitHub:
func startProvider(p provider) {
switch p {
case gitHub:
config := &config.Settings{}
config.ReadConf()
worker := github.New(config)
Expand Down
14 changes: 14 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Copyright 2021 Diego Lima. All rights reserved.

// Use of this source code is governed by a Apache license.
// license that can be found in the LICENSE file.
package config

import (
Expand All @@ -7,34 +11,41 @@ import (
"gopkg.in/yaml.v3"
)

// Settings represents the configuration and authorization aspects.
type Settings struct {
Layout Layout `yaml:"layout"`
Github Github `yaml:"github"`
}

// Layout represents permissions level and pull request functionalities.
type Layout struct {
Administration Administration `yaml:"administration"`
PullRequest PullRequest `yaml:"pullRequest"`
}

// Administration represents general permissions.
type Administration struct {
Permission Permission `yaml:"permission"`
}

// Permission represents high level user's and repository permissions.
type Permission struct {
Users []string `yaml:"users"`
Repositories []Repositories `yaml:"repositories"`
}

// Repositories represents low level permissions in repositories.
type Repositories struct {
Repository Repository `yaml:"repository"`
}

// Repository represents user permission in a single repository.
type Repository struct {
Name string `yaml:"name"`
Users []string `yaml:"users"`
}

// PullRequest represents commands and functionalities.
type PullRequest struct {
EnableOverview bool `yaml:"enableOverview"`
OverViewCommand string `yaml:"overViewCommand"`
Expand All @@ -45,13 +56,15 @@ type PullRequest struct {
TestSuite TestSuite `yaml:"testSuite"`
}

// TestSuite represents configuration for the test cases.
type TestSuite struct {
NamePattern string `yaml:"namePattern"`
Reviewers bool `yaml:"reviewers"`
Assignees bool `yaml:"assignees"`
Labels bool `yaml:"labels"`
}

// Github represents github app owner configuration.
type Github struct {
AppID int `yaml:"appId"`
Organization string `yaml:"organization"`
Expand All @@ -62,6 +75,7 @@ type Github struct {
Events []string `yaml:"events"`
}

// ReadConf initialize the configuration.
func (c *Settings) ReadConf() {
yamlFile, err := ioutil.ReadFile("build/config-local.yaml")
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions pkg/github/check.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Copyright 2021 Diego Lima. All rights reserved.

// Use of this source code is governed by a Apache license.
// license that can be found in the LICENSE file.
package github

import (
Expand All @@ -9,14 +13,17 @@ import (
v41 "github.com/google/go-github/v41/github"
)

// CheckService handles communication with the checkrun/checksuite event.
type CheckService service

// checkRunResult represents the result of a test case.
type checkRunResult struct {
title string
passed bool
body string
}

// processCheckRun process the checkrun event payload.
func (s *CheckService) processCheckRun(owner *string, pullRequest *v41.PullRequest, p *ghwebhooks.CheckRunPayload) {
if p.Action == "created" {
result, overralResults := s.runTestSuite(owner, pullRequest, p)
Expand All @@ -25,6 +32,7 @@ func (s *CheckService) processCheckRun(owner *string, pullRequest *v41.PullReque
}
}

// runTestSuite run the test suite.
func (s *CheckService) runTestSuite(owner *string, pullRequest *v41.PullRequest, p *ghwebhooks.CheckRunPayload) ([]*checkRunResult, bool) {
var results []*checkRunResult
overralResults := true
Expand All @@ -49,6 +57,7 @@ func (s *CheckService) runTestSuite(owner *string, pullRequest *v41.PullRequest,
return results, overralResults
}

// isNamePatternValid check if the pull request name is valid.
func (s *CheckService) isNamePatternValid(owner *string, pullRequest *v41.PullRequest, p *ghwebhooks.CheckRunPayload) *checkRunResult {
match, _ := regexp.MatchString(s.w.Config.Layout.PullRequest.TestSuite.NamePattern, *pullRequest.Title)
var body string
Expand All @@ -62,6 +71,7 @@ func (s *CheckService) isNamePatternValid(owner *string, pullRequest *v41.PullRe
}
}

// hasReviewers check if the pull request has reviewers.
func (s *CheckService) hasReviewers(owner *string, pullRequest *v41.PullRequest, p *ghwebhooks.CheckRunPayload) *checkRunResult {
if len(pullRequest.RequestedReviewers) == 0 {
return &checkRunResult{
Expand All @@ -76,6 +86,7 @@ func (s *CheckService) hasReviewers(owner *string, pullRequest *v41.PullRequest,
}
}

// hasAssignees check if the pull request has assignees.
func (s *CheckService) hasAssignees(owner *string, pullRequest *v41.PullRequest, p *ghwebhooks.CheckRunPayload) *checkRunResult {
if len(pullRequest.Assignees) == 0 {
return &checkRunResult{
Expand All @@ -90,6 +101,7 @@ func (s *CheckService) hasAssignees(owner *string, pullRequest *v41.PullRequest,
}
}

// hasLabels check if the pull request has labels.
func (s *CheckService) hasLabels(owner *string, pullRequest *v41.PullRequest, p *ghwebhooks.CheckRunPayload) *checkRunResult {
if len(pullRequest.Labels) == 0 {
return &checkRunResult{
Expand All @@ -104,6 +116,7 @@ func (s *CheckService) hasLabels(owner *string, pullRequest *v41.PullRequest, p
}
}

// updateCheckRunStatus update the check run status in github.
func (s *CheckService) updateCheckRunStatus(owner *string, pullRequest *v41.PullRequest, p *ghwebhooks.CheckRunPayload, overralResults bool) {
var conclusion string
if overralResults {
Expand All @@ -117,6 +130,7 @@ func (s *CheckService) updateCheckRunStatus(owner *string, pullRequest *v41.Pull
})
}

// printResults comments the result of the test suite on the pull request.
func (s *CheckService) printResults(owner *string, pullRequest *v41.PullRequest, p *ghwebhooks.CheckRunPayload, results []*checkRunResult, overralResults bool) {
var title string
var body bytes.Buffer
Expand Down
58 changes: 26 additions & 32 deletions pkg/github/common.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Copyright 2021 Diego Lima. All rights reserved.

// Use of this source code is governed by a Apache license.
// license that can be found in the LICENSE file.
package github

import (
Expand All @@ -12,6 +16,7 @@ import (
v41 "github.com/google/go-github/v41/github"
)

// GetPullRequest get a pull request.
func (w *Worker) GetPullRequest(owner string, repo string, number int) (*v41.PullRequest, error) {
resp, _, err := w.Client.PullRequests.Get(context.TODO(), owner, repo, number)
if err != nil {
Expand All @@ -20,6 +25,7 @@ func (w *Worker) GetPullRequest(owner string, repo string, number int) (*v41.Pul
return resp, err
}

// GetPullRequestFiles list files from a pull request.
func (w *Worker) GetPullRequestFiles(owner string, repo string, number int, opts *v41.ListOptions) ([]*v41.CommitFile, error) {
resp, _, err := w.Client.PullRequests.ListFiles(context.TODO(), owner, repo, number, opts)
if err != nil {
Expand All @@ -28,6 +34,7 @@ func (w *Worker) GetPullRequestFiles(owner string, repo string, number int, opts
return resp, err
}

// MergePullRequest merge a pull request.
func (w *Worker) MergePullRequest(owner string, repo string, number int, commitMessage string, options v41.PullRequestOptions) (*v41.PullRequestMergeResult, error) {
resp, _, err := w.Client.PullRequests.Merge(context.TODO(), owner, repo, number, commitMessage, &options)
if err != nil {
Expand All @@ -36,6 +43,7 @@ func (w *Worker) MergePullRequest(owner string, repo string, number int, commitM
return resp, err
}

// PullRequestCreateReview create a pull request review.
func (w *Worker) PullRequestCreateReview(owner string, repo string, number int, review v41.PullRequestReviewRequest) (*v41.PullRequestReview, error) {
resp, _, err := w.Client.PullRequests.CreateReview(context.TODO(), owner, repo, number, &review)
if err != nil {
Expand All @@ -44,14 +52,7 @@ func (w *Worker) PullRequestCreateReview(owner string, repo string, number int,
return resp, err
}

func (w *Worker) PullRequestCreateCommentReview(owner string, repo string, number int, comment v41.PullRequestComment) (*v41.PullRequestComment, error) {
resp, _, err := w.Client.PullRequests.CreateComment(context.TODO(), owner, repo, number, &comment)
if err != nil {
log.Printf("error creating pull request review comment: %v\n", err)
}
return resp, err
}

// IssueCreateComment create an issue or pull request comment.
func (w *Worker) IssueCreateComment(owner string, repo string, number int, comment v41.IssueComment) (*v41.IssueComment, error) {
resp, _, err := w.Client.Issues.CreateComment(context.TODO(), owner, repo, number, &comment)
if err != nil {
Expand All @@ -60,14 +61,16 @@ func (w *Worker) IssueCreateComment(owner string, repo string, number int, comme
return resp, err
}

func (w *Worker) IssueUpdateComment(owner string, repo string, commentId int, comment v41.IssueComment) (*v41.IssueComment, error) {
resp, _, err := w.Client.Issues.EditComment(context.TODO(), owner, repo, int64(commentId), &comment)
// IssueUpdateComment update an issue or pull request comment.
func (w *Worker) IssueUpdateComment(owner string, repo string, commentID int, comment v41.IssueComment) (*v41.IssueComment, error) {
resp, _, err := w.Client.Issues.EditComment(context.TODO(), owner, repo, int64(commentID), &comment)
if err != nil {
log.Printf("error updating issue comment: %v\n", err)
}
return resp, err
}

// IssueListComments list the comments of an issue or pull request.
func (w *Worker) IssueListComments(owner string, repo string, number int, opts *v41.IssueListCommentsOptions) ([]*v41.IssueComment, error) {
resp, _, err := w.Client.Issues.ListComments(context.TODO(), owner, repo, number, opts)
if err != nil {
Expand All @@ -76,30 +79,16 @@ func (w *Worker) IssueListComments(owner string, repo string, number int, opts *
return resp, err
}

func (w *Worker) PullRequestListReviewComments(owner string, repo string, number int, opts *v41.PullRequestListCommentsOptions) ([]*v41.PullRequestComment, error) {
resp, _, err := w.Client.PullRequests.ListComments(context.TODO(), owner, repo, number, opts)
if err != nil {
log.Printf("error getting pull list of comments: %v\n", err)
}
return resp, err
}

func (w *Worker) AddLabels(owner string, repo string, number int, labels []string) ([]*v41.Label, error) {
resp, _, err := w.Client.Issues.AddLabelsToIssue(context.TODO(), owner, repo, number, labels)
if err != nil {
log.Printf("error adding labels: %v\n", err)
}
return resp, err
}

func (w *Worker) GetCheckRun(owner string, repo string, checkrunId int64) (*v41.CheckRun, error) {
resp, _, err := w.Client.Checks.GetCheckRun(context.TODO(), owner, repo, checkrunId)
// GetCheckRun get a check run.
func (w *Worker) GetCheckRun(owner string, repo string, checkrunID int64) (*v41.CheckRun, error) {
resp, _, err := w.Client.Checks.GetCheckRun(context.TODO(), owner, repo, checkrunID)
if err != nil {
log.Printf("error creating checkrun: %v\n", err)
}
return resp, err
}

// CreateCheckRun create a check run.
func (w *Worker) CreateCheckRun(owner string, repo string, checkrun v41.CreateCheckRunOptions) (*v41.CheckRun, error) {
resp, _, err := w.Client.Checks.CreateCheckRun(context.TODO(), owner, repo, checkrun)
if err != nil {
Expand All @@ -108,14 +97,16 @@ func (w *Worker) CreateCheckRun(owner string, repo string, checkrun v41.CreateCh
return resp, err
}

func (w *Worker) UpdateCheckRun(owner string, repo string, checkRunId int64, checkRun v41.UpdateCheckRunOptions) (*v41.CheckRun, error) {
resp, _, err := w.Client.Checks.UpdateCheckRun(context.TODO(), owner, repo, checkRunId, checkRun)
// UpdateCheckRun update a check run.
func (w *Worker) UpdateCheckRun(owner string, repo string, checkrunID int64, checkRun v41.UpdateCheckRunOptions) (*v41.CheckRun, error) {
resp, _, err := w.Client.Checks.UpdateCheckRun(context.TODO(), owner, repo, checkrunID, checkRun)
if err != nil {
log.Printf("error updating checkrun: %v\n", err)
}
return resp, err
}

// GetRef get a reference.
func (w *Worker) GetRef(owner string, repo string, ref string) (*v41.Reference, error) {
resp, _, err := w.Client.Git.GetRef(context.TODO(), owner, repo, ref)
if err != nil {
Expand All @@ -124,6 +115,7 @@ func (w *Worker) GetRef(owner string, repo string, ref string) (*v41.Reference,
return resp, err
}

// DeleteRef delete a reference.
func (w *Worker) DeleteRef(owner string, repo string, ref string) (*v41.Response, error) {
resp, err := w.Client.Git.DeleteRef(context.TODO(), owner, repo, ref)
if err != nil {
Expand All @@ -132,6 +124,7 @@ func (w *Worker) DeleteRef(owner string, repo string, ref string) (*v41.Response
return resp, err
}

// CreatePulllRequestOverviewComment create a pull request comment with the report (overview diff).
func (w *Worker) CreatePulllRequestOverviewComment(owner *string, repo string, pullRequestNumber int) {
if pullRequest, err := w.GetPullRequest(*owner, repo, pullRequestNumber); err == nil {
currentIssueComment := w.GetPulllRequestOverviewComment(owner, repo, pullRequestNumber)
Expand Down Expand Up @@ -183,8 +176,9 @@ func (w *Worker) CreatePulllRequestOverviewComment(owner *string, repo string, p
}
}

func (w *Worker) GetPulllRequestOverviewComment(owner *string, repo string, pullrequestId int) *v41.IssueComment {
if comments, err := w.IssueListComments(*owner, repo, pullrequestId, nil); err == nil {
// GetPulllRequestOverviewComment get a pull request comment with the report (overview diff).
func (w *Worker) GetPulllRequestOverviewComment(owner *string, repo string, pullrequestID int) *v41.IssueComment {
if comments, err := w.IssueListComments(*owner, repo, pullrequestID, nil); err == nil {
for _, comment := range comments {
if strings.HasPrefix(*comment.Body, "\u003ch3 align=\"center\"\u003ePull request Overview :checkered_flag:") {
if strings.EqualFold("Bot", *comment.User.Type) && strings.Contains(*comment.User.AvatarURL, strconv.Itoa(w.Config.Github.AppID)) {
Expand Down
Loading

0 comments on commit d25835d

Please sign in to comment.