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
35data BuildType = Nightly | LTS BumpType
36 deriving (Show, Read, Eq, Ord)
38data BumpType = Major | Minor
39 deriving (Show, Read, Eq, Ord)
41data Settings = Settings
43 , planFile :: FilePath
44 , buildDir :: FilePath
46 , title :: Text -> Text -- ^ GHC version -> title
48 , setArgs :: Text -> UploadBundle -> UploadBundle
52getSettings :: Manager -> BuildType -> IO Settings
53getSettings man Nightly = do
54 day <- tshow . utctDay <$> getCurrentTime
55 let slug' = "nightly-" ++ day
56 plan' <- defaultBuildConstraints man >>= newBuildPlan
58 { planFile = fpFromText ("nightly-" ++ day) <.> "yaml"
59 , buildDir = fpFromText $ "builds/stackage-nightly-" ++ day
60 , logDir = fpFromText $ "logs/stackage-nightly-" ++ day
61 , title = \ghcVer -> concat
68 , setArgs = \ghcVer ub -> ub { ubNightly = Just ghcVer }
70 , postBuild = return ()
72getSettings man (LTS bumpType) = do
73 Option mlts <- fmap (fmap getMax) $ runResourceT
75 $$ foldMapC (Option . fmap Max . parseLTSVer . filename)
77 (new, plan') <- case bumpType of
82 Just (LTSVer x _) -> LTSVer (x + 1) 0
83 plan' <- defaultBuildConstraints man >>= newBuildPlan
86 old <- maybe (error "No LTS plans found in current directory") return mlts
87 oldplan <- decodeFileEither (fpToString $ renderLTSVer old)
88 >>= either throwM return
89 let new = incrLTSVer old
90 plan' <- updateBuildPlan oldplan
93 let newfile = renderLTSVer new
97 , buildDir = fpFromText $ "builds/stackage-lts-" ++ tshow new
98 , logDir = fpFromText $ "logs/stackage-lts-" ++ tshow new
99 , title = \ghcVer -> concat
105 , slug = "lts-" ++ tshow new
106 , setArgs = \_ ub -> ub { ubLTS = Just $ tshow new }
109 let git args = withCheckedProcess
110 (proc "git" args) $ \ClosedStream Inherited Inherited ->
112 putStrLn "Committing new LTS file to Git"
113 git ["add", fpToString newfile]
114 git ["commit", "-m", "Added new LTS release: " ++ show new]
115 putStrLn "Pushing to Git repository"
119data LTSVer = LTSVer !Int !Int
121instance Show LTSVer where
122 show (LTSVer x y) = concat [show x, ".", show y]
123incrLTSVer :: LTSVer -> LTSVer
124incrLTSVer (LTSVer x y) = LTSVer x (y + 1)
126parseLTSVer :: FilePath -> Maybe LTSVer
128 w <- stripPrefix "lts-" $ fpToText fp
129 x <- stripSuffix ".yaml" w
130 Right (major, y) <- Just $ decimal x
131 z <- stripPrefix "." y
132 Right (minor, "") <- Just $ decimal z
133 return $ LTSVer major minor
134renderLTSVer :: LTSVer -> FilePath
135renderLTSVer lts = fpFromText $ concat
141-- | Generate and check a new build plan, but do not execute it.
145justCheck = withManager tlsManagerSettings $ \man -> do
146 putStrLn "Loading build constraints"
147 bc <- defaultBuildConstraints man
149 putStrLn "Creating build plan"
150 plan <- newBuildPlan bc
152 putStrLn $ "Writing build plan to check-plan.yaml"
153 encodeFile "check-plan.yaml" plan
155 putStrLn "Checking plan"
158 putStrLn "Plan seems valid!"
160-- | Make a complete plan, build, test and upload bundle, docs and
162completeBuild :: BuildType -> BuildFlags -> IO ()
163completeBuild buildType buildFlags = withManager tlsManagerSettings $ \man -> do
164 hSetBuffering stdout LineBuffering
166 putStrLn $ "Loading settings for: " ++ tshow buildType
167 settings@Settings {..} <- getSettings man buildType
169 putStrLn $ "Writing build plan to: " ++ fpToText planFile
170 encodeFile (fpToString planFile) plan
172 putStrLn "Checking build plan"
175 putStrLn "Performing build"
176 let pb = PerformBuild
178 , pbInstallDest = buildDir
180 , pbLog = hPut stdout
182 , pbGlobalInstall = False
183 , pbEnableTests = bfEnableTests buildFlags
184 , pbEnableLibProfiling = bfEnableLibProfile buildFlags
186 performBuild pb >>= mapM_ putStrLn
188 when (bfDoUpload buildFlags) $
189 finallyUpload settings man pb
191-- | The final part of the complete build process: uploading a bundle,
192-- docs and a distro to hackage.
193finallyUpload :: Settings -> Manager -> PerformBuild -> IO ()
194finallyUpload Settings{..} man pb = do
195 putStrLn "Uploading bundle to Stackage Server"
196 token <- readFile "/auth-token"
198 let ghcVer = display $ siGhcVersion $ bpSystemInfo plan
199 (ident, mloc) <- flip uploadBundle man $ setArgs ghcVer def
200 { ubContents = serverBundle now (title ghcVer) slug plan
201 , ubAuthToken = decodeUtf8 token
203 putStrLn $ "New ident: " ++ unSnapshotIdent ident
205 putStrLn $ "Track progress at: " ++ loc
207 postBuild `catchAny` print
209 putStrLn "Uploading docs to Stackage Server"
210 res1 <- uploadDocs UploadDocs
212 , udAuthToken = decodeUtf8 token
213 , udDocs = pbDocDir pb
216 putStrLn $ "Doc upload response: " ++ tshow res1
218 ecreds <- tryIO $ readFile "/hackage-creds"
219 case map encodeUtf8 $ words $ decodeUtf8 $ either (const "") id ecreds of
220 [username, password] -> do
221 putStrLn "Uploading as Hackage distro"
222 res2 <- uploadHackageDistro plan username password man
223 putStrLn $ "Distro upload response: " ++ tshow res2
224 _ -> putStrLn "No creds found, skipping Hackage distro upload"
226 putStrLn "Uploading doc map"
227 uploadDocMap UploadDocMap
229 , udmAuthToken = decodeUtf8 token
230 , udmSnapshot = ident
231 , 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