Skip to content
Draft
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
46 changes: 26 additions & 20 deletions .github/scripts/publish_hive.sh
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
curl -X POST $1 \
-H 'Content-Type: application/json; charset=utf-8' \
--data @- <<EOF
$(jq -n --arg text "$(cat "$2")" '{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Daily Hive Coverage report"
}
},
#!/usr/bin/env bash
set -euo pipefail

WEBHOOK_URL="$1"
BLOCKS_FILE="$2"
RUN_URL="${3:-}"

PAYLOAD=$(jq -c --arg run_url "$RUN_URL" '
.blocks += (if ($run_url | length) > 0 then [
{
"type": "actions",
"elements": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": $text
}
"type": "button",
"text": {
"type": "plain_text",
"text": "View full breakdown"
},
"url": $run_url
}
]
}')
EOF
]
}
] else [] end)
' "$BLOCKS_FILE")

printf '%s' "$PAYLOAD" | curl -X POST "$WEBHOOK_URL" \
-H 'Content-Type: application/json; charset=utf-8' \
--data @-
7 changes: 5 additions & 2 deletions .github/workflows/daily_hive_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: results_daily.md
path: results.md
path: |
results.md
hive_slack_blocks.json
if-no-files-found: error

- name: Post results in summary
Expand Down Expand Up @@ -224,8 +226,9 @@ jobs:
)
|| secrets.TEST_CHANNEL_SLACK
}}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
for webhook in $SLACK_WEBHOOKS; do
sh .github/scripts/publish_hive.sh "$webhook" results.md
bash .github/scripts/publish_hive.sh "$webhook" hive_slack_blocks.json "$RUN_URL"
done
echo "Sending Results" >> $GITHUB_STEP_SUMMARY
119 changes: 112 additions & 7 deletions tooling/hive_report/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use serde::Deserialize;
use serde_json::json;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::fs::{self, File};
Expand All @@ -24,6 +25,8 @@ struct JsonFile {
test_cases: std::collections::HashMap<String, TestCase>,
}

const HIVE_SLACK_BLOCKS_FILE_PATH: &str = "./hive_slack_blocks.json";

struct HiveResult {
category: String,
display_name: String,
Expand All @@ -32,6 +35,25 @@ struct HiveResult {
success_percentage: f64,
}

struct CategoryResults {
name: String,
tests: Vec<HiveResult>,
}

impl CategoryResults {
fn total_passed(&self) -> usize {
self.tests.iter().map(|res| res.passed_tests).sum()
}

fn total_tests(&self) -> usize {
self.tests.iter().map(|res| res.total_tests).sum()
}

fn success_percentage(&self) -> f64 {
calculate_success_percentage(self.total_passed(), self.total_tests())
}
}

impl HiveResult {
fn new(suite: String, fork: String, passed_tests: usize, total_tests: usize) -> Self {
let (category, display_name) = match suite.as_str() {
Expand Down Expand Up @@ -109,6 +131,64 @@ fn calculate_success_percentage(passed_tests: usize, total_tests: usize) -> f64
}
}

fn build_slack_blocks(
categories: &[CategoryResults],
total_passed: usize,
total_tests: usize,
) -> serde_json::Value {
let total_percentage = calculate_success_percentage(total_passed, total_tests);
let mut blocks = vec![json!({
"type": "header",
"text": {
"type": "plain_text",
"text": format!(
"Daily Hive Coverage report — {total_passed}/{total_tests} ({total_percentage:.02}%)"
)
}
})];

for category in categories {
let category_passed = category.total_passed();
let category_total = category.total_tests();
let category_percentage = category.success_percentage();
let status = if category_passed == category_total { "✅" } else { "⚠️" };

let mut lines = vec![format!(
"*{}* {}/{} ({:.02}%) {}",
category.name, category_passed, category_total, category_percentage, status
)];

let mut failing_tests: Vec<_> = category
.tests
.iter()
.filter(|result| result.passed_tests < result.total_tests)
.collect();

failing_tests.sort_by(|a, b| {
a.success_percentage
.partial_cmp(&b.success_percentage)
.unwrap_or(Ordering::Equal)
});

for result in failing_tests {
lines.push(format!(
"- {}: {}/{} ({:.02}%)",
result.display_name, result.passed_tests, result.total_tests, result.success_percentage
));
}

blocks.push(json!({
"type": "section",
"text": {
"type": "mrkdwn",
"text": lines.join("\n"),
},
}));
}

json!({ "blocks": blocks })
}

fn aggregate_result(
aggregated_results: &mut HashMap<(String, String), (usize, usize)>,
result: HiveResult,
Expand Down Expand Up @@ -238,22 +318,47 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
})
});

let results_by_category = results.chunk_by(|a, b| a.category == b.category);
let mut grouped_results: Vec<CategoryResults> = Vec::new();
for result in results {
if let Some(last) = grouped_results.last_mut() {
if last.name == result.category {
last.tests.push(result);
continue;
}
}

let name = result.category.clone();
grouped_results.push(CategoryResults {
name,
tests: vec![result],
});
}

for results in results_by_category {
// print category
println!("*{}*", results[0].category);
for result in results {
for category in &grouped_results {
println!("*{}*", category.name);
for result in &category.tests {
println!("\t{result}");
}
println!();
}

println!();
let total_passed = results.iter().map(|r| r.passed_tests).sum::<usize>();
let total_tests = results.iter().map(|r| r.total_tests).sum::<usize>();
let total_passed = grouped_results
.iter()
.flat_map(|group| group.tests.iter().map(|r| r.passed_tests))
.sum::<usize>();
let total_tests = grouped_results
.iter()
.flat_map(|group| group.tests.iter().map(|r| r.total_tests))
.sum::<usize>();
let total_percentage = calculate_success_percentage(total_passed, total_tests);
println!("*Total: {total_passed}/{total_tests} ({total_percentage:.02}%)*");

let slack_blocks = build_slack_blocks(&grouped_results, total_passed, total_tests);
fs::write(
HIVE_SLACK_BLOCKS_FILE_PATH,
serde_json::to_string_pretty(&slack_blocks)?,
)?;

Ok(())
}
Loading