Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 80 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ type cmd struct {

// Metadata for cancellation requests
Metadata map[string]interface{} `json:"metadata,omitempty"`

// Links the original run and all its reruns together.
GroupID string `json:"group_id,omitempty"`
}

type ScenarioProgressMessage struct {
Expand All @@ -91,6 +94,8 @@ type ScenarioProgressMessage struct {
Data string `json:"data"`
TotalScenarios string `json:"total_scenarios"`
Code string `json:"code"`
TriggerType string `json:"trigger_type,omitempty"`
RerunMode string `json:"rerun_mode,omitempty"`
OverallStatus string `json:"overall_status,omitempty"`
FailedCount int64 `json:"failed_count,omitempty"`
FailedScenarios []string `json:"failed_scenarios,omitempty"`
Expand Down Expand Up @@ -604,6 +609,39 @@ func process(ctx any, data []byte) error {
log.Printf("Notify (slack) failed: %v", err)
}
}
case "rerun_started":
mode, _ := c.Metadata["rerun_mode"].(string)
rerunTotal, _ := c.Metadata["rerun_total"].(string)
repository, _ := c.Metadata["repository"].(string)
runURL, _ := c.Metadata["run_url"].(string)

log.Printf("rerun started: run_id=%s mode=%s rerun_total=%s repo=%s", c.ID, mode, rerunTotal, repository)

if repslack != "" {
modeLabel := rerunModeLabel(mode)
text := fmt.Sprintf("*Run ID:* `%s`\n*Scenarios queued:* %s", c.ID, rerunTotal)
if repository != "" {
text += fmt.Sprintf("\n*Repository:* %s", repository)
}
if runURL != "" {
text += fmt.Sprintf("\n\n<%s|View run>", runURL)
}
payload := SlackMessage{
Attachments: []SlackAttachment{
{
Color: "#439FE0",
Title: fmt.Sprintf("Rerun Started — %s", modeLabel),
Text: text,
Footer: fmt.Sprintf("oops • rerun • runid: %s", c.ID),
Timestamp: time.Now().Unix(),
MrkdwnIn: []string{"text"},
},
},
}
if err := payload.Notify(repslack); err != nil {
log.Printf("Notify (slack) rerun_started failed: %v", err)
}
}
case "process":
log.Printf("process: %+v", c)
doScenario(&doScenarioInput{
Expand All @@ -614,12 +652,26 @@ func process(ctx any, data []byte) error {
Verbose: verbose,
Metadata: c.Metadata,
RunID: c.ID,
GroupID: c.GroupID,
})
}

return nil
}

func rerunModeLabel(mode string) string {
switch mode {
case "all":
return "All Scenarios"
case "failed":
return "Failed Scenarios"
case "specific":
return "Specific Scenario"
default:
return ""
}
}

func handleScenarioCompletion(ctx any, data []byte) error {
var msg ScenarioProgressMessage
if err := json.Unmarshal(data, &msg); err != nil {
Expand Down Expand Up @@ -728,6 +780,7 @@ func handleScenarioCompletion(ctx any, data []byte) error {
}

if repslack != "" {
isRerun := msg.TriggerType == "rerun"
color := "good"
title := "Tests Done."
var text string
Expand All @@ -752,23 +805,42 @@ func handleScenarioCompletion(ctx any, data []byte) error {

if msg.OverallStatus == "failure" || msg.FailedCount > 0 {
color = "danger"
title = "Test Run Complete (With Failures)"
if isRerun {
title = fmt.Sprintf("Rerun Complete (With Failures) — %s", rerunModeLabel(msg.RerunMode))
} else {
title = "Test Run Complete (With Failures)"
}
var sb strings.Builder
sb.WriteString(header)
fmt.Fprintf(&sb, "*Run Summary*\nTotal: %s\nPassed: %d\nFailed: %d", total, successCount, msg.FailedCount)
if len(msg.FailedScenarios) > 0 {
sb.WriteString("\n\n*Failed scenarios:*")
for _, name := range msg.FailedScenarios {
fmt.Fprintf(&sb, "\n• %v", name)
if isRerun && msg.RerunMode == "specific" {
scenarioName := filepath.Base(msg.Scenario)
fmt.Fprintf(&sb, "*Scenario:* %s\n*Result:* Failed", scenarioName)
} else {
fmt.Fprintf(&sb, "*Run Summary*\nTotal: %s\nPassed: %d\nFailed: %d", total, successCount, msg.FailedCount)
if len(msg.FailedScenarios) > 0 {
sb.WriteString("\n\n*Failed scenarios:*")
for _, name := range msg.FailedScenarios {
fmt.Fprintf(&sb, "\n• %v", name)
}
}
}
if msg.RunURL != "" {
fmt.Fprintf(&sb, "\n\n<%s|View run>", msg.RunURL)
}
text = sb.String()
} else {
title = "Test Run Complete"
text = header + fmt.Sprintf("*Run Summary*\nTotal: %s\nPassed: %s\nFailed: 0", total, total)
if isRerun {
title = fmt.Sprintf("Rerun Complete — %s", rerunModeLabel(msg.RerunMode))
if msg.RerunMode == "specific" {
scenarioName := filepath.Base(msg.Scenario)
text = header + fmt.Sprintf("*Scenario:* %s\n*Result:* Passed", scenarioName)
} else {
text = header + fmt.Sprintf("*Run Summary*\nTotal: %s\nPassed: %s\nFailed: 0", total, total)
}
} else {
title = "Test Run Complete"
text = header + fmt.Sprintf("*Run Summary*\nTotal: %s\nPassed: %s\nFailed: 0", total, total)
}
if msg.RunURL != "" {
text += fmt.Sprintf("\n\n<%s|View run>", msg.RunURL)
}
Expand Down
6 changes: 6 additions & 0 deletions scenario.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type ReportPubsub struct {
Data string `json:"data"`
MessageID string `json:"message_id"` // Unique oops-generated tracking ID
RunID string `json:"run_id"` // Batch run ID from the initiating workflow
GroupID string `json:"group_id"` // Links original run + all reruns together
}

// Scenario represents a single scenario file to run.
Expand Down Expand Up @@ -174,6 +175,7 @@ type doScenarioInput struct {
Verbose bool
Metadata map[string]interface{}
RunID string
GroupID string
OnScenarioDone func(scenario, status string)
}

Expand All @@ -194,6 +196,7 @@ func publishCancelledReport(in *doScenarioInput, scenarioFile string, startedAt
for _, key := range []string{
"pr_number", "branch", "commit_sha", "actor",
"trigger_type", "run_url", "repository", "workflow", "total_scenarios",
"rerun_mode",
} {
if v, ok := in.Metadata[key].(string); ok && v != "" {
attr[key] = v
Expand All @@ -215,6 +218,7 @@ func publishCancelledReport(in *doScenarioInput, scenarioFile string, startedAt
MessageID: uuid.NewString(),
RunID: in.RunID,
Attributes: attr,
GroupID: in.GroupID,
}

if err := in.app.rpub.Publish(r.MessageID, r); err != nil {
Expand Down Expand Up @@ -458,6 +462,7 @@ func doScenario(in *doScenarioInput) error {
for _, key := range []string{
"pr_number", "branch", "commit_sha", "actor",
"trigger_type", "run_url", "repository", "workflow", "total_scenarios",
"rerun_mode",
} {
if v, ok := in.Metadata[key].(string); ok && v != "" {
attr[key] = v
Expand All @@ -483,6 +488,7 @@ func doScenario(in *doScenarioInput) error {
Data: data,
MessageID: uuid.NewString(),
RunID: in.RunID,
GroupID: in.GroupID,
}

err := in.app.rpub.Publish(r.MessageID, r)
Expand Down