Skip to content

Commit

Permalink
pipeline report
Browse files Browse the repository at this point in the history
  • Loading branch information
3ximus committed Feb 18, 2024
1 parent e27bcd4 commit 12a7787
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 4 deletions.
42 changes: 40 additions & 2 deletions api/bb-api.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ func bbApiRangedGet(endpoint string, dataRange string) []byte {
resp, err := client.Do(req)
cobra.CheckErr(err)

if resp.StatusCode == 404 {
var errResponse ErrorResponse
body, err := io.ReadAll(resp.Body)
cobra.CheckErr(err)
err = json.Unmarshal(body, &errResponse)
cobra.CheckErr(err)
cobra.CheckErr(errResponse.Error.Detail)
}

if resp.StatusCode != 200 && resp.StatusCode != 206 && resp.StatusCode != 416 {
errBody, err := io.ReadAll(resp.Body)
cobra.CheckErr(err)
Expand Down Expand Up @@ -393,11 +402,11 @@ func GetPipelineStep(repository string, id string, stepId string) <-chan Pipelin
return channel
}

func GetPipelineStepLogs(repository string, id string, stepUUID string, offset int) <-chan string {
func GetPipelineStepLogs(repository string, id string, stepId string, offset int) <-chan string {
channel := make(chan string)
go func() {
defer close(channel)
response := bbApiRangedGet(fmt.Sprintf("repositories/%s/pipelines/%s/steps/%s/log", repository, id, stepUUID), fmt.Sprintf("%d-", offset))
response := bbApiRangedGet(fmt.Sprintf("repositories/%s/pipelines/%s/steps/%s/log", repository, id, stepId), fmt.Sprintf("%d-", offset))
if bytes.Index(response, []byte("Range Not Satisfiable")) != -1 {
channel <- ""
} else {
Expand All @@ -423,6 +432,35 @@ func GetPipelineVariables(repository string) <-chan EnvironmentVariable {
return channel
}

func GetPipelineReport(repository string, id string, stepId string) <-chan PipelineReport {
channel := make(chan PipelineReport)
go func() {
defer close(channel)
var report PipelineReport
response := bbApiGet(fmt.Sprintf("repositories/%s/pipelines/%s/steps/%s/test_reports", repository, id, stepId))
err := json.Unmarshal(response, &report)
cobra.CheckErr(err)
channel <- report
}()
return channel
}

func GetPipelineReportCases(repository string, id string, stepId string) <-chan PipelineReportCase {
channel := make(chan PipelineReportCase)
go func() {
defer close(channel)
var report BBPaginatedResponse[PipelineReportCase]
// TODO pagelen is hardcoded, this should be changed if the number of tests are too big
response := bbApiGet(fmt.Sprintf("repositories/%s/pipelines/%s/steps/%s/test_reports/test_cases?pagelen=300", repository, id, stepId))
err := json.Unmarshal(response, &report)
cobra.CheckErr(err)
for _, rep := range report.Values {
channel <- rep
}
}()
return channel
}

func RunPipeline(repository string, data RunPipelineRequestBody) Pipeline {
content, err := json.Marshal(data)
cobra.CheckErr(err)
Expand Down
24 changes: 24 additions & 0 deletions api/bb-types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import (
"time"
)

type ErrorResponse struct {
Error struct {
Message string
Detail string
}
}

type User struct {
UUID string `json:"uuid"`
DisplayName string `json:"display_name"`
Expand Down Expand Up @@ -154,6 +161,23 @@ type PipelineStep struct {
}
}

type PipelineReport struct {
Total int `json:"number_of_test_cases"`
Success int `json:"number_of_successful_test_cases"`
Failed int `json:"number_of_failed_test_cases"`
Error int `json:"number_of_error_test_cases"`
Skipped int `json:"number_of_skipped_test_cases"`
}

type PipelineReportCase struct {
UUID string
Name string
FullyQualifiedName string `json:"fully_qualified_name"`
PackageName string `json:"package_name"`
Status string `json:"status"`
Duration string `json:"duration"`
}

type StepCommand struct {
Name string
Command string
Expand Down
2 changes: 1 addition & 1 deletion cmd/pipeline/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var LogsCmd = &cobra.Command{
if len(args) == 0 {
branch, err := util.GetCurrentBranch()
cobra.CheckErr(err)
// retrieve id of pr for current branch
// retrieve id of pipeline for current branch
pipeline := <-api.GetPipelineList(repo, 1, branch)
if pipeline.BuildNumber == 0 {
cobra.CheckErr("No pipelines found for this branch")
Expand Down
1 change: 1 addition & 0 deletions cmd/pipeline/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ func init() {
PipelineCmd.AddCommand(RunCmd)
PipelineCmd.AddCommand(LogsCmd)
PipelineCmd.AddCommand(VariablesCmd)
PipelineCmd.AddCommand(ReportCmd)
PipelineCmd.PersistentFlags().StringP("repo", "R", "", "selected repository")
}
80 changes: 80 additions & 0 deletions cmd/pipeline/report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package pipeline

import (
"bb/api"
"bb/util"
"fmt"
"strconv"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var ReportCmd = &cobra.Command{
Use: "report",
Short: "Show test reports of a pipeline step",
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
repo := viper.GetString("repo")

var id int
var err error
if len(args) == 0 {
branch, err := util.GetCurrentBranch()
cobra.CheckErr(err)
// retrieve id of pipeline for current branch
pipeline := <-api.GetPipelineList(repo, 1, branch)
if pipeline.BuildNumber == 0 {
cobra.CheckErr("No pipelines found for this branch")
}
id = pipeline.BuildNumber
} else {
id, err = strconv.Atoi(args[0])
cobra.CheckErr(err)
}

var selected = api.PipelineStep{}
steps := <-api.GetPipelineSteps(repo, fmt.Sprintf("%d", id))
selectedStep, _ := cmd.Flags().GetString("step")
if selectedStep == "" {
optIndex := util.SelectFZF(steps, fmt.Sprintf("Step to Log > "), func(i int) string {
return fmt.Sprintf("%s", steps[i].Name)
})
if len(optIndex) > 0 {
selected = steps[optIndex[0]]
}
} else {
for _, step := range steps {
if step.Name == selectedStep || strings.ToLower(step.Name) == selectedStep {
selected = step
}
}
}

if selected.UUID == "" {
cobra.CheckErr("Step not found")
}

fullReportChannel := api.GetPipelineReportCases(repo, fmt.Sprintf("%d", id), selected.UUID)
report := <-api.GetPipelineReport(repo, fmt.Sprintf("%d", id), selected.UUID)
fmt.Println("Test report:")
fmt.Printf("\033[1;32mPassed: %3d\033[m\n", report.Success)
fmt.Printf("\033[1;31mFailed: %3d\033[m\n", report.Failed)
fmt.Printf("\033[1;33mSkipped: %3d\033[m\n", report.Skipped)
fmt.Printf("Error: %3d\n", report.Error)
fmt.Printf("Total: %3d\n", report.Total)

showFull, _ := cmd.Flags().GetBool("full")
if showFull {
for reportCase := range fullReportChannel {
fmt.Printf("%s \033[34m%s\033[m %s \033[37m%s\033[m\n", util.FormatPipelineStatus(reportCase.Status), reportCase.PackageName, reportCase.Name, strings.Replace(reportCase.Duration, "PT", "", 1))
}
}
},
}

func init() {
ReportCmd.Flags().StringP("step", "s", "", "select step. Without this option the step is prompet interactively")
ReportCmd.Flags().BoolP("full", "f", false, "show the full report")
}
2 changes: 1 addition & 1 deletion cmd/pr/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ var ListCmd = &cobra.Command{
count++
}
if count == 0 {
fmt.Printf("\n No pull requests for \033[1;36m%s\033[m\n\n", viper.GetString("repo"))
fmt.Printf("No pull requests for \033[1;36m%s\033[m\n", viper.GetString("repo"))
}
},
}
Expand Down

0 comments on commit 12a7787

Please sign in to comment.