Precept.Reporting.Teams
Microsoft Teams reporting for Precept: one Adaptive Card per run, posted to an incoming webhook — the verdict, the counts, the pass rate, and a link to the build that produced them.
dotnet add package Precept.Reporting.Teams
public sealed class Startup : IPreceptStartup
{
public void ConfigureServices(IServiceCollection services, PreceptSettings settings) =>
services.AddPreceptTeamsReporting(teams => teams.Variant = PreceptTeamsCardVariant.Pipeline);
}
{
"Reporting": {
"Teams": {
"Variant": "Pipeline",
"NotifyOn": "Failure",
"Title": "Checkout regression",
"ImageUrl": "https://dev.azure.com/acme/Web/_apis/build/status/nightly",
"Facts": { "Owner": "Checkout squad" }
}
}
}
Variants#
Variant picks the layout — in code as above, or from precept.json, or as
PRECEPT_REPORTING__TEAMS__VARIANT for a single run.
| Variant | Card |
|---|---|
Summary (default) |
Verdict header, the counts as tiles, the pass rate, the environment. No failure messages. |
Compact |
One line: verdict, pass rate, duration, and the button. |
Detailed |
Summary, then the failed tests and their messages — MaxFailuresListed and MaxFailureMessageLength cap it. |
Pipeline |
Summary, then the build: pipeline, build number, branch, commit, who queued it. |
The pipeline facts are read from the agent's own variables (Azure DevOps and GitHub Actions), so
nothing is configured into the test project and a run off an agent renders the summary it is built
on rather than a table of blanks. The same detection gives every variant its button: leave RunUrl
unset and the card links to the build that ran the suite.
The card links the run's other reports. Register Precept.Reporting.ReportPortal or
Precept.Reporting.AzureDevOps alongside it and the card grows a button per destination — Open
ReportPortal, Open Azure DevOps — because each of those reporters posts what it opened to
PreceptRunLinks as soon as it has an address. Nothing to configure: those ids are assigned while
the run is running. One button per service, so the detected build steps aside for an Azure DevOps
test run rather than sitting next to it. "LinkToOtherReports": false turns them off, and a reporter
of your own can post to the same board and be linked the same way. See
linking a run's reports to each other.
ImageUrl puts a picture on the card — a pipeline status badge, a team logo. It must be an https
address every reader's Teams client can fetch without signing in, because the card renders in their
client and not on the agent. ImagePlacement takes Thumbnail (the default, beside the heading),
Banner (full width) or None, which is how an overlay drops the image without losing the URL.
The webhook URL is a credential — anyone holding it can post to the channel — so supply it from CI
as PRECEPT_REPORTING__TEAMS__WEBHOOKURL rather than committing it. Create it from the channel's
Workflows connector; the payload is the Adaptive Card envelope a workflow URL expects, not the
retired Office 365 connector's MessageCard.
Cards are posted from a build agent only, so a channel hears about the pipeline's runs and not
about every run somebody starts while writing a scenario. A developer's run posts nothing and asks
for nothing — the reporter is never started, so a missing webhook is not an error there. Add
{ "Reporting": { "CiOnly": false } } to precept.local.json to post from your own machine while
working on the card, and see
CI and local runs for how a run is
recognised as CI.
One HTTP call, after the last test, built from the summary Precept already keeps. Nothing is sent per test: a channel does not want one message per scenario, and reporting never runs on a test's thread in any case.
NotifyOn takes Always, Failure or FailureOrFlaky — the last of which is how a green-but-retried
run still gets noticed.
Part of Precept, a .NET 10 test automation framework. Full documentation: reporting · configuration · writing your own reporter