Skip to content

Commit

Permalink
view commit history on PR
Browse files Browse the repository at this point in the history
able to change theme from action
  • Loading branch information
kevincobain2000 committed Feb 14, 2024
1 parent b74fc5a commit 765d3ad
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 97 deletions.
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ runs:
-x "${{ inputs.http_proxy }}" \
-H 'Content-Type: application/json' \
-w "%{http_code}" \
"${{inputs.host}}/pr?org=${{github.repository_owner}}&repo=${{ github.event.repository.name }}&type=${{ inputs.type }}&theme=${{ inputs.theme }}&branch=${{ steps.branch-name.outputs.current_branch }}&base_branch=${{ steps.branch-name.outputs.base_ref_branch }}" \
"${{inputs.host}}/pr?org=${{github.repository_owner}}&repo=${{ github.event.repository.name }}&type=${{ inputs.type }}&theme=${{ inputs.theme }}&pr_num=${{ steps.pr-number-id.outputs.pr }}&branch=${{ steps.branch-name.outputs.current_branch }}&base_branch=${{ steps.branch-name.outputs.base_ref_branch }}" \
-o comment_body.txt)
echo "PR_HTTP_RESPONSE=$response" >> $GITHUB_ENV
Expand Down
119 changes: 53 additions & 66 deletions app/models/coverage.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,72 +36,6 @@ func (c *Coverage) GetByBranchName(branchName string) ([]Coverage, error) {
return ret, err
}

func (c *Coverage) GetNumberOfContributors(orgName string, repoName string) (int, error) {
var ret int
query := `
SELECT
COUNT(DISTINCT c.user_id) AS num
FROM
coverages c
INNER JOIN
orgs o ON c.org_id = o.id
INNER JOIN
repos r ON c.repo_id = r.id
WHERE
o.name = @orgName
AND
r.name = @repoName
`
err := db.Db().Raw(
query,
sql.Named("orgName", orgName),
sql.Named("repoName", repoName)).
Scan(&ret).Error
return ret, err
}

func (c *Coverage) GetAveragePRDays(orgName string, repoName string) (int, error) {
var ret float64
query := `
SELECT
COALESCE(AVG(duration_in_days), 0) AS avg
FROM (
SELECT
c.pr_num,
DATEDIFF(
MAX(c.created_at),
MIN(c.created_at)
) AS duration_in_days
FROM
coverages c
INNER JOIN
orgs o ON c.org_id = o.id
INNER JOIN
repos r ON c.repo_id = r.id
WHERE
o.name = @orgName
AND r.name = @repoName
AND c.pr_num != 0
GROUP BY
c.pr_num
) AS durations
`
err := db.Db().Raw(
query,
sql.Named("orgName", orgName),
sql.Named("repoName", repoName)).
Scan(&ret).Error
return int(ret), err
}

type LatestBranchScore struct {
BranchName string `json:"branch_name"`
Score float64 `json:"score"`
TypeName string `json:"type_name"`
Metric string `json:"metric"`
CreatedAt string `json:"created_at"`
}

func (c *Coverage) GetAllBranches(orgName string, repoName string, typeName string) ([]string, error) {
var ret []string
query := `
Expand Down Expand Up @@ -138,6 +72,15 @@ func (c *Coverage) GetAllBranches(orgName string, repoName string, typeName stri
return ret, err

}

type LatestBranchScore struct {
BranchName string `json:"branch_name"`
Score float64 `json:"score"`
TypeName string `json:"type_name"`
Metric string `json:"metric"`
CreatedAt string `json:"created_at"`
}

func (c *Coverage) GetLatestBranchScore(orgName string, repoName string, branchName string, typeName string) (LatestBranchScore, error) {

var ret LatestBranchScore
Expand Down Expand Up @@ -282,6 +225,50 @@ func (c *Coverage) GetLatestBranchScores(orgName string, repoName string, branch
return ret, err
}

type LatestPRScore struct {
Commit string `json:"commit"`
BranchName string `json:"branch_name"`
Score float64 `json:"score"`
TypeName string `json:"type_name"`
Metric string `json:"metric"`
}

func (c *Coverage) GetLatestPRScores(orgName string, repoName string, prNum int, typeName string) ([]LatestPRScore, error) {
var ret []LatestPRScore
query := `
SELECT
c.commit, c.branch_name,
Round(c.score, 1) as score
FROM coverages c
LEFT JOIN
orgs o ON c.org_id = o.id
LEFT JOIN
repos r ON c.repo_id = r.id
LEFT JOIN
types t ON c.type_id = t.id
WHERE
o.name = @orgName
AND
r.name = @repoName
AND
c.pr_num = @prNum
AND
t.name = @typeName
LIMIT 150;
`
err := db.Db().Raw(
query,
sql.Named("orgName", orgName),
sql.Named("repoName", repoName),
sql.Named("prNum", prNum),
sql.Named("typeName", typeName)).
Scan(&ret).Error
if err != nil {
return ret, err
}
return ret, err
}

type LatestUserScore struct {
UserName string `json:"user_name"`
Score float64 `json:"score"`
Expand Down
21 changes: 0 additions & 21 deletions app/pkg/badge.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package pkg

import (
"strconv"
"strings"

"github.com/kevincobain2000/action-coveritup/models"
Expand All @@ -19,26 +18,6 @@ func NewBadge() *Badge {
}

func (b *Badge) Get(req *BadgeRequest, t *models.Type) ([]byte, error) {
if t.Name == models.TYPE_AVERAGE_PR_DAYS {
num, err := b.coverageModel.GetAveragePRDays(req.Org, req.Repo)
if err != nil {
return nil, err
}
numStr := strconv.Itoa(num)
badge, err := stars.RenderBytes("social", models.TYPE_AVERAGE_PR_DAYS, numStr, "")
return badge, err
}

if t.Name == models.TYPE_NUMBER_OF_CONTRIBUTORS {
num, err := b.coverageModel.GetNumberOfContributors(req.Org, req.Repo)
if err != nil {
return nil, err
}
numStr := strconv.Itoa(num)
badge, err := stars.RenderBytes("social", models.TYPE_NUMBER_OF_CONTRIBUTORS, numStr, "")
return badge, err
}

ret, err := b.coverageModel.GetLatestBranchScore(req.Org, req.Repo, req.Branch, t.Name)

if err != nil {
Expand Down
61 changes: 54 additions & 7 deletions app/pkg/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,25 @@ func (e *Chart) GetType(name string) (*models.Type, error) {
return e.typeModel.Get(name)
}

func (e *Chart) GetInstaChartForBranch(req *ChartRequest, t *models.Type) ([]byte, error) {
func (e *Chart) GetInstaChartForPR(req *ChartRequest, t *models.Type) ([]byte, error) {
ret, err := e.coverageModel.GetLatestPRScores(req.Org, req.Repo, req.PRNum, t.Name)
if err != nil {
return nil, err
}
if len(ret) > 0 {
req.Branch = ret[0].BranchName
}

cReq := e.makeChartRequest(req, t)
line := instachart.NewLineChart()
xData := []string{}
yData := []float64{}
yyData := [][]float64{}

names := []string{t.Name}
ret, err := e.coverageModel.GetLatestBranchScores(req.Org, req.Repo, req.Branch, t.Name)
if err != nil {
return nil, err
}

for i := len(ret) - 1; i >= 0; i-- {
r := ret[i]
xData = append(xData, r.CreatedAt)
xData = append(xData, r.Commit)
yData = append(yData, r.Score)
yyData = append(yyData, yData)
}
Expand All @@ -57,6 +60,46 @@ func (e *Chart) GetInstaChartForBranch(req *ChartRequest, t *models.Type) ([]byt

return line.Get(xData, yyData, names, cReq)
}

// Line chart with dates on x-axis and scores on y-axis
func (e *Chart) GetInstaChartForBranch(req *ChartRequest, t *models.Type) ([]byte, error) {
cReq := e.makeChartRequest(req, t)
bar := instachart.NewBarChart()

if req.Branches == "all" {
bs, err := e.coverageModel.GetAllBranches(req.Org, req.Repo, t.Name)
if err != nil {
return nil, err
}
req.Branches = strings.Join(bs, ",")
}

xData := []string{}
yData := []float64{}
zData := []float64{}
names := []string{t.Name}
branches := strings.Split(req.Branches, ",")
var hasErr error
for _, branch := range branches {
ret, err := e.coverageModel.GetLatestBranchScore(req.Org, req.Repo, branch, t.Name)
if err != nil {
hasErr = err
break
}
xData = append(xData, ret.BranchName)
yData = append(yData, ret.Score)
zData = append(zData, ret.Score)
}
if hasErr != nil {
return nil, hasErr
}
yyData := [][]float64{yData}
zzData := [][]float64{zData}

return bar.GetStacked(xData, yyData, zzData, names, cReq)
}

// Line chart with dates on x-axis and scores on y-axis
func (e *Chart) GetInstaChartForUser(req *ChartRequest, t *models.Type) ([]byte, error) {
cReq := e.makeChartRequest(req, t)
line := instachart.NewLineChart()
Expand Down Expand Up @@ -85,6 +128,8 @@ func (e *Chart) GetInstaChartForUser(req *ChartRequest, t *models.Type) ([]byte,

return line.Get(xData, yyData, names, cReq)
}

// bar chart with branch names on x-axis and scores on y-axis
func (e *Chart) GetInstaChartForBranches(req *ChartRequest, t *models.Type) ([]byte, error) {
cReq := e.makeChartRequest(req, t)
bar := instachart.NewBarChart()
Expand Down Expand Up @@ -121,6 +166,8 @@ func (e *Chart) GetInstaChartForBranches(req *ChartRequest, t *models.Type) ([]b

return bar.GetStacked(xData, yyData, zzData, names, cReq)
}

// bar chart with user names on x-axis and scores on y-axis
func (e *Chart) GetInstaChartForUsers(req *ChartRequest, t *models.Type) ([]byte, error) {
cReq := e.makeChartRequest(req, t)
bar := instachart.NewBarChart()
Expand Down
12 changes: 10 additions & 2 deletions app/pkg/chart_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type ChartRequest struct {
Type string `json:"type" query:"type" validate:"ascii,required,excludes=/" message:"ascii type is required"`
Branches string `json:"branches" query:"branches" validate:"ascii" message:"ascii branches is required"`
Users string `json:"users" query:"users" validate:"ascii" message:"ascii users is required"`
PRNum int `json:"pr_num" query:"pr_num"`

Output string `json:"output" query:"output" default:"png" validate:"oneof=svg png" message:"output must be svg or png"`
Theme string `json:"theme" query:"theme" default:"light" validate:"oneof=light dark" message:"theme must be light or dark"`
Expand Down Expand Up @@ -55,8 +56,15 @@ func (h *ChartHandler) Get(c echo.Context) error {
return echo.NewHTTPError(http.StatusNotFound, "type not found")
}

if req.Branches == "" && req.Users == "" && req.Branch == "" && req.User == "" {
return echo.NewHTTPError(http.StatusUnprocessableEntity, "branches, users, branch or user, branch or base_branch are required")
if req.Branches == "" && req.Users == "" && req.Branch == "" && req.User == "" && req.PRNum == 0 {
return echo.NewHTTPError(http.StatusUnprocessableEntity, "branches, users, pr, branch or user, branch or base_branch are required")
}
if req.PRNum > 0 {
buf, err := h.Chart.GetInstaChartForPR(req, t)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err)
}
return ResponseMedia(c, buf, req.Output)
}

if req.Branch != "" && req.BaseBranch == "" {
Expand Down
11 changes: 11 additions & 0 deletions app/pkg/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func (p *PR) Get(req *PRRequest, types []models.Type) (string, error) {
Rows: [][]string{},
}
urls := []string{}
chUrls := []string{}
mdText.H4("CoverItUp Report")
mdText.PlainText("")

Expand Down Expand Up @@ -85,6 +86,9 @@ func (p *PR) Get(req *PRRequest, types []models.Type) (string, error) {
}
u = u + "&data=" + string(jsonData)
urls = append(urls, u)

cu := fmt.Sprintf("%s://%s%schart?org=%s&repo=%s&pr_num=%d&type=%s&theme=%s&height=%d&line=%s", req.scheme, req.host, os.Getenv("BASE_URL"), req.Org, req.Repo, req.PRNum, t.Name, req.Theme, 320, "fill")
chUrls = append(chUrls, cu)
}
mdText.Table(mdTable)
images := ""
Expand All @@ -93,6 +97,13 @@ func (p *PR) Get(req *PRRequest, types []models.Type) (string, error) {
}
mdText.PlainText(images)

cImages := ""
for _, u := range chUrls {
cImages += fmt.Sprintf("<img src='%s' alt='commit history' />", u)
}

mdText.Details(fmt.Sprintf("Commit history for this PR %d", req.PRNum), cImages)

mdText.PlainText("")
readmeLink := fmt.Sprintf("%s://%s%sreadme?org=%s&repo=%s&branch=%s",
req.scheme, req.host, os.Getenv("BASE_URL"), req.Org, req.Repo, req.Branch)
Expand Down
1 change: 1 addition & 0 deletions app/pkg/pr_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type PRRequest struct {
Repo string `json:"repo" query:"repo" validate:"required,ascii,excludes=/" message:"repo is required"`
Branch string `json:"branch" query:"branch" validate:"required,ascii" message:"ascii branch is required"`
BaseBranch string `json:"base_branch" query:"base_branch" validate:"required,ascii" message:"ascii base_branch is required"`
PRNum int `json:"pr_num" query:"pr_num"`
Theme string `json:"theme" query:"theme" default:"light" validate:"oneof=light dark" message:"theme must be light or dark"`

host string
Expand Down

0 comments on commit 765d3ad

Please sign in to comment.