diff --git a/src/pkgchk-cli/Markdown.fs b/src/pkgchk-cli/Markdown.fs index 8763a4d2..8e16bddd 100644 --- a/src/pkgchk-cli/Markdown.fs +++ b/src/pkgchk-cli/Markdown.fs @@ -52,6 +52,11 @@ module Markdown = | [] -> seq { "# :heavy_check_mark: No vulnerabilities found!" } | _ -> seq { "# :warning: Vulnerabilities found!" } + let titleUpgrades hits = + match hits with + | [] -> seq { "# :heavy_check_mark: No upgrades found!" } + | _ -> seq { "# :warning: Upgrades found!" } + let formatHitCounts (severities: seq, counts: seq) = let tableHdr = seq { @@ -151,3 +156,14 @@ module Markdown = yield! formatHits hits yield! footer } + + let generateUpgrades (hits, imageUri) = + seq { + yield! titleUpgrades hits + + if String.isNotEmpty imageUri then + yield imgLink imageUri + + yield! formatHits hits + yield! footer + } diff --git a/src/pkgchk-cli/PackageUpgradeCommand.fs b/src/pkgchk-cli/PackageUpgradeCommand.fs index 5a1c82d3..7cad3783 100644 --- a/src/pkgchk-cli/PackageUpgradeCommand.fs +++ b/src/pkgchk-cli/PackageUpgradeCommand.fs @@ -1,5 +1,7 @@ namespace pkgchk +open System +open System.ComponentModel open System.Diagnostics.CodeAnalysis open Spectre.Console.Cli @@ -7,10 +9,73 @@ open Spectre.Console.Cli type PackageUpgradeCommandSettings() = inherit PackageCommandSettings() + [] + [] + [] + member val OutputDirectory = "" with get, set + + [] + [] + [] + member val BreakOnUpgrades = false with get, set + + [] + [] + [] + member val GithubToken = "" with get, set + + [] + [/, e.g. github/octokit.")>] + [] + member val GithubRepo = "" with get, set + + [] + [] + [] + member val GithubSummaryTitle = "" with get, set + + [] + [] + [] + member val GithubPrId = "" with get, set + + [] + [] + [] + member val GithubCommit = "" with get, set + + [] + [] + [] + member val GoodImageUri = "" with get, set + + [] + [] + [] + member val BadImageUri = "" with get, set + [] type PackageUpgradeCommand(nuget: Tk.Nuget.INugetClient) = inherit Command() + let genComment (settings: PackageUpgradeCommandSettings, hits, reportImg) = + let markdown = (hits, reportImg) |> Markdown.generateUpgrades |> String.joinLines + + if markdown.Length < Github.maxCommentSize then + GithubComment.create settings.GithubSummaryTitle markdown + else + GithubComment.create settings.GithubSummaryTitle "_The report is too big for Github - Please check logs_" + + let isSuccessScan (settings: PackageUpgradeCommandSettings, hits: ScaHit list) = + match hits with + | [] -> true + | _ -> not settings.BreakOnUpgrades + + let returnCode (settings: PackageUpgradeCommandSettings, hits: ScaHit list) = + match isSuccessScan (settings, hits) with + | true -> ReturnCodes.validationOk + | false -> ReturnCodes.validationFailed + override _.Execute(context, settings) = let trace = Commands.trace settings.TraceLogging @@ -44,4 +109,47 @@ type PackageUpgradeCommand(nuget: Tk.Nuget.INugetClient) = Commands.renderTables renderables - ReturnCodes.validationOk + let reportImg = + match isSuccessScan (settings, hits) with + | true -> settings.GoodImageUri + | false -> settings.BadImageUri + + if settings.OutputDirectory <> "" then + trace "Building reports..." + let reportFile = Io.toFullPath >> Io.combine "pkgchk-upgrades.md" >> Io.normalise + + let reportFile = + (hits, reportImg) + |> Markdown.generateUpgrades + |> Io.writeFile (reportFile settings.OutputDirectory) + + $"{Environment.NewLine}Report file [link={reportFile}]{reportFile}[/] built." + |> Console.italic + |> Commands.console + + if + String.isNotEmpty settings.GithubToken + && String.isNotEmpty settings.GithubRepo + && (String.isNotEmpty settings.GithubPrId || String.isNotEmpty settings.GithubCommit) + then + trace "Building Github reports..." + let prId = String.toInt settings.GithubPrId + let repo = Github.repo settings.GithubRepo + let client = Github.client settings.GithubToken + let commit = settings.GithubCommit + + let comment = genComment (settings, hits, reportImg) + + if String.isNotEmpty settings.GithubPrId then + trace $"Posting {comment.title} PR comment to Github repo {repo}..." + let _ = (comment |> Github.setPrComment trace client repo prId).Result + $"{comment.title} report sent to Github." |> Console.italic |> Commands.console + + if String.isNotEmpty settings.GithubCommit then + trace $"Posting {comment.title} build check to Github repo {repo}..." + let isSuccess = isSuccessScan (settings, hits) + + (comment |> Github.createCheck trace client repo commit isSuccess).Result + |> ignore + + returnCode (settings, hits)