-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use checks instead of posting comments (#122)
* Fixed warnings * wip * wip * wip * sha * wip * Added project name * Made check not fail * Removed Pull Request * Removed testing things * Updated docs
- Loading branch information
Showing
12 changed files
with
276 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,86 @@ | ||
module CompaREST.GitHub.API | ||
( mapComment, | ||
createOrUpdateComment, | ||
( postStatus, | ||
postStatusProcessing, | ||
) | ||
where | ||
|
||
import CompaREST.GitHub.Action.Config | ||
import Control.Monad | ||
import Control.Monad.Freer | ||
import Control.Monad.Freer.GitHub | ||
import Control.Monad.Freer.Reader | ||
import Data.Foldable | ||
import Control.Monad.IO.Class | ||
import Data.Aeson | ||
import qualified Data.ByteString.Lazy.Char8 as BSLC | ||
import Data.OpenApi.Compare.Report | ||
import Data.Proxy | ||
import Data.Text (Text) | ||
import qualified Data.Text as T | ||
import qualified Data.Vector as V | ||
import GitHub | ||
import qualified GitHub as GH | ||
import GitHub.Data.Checks | ||
import GitHub.Endpoints.Checks | ||
|
||
findComment :: Members '[GitHub, Reader Config] effs => Eff effs (Maybe GH.IssueComment) | ||
findComment = do | ||
postStatusProcessing :: | ||
(Members '[GitHub, Reader Config] effs, MonadIO (Eff effs)) => | ||
Eff effs () | ||
postStatusProcessing = do | ||
Config {..} <- ask | ||
comments <- sendGitHub $ GH.commentsR repoOwner repoName issue GH.FetchAll | ||
htmlComment <- getHTMLComment | ||
let tryStripPrefix :: GH.IssueComment -> Maybe GH.IssueComment | ||
tryStripPrefix c@GH.IssueComment {issueCommentBody = (T.stripSuffix htmlComment -> Just b)} = | ||
Just $ c {GH.issueCommentBody = b} | ||
tryStripPrefix _ = Nothing | ||
pure . (V.!? 0) $ V.mapMaybe tryStripPrefix comments | ||
printJSON $ | ||
sendGitHub $ | ||
checkR | ||
repoOwner | ||
repoName | ||
Check | ||
{ checkName = mkName Proxy $ "compaREST – " <> projectName | ||
, checkSha = sha | ||
, checkDetailsURL = Nothing | ||
, checkExternalId = Nothing | ||
, checkStatus = Just CheckInProgress | ||
, checkStartedAt = Nothing | ||
, checkConclusion = Nothing | ||
, checkCompletedAt = Nothing | ||
, checkOutput = Nothing | ||
, checkActions = Nothing | ||
} | ||
|
||
mapComment :: Members '[GitHub, Reader Config] effs => (Text -> Text) -> Eff effs () | ||
mapComment f = do | ||
findComment | ||
>>= traverse_ | ||
( \comment -> do | ||
Config {..} <- ask | ||
htmlComment <- getHTMLComment | ||
sendGitHub $ editCommentR repoOwner repoName (GH.mkId Proxy $ GH.issueCommentId comment) ((<> htmlComment) . f $ GH.issueCommentBody comment) | ||
pure () | ||
) | ||
|
||
createOrUpdateComment :: Members '[GitHub, Reader Config] effs => Text -> Eff effs () | ||
createOrUpdateComment body' = do | ||
postStatus :: | ||
(Members '[GitHub, Reader Config] effs, MonadIO (Eff effs)) => | ||
-- | 'Nothing' means that there were no changes at all | ||
Maybe (Text, ReportStatus) -> | ||
Eff effs () | ||
postStatus x = do | ||
let (body, (title, conclusion)) = case x of | ||
Just (b, s) -> (b,) $ case s of | ||
BreakingChanges -> ("⚠️ Breaking changes found!", CheckNeutral) | ||
NoBreakingChanges -> ("No breaking changes found ✨", CheckSuccess) | ||
OnlyUnsupportedChanges -> ("🤷 Couldn't determine compatibility", CheckNeutral) | ||
Nothing -> ("", ("✅ The API did not change", CheckSuccess)) | ||
Config {..} <- ask | ||
htmlComment <- getHTMLComment | ||
let body = body' <> htmlComment | ||
void $ | ||
findComment >>= \case | ||
Just comment -> sendGitHub $ editCommentR repoOwner repoName (GH.mkId Proxy $ GH.issueCommentId comment) body | ||
Nothing -> sendGitHub $ createCommentR repoOwner repoName issue body | ||
printJSON $ | ||
sendGitHub $ | ||
checkR | ||
repoOwner | ||
repoName | ||
Check | ||
{ checkName = mkName Proxy $ "compaREST – " <> projectName | ||
, checkSha = sha | ||
, checkDetailsURL = Nothing | ||
, checkExternalId = Nothing | ||
, checkStatus = Just CheckCompleted | ||
, checkStartedAt = Nothing | ||
, checkConclusion = Just conclusion | ||
, checkCompletedAt = Nothing | ||
, checkOutput = | ||
Just $ | ||
CheckOutput | ||
{ checkTitle = title | ||
, checkSummary = body | ||
, checkText = Nothing | ||
, checkAnnotations = Nothing | ||
, checkImages = Nothing | ||
} | ||
, checkActions = Nothing | ||
} | ||
|
||
getHTMLComment :: Member (Reader Config) effs => Eff effs Text | ||
getHTMLComment = do | ||
name <- asks projectName | ||
pure $ "\n\n<!-- compaREST comment – " <> name <> " -->" | ||
printJSON :: MonadIO (Eff effs) => Eff effs Value -> Eff effs () | ||
printJSON m = do | ||
x <- m | ||
liftIO . BSLC.putStrLn $ encode x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
module GitHub.Data.Checks | ||
( Check (..), | ||
CheckStatus (..), | ||
CheckConclusion (..), | ||
CheckOutput (..), | ||
CheckAnnotation (..), | ||
CheckAnnotationLevel (..), | ||
CheckImage (..), | ||
CheckAction (..), | ||
) | ||
where | ||
|
||
import Data.Aeson | ||
import Data.Aeson.Types | ||
import Data.Text (Text) | ||
import Data.Vector (Vector) | ||
import GHC.Generics (Generic) | ||
import GitHub | ||
import GitHub.Internal.Prelude (UTCTime) | ||
|
||
data Check = Check | ||
{ checkName :: !(Name Check) | ||
, checkSha :: !(Name Commit) | ||
, checkDetailsURL :: !(Maybe URL) | ||
, checkExternalId :: !(Maybe (Id Check)) | ||
, checkStatus :: !(Maybe CheckStatus) | ||
, checkStartedAt :: !(Maybe UTCTime) | ||
, checkConclusion :: !(Maybe CheckConclusion) | ||
, checkCompletedAt :: !(Maybe UTCTime) | ||
, checkOutput :: !(Maybe CheckOutput) | ||
, checkActions :: !(Maybe (Vector CheckAction)) | ||
} | ||
deriving stock (Show, Eq, Ord, Generic) | ||
|
||
instance ToJSON Check where | ||
toJSON (Check n sha durl eid s sa c ca o a) = | ||
object' | ||
[ "name" .= n | ||
, "head_sha" .= sha | ||
, "details_url" .= durl | ||
, "external_id" .= eid | ||
, "status" .= s | ||
, "started_at" .= sa | ||
, "conclusion" .= c | ||
, "completed_at" .= ca | ||
, "output" .= o | ||
, "actions" .= a | ||
] | ||
|
||
data CheckStatus | ||
= CheckQueued | ||
| CheckInProgress | ||
| CheckCompleted | ||
deriving stock (Show, Enum, Bounded, Eq, Ord, Generic) | ||
|
||
instance ToJSON CheckStatus where | ||
toJSON CheckQueued = String "queued" | ||
toJSON CheckInProgress = String "in_progress" | ||
toJSON CheckCompleted = String "completed" | ||
|
||
data CheckConclusion | ||
= CheckActionRequired | ||
| CheckCancelled | ||
| CheckFailure | ||
| CheckNeutral | ||
| CheckSuccess | ||
| CheckSkipped | ||
| CheckStale | ||
| CheckTimedOut | ||
deriving stock (Show, Enum, Bounded, Eq, Ord, Generic) | ||
|
||
instance ToJSON CheckConclusion where | ||
toJSON CheckActionRequired = String "action_required" | ||
toJSON CheckCancelled = String "cancelled" | ||
toJSON CheckFailure = String "failure" | ||
toJSON CheckNeutral = String "neutral" | ||
toJSON CheckSuccess = String "success" | ||
toJSON CheckSkipped = String "skipped" | ||
toJSON CheckStale = String "stale" | ||
toJSON CheckTimedOut = String "timed_out" | ||
|
||
data CheckOutput = CheckOutput | ||
{ checkTitle :: !Text | ||
, checkSummary :: !Text | ||
, checkText :: !(Maybe Text) | ||
, checkAnnotations :: !(Maybe (Vector CheckAnnotation)) | ||
, checkImages :: !(Maybe (Vector CheckImage)) | ||
} | ||
deriving stock (Show, Eq, Ord, Generic) | ||
|
||
instance ToJSON CheckOutput where | ||
toJSON (CheckOutput t s txt a i) = | ||
object' | ||
[ "title" .= t | ||
, "summary" .= s | ||
, "text" .= txt | ||
, "annotations" .= a | ||
, "images" .= i | ||
] | ||
|
||
data CheckAnnotation = CheckAnnotation | ||
{ checkPath :: !Text | ||
, checkStartLine :: !Int | ||
, checkEndLine :: !Int | ||
, checkStartColumn :: !(Maybe Int) | ||
, checkEndColumn :: !(Maybe Int) | ||
, checkAnnotationLevel :: !CheckAnnotationLevel | ||
, checkMessage :: !Text | ||
, checkTitle :: !(Maybe Text) | ||
, checkRawDetails :: !(Maybe Text) | ||
} | ||
deriving stock (Show, Eq, Ord, Generic) | ||
|
||
instance ToJSON CheckAnnotation where | ||
toJSON (CheckAnnotation p sl el sc ec al m t rd) = | ||
object' | ||
[ "path" .= p | ||
, "start_line" .= sl | ||
, "end_line" .= el | ||
, "start_column" .= sc | ||
, "end_column" .= ec | ||
, "annotation_level" .= al | ||
, "message" .= m | ||
, "title" .= t | ||
, "raw_details" .= rd | ||
] | ||
|
||
data CheckAnnotationLevel | ||
= NoticeAnnotation | ||
| WarningAnnotation | ||
| FailureAnnotation | ||
deriving stock (Show, Enum, Bounded, Eq, Ord, Generic) | ||
|
||
instance ToJSON CheckAnnotationLevel where | ||
toJSON NoticeAnnotation = String "notice" | ||
toJSON WarningAnnotation = String "warning" | ||
toJSON FailureAnnotation = String "failure" | ||
|
||
data CheckImage = CheckImage | ||
{ checkImageAlt :: !Text | ||
, checkImageURL :: !URL | ||
, checkImageCaption :: !(Maybe Text) | ||
} | ||
deriving stock (Show, Eq, Ord, Generic) | ||
|
||
instance ToJSON CheckImage where | ||
toJSON (CheckImage a url c) = | ||
object' | ||
[ "alt" .= a | ||
, "image_url" .= url | ||
, "caption" .= c | ||
] | ||
|
||
data CheckAction = CheckAction | ||
{ checkActionLabel :: !Text | ||
, checkActionDescription :: !Text | ||
, checkActionIdentifier :: !Text | ||
} | ||
deriving stock (Show, Eq, Ord, Generic) | ||
|
||
instance ToJSON CheckAction where | ||
toJSON (CheckAction l d i) = | ||
object' | ||
[ "label" .= l | ||
, "description" .= d | ||
, "identifier" .= i | ||
] | ||
|
||
object' :: [Pair] -> Value | ||
object' = object . filter notNull | ||
where | ||
notNull (_, Null) = False | ||
notNull (_, _) = True |
Oops, something went wrong.