1{-# LANGUAGE NoImplicitPrelude #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE RecordWildCards #-}
4module Stackage.CompleteBuild
11import Data.Default.Class (def)
12import Data.Semigroup (Max (..), Option (..))
13import Data.Text.Read (decimal)
15import Data.Yaml (decodeFileEither, encodeFile)
16import Network.HTTP.Client
17import Network.HTTP.Client.TLS (tlsManagerSettings)
18import Stackage.BuildConstraints
19import Stackage.BuildPlan
20import Stackage.CheckBuildPlan
21import Stackage.PerformBuild
22import Stackage.Prelude
23import Stackage.ServerBundle
24import Stackage.UpdateBuildPlan
26import System.IO (BufferMode (LineBuffering), hSetBuffering)
28-- | Flags passed in from the command line.
29data BuildFlags = BuildFlags
30 { bfEnableTests :: !Bool
32 , bfEnableLibProfile :: !Bool
36data BuildType = Nightly | LTS BumpType
37 deriving (Show, Read, Eq, Ord)
39data BumpType = Major | Minor
40 deriving (Show, Read, Eq, Ord)
42data Settings = Settings
44 , planFile :: FilePath
45 , buildDir :: FilePath
47 , title :: Text -> Text -- ^ GHC version -> title
49 , setArgs :: Text -> UploadBundle -> UploadBundle
53getSettings :: Manager -> BuildType -> IO Settings
54getSettings man Nightly = do
55 day <- tshow . utctDay <$> getCurrentTime
56 let slug' = "nightly-" ++ day
57 plan' <- defaultBuildConstraints man >>= newBuildPlan
59 { planFile = fpFromText ("nightly-" ++ day) <.> "yaml"
60 , buildDir = fpFromText $ "builds/stackage-nightly-" ++ day
61 , logDir = fpFromText $ "logs/stackage-nightly-" ++ day
62 , title = \ghcVer -> concat
69 , setArgs = \ghcVer ub -> ub { ubNightly = Just ghcVer }
71 , postBuild = return ()
73getSettings man (LTS bumpType) = do
74 Option mlts <- fmap (fmap getMax) $ runResourceT
76 $$ foldMapC (Option . fmap Max . parseLTSVer . filename)
78 (new, plan') <- case bumpType of
83 Just (LTSVer x _) -> LTSVer (x + 1) 0
84 plan' <- defaultBuildConstraints man >>= newBuildPlan
87 old <- maybe (error "No LTS plans found in current directory") return mlts
88 oldplan <- decodeFileEither (fpToString $ renderLTSVer old)
89 >>= either throwM return
90 let new = incrLTSVer old
91 plan' <- updateBuildPlan oldplan
94 let newfile = renderLTSVer new
98 , buildDir = fpFromText $ "builds/stackage-lts-" ++ tshow new
99 , logDir = fpFromText $ "logs/stackage-lts-" ++ tshow new
100 , title = \ghcVer -> concat
106 , slug = "lts-" ++ tshow new
107 , setArgs = \_ ub -> ub { ubLTS = Just $ tshow new }
110 let git args = withCheckedProcess
111 (proc "git" args) $ \ClosedStream Inherited Inherited ->
113 putStrLn "Committing new LTS file to Git"
114 git ["add", fpToString newfile]
115 git ["commit", "-m", "Added new LTS release: " ++ show new]
116 putStrLn "Pushing to Git repository"
120data LTSVer = LTSVer !Int !Int
122instance Show LTSVer where
123 show (LTSVer x y) = concat [show x, ".", show y]
124incrLTSVer :: LTSVer -> LTSVer
125incrLTSVer (LTSVer x y) = LTSVer x (y + 1)
127parseLTSVer :: FilePath -> Maybe LTSVer
129 w <- stripPrefix "lts-" $ fpToText fp
130 x <- stripSuffix ".yaml" w
131 Right (major, y) <- Just $ decimal x
132 z <- stripPrefix "." y
133 Right (minor, "") <- Just $ decimal z
134 return $ LTSVer major minor
135renderLTSVer :: LTSVer -> FilePath
136renderLTSVer lts = fpFromText $ concat
142-- | Generate and check a new build plan, but do not execute it.
146justCheck = withManager tlsManagerSettings $ \man -> do
147 putStrLn "Loading build constraints"
148 bc <- defaultBuildConstraints man
150 putStrLn "Creating build plan"
151 plan <- newBuildPlan bc
153 putStrLn $ "Writing build plan to check-plan.yaml"
154 encodeFile "check-plan.yaml" plan
156 putStrLn "Checking plan"
159 putStrLn "Plan seems valid!"
161-- | Make a complete plan, build, test and upload bundle, docs and
163completeBuild :: BuildType -> BuildFlags -> IO ()
164completeBuild buildType buildFlags = withManager tlsManagerSettings $ \man -> do
165 hSetBuffering stdout LineBuffering
167 putStrLn $ "Loading settings for: " ++ tshow buildType
168 settings@Settings {..} <- getSettings man buildType
170 putStrLn $ "Writing build plan to: " ++ fpToText planFile
171 encodeFile (fpToString planFile) plan
173 putStrLn "Checking build plan"
176 putStrLn "Performing build"
177 let pb = PerformBuild
179 , pbInstallDest = buildDir
181 , pbLog = hPut stdout
183 , pbGlobalInstall = False
184 , pbEnableTests = bfEnableTests buildFlags
185 , pbEnableLibProfiling = bfEnableLibProfile buildFlags
186 , pbVerbose = bfVerbose buildFlags
188 performBuild pb >>= mapM_ putStrLn
190 when (bfDoUpload buildFlags) $
191 finallyUpload settings man pb
193-- | The final part of the complete build process: uploading a bundle,
194-- docs and a distro to hackage.
195finallyUpload :: Settings -> Manager -> PerformBuild -> IO ()
196finallyUpload Settings{..} man pb = do
197 putStrLn "Uploading bundle to Stackage Server"
198 token <- readFile "/auth-token"
200 let ghcVer = display $ siGhcVersion $ bpSystemInfo plan
201 (ident, mloc) <- flip uploadBundle man $ setArgs ghcVer def
202 { ubContents = serverBundle now (title ghcVer) slug plan
203 , ubAuthToken = decodeUtf8 token
205 putStrLn $ "New ident: " ++ unSnapshotIdent ident
207 putStrLn $ "Track progress at: " ++ loc
209 postBuild `catchAny` print
211 putStrLn "Uploading docs to Stackage Server"
212 res1 <- uploadDocs UploadDocs
214 , udAuthToken = decodeUtf8 token
215 , udDocs = pbDocDir pb
218 putStrLn $ "Doc upload response: " ++ tshow res1
220 ecreds <- tryIO $ readFile "/hackage-creds"
221 case map encodeUtf8 $ words $ decodeUtf8 $ either (const "") id ecreds of
222 [username, password] -> do
223 putStrLn "Uploading as Hackage distro"
224 res2 <- uploadHackageDistro plan username password man
225 putStrLn $ "Distro upload response: " ++ tshow res2
226 _ -> putStrLn "No creds found, skipping Hackage distro upload"
228 putStrLn "Uploading doc map"
229 uploadDocMap UploadDocMap
231 , udmAuthToken = decodeUtf8 token
232 , udmSnapshot = ident
233 , udmDocDir = pbDocDir pb
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list