Skip to content

Commit

Permalink
feat: test report links output from interactive test cmd (#1271)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryan-timothy-albert authored Feb 19, 2025
1 parent 3a99c19 commit 9f9e960
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
2 changes: 1 addition & 1 deletion internal/run/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (w Workflow) runTesting(ctx context.Context, workflowTargetName string, tar
return err
}

if err := testcmd.ExecuteTargetTesting(testingCtx, generator, target, workflowTargetName, outputDir); err != nil {
if _, err := testcmd.ExecuteTargetTesting(testingCtx, generator, target, workflowTargetName, outputDir); err != nil {
return fmt.Errorf("error running workflow target %s (%s) testing: %w", workflowTargetName, target.Target, err)
}

Expand Down
30 changes: 28 additions & 2 deletions internal/testcmd/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import (
"path/filepath"
"strings"

"github.com/charmbracelet/lipgloss"
"github.com/speakeasy-api/openapi-generation/v2/pkg/generate"
"github.com/speakeasy-api/sdk-gen-config/workflow"
"github.com/speakeasy-api/speakeasy-core/auth"
"github.com/speakeasy-api/speakeasy/internal/charm/styles"
"github.com/speakeasy-api/speakeasy/internal/env"
"github.com/speakeasy-api/speakeasy/internal/links"
"github.com/speakeasy-api/speakeasy/internal/log"
"github.com/speakeasy-api/speakeasy/internal/utils"
"github.com/speakeasy-api/speakeasy/internal/workflowTracking"
Expand Down Expand Up @@ -42,6 +44,8 @@ type Runner struct {

// Enhanced CLI visualization tracker for the workflow.
workflowTracker *workflowTracking.WorkflowStep

testReportURLs []string
}

// NewRunner creates a new Runner with the given options.
Expand Down Expand Up @@ -113,6 +117,22 @@ func (r *Runner) RunWithVisualization(ctx context.Context) error {
logger.PrintlnUnstyled(styles.MakeSection("Workflow testing run logs", output, styles.Colors.Grey))
}

if len(r.testReportURLs) > 0 {
msg := "view your test report here"
if len(r.testReportURLs) > 1 {
msg = "view your test reports here"
}
shortenedURLs := make([]string, 0, len(r.testReportURLs))
for _, url := range r.testReportURLs {
shortenedURLs = append(shortenedURLs, links.Shorten(ctx, url))
}
if runErr != nil {
logger.Println("\n\n" + styles.RenderErrorMessage("Tests Failed - "+msg, lipgloss.Center, shortenedURLs...))
} else {
logger.Println("\n\n" + styles.RenderSuccessMessage("Tests Succeeded - "+msg, shortenedURLs...))
}
}

return errors.Join(err, runErr)
}

Expand Down Expand Up @@ -231,8 +251,14 @@ func (r *Runner) runSingleWorkflowTargetTesting(ctx context.Context, workflowTar
return err
}

if err := ExecuteTargetTesting(testingCtx, generator, workflowTarget, workflowTargetName, outputDir); err != nil {
return fmt.Errorf("error running workflow target %s (%s) testing: %w", workflowTargetName, workflowTarget.Target, err)
testReportURL, err := ExecuteTargetTesting(testingCtx, generator, workflowTarget, workflowTargetName, outputDir)

if testReportURL != "" {
r.testReportURLs = append(r.testReportURLs, testReportURL)
}

if err != nil {
return fmt.Errorf("error running tests for target %s (%s): %w", workflowTargetName, workflowTarget.Target, err)
}

targetTracker.SucceedWorkflow()
Expand Down
26 changes: 20 additions & 6 deletions internal/testcmd/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package testcmd

import (
"context"
"fmt"
"os"
"slices"
"strings"
Expand All @@ -11,10 +12,12 @@ import (
"github.com/speakeasy-api/sdk-gen-config/workflow"
"github.com/speakeasy-api/sdk-gen-config/workspace"
"github.com/speakeasy-api/speakeasy-client-sdk-go/v3/pkg/models/shared"
"github.com/speakeasy-api/speakeasy-core/auth"
"github.com/speakeasy-api/speakeasy-core/events"
)

func ExecuteTargetTesting(ctx context.Context, generator *generate.Generator, workflowTarget workflow.Target, targetName, outDir string) error {
func ExecuteTargetTesting(ctx context.Context, generator *generate.Generator, workflowTarget workflow.Target, targetName, outDir string) (string, error) {
testReportURL := ""
err := events.Telemetry(ctx, shared.InteractionTypeTest, func(ctx context.Context, event *shared.CliEvent) error {
event.GenerateTargetName = &targetName
if prReference := os.Getenv("GH_PULL_REQUEST"); prReference != "" {
Expand All @@ -24,35 +27,46 @@ func ExecuteTargetTesting(ctx context.Context, generator *generate.Generator, wo

err := generator.RunTargetTesting(ctx, workflowTarget.Target, outDir)

populateRawTestReport(outDir, event)
populateGenLockDetails(outDir, event)
foundTestReport := populateRawTestReport(outDir, event)
genLockID := populateGenLockDetails(outDir, event)
orgSlug := auth.GetOrgSlugFromContext(ctx)
workspaceSlug := auth.GetWorkspaceSlugFromContext(ctx)
if foundTestReport && genLockID != "" {
testReportURL = fmt.Sprintf("https://app.speakeasy.com/org/%s/%s/targets/%s/tests/%s", orgSlug, workspaceSlug, genLockID, event.ExecutionID)
}
return err
})

return err
return testReportURL, err
}

func CheckTestingAccountType(accountType shared.AccountType) bool {
return slices.Contains([]shared.AccountType{shared.AccountTypeEnterprise, shared.AccountTypeBusiness}, accountType)
}

func populateRawTestReport(outDir string, event *shared.CliEvent) {
func populateRawTestReport(outDir string, event *shared.CliEvent) bool {
foundTestReport := false
if res, _ := workspace.FindWorkspace(outDir, workspace.FindWorkspaceOptions{
FindFile: "reports/tests.xml",
Recursive: true,
}); res != nil && len(res.Data) > 0 {
testReportContent := string(res.Data)
event.TestReportRaw = &testReportContent
foundTestReport = true
}
return foundTestReport
}

func populateGenLockDetails(outDir string, event *shared.CliEvent) {
func populateGenLockDetails(outDir string, event *shared.CliEvent) string {
if cfg, err := config.Load(outDir); err == nil && cfg.LockFile != nil {
// The generator marks a testing run's version as internal to avoid a bump
// So we pull current version of the SDK from the lock file
currentVersion := cfg.LockFile.Management.ReleaseVersion
event.GenerateVersion = &currentVersion
return cfg.LockFile.ID
}

return ""
}

func reformatPullRequestURL(url string) string {
Expand Down

0 comments on commit 9f9e960

Please sign in to comment.