@@ -30,6 +30,7 @@ import Data.Submission.Query
30import Data.Tasks.Build
30import Data.Tasks.Build
31import Data.Tasks.StatusUpdate
31import Data.Tasks.StatusUpdate
32import qualified Data.Text as T
32import qualified Data.Text as T
33+import Data.Time.Clock
33import Data.Yaml
34import Data.Yaml
34import GHC.Generics
35import GHC.Generics
35import GitHub hiding (Accept)
36import GitHub hiding (Accept)
@@ -49,7 +50,6 @@ import Server.Config
49import Server.Html
50import Server.Html
50import Server.Schema
51import Server.Schema
51import Squeal.PostgreSQL
52import Squeal.PostgreSQL
53import Text.Blaze.Html
53import Text.Blaze.Html
54import UnliftIO.Exception (catch, displayException, handleAny, throwIO, try)
54import UnliftIO.Exception (catch, displayException, handleAny, throwIO, try)
@@ -75,14 +75,18 @@ type API =
75 :> Post '[HTML] Markup
75 :> Post '[HTML] Markup
76 :<|> "results" :> Capture "task name" String :> Get '[CSV, HTML] [Score]
76 :<|> "results" :> Capture "task name" String :> Get '[CSV, HTML] [Score]
78−webhookInstallation :: MonadIO m => RepoWebhookEvent -> ((), InstallationEvent) -> m ()
78+webhookInstallation :: WithLog env Message m => RepoWebhookEvent -> ((), InstallationEvent) -> m ()
79webhookInstallation _ ((), ev) =
79webhookInstallation _ ((), ev) =
80− liftIO $ do
80+ logInfo . T.pack . show $ ev
84webhookPushEvent ::
82webhookPushEvent ::
85− (StaticPQ m, MonadReader (ServerData m) m, MonadUnliftIO m, HasTasks m, MonadError ServerError m) =>
84+ MonadReader (ServerData m) m,
87+ MonadError ServerError m,
88+ WithLog env Message m
86 RepoWebhookEvent ->
90 RepoWebhookEvent ->
87 ((), PushEvent) ->
91 ((), PushEvent) ->
@@ -100,18 +104,28 @@ webhookPushEvent _ ((), ev) = do
100 M.takeWhileAntitone (repoName >) tasks
104 M.takeWhileAntitone (repoName >) tasks
101 case task of
105 case task of
102 Just (name, TaskConfig {..}) | T.take (T.length name) repoName == name -> do
106 Just (name, TaskConfig {..}) | T.take (T.length name) repoName == name -> do
107+ nowTime <- liftIO getCurrentTime
108+ if nowTime > deadline
110+ deadlineHasPassedStatus (N owner) (N repoName) (N sha)
114+ (T.unpack fullRepoName)
117+ (Jsonb PastDeadline)
103− schedulePendingStatus (N owner) (N repoName) (N sha)
119+ schedulePendingStatus (N owner) (N repoName) (N sha)
104− createSubmission $
120+ createSubmission $
105− Submission
121+ Submission
107− (T.unpack fullRepoName)
123+ (T.unpack fullRepoName)
108− (T.unpack name)
124+ (T.unpack name)
109− (T.unpack sha)
125+ (T.unpack sha)
110− (Jsonb BuildScheduled)
126+ (Jsonb BuildScheduled)
111− scheduleTask $ Build prebuild dockerfile (N owner) (N repoName) (N sha) timeoutMinutes
127+ scheduleTask $ Build prebuild dockerfile (N owner) (N repoName) (N sha) timeoutMinutes
112− liftIO $ do
128+ logInfo . T.pack . show $ ev
115 _ -> return ()
129 _ -> return ()
117retestSubmission ::
131retestSubmission ::
@@ -161,9 +175,9 @@ instance MonadError ServerError (ServerM schema) where
161server :: ServerT API (ServerM Schema)
175server :: ServerT API (ServerM Schema)
162server = (webhookInstallation :<|> webhookPushEvent) :<|> getSubmissionR :<|> retestSubmission :<|> getResults
176server = (webhookInstallation :<|> webhookPushEvent) :<|> getSubmissionR :<|> retestSubmission :<|> getResults
164−runServer :: IO ()
178+runServer :: FilePath -> IO ()
165−runServer = do
179+runServer config = do
166− c@Config {..} <- getConfig
180+ c@Config {..} <- getConfig config
168 pem <- BS.readFile appPkPemPath
182 pem <- BS.readFile appPkPemPath
169 appPkPem <- case readRsaPem pem of
183 appPkPem <- case readRsaPem pem of
@@ -278,7 +292,7 @@ instance (MonadReader (ServerData m) m, StaticPQ m, MonadUnliftIO m) => HasGithu
278 ( NewStatus
292 ( NewStatus
279 StatusPending
293 StatusPending
280 (Just . URL $ h <> "/submission/" <> owner <> "/" <> repo <> "/" <> sha)
294 (Just . URL $ h <> "/submission/" <> owner <> "/" <> repo <> "/" <> sha)
281− Nothing
295+ (Just "⌛")
284 scheduleTestedStatus TestResult {..} nOwner@(N owner) nRepo@(N repo) nCommit@(N sha) = do
298 scheduleTestedStatus TestResult {..} nOwner@(N owner) nRepo@(N repo) nCommit@(N sha) = do
@@ -286,7 +300,7 @@ instance (MonadReader (ServerData m) m, StaticPQ m, MonadUnliftIO m) => HasGithu
286 c <- asks context
300 c <- asks context
287 let total = M.size tests
301 let total = M.size tests
288 passed = M.size . M.filter id $ tests
302 passed = M.size . M.filter id $ tests
289− description = T.pack $ show passed <> "/" <> show total
303+ description = T.pack $ show passed <> "/" <> show total <> if passed == total then " ✅" else " ❌"
291 StatusUpdate
305 StatusUpdate
@@ -311,7 +325,22 @@ instance (MonadReader (ServerData m) m, StaticPQ m, MonadUnliftIO m) => HasGithu
311 NewStatus
325 NewStatus
312 { newStatusState = StatusError,
326 { newStatusState = StatusError,
313 newStatusTargetUrl = Just . URL $ h <> "/submission/" <> owner <> "/" <> repo <> "/" <> sha,
327 newStatusTargetUrl = Just . URL $ h <> "/submission/" <> owner <> "/" <> repo <> "/" <> sha,
314− newStatusDescription = Just "Build failed",
328+ newStatusDescription = Just "Build failed ☠️",
329+ newStatusContext = Just c
332+ deadlineHasPassedStatus nOwner@(N owner) nRepo@(N repo) nCommit@(N sha) = do
341+ { newStatusState = StatusError,
342+ newStatusTargetUrl = Just . URL $ h <> "/submission/" <> owner <> "/" <> repo <> "/" <> sha,
343+ newStatusDescription = Just "The deadline has passed ⏰",
315 newStatusContext = Just c
344 newStatusContext = Just c
317 scheduleTask status
346 scheduleTask status
@@ -325,7 +354,8 @@ data TaskConfig
325 = TaskConfig
354 = TaskConfig
326 { prebuild :: String,
355 { prebuild :: String,
327 dockerfile :: String,
356 dockerfile :: String,
328− timeoutMinutes :: Int
357+ timeoutMinutes :: Int,
330 deriving stock (Show, Eq, Generic)
360 deriving stock (Show, Eq, Generic)
331 deriving anyclass (FromJSON, ToJSON)
361 deriving anyclass (FromJSON, ToJSON)