GitHub Actions test reporter

Does anybody know of an existing GitHub Action to report on PureScript test results (with purescript-spec) without crawling through the run logs? I’m used to something like this or this. Or does someone have an example of code setting up a reporter for GitHub Actions with purescript-spec?

1 Like

That’s pretty cool @ntwilson There’s a reporter for the teamcity format in specs. Maybe there’s an action that supports that?

I haven’t been able to find anything. I get the sense that a Reporter in spec is supposed to be something that gives realtime status, and I’m just interested in a finished report when it’s done running. I ended up just cobbling some code together to consume the output of runSpecT and write a summary.

type SpecTestResults = Array (Tree String Void Result)

printGitHubSummary :: SpecTestResults -> Aff Unit
printGitHubSummary testResults = do
  isGitHub <- liftEffect $ lookupEnv "GITHUB_ACTIONS"

  when (isGitHub == Just "true") do
    summaryFile <-
      liftEffect (lookupEnv "GITHUB_STEP_SUMMARY") <#> note (error "GITHUB_STEP_SUMMARY not found") >>= liftEither

    let
      (Count { failed, passed }) = summarize testResults
      writeToSummary = appendTextFile UTF8 summaryFile <<< (_ <> "\n")

    writeToSummary "## PureScript Test Results"
    if failed == 0 then
      writeToSummary $ i "### ✔ All " passed " tests passed!"
    else do
      writeToSummary $ i "### ❌  " failed " tests failed.  " passed " tests passed."
      writeToSummary "#### Failed Tests:"
      let
        foldlWithAnnotations ::
          ∀ state.
          (state -> { annotation :: Array String, value :: Result } -> state) ->
          state ->
          Tree (Array String) Void Result ->
          state
        foldlWithAnnotations f i (Leaf annotation value) =
          maybe i (\value' -> f i { annotation, value: value' }) value
        foldlWithAnnotations f i (Node annotation values) =
          let
            newAnnotation = either identity absurd annotation
            newTree = mapTreeAnnotations (newAnnotation <> _) <$> values
          in
            foldl (\i' value -> foldlWithAnnotations f i' value) i newTree

        allTests :: List { annotation :: Array String, value :: Result }
        allTests =
          testResults
            <#> mapTreeAnnotations Array.singleton
            <#> foldlWithAnnotations (flip List.Cons) List.Nil
            # List.fromFoldable
            # List.concat

        failedTests = allTests # List.mapMaybe
          ( case _ of
              { annotation, value: Failure err } -> Just { annotation, err }
              _ -> Nothing
          )

      for_ failedTests \{ annotation, err } -> do
        let
          testName = Array.intercalate " >> " $ Array.nub annotation
        writeToSummary $ i "\n---\n_" testName "_\n**" (message err) "**"

1 Like