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
33data BuildType = Nightly | LTS BumpType
34 deriving (Show, Read, Eq, Ord)
36data BumpType = Major | Minor
37 deriving (Show, Read, Eq, Ord)
39data Settings = Settings
41 , planFile :: FilePath
42 , buildDir :: FilePath
44 , title :: Text -> Text -- ^ GHC version -> title
46 , setArgs :: Text -> UploadBundle -> UploadBundle
50getSettings :: Manager -> BuildType -> IO Settings
51getSettings man Nightly = do
52 day <- tshow . utctDay <$> getCurrentTime
53 let slug' = "nightly-" ++ day
54 plan' <- defaultBuildConstraints man >>= newBuildPlan
56 { planFile = fpFromText ("nightly-" ++ day) <.> "yaml"
57 , buildDir = fpFromText $ "builds/stackage-nightly-" ++ day
58 , logDir = fpFromText $ "logs/stackage-nightly-" ++ day
59 , title = \ghcVer -> concat
66 , setArgs = \ghcVer ub -> ub { ubNightly = Just ghcVer }
68 , postBuild = return ()
70getSettings man (LTS bumpType) = do
71 Option mlts <- fmap (fmap getMax) $ runResourceT
73 $$ foldMapC (Option . fmap Max . parseLTSVer . filename)
75 (new, plan') <- case bumpType of
80 Just (LTSVer x _) -> LTSVer (x + 1) 0
81 plan' <- defaultBuildConstraints man >>= newBuildPlan
84 old <- maybe (error "No LTS plans found in current directory") return mlts
85 oldplan <- decodeFileEither (fpToString $ renderLTSVer old)
86 >>= either throwM return
87 let new = incrLTSVer old
88 plan' <- updateBuildPlan oldplan
91 let newfile = renderLTSVer new
95 , buildDir = fpFromText $ "builds/stackage-lts-" ++ tshow new
96 , logDir = fpFromText $ "logs/stackage-lts-" ++ tshow new
97 , title = \ghcVer -> concat
103 , slug = "lts-" ++ tshow new
104 , setArgs = \_ ub -> ub { ubLTS = Just $ tshow new }
107 let git args = withCheckedProcess
108 (proc "git" args) $ \ClosedStream Inherited Inherited ->
110 putStrLn "Committing new LTS file to Git"
111 git ["add", fpToString newfile]
112 git ["commit", "-m", "Added new LTS release: " ++ show new]
113 putStrLn "Pushing to Git repository"
117data LTSVer = LTSVer !Int !Int
119instance Show LTSVer where
120 show (LTSVer x y) = concat [show x, ".", show y]
121incrLTSVer :: LTSVer -> LTSVer
122incrLTSVer (LTSVer x y) = LTSVer x (y + 1)
124parseLTSVer :: FilePath -> Maybe LTSVer
126 w <- stripPrefix "lts-" $ fpToText fp
127 x <- stripSuffix ".yaml" w
128 Right (major, y) <- Just $ decimal x
129 z <- stripPrefix "." y
130 Right (minor, "") <- Just $ decimal z
131 return $ LTSVer major minor
132renderLTSVer :: LTSVer -> FilePath
133renderLTSVer lts = fpFromText $ concat
139-- | Generate and check a new build plan, but do not execute it.
143justCheck = withManager tlsManagerSettings $ \man -> do
144 putStrLn "Loading build constraints"
145 bc <- defaultBuildConstraints man
147 putStrLn "Creating build plan"
148 plan <- newBuildPlan bc
150 putStrLn $ "Writing build plan to check-plan.yaml"
151 encodeFile "check-plan.yaml" plan
153 putStrLn "Checking plan"
156 putStrLn "Plan seems valid!"
158completeBuild :: BuildType -> BuildFlags -> IO ()
159completeBuild buildType buildFlags = withManager tlsManagerSettings $ \man -> do
160 hSetBuffering stdout LineBuffering
162 putStrLn $ "Loading settings for: " ++ tshow buildType
163 Settings {..} <- getSettings man buildType
165 putStrLn $ "Writing build plan to: " ++ fpToText planFile
166 encodeFile (fpToString planFile) plan
168 putStrLn "Checking build plan"
171 putStrLn "Performing build"
172 let pb = PerformBuild
174 , pbInstallDest = buildDir
176 , pbLog = hPut stdout
178 , pbGlobalInstall = False
179 , pbEnableTests = bfEnableTests buildFlags
181 performBuild pb >>= mapM_ putStrLn
183 putStrLn "Uploading bundle to Stackage Server"
184 token <- readFile "/auth-token"
186 let ghcVer = display $ siGhcVersion $ bpSystemInfo plan
187 (ident, mloc) <- flip uploadBundle man $ setArgs ghcVer def
188 { ubContents = serverBundle now (title ghcVer) slug plan
189 , ubAuthToken = decodeUtf8 token
191 putStrLn $ "New ident: " ++ unSnapshotIdent ident
193 putStrLn $ "Track progress at: " ++ loc
195 postBuild `catchAny` print
197 putStrLn "Uploading docs to Stackage Server"
198 res1 <- uploadDocs UploadDocs
200 , udAuthToken = decodeUtf8 token
201 , udDocs = pbDocDir pb
204 putStrLn $ "Doc upload response: " ++ tshow res1
206 ecreds <- tryIO $ readFile "/hackage-creds"
207 case map encodeUtf8 $ words $ decodeUtf8 $ either (const "") id ecreds of
208 [username, password] -> do
209 putStrLn "Uploading as Hackage distro"
210 res2 <- uploadHackageDistro plan username password man
211 putStrLn $ "Distro upload response: " ++ tshow res2
212 _ -> putStrLn "No creds found, skipping Hackage distro upload"
214 putStrLn "Uploading doc map"
215 uploadDocMap UploadDocMap
217 , udmAuthToken = decodeUtf8 token
218 , udmSnapshot = ident
219 , 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