2021-03-30 15:17:14 +07:00
|
|
|
package db
|
|
|
|
|
|
|
|
import (
|
2021-06-09 10:30:54 +07:00
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
2021-03-30 15:17:14 +07:00
|
|
|
"fmt"
|
2021-06-09 10:30:54 +07:00
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
2021-03-30 15:17:14 +07:00
|
|
|
"strconv"
|
2021-06-09 10:30:54 +07:00
|
|
|
"time"
|
2021-03-30 15:17:14 +07:00
|
|
|
)
|
|
|
|
|
|
|
|
func UploadBranchData(namespace, project, branch, coverageStr, html string) error {
|
|
|
|
coverage, err := strconv.ParseFloat(coverageStr, 64)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("coverage param must be valid float, instead got %s", coverageStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Because we don't have have a primary key, we must do the upsert manually.
|
|
|
|
_, err = QueryByBranch(namespace, project, branch)
|
|
|
|
if err == ErrNoData {
|
|
|
|
_, err = db.Exec("INSERT INTO badge (namespace, project_name, branch, coverage, html) VALUES (?, ?, ?, ?, ?)",
|
|
|
|
namespace, project, branch, coverage, html)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not update database: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = db.Exec("UPDATE badge SET coverage=?, html=? WHERE namespace=? AND project_name=? AND branch=?",
|
|
|
|
coverage, html, namespace, project, branch)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not update database: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func UploadPullData(namespace, project, pullStr, coverageStr, html string) error {
|
|
|
|
pull, err := strconv.Atoi(pullStr)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("pull param must be valid int, instead got %s", pullStr)
|
|
|
|
}
|
|
|
|
coverage, err := strconv.ParseFloat(coverageStr, 64)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("coverage param must be valid float, instead got %s", coverageStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Because we don't have have a primary key, we must do the upsert manually.
|
|
|
|
_, err = QueryByPull(namespace, project, pullStr)
|
|
|
|
if err == ErrNoData {
|
|
|
|
_, err = db.Exec("INSERT INTO badge (namespace, project_name, pull, coverage, html) VALUES (?, ?, ?, ?, ?)",
|
|
|
|
namespace, project, pull, coverage, html)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not update database: %v", err)
|
|
|
|
}
|
2021-06-09 10:30:54 +07:00
|
|
|
createIssueMessage(namespace, project, pullStr, coverage)
|
|
|
|
return nil
|
2021-03-30 15:17:14 +07:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = db.Exec("UPDATE badge SET coverage=?, html=? WHERE namespace=? AND project_name=? AND pull=?",
|
|
|
|
coverage, html, namespace, project, pull)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not update database: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2021-06-09 10:30:54 +07:00
|
|
|
|
|
|
|
const urlTemplate = "%s/api/v1/repos/%s/%s/issues/%s/comments"
|
|
|
|
|
|
|
|
const messageTemplate = `## Coverage Report Ready
|
|
|
|
[![Coverage %.01f%%](%s)](%s)
|
|
|
|
|
|
|
|
The coverage report can be found [here](%s). You can also click the badge above.
|
|
|
|
|
|
|
|
---
|
|
|
|
I am a bot and this was done automatically as part of CI.
|
|
|
|
The badge and report content will automatically stay up to date to the PR.`
|
|
|
|
|
|
|
|
type messageBody struct {
|
|
|
|
Body string `json:"body"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func createIssueMessage(namespace, project, pull string, coverage float64) {
|
|
|
|
badgeURL := fmt.Sprintf("https://coverage.teamortix.com/badge/pulls/%s/%s/%s", namespace, project, pull)
|
|
|
|
reportURL := fmt.Sprintf("https://coverage.teamortix.com/report/pulls/%s/%s/%s", namespace, project, pull)
|
|
|
|
|
|
|
|
message := fmt.Sprintf(messageTemplate, coverage*100, badgeURL, reportURL, reportURL)
|
|
|
|
url := fmt.Sprintf(urlTemplate, os.Getenv("GITEA_HOST"), namespace, project, pull)
|
|
|
|
|
|
|
|
jsonBytes, err := json.Marshal(messageBody{message})
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Could not marshal json: %v\n", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
body := bytes.NewReader(jsonBytes)
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
|
|
|
defer cancel()
|
|
|
|
req, err := http.NewRequestWithContext(ctx, "POST", url, body)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Could not make request: %v\n", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
req.Header.Set("Authorization", "token "+os.Getenv("COVERAGE_TOKEN"))
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
res, err := http.DefaultClient.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Issuecomment request error: %v\n", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
err = res.Body.Close()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Could not close request body: %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if res.StatusCode != 201 {
|
|
|
|
log.Printf("Issuecomment unexpected statuscode: %d\n", res.StatusCode)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|