From fa9b8b8b4874aa8e0baecbb1813114629cebecb5 Mon Sep 17 00:00:00 2001 From: Pulkit Kathuria Date: Sun, 25 Feb 2024 15:20:09 +0900 Subject: [PATCH] A few validations (#14) * add user history and more info to pr message * add user history and fixed info card * handle errors * wording changed --- action.yml | 4 +- app/main.go | 4 + app/models/coverage.go | 153 +++++++++++++++++++++++++++++++++---- app/pkg/chart.go | 40 +++++++++- app/pkg/chart_handler.go | 19 ++++- app/pkg/pr.go | 150 ++++++++++++++++++++++++++---------- app/pkg/pr_handler.go | 6 +- app/pkg/pr_handler_test.go | 8 +- app/pkg/routes.go | 12 ++- 9 files changed, 325 insertions(+), 71 deletions(-) diff --git a/action.yml b/action.yml index cd575f3..a1201f5 100644 --- a/action.yml +++ b/action.yml @@ -88,7 +88,7 @@ runs: if: ${{inputs.pr_comment != 'true' &&inputs.destroy != 'true'}} run: | git config remote.origin.prune true && git fetch - echo CIU_ACTIVE_BRANCHES=`git branch -r | grep -v HEAD | sed 's/origin\///' | tr '\n' ' '` >> "$GITHUB_ENV" + echo ACTIVE_BRANCHES=`git branch -r | grep -v HEAD | sed 's/origin\///' | tr '\n' ' '` >> "$GITHUB_ENV" ### End ### ### PREPARE ENVIRONMENT and VARIABLES ### @@ -117,7 +117,7 @@ runs: "user": "${{ github.actor }}", "branch": "${{ env.BRANCH_OR_TAG_NAME }}", "pr_num": "${{ steps.pr-number-id.outputs.pr }}", - "branches": "${{ env.CIU_ACTIVE_BRANCHES }}" + "branches": "${{ env.ACTIVE_BRANCHES }}" }' \ "${{inputs.host}}/upload" diff --git a/app/main.go b/app/main.go index 1336388..3b3257e 100644 --- a/app/main.go +++ b/app/main.go @@ -35,6 +35,10 @@ var f Flags var version = "dev" func main() { + err := os.Setenv("VERSION", version) + if err != nil { + pkg.Logger().Error(err) + } if len(os.Args) > 1 && os.Args[1] == "version" { fmt.Println(version) return diff --git a/app/models/coverage.go b/app/models/coverage.go index f9a594a..cc50d85 100644 --- a/app/models/coverage.go +++ b/app/models/coverage.go @@ -129,7 +129,9 @@ func (c *Coverage) GetLatestBranchScore(orgName string, repoName string, branchN } type LatestBranchScorePR struct { + ID int64 `json:"id"` BranchName string `json:"branch_name"` + Commit string `json:"commit"` Score float64 `json:"score"` TypeName string `json:"type_name"` Metric string `json:"metric"` @@ -137,13 +139,19 @@ type LatestBranchScorePR struct { CreatedAt string `json:"created_at"` } -// GetLatestBranchScoresByLimit is same as GetLatestBranchScore but with limit and PR -func (c *Coverage) GetLatestBranchScoresWithPR(orgName string, repoName string, branchName string, typeName string, limit int) ([]LatestBranchScorePR, error) { +func (c *Coverage) GetLatestBranchScoreByPR( + orgName string, + repoName string, + branchName string, + typeName string, + prNum int) (LatestBranchScorePR, error) { - var ret []LatestBranchScorePR + var ret LatestBranchScorePR query := ` SELECT + c.id, c.branch_name, + c.commit, c.pr_num, Round(c.score, 1) as score, t.name as type_name, @@ -164,12 +172,12 @@ func (c *Coverage) GetLatestBranchScoresWithPR(orgName string, repoName string, AND c.branch_name = @branchName AND - t.name = @typeName + c.pr_num = @prNum AND - c.pr_num != 0 + t.name = @typeName ORDER BY c.created_at DESC, c.id DESC - LIMIT @limit; + LIMIT 1; ` err := db.Db().Raw( query, @@ -177,11 +185,12 @@ func (c *Coverage) GetLatestBranchScoresWithPR(orgName string, repoName string, sql.Named("repoName", repoName), sql.Named("branchName", branchName), sql.Named("typeName", typeName), - sql.Named("limit", limit)). + sql.Named("prNum", prNum)). Scan(&ret).Error if err != nil { return ret, err } + ret.Metric = strings.TrimSpace(ret.Metric) return ret, err } @@ -227,7 +236,8 @@ func (c *Coverage) GetLatestBranchScores(orgName string, repoName string, branch return ret, err } -type LatestPRScore struct { +type LatestPRScoreForCommits struct { + ID int64 `json:"id"` Commit string `json:"commit"` BranchName string `json:"branch_name"` Score float64 `json:"score"` @@ -235,11 +245,59 @@ type LatestPRScore struct { Metric string `json:"metric"` } -func (c *Coverage) GetLatestPRScores(orgName string, repoName string, prNum int, typeName string) ([]LatestPRScore, error) { - var ret []LatestPRScore +func (c *Coverage) GetIDFromCommit(orgName string, repoName string, typeName string, commit string) (int, error) { + var ret int + query := ` + SELECT + c.id + 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.commit = @commit + AND + t.name = @typeName + ORDER BY + c.id DESC + LIMIT 1; + ` + err := db.Db().Raw( + query, + sql.Named("orgName", orgName), + sql.Named("repoName", repoName), + sql.Named("commit", commit), + sql.Named("typeName", typeName)). + Scan(&ret).Error + if err != nil { + return ret, err + } + return ret, err +} + +func (c *Coverage) GetLatestPRScoresForCommits( + orgName string, + repoName string, + prNum int, + typeName string, + lastCommit string) ([]LatestPRScoreForCommits, error) { + + var ret []LatestPRScoreForCommits + fromID, err := c.GetIDFromCommit(orgName, repoName, typeName, lastCommit) + if err != nil { + return ret, err + } + query := ` SELECT - c.commit, c.branch_name, + c.id, c.commit, c.branch_name, Round(c.score, 1) as score FROM coverages c LEFT JOIN @@ -256,14 +314,81 @@ func (c *Coverage) GetLatestPRScores(orgName string, repoName string, prNum int, c.pr_num = @prNum AND t.name = @typeName + AND + c.id <= @fromID + ORDER BY c.id DESC LIMIT 150; ` - err := db.Db().Raw( + err = db.Db().Raw( query, sql.Named("orgName", orgName), sql.Named("repoName", repoName), sql.Named("prNum", prNum), - sql.Named("typeName", typeName)). + sql.Named("typeName", typeName), + sql.Named("fromID", fromID)). + Scan(&ret).Error + if err != nil { + return ret, err + } + return ret, err +} + +type LatestPRScoreForUsers struct { + ID int64 `json:"id"` + UserName string `json:"user_name"` + BranchName string `json:"branch_name"` + Score float64 `json:"score"` + TypeName string `json:"type_name"` + Metric string `json:"metric"` +} + +func (c *Coverage) GetLatestPRScoresForUsers( + orgName string, + repoName string, + prNum int, + typeName string, + lastCommit string) ([]LatestPRScoreForUsers, error) { + var ret []LatestPRScoreForUsers + fromID, err := c.GetIDFromCommit(orgName, repoName, typeName, lastCommit) + if err != nil { + return ret, err + } + query := ` + SELECT + max(c.id) as id, + u.name as user_name, + 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 + LEFT JOIN + users u ON c.user_id = u.id + WHERE + o.name = @orgName + AND + r.name = @repoName + AND + c.pr_num = @prNum + AND + t.name = @typeName + AND + c.id <= @fromID + GROUP BY user_name + ORDER BY id DESC + LIMIT 150; + ` + err = db.Db().Raw( + query, + sql.Named("orgName", orgName), + sql.Named("repoName", repoName), + sql.Named("prNum", prNum), + sql.Named("typeName", typeName), + sql.Named("fromID", fromID)). Scan(&ret).Error if err != nil { return ret, err @@ -366,7 +491,7 @@ func (c *Coverage) GetLatestUserScores(orgName string, repoName string, userName var ret []LatestUserScore query := ` SELECT - c.branch_name, + u.name as user_name, DATE_FORMAT(MAX(c.created_at), '%Y/%m/%d') as created_at, Round(c.score, 1) as score FROM coverages c diff --git a/app/pkg/chart.go b/app/pkg/chart.go index 83682a8..b8e604c 100644 --- a/app/pkg/chart.go +++ b/app/pkg/chart.go @@ -1,6 +1,7 @@ package pkg import ( + "fmt" "strings" "github.com/kevincobain2000/action-coveritup/models" @@ -29,8 +30,8 @@ func (e *Chart) GetType(name string) (*models.Type, error) { return e.typeModel.Get(name) } -func (e *Chart) GetInstaChartForPR(req *ChartRequest, t *models.Type) ([]byte, error) { - ret, err := e.coverageModel.GetLatestPRScores(req.Org, req.Repo, req.PRNum, t.Name) +func (e *Chart) GetInstaChartForPRCommits(req *ChartRequest, t *models.Type) ([]byte, error) { + ret, err := e.coverageModel.GetLatestPRScoresForCommits(req.Org, req.Repo, req.PRNum, t.Name, req.LastCommit) if err != nil { return nil, err } @@ -60,6 +61,41 @@ func (e *Chart) GetInstaChartForPR(req *ChartRequest, t *models.Type) ([]byte, e return line.Get(xData, yyData, names, cReq) } +func (e *Chart) GetInstaChartForPRUsers(req *ChartRequest, t *models.Type) ([]byte, error) { + ret, err := e.coverageModel.GetLatestPRScoresForUsers(req.Org, req.Repo, req.PRNum, t.Name, req.LastCommit) + if err != nil { + return nil, err + } + + if len(ret) > 0 { + req.Branch = fmt.Sprintf("%s #%d", ret[0].BranchName, req.PRNum) + } + + cReq := e.makeChartRequest(req, t) + bar := instachart.NewBarChart() + xData := []string{} + yData := []float64{} + zData := []float64{} + names := []string{t.Name} + + for i := len(ret) - 1; i >= 0; i-- { + r := ret[i] + xData = append(xData, r.UserName) + yData = append(yData, r.Score) + zData = append(zData, r.Score) + } + yyData := [][]float64{yData} + zzData := [][]float64{zData} + + // this will never happen, to prevent errors and display blank chart + if len(xData) == 0 { + xData = append(xData, "0") + yyData = append(yyData, []float64{0}) + zzData = append(zzData, []float64{0}) + } + + return bar.GetStacked(xData, yyData, zzData, 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) { diff --git a/app/pkg/chart_handler.go b/app/pkg/chart_handler.go index e1e12ef..f7b0031 100644 --- a/app/pkg/chart_handler.go +++ b/app/pkg/chart_handler.go @@ -27,6 +27,8 @@ type ChartRequest struct { 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"` + PRHistory string `json:"pr_history" query:"pr_history" default:"commits" validate:"oneof=commits users" message:"pr_history must be commits or users"` + LastCommit string `json:"last_commit" query:"last_commit" validate:"ascii" message:"ascii last_commit is required"` 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"` @@ -60,11 +62,20 @@ func (h *ChartHandler) Get(c echo.Context) error { 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) + if req.PRHistory == "commits" { + buf, err := h.Chart.GetInstaChartForPRCommits(req, t) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err) + } + return ResponseMedia(c, buf, req.Output) + } + if req.PRHistory == "users" { + buf, err := h.Chart.GetInstaChartForPRUsers(req, t) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err) + } + return ResponseMedia(c, buf, req.Output) } - return ResponseMedia(c, buf, req.Output) } if req.Branch != "" && req.BaseBranch == "" { diff --git a/app/pkg/pr.go b/app/pkg/pr.go index 9cd6661..378c9ff 100644 --- a/app/pkg/pr.go +++ b/app/pkg/pr.go @@ -11,7 +11,11 @@ import ( "github.com/sirupsen/logrus" ) -const () +const ( + DOWN_SYMBOL = "📉" + UP_SYMBOL = "📈" + NO_CHANGE_SYMBOL = "" +) type PR struct { coverageModel *models.Coverage @@ -26,46 +30,66 @@ func NewPR() *PR { } func (p *PR) Get(req *PRRequest, types []models.Type) (string, error) { + totalPlus := 0 + totalMinus := 0 + verdict := "" + commitBranch := "" + commitBaseBranch := "" isFirstPR := p.coverageModel.IsFirstPR(req.Org, req.Repo, req.PRNum) mdText := md.NewMarkdown(os.Stdout) mdTable := md.TableSet{ Rows: [][]string{}, } - urls := []string{} // stores urls for bar charts for comparison of base and branch - chUrls := []string{} // stores urls for commit history trends (line charts) + baseAndBranchImgUrls := []string{} // stores urls for bar charts for comparison of base and branch + commitHistoryImgUrls := []string{} // stores urls for commit history trends (line charts) + userHistoryImgUrls := []string{} // stores urls for user history trends (line charts) mdText.H4("CoverItUp Report") for _, t := range types { y := make([]float64, 2) - row := make([]string, 3) - row[0] = "*" + t.Name + "*" + tableRow := make([]string, 4) + tableRow[0] = "*" + t.Name + "*" - sb, err := p.coverageModel.GetLatestBranchScore(req.Org, req.Repo, req.BaseBranch, t.Name) + scoreBaseBranch, err := p.coverageModel.GetLatestBranchScore(req.Org, req.Repo, req.BaseBranch, t.Name) + if commitBaseBranch == "" { + commitBaseBranch = scoreBaseBranch.Commit + } if err != nil { y[0] = 0 - row[1] = "" + tableRow[1] = "" } else { - y[0] = sb.Score - row[1] = F64NumberToK(&sb.Score) + "" + t.Metric + y[0] = scoreBaseBranch.Score + tableRow[1] = F64NumberToK(&scoreBaseBranch.Score) + "" + t.Metric } - s, err := p.coverageModel.GetLatestBranchScore(req.Org, req.Repo, req.Branch, t.Name) + scoreBranch, err := p.coverageModel.GetLatestBranchScoreByPR(req.Org, req.Repo, req.Branch, t.Name, req.PRNum) + if commitBranch == "" { + commitBranch = scoreBranch.Commit + } if err != nil { y[1] = 0 - row[2] = "" + tableRow[2] = "" + tableRow[3] = "" } else { - ud := p.UpOrDown(&sb.Score, &s.Score) - y[1] = s.Score - row[2] = F64NumberToK(&s.Score) + "" + t.Metric + ud - if ud != "" && ud != "-" { - row[2] = "**" + row[2] + "**" + symbol := p.UpOrDown(&scoreBaseBranch.Score, &scoreBranch.Score) + y[1] = scoreBranch.Score + tableRow[2] = F64NumberToK(&scoreBranch.Score) + "" + t.Metric + tableRow[3] = symbol + if symbol == UP_SYMBOL || symbol == DOWN_SYMBOL { + tableRow[2] = "**" + tableRow[2] + "**" + } + if symbol == UP_SYMBOL { + totalPlus++ + } + if symbol == DOWN_SYMBOL { + totalMinus++ } } - mdTable.Rows = append(mdTable.Rows, row) + mdTable.Rows = append(mdTable.Rows, tableRow) - data := struct { + bbData := struct { X []string `json:"x"` Y [][]float64 `json:"y"` Z [][]float64 `json:"z"` @@ -76,10 +100,11 @@ func (p *PR) Get(req *PRRequest, types []models.Type) (string, error) { Z: [][]float64{}, N: []string{t.Name}, } - data.Y = append(data.Y, y) - data.Z = append(data.Z, y) + bbData.Y = append(bbData.Y, y) + bbData.Z = append(bbData.Z, y) - u := fmt.Sprintf("%s://%s%sbar?title=%s&metric=%s&width=%d&height=%d&grid=hide&output=%s&theme=%s&grid=%s", + // this is a static bar chart, that doesn't change once commented + bbUrl := fmt.Sprintf("%s://%s%sbar?title=%s&metric=%s&width=%d&height=%d&grid=hide&output=%s&theme=%s&grid=%s", req.scheme, req.host, os.Getenv("BASE_URL"), @@ -91,14 +116,30 @@ func (p *PR) Get(req *PRRequest, types []models.Type) (string, error) { req.Theme, "hide") - jsonData, err := json.Marshal(data) + jsonData, err := json.Marshal(bbData) if err != nil { return "", err } - u = u + "&data=" + string(jsonData) - urls = append(urls, u) + bbUrl = bbUrl + "&data=" + string(jsonData) + baseAndBranchImgUrls = append(baseAndBranchImgUrls, bbUrl) + + // this is dynamic bar chart, that changes upon new commits, so previous commits comments also change dynamically + chUrl := fmt.Sprintf("%s://%s%schart?org=%s&repo=%s&pr_num=%d&type=%s&theme=%s&height=%d&line=%s&pr_history=%s&last_commit=%s", + req.scheme, + req.host, + os.Getenv("BASE_URL"), + req.Org, + req.Repo, + req.PRNum, + t.Name, + req.Theme, + 320, + "fill", + "commits", + commitBranch) + commitHistoryImgUrls = append(commitHistoryImgUrls, chUrl) - cu := fmt.Sprintf("%s://%s%schart?org=%s&repo=%s&pr_num=%d&type=%s&theme=%s&height=%d&line=%s", + uhUrl := fmt.Sprintf("%s://%s%schart?org=%s&repo=%s&pr_num=%d&type=%s&theme=%s&height=%d&line=%s&pr_history=%s&last_commit=%s", req.scheme, req.host, os.Getenv("BASE_URL"), @@ -108,46 +149,71 @@ func (p *PR) Get(req *PRRequest, types []models.Type) (string, error) { t.Name, req.Theme, 320, - "fill") - chUrls = append(chUrls, cu) + "fill", + "users", + commitBranch) + userHistoryImgUrls = append(userHistoryImgUrls, uhUrl) } basicTable, err := markdown.NewTableFormatterBuilder(). WithPrettyPrint(). - Build("Type", fmt.Sprintf("`%s`", req.BaseBranch), fmt.Sprintf("`%s`", req.Branch)). + Build("Type", + fmt.Sprintf("`%s`", req.BaseBranch), + fmt.Sprintf("`%s`", req.Branch), + fmt.Sprintf("[%s](/%s/%s/commit/%s) from [%s](/%s/%s/pull/%d/commits/%s)", + commitBaseBranch, + req.Org, + req.Repo, + commitBaseBranch, + commitBranch, + req.Org, + req.Repo, + req.PRNum, + commitBranch)). Format(mdTable.Rows) if err != nil { return "", err } + if totalPlus > totalMinus { + verdict = UP_SYMBOL + } else if totalPlus < totalMinus { + verdict = DOWN_SYMBOL + } mdText.PlainText("") if isFirstPR { mdText.PlainText(basicTable) } else { - basicTable = "\n" + basicTable + "\n" - mdText.Details("Comparison Table", basicTable) + mdText.Details(fmt.Sprintf("Comparison Table - %d Types %s", + len(types), + verdict), + "\n"+basicTable+"\n") } images := "" - for _, u := range urls { + for _, u := range baseAndBranchImgUrls { images += fmt.Sprintf("base vs branch", u) } mdText.PlainText("") - if isFirstPR { - mdText.PlainText(images) - } else { - mdText.Details("Base vs Branch", images) - } + mdText.Details(fmt.Sprintf("Comparisons Chart - %s from %s", req.BaseBranch, req.Branch), "\n"+images+"\n") cImages := "" - for _, u := range chUrls { + for _, u := range commitHistoryImgUrls { cImages += fmt.Sprintf("commit history", u) } mdText.PlainText("") - mdText.Details("Commit History", cImages) + uptoCommitsText := fmt.Sprintf("Upto %s for #%d", commitBranch, req.PRNum) + mdText.Details("Commits History", "\n"+uptoCommitsText+"\n"+cImages+"\n") + + uImages := "" + for _, u := range userHistoryImgUrls { + uImages += fmt.Sprintf("user history", u) + } + mdText.PlainText("") + mdText.Details("Users History", "\n"+uptoCommitsText+"\n"+uImages+"\n") mdText.PlainText("") readmeLink := fmt.Sprintf("%s://%s%sreadme?org=%s&repo=%s&branch=%s", @@ -157,19 +223,19 @@ func (p *PR) Get(req *PRRequest, types []models.Type) (string, error) { req.Org, req.Repo, req.Branch) - mdText.PlainTextf(md.Link("Embed into Readme➲", readmeLink)) + mdText.PlainTextf(md.Link("Embed README.md", readmeLink)) return mdText.String(), nil } func (p *PR) UpOrDown(baseScore *float64, branchScore *float64) string { if *baseScore > *branchScore { - return "-" + return DOWN_SYMBOL } if *baseScore < *branchScore { - return "+" + return UP_SYMBOL } - return "" + return NO_CHANGE_SYMBOL } func (p *PR) TypesToReport(req *PRRequest) ([]models.Type, error) { diff --git a/app/pkg/pr_handler.go b/app/pkg/pr_handler.go index a65c0fe..459a866 100644 --- a/app/pkg/pr_handler.go +++ b/app/pkg/pr_handler.go @@ -21,9 +21,9 @@ func NewPRHandler() *PRHandler { type PRRequest struct { Org string `json:"org" query:"org" validate:"required,ascii,excludes=/" message:"org is required"` 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"` + Branch string `json:"branch" query:"branch" validate:"required,ascii" message:"branch is required"` + BaseBranch string `json:"base_branch" query:"base_branch" validate:"required,ascii" message:"base_branch is required"` + PRNum int `json:"pr_num" query:"pr_num" validate:"required,numeric" message:"pr_num is required"` Theme string `json:"theme" query:"theme" default:"light" validate:"oneof=light dark" message:"theme must be light or dark"` Type string `json:"type" query:"type" validate:"ascii" message:"ascii type is required"` diff --git a/app/pkg/pr_handler_test.go b/app/pkg/pr_handler_test.go index e89a77c..0ceb3c5 100644 --- a/app/pkg/pr_handler_test.go +++ b/app/pkg/pr_handler_test.go @@ -32,7 +32,7 @@ func TestPRErrors(t *testing.T) { testCases := []TestCase{ { Name: "409", - Query: `?org=org&repo=repo&branch=branch&base_branch=master&type=type`, + Query: `?org=org&repo=repo&branch=branch&base_branch=master&pr_num=2&type=type`, ContentType: "application/json; charset=UTF-8", Status: http.StatusConflict, }, @@ -100,8 +100,9 @@ func TestPROK(t *testing.T) { Type: "type", Branch: "branch", Commit: "commit", + PRNum: "2", }, - Query: `?org=org&repo=repo&branch=branch&base_branch=master&type=type`, + Query: `?org=org&repo=repo&branch=branch&base_branch=master&pr_num=2&type=type`, Status: http.StatusCreated, ContentType: "text/plain; charset=UTF-8", }, @@ -114,8 +115,9 @@ func TestPROK(t *testing.T) { Branch: "branch", Commit: "commit", Score: "1999", + PRNum: "2", }, - Query: `?org=org&repo=repo&branch=branch&base_branch=master&type=type`, + Query: `?org=org&repo=repo&branch=branch&base_branch=master&pr_num=2&type=type`, Status: http.StatusCreated, ContentType: "text/plain; charset=UTF-8", }, diff --git a/app/pkg/routes.go b/app/pkg/routes.go index fa610e3..1cb0434 100644 --- a/app/pkg/routes.go +++ b/app/pkg/routes.go @@ -4,6 +4,7 @@ import ( "embed" "fmt" "net/http" + "os" instachart "github.com/kevincobain2000/instachart/pkg" "github.com/labstack/echo/v4" @@ -30,7 +31,7 @@ func SetupRoutes(e *echo.Echo, baseURL string, publicDir embed.FS, favicon embed filename := fmt.Sprintf("%s/%s", DIST_DIR, "index.html") content, err := publicDir.ReadFile(filename) if err != nil { - return c.String(http.StatusNotFound, "404") + return c.String(http.StatusOK, os.Getenv("VERSION")) } return ResponseHTML(c, content) }) @@ -62,6 +63,15 @@ func SetupRoutes(e *echo.Echo, baseURL string, publicDir embed.FS, favicon embed return c.Blob(http.StatusOK, "", img) }) + // /line + e.GET(baseURL+"line", func(c echo.Context) error { + img, err := instachart.NewLineChartHandler().Get(c) + if err != nil { + return err + } + return c.Blob(http.StatusOK, "", img) + }) + // /chart to return charts e.GET(baseURL+"chart", NewChartHandler().Get)